From ea054cae0e52473119e519474f1f24e6749e5204 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 13 Dec 2024 19:48:51 +0000 Subject: [PATCH 01/35] B-21507 Add descriptions for POE/POD Locations in swagger. --- pkg/gen/ghcapi/embedded_spec.go | 4 +- .../mto_shipment/update_m_t_o_shipment.go | 1 + pkg/gen/primeapi/embedded_spec.go | 70 ++++- pkg/gen/primev3api/embedded_spec.go | 246 +++++++++++++++++- swagger-def/ghc.yaml | 1 + swagger/ghc.yaml | 1 + swagger/prime.yaml | 27 +- swagger/prime_v3.yaml | 106 +++++++- 8 files changed, 444 insertions(+), 12 deletions(-) diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index 5f49076d209..f96b168f451 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -1873,7 +1873,7 @@ func init() { }, "/move_task_orders/{moveTaskOrderID}/mto_shipments/{shipmentID}": { "patch": { - "description": "Updates a specified MTO shipment.\nRequired fields include:\n* MTO Shipment ID required in path\n* If-Match required in headers\n* No fields required in body\nOptional fields include:\n* New shipment status type\n* Shipment Type\n* Customer requested pick-up date\n* Pick-up Address\n* Delivery Address\n* Secondary Pick-up Address\n* SecondaryDelivery Address\n* Delivery Address Type\n* Customer Remarks\n* Counselor Remarks\n* Releasing / Receiving agents\n* Actual Pro Gear Weight\n* Actual Spouse Pro Gear Weight\n", + "description": "Updates a specified MTO shipment.\nRequired fields include:\n* MTO Shipment ID required in path\n* If-Match required in headers\n* No fields required in body\nOptional fields include:\n* New shipment status type\n* Shipment Type\n* Customer requested pick-up date\n* Pick-up Address\n* Delivery Address\n* Secondary Pick-up Address\n* SecondaryDelivery Address\n* Delivery Address Type\n* Customer Remarks\n* Counselor Remarks\n* Releasing / Receiving agents\n* Actual Pro Gear Weight\n* Actual Spouse Pro Gear Weight\n* Location of the POE/POD\n", "consumes": [ "application/json" ], @@ -17349,7 +17349,7 @@ func init() { }, "/move_task_orders/{moveTaskOrderID}/mto_shipments/{shipmentID}": { "patch": { - "description": "Updates a specified MTO shipment.\nRequired fields include:\n* MTO Shipment ID required in path\n* If-Match required in headers\n* No fields required in body\nOptional fields include:\n* New shipment status type\n* Shipment Type\n* Customer requested pick-up date\n* Pick-up Address\n* Delivery Address\n* Secondary Pick-up Address\n* SecondaryDelivery Address\n* Delivery Address Type\n* Customer Remarks\n* Counselor Remarks\n* Releasing / Receiving agents\n* Actual Pro Gear Weight\n* Actual Spouse Pro Gear Weight\n", + "description": "Updates a specified MTO shipment.\nRequired fields include:\n* MTO Shipment ID required in path\n* If-Match required in headers\n* No fields required in body\nOptional fields include:\n* New shipment status type\n* Shipment Type\n* Customer requested pick-up date\n* Pick-up Address\n* Delivery Address\n* Secondary Pick-up Address\n* SecondaryDelivery Address\n* Delivery Address Type\n* Customer Remarks\n* Counselor Remarks\n* Releasing / Receiving agents\n* Actual Pro Gear Weight\n* Actual Spouse Pro Gear Weight\n* Location of the POE/POD\n", "consumes": [ "application/json" ], diff --git a/pkg/gen/ghcapi/ghcoperations/mto_shipment/update_m_t_o_shipment.go b/pkg/gen/ghcapi/ghcoperations/mto_shipment/update_m_t_o_shipment.go index eb0db5e29ab..2ad855d4d8b 100644 --- a/pkg/gen/ghcapi/ghcoperations/mto_shipment/update_m_t_o_shipment.go +++ b/pkg/gen/ghcapi/ghcoperations/mto_shipment/update_m_t_o_shipment.go @@ -53,6 +53,7 @@ Optional fields include: * Releasing / Receiving agents * Actual Pro Gear Weight * Actual Spouse Pro Gear Weight +* Location of the POE/POD */ type UpdateMTOShipment struct { Context *middleware.Context diff --git a/pkg/gen/primeapi/embedded_spec.go b/pkg/gen/primeapi/embedded_spec.go index eafb712633b..457816279b9 100644 --- a/pkg/gen/primeapi/embedded_spec.go +++ b/pkg/gen/primeapi/embedded_spec.go @@ -1791,7 +1791,7 @@ func init() { "x-formatting": "weight", "example": 500 }, - "ubAllowance": { + "unaccompaniedBaggageAllowance": { "description": "The amount of weight in pounds that the move is entitled for shipment types of Unaccompanied Baggage.", "type": "integer", "x-nullable": true, @@ -3892,12 +3892,41 @@ func init() { }, "discriminator": "modelType" }, + "UpdateMTOServiceItemInternationalPortFSC": { + "description": "Subtype used to provide the port for fuel surcharge. This is not creating a new service item but rather updating an existing service item.\n", + "allOf": [ + { + "$ref": "#/definitions/UpdateMTOServiceItem" + }, + { + "type": "object", + "properties": { + "portCode": { + "description": "Port used for the shipment. Relevant for moving (PODFSC \u0026 POEFSC) service items.", + "type": "string", + "x-nullable": true, + "x-omitempty": false, + "example": "PDX" + }, + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "PODFSC", + "POEFSC" + ] + } + } + } + ] + }, "UpdateMTOServiceItemModelType": { - "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DDFSIT - UpdateMTOServiceItemSIT\n * DDASIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DOSFSC - UpdateMTOServiceItemSIT\n * DDSFSC - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n\nThe documentation will then update with the supported fields.\n", + "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DDFSIT - UpdateMTOServiceItemSIT\n * DDASIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DOSFSC - UpdateMTOServiceItemSIT\n * DDSFSC - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * PODFSC - UpdateMTOServiceItemInternationalPortFSC\n * POEFSC - UpdateMTOServiceItemInternationalPortFSC\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "UpdateMTOServiceItemSIT", - "UpdateMTOServiceItemShuttle" + "UpdateMTOServiceItemShuttle", + "UpdateMTOServiceItemInternationalPortFSC" ] }, "UpdateMTOServiceItemSIT": { @@ -6621,7 +6650,7 @@ func init() { "x-formatting": "weight", "example": 500 }, - "ubAllowance": { + "unaccompaniedBaggageAllowance": { "description": "The amount of weight in pounds that the move is entitled for shipment types of Unaccompanied Baggage.", "type": "integer", "x-nullable": true, @@ -8727,12 +8756,41 @@ func init() { }, "discriminator": "modelType" }, + "UpdateMTOServiceItemInternationalPortFSC": { + "description": "Subtype used to provide the port for fuel surcharge. This is not creating a new service item but rather updating an existing service item.\n", + "allOf": [ + { + "$ref": "#/definitions/UpdateMTOServiceItem" + }, + { + "type": "object", + "properties": { + "portCode": { + "description": "Port used for the shipment. Relevant for moving (PODFSC \u0026 POEFSC) service items.", + "type": "string", + "x-nullable": true, + "x-omitempty": false, + "example": "PDX" + }, + "reServiceCode": { + "description": "Service code allowed for this model type.", + "type": "string", + "enum": [ + "PODFSC", + "POEFSC" + ] + } + } + } + ] + }, "UpdateMTOServiceItemModelType": { - "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DDFSIT - UpdateMTOServiceItemSIT\n * DDASIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DOSFSC - UpdateMTOServiceItemSIT\n * DDSFSC - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n\nThe documentation will then update with the supported fields.\n", + "description": "Using this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DDDSIT - UpdateMTOServiceItemSIT\n * DDFSIT - UpdateMTOServiceItemSIT\n * DDASIT - UpdateMTOServiceItemSIT\n * DOPSIT - UpdateMTOServiceItemSIT\n * DOASIT - UpdateMTOServiceItemSIT\n * DOFSIT - UpdateMTOServiceItemSIT\n * DOSFSC - UpdateMTOServiceItemSIT\n * DDSFSC - UpdateMTOServiceItemSIT\n * DDSHUT - UpdateMTOServiceItemShuttle\n * DOSHUT - UpdateMTOServiceItemShuttle\n * PODFSC - UpdateMTOServiceItemInternationalPortFSC\n * POEFSC - UpdateMTOServiceItemInternationalPortFSC\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "UpdateMTOServiceItemSIT", - "UpdateMTOServiceItemShuttle" + "UpdateMTOServiceItemShuttle", + "UpdateMTOServiceItemInternationalPortFSC" ] }, "UpdateMTOServiceItemSIT": { diff --git a/pkg/gen/primev3api/embedded_spec.go b/pkg/gen/primev3api/embedded_spec.go index 5c74db9c476..01cffcd599e 100644 --- a/pkg/gen/primev3api/embedded_spec.go +++ b/pkg/gen/primev3api/embedded_spec.go @@ -1189,7 +1189,7 @@ func init() { "x-formatting": "weight", "example": 500 }, - "ubAllowance": { + "unaccompaniedBaggageAllowance": { "description": "The amount of weight in pounds that the move is entitled for shipment types of Unaccompanied Baggage.", "type": "integer", "x-nullable": true, @@ -1965,6 +1965,12 @@ func init() { "description": "Email or ID of the person who will be contacted in the event of questions or concerns about this update. May be the person performing the update, or someone else working with the Prime contractor.\n", "type": "string" }, + "portOfDebarkation": { + "$ref": "#/definitions/Port" + }, + "portOfEmbarkation": { + "$ref": "#/definitions/Port" + }, "ppmShipment": { "$ref": "#/definitions/PPMShipment" }, @@ -2976,6 +2982,115 @@ func init() { "$ref": "#/definitions/PaymentServiceItem" } }, + "Port": { + "description": "A port that is used to move an international shipment.", + "type": "object", + "properties": { + "city": { + "type": "string", + "example": "PORTLAND" + }, + "country": { + "description": "Two-letter country code", + "type": "string", + "pattern": "^[A-Z]{2}$", + "example": "US" + }, + "county": { + "type": "string", + "example": "MULTNOMAH" + }, + "id": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" + }, + "portCode": { + "description": "3 or 4 digit port code", + "type": "string", + "example": "0431" + }, + "portName": { + "description": "Name of the port", + "type": "string", + "example": "PORTLAND INTL" + }, + "portType": { + "description": "Port type A (Air), B (Border Crossing), S (Sea)", + "type": "string", + "enum": [ + "A", + "P", + "S" + ] + }, + "state": { + "description": "US state", + "type": "string", + "enum": [ + "AL", + "AK", + "AR", + "AZ", + "CA", + "CO", + "CT", + "DC", + "DE", + "FL", + "GA", + "HI", + "IA", + "ID", + "IL", + "IN", + "KS", + "KY", + "LA", + "MA", + "MD", + "ME", + "MI", + "MN", + "MO", + "MS", + "MT", + "NC", + "ND", + "NE", + "NH", + "NJ", + "NM", + "NV", + "NY", + "OH", + "OK", + "OR", + "PA", + "RI", + "SC", + "SD", + "TN", + "TX", + "UT", + "VA", + "VT", + "WA", + "WI", + "WV", + "WY" + ], + "example": "OR" + }, + "zip": { + "type": "string", + "format": "zip", + "title": "ZIP", + "pattern": "^(\\d{5}([\\-]\\d{4})?)$", + "example": "99501" + } + } + }, "ProofOfServiceDoc": { "type": "object", "properties": { @@ -3668,6 +3783,12 @@ func init() { "description": "Email or ID of the person who will be contacted in the event of questions or concerns about this update. May be the person performing the update, or someone else working with the Prime contractor.\n", "type": "string" }, + "portOfDebarkation": { + "$ref": "#/definitions/Port" + }, + "portOfEmbarkation": { + "$ref": "#/definitions/Port" + }, "ppmShipment": { "$ref": "#/definitions/UpdatePPMShipment" }, @@ -5307,7 +5428,7 @@ func init() { "x-formatting": "weight", "example": 500 }, - "ubAllowance": { + "unaccompaniedBaggageAllowance": { "description": "The amount of weight in pounds that the move is entitled for shipment types of Unaccompanied Baggage.", "type": "integer", "x-nullable": true, @@ -6083,6 +6204,12 @@ func init() { "description": "Email or ID of the person who will be contacted in the event of questions or concerns about this update. May be the person performing the update, or someone else working with the Prime contractor.\n", "type": "string" }, + "portOfDebarkation": { + "$ref": "#/definitions/Port" + }, + "portOfEmbarkation": { + "$ref": "#/definitions/Port" + }, "ppmShipment": { "$ref": "#/definitions/PPMShipment" }, @@ -7094,6 +7221,115 @@ func init() { "$ref": "#/definitions/PaymentServiceItem" } }, + "Port": { + "description": "A port that is used to move an international shipment.", + "type": "object", + "properties": { + "city": { + "type": "string", + "example": "PORTLAND" + }, + "country": { + "description": "Two-letter country code", + "type": "string", + "pattern": "^[A-Z]{2}$", + "example": "US" + }, + "county": { + "type": "string", + "example": "MULTNOMAH" + }, + "id": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" + }, + "portCode": { + "description": "3 or 4 digit port code", + "type": "string", + "example": "0431" + }, + "portName": { + "description": "Name of the port", + "type": "string", + "example": "PORTLAND INTL" + }, + "portType": { + "description": "Port type A (Air), B (Border Crossing), S (Sea)", + "type": "string", + "enum": [ + "A", + "P", + "S" + ] + }, + "state": { + "description": "US state", + "type": "string", + "enum": [ + "AL", + "AK", + "AR", + "AZ", + "CA", + "CO", + "CT", + "DC", + "DE", + "FL", + "GA", + "HI", + "IA", + "ID", + "IL", + "IN", + "KS", + "KY", + "LA", + "MA", + "MD", + "ME", + "MI", + "MN", + "MO", + "MS", + "MT", + "NC", + "ND", + "NE", + "NH", + "NJ", + "NM", + "NV", + "NY", + "OH", + "OK", + "OR", + "PA", + "RI", + "SC", + "SD", + "TN", + "TX", + "UT", + "VA", + "VT", + "WA", + "WI", + "WV", + "WY" + ], + "example": "OR" + }, + "zip": { + "type": "string", + "format": "zip", + "title": "ZIP", + "pattern": "^(\\d{5}([\\-]\\d{4})?)$", + "example": "99501" + } + } + }, "ProofOfServiceDoc": { "type": "object", "properties": { @@ -7788,6 +8024,12 @@ func init() { "description": "Email or ID of the person who will be contacted in the event of questions or concerns about this update. May be the person performing the update, or someone else working with the Prime contractor.\n", "type": "string" }, + "portOfDebarkation": { + "$ref": "#/definitions/Port" + }, + "portOfEmbarkation": { + "$ref": "#/definitions/Port" + }, "ppmShipment": { "$ref": "#/definitions/UpdatePPMShipment" }, diff --git a/swagger-def/ghc.yaml b/swagger-def/ghc.yaml index a0e8923ec1a..a4e3f65e433 100644 --- a/swagger-def/ghc.yaml +++ b/swagger-def/ghc.yaml @@ -1021,6 +1021,7 @@ paths: * Releasing / Receiving agents * Actual Pro Gear Weight * Actual Spouse Pro Gear Weight + * Location of the POE/POD consumes: - application/json produces: diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index 531f91964c6..c952c4f7ae9 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -1068,6 +1068,7 @@ paths: * Releasing / Receiving agents * Actual Pro Gear Weight * Actual Spouse Pro Gear Weight + * Location of the POE/POD consumes: - application/json produces: diff --git a/swagger/prime.yaml b/swagger/prime.yaml index afc8f3ec906..3faac8da757 100644 --- a/swagger/prime.yaml +++ b/swagger/prime.yaml @@ -2326,12 +2326,15 @@ definitions: * DDSFSC - UpdateMTOServiceItemSIT * DDSHUT - UpdateMTOServiceItemShuttle * DOSHUT - UpdateMTOServiceItemShuttle + * PODFSC - UpdateMTOServiceItemInternationalPortFSC + * POEFSC - UpdateMTOServiceItemInternationalPortFSC The documentation will then update with the supported fields. type: string enum: - UpdateMTOServiceItemSIT - UpdateMTOServiceItemShuttle + - UpdateMTOServiceItemInternationalPortFSC UpdateMTOServiceItemShuttle: description: > Subtype used to provide the estimated weight and actual weight for @@ -2463,6 +2466,28 @@ definitions: description: Indicates if "Approvals Requested" status is being requested. type: boolean x-nullable: true + UpdateMTOServiceItemInternationalPortFSC: + description: > + Subtype used to provide the port for fuel surcharge. This is not creating + a new service item but rather updating an existing service item. + allOf: + - $ref: '#/definitions/UpdateMTOServiceItem' + - type: object + properties: + portCode: + type: string + example: PDX + description: >- + Port used for the shipment. Relevant for moving (PODFSC & POEFSC) + service items. + x-nullable: true + x-omitempty: false + reServiceCode: + type: string + description: Service code allowed for this model type. + enum: + - PODFSC + - POEFSC UpdateMTOShipment: properties: actualProGearWeight: @@ -2934,7 +2959,7 @@ definitions: type: integer x-formatting: weight x-nullable: true - ubAllowance: + unaccompaniedBaggageAllowance: type: integer example: 3 x-nullable: true diff --git a/swagger/prime_v3.yaml b/swagger/prime_v3.yaml index a88107d16e6..005c6f966c4 100644 --- a/swagger/prime_v3.yaml +++ b/swagger/prime_v3.yaml @@ -1312,6 +1312,10 @@ definitions: x-nullable: true ppmShipment: $ref: '#/definitions/UpdatePPMShipment' + portOfEmbarkation: + $ref: '#/definitions/Port' + portOfDebarkation: + $ref: '#/definitions/Port' UpdateMTOShipmentStatus: description: >- Contains the statuses available to the Prime when updating the state of a @@ -1700,7 +1704,7 @@ definitions: type: integer x-formatting: weight x-nullable: true - ubAllowance: + unaccompaniedBaggageAllowance: type: integer example: 3 x-nullable: true @@ -3097,6 +3101,102 @@ definitions: - originalAddress - newAddress - contractorRemarks + Port: + description: A port that is used to move an international shipment. + type: object + properties: + id: + type: string + format: uuid + example: c56a4180-65aa-42ec-a945-5fd21dec0538 + portType: + type: string + description: Port type A (Air), B (Border Crossing), S (Sea) + enum: + - A + - P + - S + portCode: + type: string + description: 3 or 4 digit port code + example: '0431' + portName: + type: string + description: Name of the port + example: PORTLAND INTL + city: + type: string + example: PORTLAND + county: + type: string + example: MULTNOMAH + state: + type: string + description: US state + example: OR + enum: + - AL + - AK + - AR + - AZ + - CA + - CO + - CT + - DC + - DE + - FL + - GA + - HI + - IA + - ID + - IL + - IN + - KS + - KY + - LA + - MA + - MD + - ME + - MI + - MN + - MO + - MS + - MT + - NC + - ND + - NE + - NH + - NJ + - NM + - NV + - NY + - OH + - OK + - OR + - PA + - RI + - SC + - SD + - TN + - TX + - UT + - VA + - VT + - WA + - WI + - WV + - WY + zip: + type: string + format: zip + title: ZIP + example: '99501' + pattern: ^(\d{5}([\-]\d{4})?)$ + country: + type: string + example: US + pattern: ^[A-Z]{2}$ + description: Two-letter country code MTOShipmentWithoutServiceItems: type: object properties: @@ -3383,6 +3483,10 @@ definitions: description: >- Single-letter designator for domestic (d) or international (i) shipments + portOfDebarkation: + $ref: '#/definitions/Port' + portOfEmbarkation: + $ref: '#/definitions/Port' MTOShipmentsWithoutServiceObjects: description: A list of shipments without their associated service items. items: From f229337c2fe712dca3ab372584cd90d32cddcc4a Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Wed, 18 Dec 2024 15:01:03 +0000 Subject: [PATCH 02/35] B-21507 Update API call to pull Port info Update MTOShipment.yaml to include Port --- pkg/services/mto_shipment/mto_shipment_fetcher.go | 2 ++ swagger-def/definitions/MTOShipment.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/pkg/services/mto_shipment/mto_shipment_fetcher.go b/pkg/services/mto_shipment/mto_shipment_fetcher.go index 6796fec5b30..77a1b217b2a 100644 --- a/pkg/services/mto_shipment/mto_shipment_fetcher.go +++ b/pkg/services/mto_shipment/mto_shipment_fetcher.go @@ -53,6 +53,8 @@ func (f mtoShipmentFetcher) ListMTOShipments(appCtx appcontext.AppContext, moveI "SecondaryDeliveryAddress.Country", "TertiaryDeliveryAddress.Country", "MTOServiceItems.Dimensions", + "MTOServiceItems.PODLocation.Port", + "MTOServiceItems.POELocation.Port", "BoatShipment", "MobileHome", "PPMShipment.W2Address", diff --git a/swagger-def/definitions/MTOShipment.yaml b/swagger-def/definitions/MTOShipment.yaml index 2e3f55c6fbc..1b9ac8ed8fb 100644 --- a/swagger-def/definitions/MTOShipment.yaml +++ b/swagger-def/definitions/MTOShipment.yaml @@ -191,6 +191,8 @@ properties: storageFacility: x-nullable: true $ref: 'StorageFacility.yaml' + port: + $ref: 'Port.yaml' ppmShipment: $ref: 'PPMShipment.yaml' boatShipment: From deeb1d575b56be26482026b409d6ee77cb6829ea Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Thu, 19 Dec 2024 19:16:13 +0000 Subject: [PATCH 03/35] B-21507 Add POE/POD Location to MTOShipment payload Make methods to pull the port location into the payload update swagger definitions for POE/POD locations --- pkg/gen/ghcapi/embedded_spec.go | 358 +++++++++++++++- pkg/gen/ghcmessages/m_t_o_shipment.go | 153 +++++++ pkg/gen/ghcmessages/port.go | 385 ++++++++++++++++++ pkg/gen/primeapi/embedded_spec.go | 12 +- pkg/gen/primev3api/embedded_spec.go | 12 +- .../internal/payloads/model_to_payload.go | 45 ++ swagger-def/definitions/MTOShipment.yaml | 4 + swagger/ghc.yaml | 161 +++++++- swagger/prime.yaml | 4 + swagger/prime_v3.yaml | 4 + 10 files changed, 1120 insertions(+), 18 deletions(-) create mode 100644 pkg/gen/ghcmessages/port.go diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index f96b168f451..413f047e8be 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -4466,7 +4466,7 @@ func init() { }, { "type": "string", - "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role. The parameter is ignored if the requesting user does not have the necessary role.\n", + "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role or a secondary transportation office assignment. The parameter is ignored if the requesting user does not have the necessary role or assignment.\n", "name": "viewAsGBLOC", "in": "query" }, @@ -4510,6 +4510,12 @@ func init() { "description": "Only used for Services Counseling queue. If true, show PPM moves origin locations that are ready for closeout. Otherwise, show all other moves origin locations.", "name": "needsPPMCloseout", "in": "query" + }, + { + "type": "string", + "description": "Used to return an origins list for a GBLOC other than the default of the current user. Requires the HQ role or a secondary transportation office assignment. The parameter is ignored if the requesting user does not have the necessary role or assignment.", + "name": "viewAsGBLOC", + "in": "query" } ], "responses": { @@ -4657,7 +4663,7 @@ func init() { }, { "type": "string", - "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role. The parameter is ignored if the requesting user does not have the necessary role.\n", + "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role or a secondary transportation office assignment. The parameter is ignored if the requesting user does not have the necessary role or assignment.\n", "name": "viewAsGBLOC", "in": "query" }, @@ -4823,7 +4829,7 @@ func init() { }, { "type": "string", - "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role. The parameter is ignored if the requesting user does not have the necessary role.\n", + "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role or a secondary transportation office assignment. The parameter is ignored if the requesting user does not have the necessary role or assignment.\n", "name": "viewAsGBLOC", "in": "query" } @@ -9632,6 +9638,15 @@ func init() { "x-nullable": true, "$ref": "#/definitions/Address" }, + "podLocation": { + "$ref": "#/definitions/Port" + }, + "poeLocation": { + "$ref": "#/definitions/Port" + }, + "port": { + "$ref": "#/definitions/Port" + }, "ppmShipment": { "$ref": "#/definitions/PPMShipment" }, @@ -10641,6 +10656,12 @@ func init() { "transportationOffice": { "$ref": "#/definitions/TransportationOffice" }, + "transportationOfficeAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/TransportationOfficeAssignment" + } + }, "transportationOfficeId": { "type": "string", "format": "uuid" @@ -10956,15 +10977,19 @@ func init() { "WOUNDED_WARRIOR", "BLUEBARK", "SAFETY", - "TEMPORARY_DUTY" + "TEMPORARY_DUTY", + "EARLY_RETURN_OF_DEPENDENTS", + "STUDENT_TRAVEL" ], "x-display-value": { "BLUEBARK": "BLUEBARK", + "EARLY_RETURN_OF_DEPENDENTS": "Early Return of Dependents", "LOCAL_MOVE": "Local Move", "PERMANENT_CHANGE_OF_STATION": "Permanent Change Of Station", "RETIREMENT": "Retirement", "SAFETY": "Safety", "SEPARATION": "Separation", + "STUDENT_TRAVEL": "Student Travel", "TEMPORARY_DUTY": "Temporary Duty (TDY)", "WOUNDED_WARRIOR": "Wounded Warrior" } @@ -12188,6 +12213,115 @@ func init() { "$ref": "#/definitions/PaymentServiceItem" } }, + "Port": { + "description": "A port that is used to move an international shipment.", + "type": "object", + "properties": { + "city": { + "type": "string", + "example": "PORTLAND" + }, + "country": { + "description": "Two-letter country code", + "type": "string", + "pattern": "^[A-Z]{2}$", + "example": "US" + }, + "county": { + "type": "string", + "example": "MULTNOMAH" + }, + "id": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" + }, + "portCode": { + "description": "3 or 4 digit port code", + "type": "string", + "example": "0431" + }, + "portName": { + "description": "Name of the port", + "type": "string", + "example": "PORTLAND INTL" + }, + "portType": { + "description": "Port type A (Air), B (Border Crossing), S (Sea)", + "type": "string", + "enum": [ + "A", + "P", + "S" + ] + }, + "state": { + "description": "US state", + "type": "string", + "enum": [ + "AL", + "AK", + "AR", + "AZ", + "CA", + "CO", + "CT", + "DC", + "DE", + "FL", + "GA", + "HI", + "IA", + "ID", + "IL", + "IN", + "KS", + "KY", + "LA", + "MA", + "MD", + "ME", + "MI", + "MN", + "MO", + "MS", + "MT", + "NC", + "ND", + "NE", + "NH", + "NJ", + "NM", + "NV", + "NY", + "OH", + "OK", + "OR", + "PA", + "RI", + "SC", + "SD", + "TN", + "TX", + "UT", + "VA", + "VT", + "WA", + "WI", + "WV", + "WY" + ], + "example": "OR" + }, + "zip": { + "type": "string", + "format": "zip", + "title": "ZIP", + "pattern": "^(\\d{5}([\\-]\\d{4})?)$", + "example": "99501" + } + } + }, "PostDocumentPayload": { "type": "object", "properties": { @@ -13674,6 +13808,43 @@ func init() { } } }, + "TransportationOfficeAssignment": { + "type": "object", + "required": [ + "officeUserId", + "transportationOfficeId", + "primaryOffice" + ], + "properties": { + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "officeUserId": { + "type": "string", + "format": "uuid", + "example": "c56a4780-65aa-42ec-a945-5fd87dec0538" + }, + "primaryOffice": { + "type": "boolean", + "x-omitempty": false + }, + "transportationOffice": { + "$ref": "#/definitions/TransportationOffice" + }, + "transportationOfficeId": { + "type": "string", + "format": "uuid", + "example": "d67a4780-65aa-42ec-a945-5fd87dec0549" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + } + } + }, "TransportationOffices": { "type": "array", "items": { @@ -20551,7 +20722,7 @@ func init() { }, { "type": "string", - "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role. The parameter is ignored if the requesting user does not have the necessary role.\n", + "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role or a secondary transportation office assignment. The parameter is ignored if the requesting user does not have the necessary role or assignment.\n", "name": "viewAsGBLOC", "in": "query" }, @@ -20601,6 +20772,12 @@ func init() { "description": "Only used for Services Counseling queue. If true, show PPM moves origin locations that are ready for closeout. Otherwise, show all other moves origin locations.", "name": "needsPPMCloseout", "in": "query" + }, + { + "type": "string", + "description": "Used to return an origins list for a GBLOC other than the default of the current user. Requires the HQ role or a secondary transportation office assignment. The parameter is ignored if the requesting user does not have the necessary role or assignment.", + "name": "viewAsGBLOC", + "in": "query" } ], "responses": { @@ -20754,7 +20931,7 @@ func init() { }, { "type": "string", - "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role. The parameter is ignored if the requesting user does not have the necessary role.\n", + "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role or a secondary transportation office assignment. The parameter is ignored if the requesting user does not have the necessary role or assignment.\n", "name": "viewAsGBLOC", "in": "query" }, @@ -20926,7 +21103,7 @@ func init() { }, { "type": "string", - "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role. The parameter is ignored if the requesting user does not have the necessary role.\n", + "description": "Used to return a queue for a GBLOC other than the default of the current user. Requires the HQ role or a secondary transportation office assignment. The parameter is ignored if the requesting user does not have the necessary role or assignment.\n", "name": "viewAsGBLOC", "in": "query" } @@ -26115,6 +26292,15 @@ func init() { "x-nullable": true, "$ref": "#/definitions/Address" }, + "podLocation": { + "$ref": "#/definitions/Port" + }, + "poeLocation": { + "$ref": "#/definitions/Port" + }, + "port": { + "$ref": "#/definitions/Port" + }, "ppmShipment": { "$ref": "#/definitions/PPMShipment" }, @@ -27124,6 +27310,12 @@ func init() { "transportationOffice": { "$ref": "#/definitions/TransportationOffice" }, + "transportationOfficeAssignments": { + "type": "array", + "items": { + "$ref": "#/definitions/TransportationOfficeAssignment" + } + }, "transportationOfficeId": { "type": "string", "format": "uuid" @@ -27439,15 +27631,19 @@ func init() { "WOUNDED_WARRIOR", "BLUEBARK", "SAFETY", - "TEMPORARY_DUTY" + "TEMPORARY_DUTY", + "EARLY_RETURN_OF_DEPENDENTS", + "STUDENT_TRAVEL" ], "x-display-value": { "BLUEBARK": "BLUEBARK", + "EARLY_RETURN_OF_DEPENDENTS": "Early Return of Dependents", "LOCAL_MOVE": "Local Move", "PERMANENT_CHANGE_OF_STATION": "Permanent Change Of Station", "RETIREMENT": "Retirement", "SAFETY": "Safety", "SEPARATION": "Separation", + "STUDENT_TRAVEL": "Student Travel", "TEMPORARY_DUTY": "Temporary Duty (TDY)", "WOUNDED_WARRIOR": "Wounded Warrior" } @@ -28745,6 +28941,115 @@ func init() { "$ref": "#/definitions/PaymentServiceItem" } }, + "Port": { + "description": "A port that is used to move an international shipment.", + "type": "object", + "properties": { + "city": { + "type": "string", + "example": "PORTLAND" + }, + "country": { + "description": "Two-letter country code", + "type": "string", + "pattern": "^[A-Z]{2}$", + "example": "US" + }, + "county": { + "type": "string", + "example": "MULTNOMAH" + }, + "id": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" + }, + "portCode": { + "description": "3 or 4 digit port code", + "type": "string", + "example": "0431" + }, + "portName": { + "description": "Name of the port", + "type": "string", + "example": "PORTLAND INTL" + }, + "portType": { + "description": "Port type A (Air), B (Border Crossing), S (Sea)", + "type": "string", + "enum": [ + "A", + "P", + "S" + ] + }, + "state": { + "description": "US state", + "type": "string", + "enum": [ + "AL", + "AK", + "AR", + "AZ", + "CA", + "CO", + "CT", + "DC", + "DE", + "FL", + "GA", + "HI", + "IA", + "ID", + "IL", + "IN", + "KS", + "KY", + "LA", + "MA", + "MD", + "ME", + "MI", + "MN", + "MO", + "MS", + "MT", + "NC", + "ND", + "NE", + "NH", + "NJ", + "NM", + "NV", + "NY", + "OH", + "OK", + "OR", + "PA", + "RI", + "SC", + "SD", + "TN", + "TX", + "UT", + "VA", + "VT", + "WA", + "WI", + "WV", + "WY" + ], + "example": "OR" + }, + "zip": { + "type": "string", + "format": "zip", + "title": "ZIP", + "pattern": "^(\\d{5}([\\-]\\d{4})?)$", + "example": "99501" + } + } + }, "PostDocumentPayload": { "type": "object", "properties": { @@ -30285,6 +30590,43 @@ func init() { } } }, + "TransportationOfficeAssignment": { + "type": "object", + "required": [ + "officeUserId", + "transportationOfficeId", + "primaryOffice" + ], + "properties": { + "createdAt": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "officeUserId": { + "type": "string", + "format": "uuid", + "example": "c56a4780-65aa-42ec-a945-5fd87dec0538" + }, + "primaryOffice": { + "type": "boolean", + "x-omitempty": false + }, + "transportationOffice": { + "$ref": "#/definitions/TransportationOffice" + }, + "transportationOfficeId": { + "type": "string", + "format": "uuid", + "example": "d67a4780-65aa-42ec-a945-5fd87dec0549" + }, + "updatedAt": { + "type": "string", + "format": "date-time", + "readOnly": true + } + } + }, "TransportationOffices": { "type": "array", "items": { diff --git a/pkg/gen/ghcmessages/m_t_o_shipment.go b/pkg/gen/ghcmessages/m_t_o_shipment.go index 78a6420cee4..144c129df34 100644 --- a/pkg/gen/ghcmessages/m_t_o_shipment.go +++ b/pkg/gen/ghcmessages/m_t_o_shipment.go @@ -151,6 +151,15 @@ type MTOShipment struct { // pickup address PickupAddress *Address `json:"pickupAddress,omitempty"` + // pod location + PodLocation *Port `json:"podLocation,omitempty"` + + // poe location + PoeLocation *Port `json:"poeLocation,omitempty"` + + // port + Port *Port `json:"port,omitempty"` + // ppm shipment PpmShipment *PPMShipment `json:"ppmShipment,omitempty"` @@ -318,6 +327,18 @@ func (m *MTOShipment) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validatePodLocation(formats); err != nil { + res = append(res, err) + } + + if err := m.validatePoeLocation(formats); err != nil { + res = append(res, err) + } + + if err := m.validatePort(formats); err != nil { + res = append(res, err) + } + if err := m.validatePpmShipment(formats); err != nil { res = append(res, err) } @@ -698,6 +719,63 @@ func (m *MTOShipment) validatePickupAddress(formats strfmt.Registry) error { return nil } +func (m *MTOShipment) validatePodLocation(formats strfmt.Registry) error { + if swag.IsZero(m.PodLocation) { // not required + return nil + } + + if m.PodLocation != nil { + if err := m.PodLocation.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("podLocation") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("podLocation") + } + return err + } + } + + return nil +} + +func (m *MTOShipment) validatePoeLocation(formats strfmt.Registry) error { + if swag.IsZero(m.PoeLocation) { // not required + return nil + } + + if m.PoeLocation != nil { + if err := m.PoeLocation.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("poeLocation") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("poeLocation") + } + return err + } + } + + return nil +} + +func (m *MTOShipment) validatePort(formats strfmt.Registry) error { + if swag.IsZero(m.Port) { // not required + return nil + } + + if m.Port != nil { + if err := m.Port.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("port") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("port") + } + return err + } + } + + return nil +} + func (m *MTOShipment) validatePpmShipment(formats strfmt.Registry) error { if swag.IsZero(m.PpmShipment) { // not required return nil @@ -1051,6 +1129,18 @@ func (m *MTOShipment) ContextValidate(ctx context.Context, formats strfmt.Regist res = append(res, err) } + if err := m.contextValidatePodLocation(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidatePoeLocation(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidatePort(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidatePpmShipment(ctx, formats); err != nil { res = append(res, err) } @@ -1276,6 +1366,69 @@ func (m *MTOShipment) contextValidatePickupAddress(ctx context.Context, formats return nil } +func (m *MTOShipment) contextValidatePodLocation(ctx context.Context, formats strfmt.Registry) error { + + if m.PodLocation != nil { + + if swag.IsZero(m.PodLocation) { // not required + return nil + } + + if err := m.PodLocation.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("podLocation") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("podLocation") + } + return err + } + } + + return nil +} + +func (m *MTOShipment) contextValidatePoeLocation(ctx context.Context, formats strfmt.Registry) error { + + if m.PoeLocation != nil { + + if swag.IsZero(m.PoeLocation) { // not required + return nil + } + + if err := m.PoeLocation.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("poeLocation") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("poeLocation") + } + return err + } + } + + return nil +} + +func (m *MTOShipment) contextValidatePort(ctx context.Context, formats strfmt.Registry) error { + + if m.Port != nil { + + if swag.IsZero(m.Port) { // not required + return nil + } + + if err := m.Port.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("port") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("port") + } + return err + } + } + + return nil +} + func (m *MTOShipment) contextValidatePpmShipment(ctx context.Context, formats strfmt.Registry) error { if m.PpmShipment != nil { diff --git a/pkg/gen/ghcmessages/port.go b/pkg/gen/ghcmessages/port.go new file mode 100644 index 00000000000..a2fa6787aa0 --- /dev/null +++ b/pkg/gen/ghcmessages/port.go @@ -0,0 +1,385 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package ghcmessages + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// Port A port that is used to move an international shipment. +// +// swagger:model Port +type Port struct { + + // city + // Example: PORTLAND + City string `json:"city,omitempty"` + + // Two-letter country code + // Example: US + // Pattern: ^[A-Z]{2}$ + Country string `json:"country,omitempty"` + + // county + // Example: MULTNOMAH + County string `json:"county,omitempty"` + + // id + // Example: c56a4180-65aa-42ec-a945-5fd21dec0538 + // Format: uuid + ID strfmt.UUID `json:"id,omitempty"` + + // 3 or 4 digit port code + // Example: 0431 + PortCode string `json:"portCode,omitempty"` + + // Name of the port + // Example: PORTLAND INTL + PortName string `json:"portName,omitempty"` + + // Port type A (Air), B (Border Crossing), S (Sea) + // Enum: [A P S] + PortType string `json:"portType,omitempty"` + + // US state + // Example: OR + // Enum: [AL AK AR AZ CA CO CT DC DE FL GA HI IA ID IL IN KS KY LA MA MD ME MI MN MO MS MT NC ND NE NH NJ NM NV NY OH OK OR PA RI SC SD TN TX UT VA VT WA WI WV WY] + State string `json:"state,omitempty"` + + // ZIP + // Example: 99501 + // Pattern: ^(\d{5}([\-]\d{4})?)$ + Zip string `json:"zip,omitempty"` +} + +// Validate validates this port +func (m *Port) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateCountry(formats); err != nil { + res = append(res, err) + } + + if err := m.validateID(formats); err != nil { + res = append(res, err) + } + + if err := m.validatePortType(formats); err != nil { + res = append(res, err) + } + + if err := m.validateState(formats); err != nil { + res = append(res, err) + } + + if err := m.validateZip(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *Port) validateCountry(formats strfmt.Registry) error { + if swag.IsZero(m.Country) { // not required + return nil + } + + if err := validate.Pattern("country", "body", m.Country, `^[A-Z]{2}$`); err != nil { + return err + } + + return nil +} + +func (m *Port) validateID(formats strfmt.Registry) error { + if swag.IsZero(m.ID) { // not required + return nil + } + + if err := validate.FormatOf("id", "body", "uuid", m.ID.String(), formats); err != nil { + return err + } + + return nil +} + +var portTypePortTypePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["A","P","S"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + portTypePortTypePropEnum = append(portTypePortTypePropEnum, v) + } +} + +const ( + + // PortPortTypeA captures enum value "A" + PortPortTypeA string = "A" + + // PortPortTypeP captures enum value "P" + PortPortTypeP string = "P" + + // PortPortTypeS captures enum value "S" + PortPortTypeS string = "S" +) + +// prop value enum +func (m *Port) validatePortTypeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, portTypePortTypePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *Port) validatePortType(formats strfmt.Registry) error { + if swag.IsZero(m.PortType) { // not required + return nil + } + + // value enum + if err := m.validatePortTypeEnum("portType", "body", m.PortType); err != nil { + return err + } + + return nil +} + +var portTypeStatePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["AL","AK","AR","AZ","CA","CO","CT","DC","DE","FL","GA","HI","IA","ID","IL","IN","KS","KY","LA","MA","MD","ME","MI","MN","MO","MS","MT","NC","ND","NE","NH","NJ","NM","NV","NY","OH","OK","OR","PA","RI","SC","SD","TN","TX","UT","VA","VT","WA","WI","WV","WY"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + portTypeStatePropEnum = append(portTypeStatePropEnum, v) + } +} + +const ( + + // PortStateAL captures enum value "AL" + PortStateAL string = "AL" + + // PortStateAK captures enum value "AK" + PortStateAK string = "AK" + + // PortStateAR captures enum value "AR" + PortStateAR string = "AR" + + // PortStateAZ captures enum value "AZ" + PortStateAZ string = "AZ" + + // PortStateCA captures enum value "CA" + PortStateCA string = "CA" + + // PortStateCO captures enum value "CO" + PortStateCO string = "CO" + + // PortStateCT captures enum value "CT" + PortStateCT string = "CT" + + // PortStateDC captures enum value "DC" + PortStateDC string = "DC" + + // PortStateDE captures enum value "DE" + PortStateDE string = "DE" + + // PortStateFL captures enum value "FL" + PortStateFL string = "FL" + + // PortStateGA captures enum value "GA" + PortStateGA string = "GA" + + // PortStateHI captures enum value "HI" + PortStateHI string = "HI" + + // PortStateIA captures enum value "IA" + PortStateIA string = "IA" + + // PortStateID captures enum value "ID" + PortStateID string = "ID" + + // PortStateIL captures enum value "IL" + PortStateIL string = "IL" + + // PortStateIN captures enum value "IN" + PortStateIN string = "IN" + + // PortStateKS captures enum value "KS" + PortStateKS string = "KS" + + // PortStateKY captures enum value "KY" + PortStateKY string = "KY" + + // PortStateLA captures enum value "LA" + PortStateLA string = "LA" + + // PortStateMA captures enum value "MA" + PortStateMA string = "MA" + + // PortStateMD captures enum value "MD" + PortStateMD string = "MD" + + // PortStateME captures enum value "ME" + PortStateME string = "ME" + + // PortStateMI captures enum value "MI" + PortStateMI string = "MI" + + // PortStateMN captures enum value "MN" + PortStateMN string = "MN" + + // PortStateMO captures enum value "MO" + PortStateMO string = "MO" + + // PortStateMS captures enum value "MS" + PortStateMS string = "MS" + + // PortStateMT captures enum value "MT" + PortStateMT string = "MT" + + // PortStateNC captures enum value "NC" + PortStateNC string = "NC" + + // PortStateND captures enum value "ND" + PortStateND string = "ND" + + // PortStateNE captures enum value "NE" + PortStateNE string = "NE" + + // PortStateNH captures enum value "NH" + PortStateNH string = "NH" + + // PortStateNJ captures enum value "NJ" + PortStateNJ string = "NJ" + + // PortStateNM captures enum value "NM" + PortStateNM string = "NM" + + // PortStateNV captures enum value "NV" + PortStateNV string = "NV" + + // PortStateNY captures enum value "NY" + PortStateNY string = "NY" + + // PortStateOH captures enum value "OH" + PortStateOH string = "OH" + + // PortStateOK captures enum value "OK" + PortStateOK string = "OK" + + // PortStateOR captures enum value "OR" + PortStateOR string = "OR" + + // PortStatePA captures enum value "PA" + PortStatePA string = "PA" + + // PortStateRI captures enum value "RI" + PortStateRI string = "RI" + + // PortStateSC captures enum value "SC" + PortStateSC string = "SC" + + // PortStateSD captures enum value "SD" + PortStateSD string = "SD" + + // PortStateTN captures enum value "TN" + PortStateTN string = "TN" + + // PortStateTX captures enum value "TX" + PortStateTX string = "TX" + + // PortStateUT captures enum value "UT" + PortStateUT string = "UT" + + // PortStateVA captures enum value "VA" + PortStateVA string = "VA" + + // PortStateVT captures enum value "VT" + PortStateVT string = "VT" + + // PortStateWA captures enum value "WA" + PortStateWA string = "WA" + + // PortStateWI captures enum value "WI" + PortStateWI string = "WI" + + // PortStateWV captures enum value "WV" + PortStateWV string = "WV" + + // PortStateWY captures enum value "WY" + PortStateWY string = "WY" +) + +// prop value enum +func (m *Port) validateStateEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, portTypeStatePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *Port) validateState(formats strfmt.Registry) error { + if swag.IsZero(m.State) { // not required + return nil + } + + // value enum + if err := m.validateStateEnum("state", "body", m.State); err != nil { + return err + } + + return nil +} + +func (m *Port) validateZip(formats strfmt.Registry) error { + if swag.IsZero(m.Zip) { // not required + return nil + } + + if err := validate.Pattern("zip", "body", m.Zip, `^(\d{5}([\-]\d{4})?)$`); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this port based on context it is used +func (m *Port) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *Port) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *Port) UnmarshalBinary(b []byte) error { + var res Port + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/gen/primeapi/embedded_spec.go b/pkg/gen/primeapi/embedded_spec.go index 457816279b9..d963da8870d 100644 --- a/pkg/gen/primeapi/embedded_spec.go +++ b/pkg/gen/primeapi/embedded_spec.go @@ -2970,15 +2970,19 @@ func init() { "WOUNDED_WARRIOR", "BLUEBARK", "SAFETY", - "TEMPORARY_DUTY" + "TEMPORARY_DUTY", + "EARLY_RETURN_OF_DEPENDENTS", + "STUDENT_TRAVEL" ], "x-display-value": { "BLUEBARK": "BLUEBARK", + "EARLY_RETURN_OF_DEPENDENTS": "Early Return of Dependents", "LOCAL_MOVE": "Local Move", "PERMANENT_CHANGE_OF_STATION": "Permanent Change Of Station", "RETIREMENT": "Retirement", "SAFETY": "Safety", "SEPARATION": "Separation", + "STUDENT_TRAVEL": "Student Travel", "TEMPORARY_DUTY": "Temporary Duty (TDY)", "WOUNDED_WARRIOR": "Wounded Warrior" } @@ -7829,15 +7833,19 @@ func init() { "WOUNDED_WARRIOR", "BLUEBARK", "SAFETY", - "TEMPORARY_DUTY" + "TEMPORARY_DUTY", + "EARLY_RETURN_OF_DEPENDENTS", + "STUDENT_TRAVEL" ], "x-display-value": { "BLUEBARK": "BLUEBARK", + "EARLY_RETURN_OF_DEPENDENTS": "Early Return of Dependents", "LOCAL_MOVE": "Local Move", "PERMANENT_CHANGE_OF_STATION": "Permanent Change Of Station", "RETIREMENT": "Retirement", "SAFETY": "Safety", "SEPARATION": "Separation", + "STUDENT_TRAVEL": "Student Travel", "TEMPORARY_DUTY": "Temporary Duty (TDY)", "WOUNDED_WARRIOR": "Wounded Warrior" } diff --git a/pkg/gen/primev3api/embedded_spec.go b/pkg/gen/primev3api/embedded_spec.go index 01cffcd599e..c0990b8fa51 100644 --- a/pkg/gen/primev3api/embedded_spec.go +++ b/pkg/gen/primev3api/embedded_spec.go @@ -2349,15 +2349,19 @@ func init() { "WOUNDED_WARRIOR", "BLUEBARK", "SAFETY", - "TEMPORARY_DUTY" + "TEMPORARY_DUTY", + "EARLY_RETURN_OF_DEPENDENTS", + "STUDENT_TRAVEL" ], "x-display-value": { "BLUEBARK": "BLUEBARK", + "EARLY_RETURN_OF_DEPENDENTS": "Early Return of Dependents", "LOCAL_MOVE": "Local Move", "PERMANENT_CHANGE_OF_STATION": "Permanent Change Of Station", "RETIREMENT": "Retirement", "SAFETY": "Safety", "SEPARATION": "Separation", + "STUDENT_TRAVEL": "Student Travel", "TEMPORARY_DUTY": "Temporary Duty (TDY)", "WOUNDED_WARRIOR": "Wounded Warrior" } @@ -6588,15 +6592,19 @@ func init() { "WOUNDED_WARRIOR", "BLUEBARK", "SAFETY", - "TEMPORARY_DUTY" + "TEMPORARY_DUTY", + "EARLY_RETURN_OF_DEPENDENTS", + "STUDENT_TRAVEL" ], "x-display-value": { "BLUEBARK": "BLUEBARK", + "EARLY_RETURN_OF_DEPENDENTS": "Early Return of Dependents", "LOCAL_MOVE": "Local Move", "PERMANENT_CHANGE_OF_STATION": "Permanent Change Of Station", "RETIREMENT": "Retirement", "SAFETY": "Safety", "SEPARATION": "Separation", + "STUDENT_TRAVEL": "Student Travel", "TEMPORARY_DUTY": "Temporary Duty (TDY)", "WOUNDED_WARRIOR": "Wounded Warrior" } diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go index 1cfbe5eec4e..b1898c2ad91 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go @@ -1514,6 +1514,8 @@ func MTOShipment(storer storage.FileStorer, mtoShipment *models.MTOShipment, sit DeliveryAddressUpdate: ShipmentAddressUpdate(mtoShipment.DeliveryAddressUpdate), ShipmentLocator: handlers.FmtStringPtr(mtoShipment.ShipmentLocator), MarketCode: MarketCode(&mtoShipment.MarketCode), + PoeLocation: getPoeLocation(mtoShipment.MTOServiceItems), + PodLocation: getPodLocation(mtoShipment.MTOServiceItems), } if mtoShipment.Distance != nil { @@ -2671,3 +2673,46 @@ func ReServiceItems(reServiceItems models.ReServiceItems) ghcmessages.ReServiceI } return payload } + +// Convert a PortLocation model to Port message +func Port(portLocation *models.PortLocation) *ghcmessages.Port { + return &ghcmessages.Port{ + ID: strfmt.UUID(portLocation.ID.String()), + PortType: portLocation.Port.PortType.String(), + PortCode: portLocation.Port.PortCode, + PortName: portLocation.Port.PortName, + City: portLocation.City.CityName, + County: portLocation.UsPostRegionCity.UsprcCountyNm, + State: portLocation.UsPostRegionCity.UsPostRegion.State.StateName, + Zip: portLocation.UsPostRegionCity.UsprZipID, + Country: portLocation.Country.CountryName, + } +} + +// Get POD/POE info from MTO shipment's service items +func getPoeLocation(mtoServiceItems models.MTOServiceItems) *ghcmessages.Port { + if mtoServiceItems == nil { + return nil + } + var portLocation *ghcmessages.Port + for _, mtoServiceItem := range mtoServiceItems { + if mtoServiceItem.POELocation != nil { + portLocation = Port(mtoServiceItem.POELocation) + } + } + return portLocation +} + +// Get POD/POE info from MTO shipment's service items +func getPodLocation(mtoServiceItems models.MTOServiceItems) *ghcmessages.Port { + if mtoServiceItems == nil { + return nil + } + var portLocation *ghcmessages.Port + for _, mtoServiceItem := range mtoServiceItems { + if mtoServiceItem.PODLocation != nil { + portLocation = Port(mtoServiceItem.PODLocation) + } + } + return portLocation +} diff --git a/swagger-def/definitions/MTOShipment.yaml b/swagger-def/definitions/MTOShipment.yaml index 1b9ac8ed8fb..ecb1b141630 100644 --- a/swagger-def/definitions/MTOShipment.yaml +++ b/swagger-def/definitions/MTOShipment.yaml @@ -219,3 +219,7 @@ properties: - 'i' example: 'd' description: 'Single-letter designator for domestic (d) or international (i) shipments' + podLocation: + $ref: 'Port.yaml' + poeLocation: + $ref: 'Port.yaml' diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index c952c4f7ae9..f91f7538d48 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -3583,8 +3583,9 @@ paths: type: string description: > Used to return a queue for a GBLOC other than the default of the - current user. Requires the HQ role. The parameter is ignored if the - requesting user does not have the necessary role. + current user. Requires the HQ role or a secondary transportation + office assignment. The parameter is ignored if the requesting user + does not have the necessary role or assignment. - in: query name: assignedTo type: string @@ -3620,6 +3621,14 @@ paths: Only used for Services Counseling queue. If true, show PPM moves origin locations that are ready for closeout. Otherwise, show all other moves origin locations. + - in: query + name: viewAsGBLOC + type: string + description: >- + Used to return an origins list for a GBLOC other than the default of + the current user. Requires the HQ role or a secondary transportation + office assignment. The parameter is ignored if the requesting user + does not have the necessary role or assignment. responses: '200': description: Successfully returned all moves matching the criteria @@ -3791,8 +3800,9 @@ paths: type: string description: > Used to return a queue for a GBLOC other than the default of the - current user. Requires the HQ role. The parameter is ignored if the - requesting user does not have the necessary role. + current user. Requires the HQ role or a secondary transportation + office assignment. The parameter is ignored if the requesting user + does not have the necessary role or assignment. - in: query name: assignedTo type: string @@ -3915,8 +3925,9 @@ paths: type: string description: > Used to return a queue for a GBLOC other than the default of the - current user. Requires the HQ role. The parameter is ignored if the - requesting user does not have the necessary role. + current user. Requires the HQ role or a secondary transportation + office assignment. The parameter is ignored if the requesting user + does not have the necessary role or assignment. responses: '200': description: Successfully returned all moves matching the criteria @@ -4679,6 +4690,10 @@ definitions: format: uuid transportationOffice: $ref: '#/definitions/TransportationOffice' + transportationOfficeAssignments: + type: array + items: + $ref: '#/definitions/TransportationOfficeAssignment' active: type: boolean roles: @@ -8296,6 +8311,34 @@ definitions: - address - created_at - updated_at + TransportationOfficeAssignment: + type: object + properties: + officeUserId: + type: string + format: uuid + example: c56a4780-65aa-42ec-a945-5fd87dec0538 + transportationOfficeId: + type: string + format: uuid + example: d67a4780-65aa-42ec-a945-5fd87dec0549 + transportationOffice: + $ref: '#/definitions/TransportationOffice' + primaryOffice: + type: boolean + x-omitempty: false + createdAt: + type: string + format: date-time + readOnly: true + updatedAt: + type: string + format: date-time + readOnly: true + required: + - officeUserId + - transportationOfficeId + - primaryOffice DutyLocation: type: object properties: @@ -8326,6 +8369,8 @@ definitions: - BLUEBARK - SAFETY - TEMPORARY_DUTY + - EARLY_RETURN_OF_DEPENDENTS + - STUDENT_TRAVEL x-display-value: PERMANENT_CHANGE_OF_STATION: Permanent Change Of Station LOCAL_MOVE: Local Move @@ -8335,6 +8380,8 @@ definitions: BLUEBARK: BLUEBARK SAFETY: Safety TEMPORARY_DUTY: Temporary Duty (TDY) + EARLY_RETURN_OF_DEPENDENTS: Early Return of Dependents + STUDENT_TRAVEL: Student Travel Upload: description: An uploaded file. type: object @@ -9189,6 +9236,102 @@ definitions: given SIT service items for an instance of SIT (Either Origin or Destination), grouped by the date they went into SIT and service items limited explicitly to SIT related Re Service Codes. + Port: + description: A port that is used to move an international shipment. + type: object + properties: + id: + type: string + format: uuid + example: c56a4180-65aa-42ec-a945-5fd21dec0538 + portType: + type: string + description: Port type A (Air), B (Border Crossing), S (Sea) + enum: + - A + - P + - S + portCode: + type: string + description: 3 or 4 digit port code + example: '0431' + portName: + type: string + description: Name of the port + example: PORTLAND INTL + city: + type: string + example: PORTLAND + county: + type: string + example: MULTNOMAH + state: + type: string + description: US state + example: OR + enum: + - AL + - AK + - AR + - AZ + - CA + - CO + - CT + - DC + - DE + - FL + - GA + - HI + - IA + - ID + - IL + - IN + - KS + - KY + - LA + - MA + - MD + - ME + - MI + - MN + - MO + - MS + - MT + - NC + - ND + - NE + - NH + - NJ + - NM + - NV + - NY + - OH + - OK + - OR + - PA + - RI + - SC + - SD + - TN + - TX + - UT + - VA + - VT + - WA + - WI + - WV + - WY + zip: + type: string + format: zip + title: ZIP + example: '99501' + pattern: ^(\d{5}([\-]\d{4})?)$ + country: + type: string + example: US + pattern: ^[A-Z]{2}$ + description: Two-letter country code PPMShipmentStatus: description: | Status of the PPM Shipment: @@ -10499,6 +10642,8 @@ definitions: storageFacility: x-nullable: true $ref: '#/definitions/StorageFacility' + port: + $ref: '#/definitions/Port' ppmShipment: $ref: '#/definitions/PPMShipment' boatShipment: @@ -10527,6 +10672,10 @@ definitions: description: >- Single-letter designator for domestic (d) or international (i) shipments + podLocation: + $ref: '#/definitions/Port' + poeLocation: + $ref: '#/definitions/Port' LOATypeNullable: description: The Line of accounting (TAC/SAC) type that will be used for the shipment type: string diff --git a/swagger/prime.yaml b/swagger/prime.yaml index 3faac8da757..41dbd01f69a 100644 --- a/swagger/prime.yaml +++ b/swagger/prime.yaml @@ -3040,6 +3040,8 @@ definitions: - BLUEBARK - SAFETY - TEMPORARY_DUTY + - EARLY_RETURN_OF_DEPENDENTS + - STUDENT_TRAVEL x-display-value: PERMANENT_CHANGE_OF_STATION: Permanent Change Of Station LOCAL_MOVE: Local Move @@ -3049,6 +3051,8 @@ definitions: BLUEBARK: BLUEBARK SAFETY: Safety TEMPORARY_DUTY: Temporary Duty (TDY) + EARLY_RETURN_OF_DEPENDENTS: Early Return of Dependents + STUDENT_TRAVEL: Student Travel Order: type: object required: diff --git a/swagger/prime_v3.yaml b/swagger/prime_v3.yaml index 005c6f966c4..f4d30feeb6f 100644 --- a/swagger/prime_v3.yaml +++ b/swagger/prime_v3.yaml @@ -1785,6 +1785,8 @@ definitions: - BLUEBARK - SAFETY - TEMPORARY_DUTY + - EARLY_RETURN_OF_DEPENDENTS + - STUDENT_TRAVEL x-display-value: PERMANENT_CHANGE_OF_STATION: Permanent Change Of Station LOCAL_MOVE: Local Move @@ -1794,6 +1796,8 @@ definitions: BLUEBARK: BLUEBARK SAFETY: Safety TEMPORARY_DUTY: Temporary Duty (TDY) + EARLY_RETURN_OF_DEPENDENTS: Early Return of Dependents + STUDENT_TRAVEL: Student Travel Order: type: object required: From a416aaa504718ca1ac72680f6b756b14f3c39187 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Mon, 23 Dec 2024 20:46:06 +0000 Subject: [PATCH 04/35] B-21507 Display Port Location and data on frontend MTO page --- .envrc | 2 +- .../Office/ShipmentAddresses/ShipmentAddresses.jsx | 2 ++ .../Office/ShipmentDetails/ShipmentDetailsMain.jsx | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.envrc b/.envrc index 3891c5b8d85..02c400ca703 100644 --- a/.envrc +++ b/.envrc @@ -154,7 +154,7 @@ export FEATURE_FLAG_NTS=true export FEATURE_FLAG_NTSR=true export FEATURE_FLAG_BOAT=true export FEATURE_FLAG_MOBILE_HOME=true -export FEATURE_FLAG_UNACCOMPANIED_BAGGAGE=false +export FEATURE_FLAG_UNACCOMPANIED_BAGGAGE=true # Feature flag to allow AK to be entered as a state export FEATURE_FLAG_ENABLE_ALASKA=true diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx index 34b8f0c791d..83b69434ec5 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx @@ -25,6 +25,7 @@ const ShipmentAddresses = ({ handleShowDiversionModal, shipmentInfo, isMoveLocked, + poeLocation, }) => { let pickupHeader; let destinationHeader; @@ -85,6 +86,7 @@ const ShipmentAddresses = ({ icon={} data-testid="pickupDestinationAddress" /> + ); }; diff --git a/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx b/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx index 430d0808f60..f0c01c85530 100644 --- a/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx +++ b/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx @@ -67,6 +67,7 @@ const ShipmentDetailsMain = ({ storageInTransit, shipmentType, storageFacility, + poeLocation, } = shipment; const { originDutyLocationAddress, destinationDutyLocationAddress } = dutyLocationAddresses; @@ -135,6 +136,7 @@ const ShipmentDetailsMain = ({ let pickupActualDate; let plannedMoveDate; let actualMoveDate; + let displayPoeLocation; switch (shipmentType) { case SHIPMENT_OPTIONS.HHG: @@ -144,6 +146,7 @@ const ShipmentDetailsMain = ({ weightResult = primeEstimatedWeight; displayedPickupAddress = pickupAddress; displayedDeliveryAddress = destinationAddress || destinationDutyLocationAddress; + displayPoeLocation = poeLocation.portCode; break; case SHIPMENT_OPTIONS.NTS: pickupRequestedDate = requestedPickupDate; @@ -175,6 +178,7 @@ const ShipmentDetailsMain = ({ weightResult = primeEstimatedWeight; displayedPickupAddress = pickupAddress; displayedDeliveryAddress = destinationAddress || destinationDutyLocationAddress; + displayPoeLocation = poeLocation.portCode; break; } @@ -260,6 +264,7 @@ const ShipmentDetailsMain = ({ }} handleShowDiversionModal={handleShowDiversionModal} isMoveLocked={isMoveLocked} + poeLocation={displayPoeLocation} /> Date: Mon, 23 Dec 2024 21:58:07 +0000 Subject: [PATCH 05/35] B-21507 Pull the port location back in mto_shipment_fetcher --- pkg/services/mto_shipment/mto_shipment_fetcher.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pkg/services/mto_shipment/mto_shipment_fetcher.go b/pkg/services/mto_shipment/mto_shipment_fetcher.go index 77a1b217b2a..fa0f5807da3 100644 --- a/pkg/services/mto_shipment/mto_shipment_fetcher.go +++ b/pkg/services/mto_shipment/mto_shipment_fetcher.go @@ -148,6 +148,21 @@ func (f mtoShipmentFetcher) ListMTOShipments(appCtx appcontext.AppContext, moveI return nil, err } shipments[i].MTOAgents = agents + + for _, serviceItem := range shipments[i].MTOServiceItems { + if serviceItem.PODLocation != nil { + loadErr := appCtx.DB().Load(serviceItem.PODLocation, "City", "Country", "UsPostRegionCity.UsPostRegion.State") + if loadErr != nil { + return nil, loadErr + } + } + if serviceItem.POELocation != nil { + loadErr := appCtx.DB().Load(serviceItem.POELocation, "City", "Country", "UsPostRegionCity.UsPostRegion.State") + if loadErr != nil { + return nil, loadErr + } + } + } } return shipments, nil From 6ea7a0786d1516f6629b20fe9564b368d13600f6 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Mon, 23 Dec 2024 22:50:28 +0000 Subject: [PATCH 06/35] B-21507 Add shipment display function for ports --- pkg/services/mto_shipment/mto_shipment_fetcher.go | 1 + .../Office/ShipmentAddresses/ShipmentAddresses.jsx | 4 ++-- .../Office/ShipmentDetails/ShipmentDetailsMain.jsx | 4 ++-- src/utils/shipmentDisplay.jsx | 12 ++++++++++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/pkg/services/mto_shipment/mto_shipment_fetcher.go b/pkg/services/mto_shipment/mto_shipment_fetcher.go index fa0f5807da3..01a19c9fbdb 100644 --- a/pkg/services/mto_shipment/mto_shipment_fetcher.go +++ b/pkg/services/mto_shipment/mto_shipment_fetcher.go @@ -149,6 +149,7 @@ func (f mtoShipmentFetcher) ListMTOShipments(appCtx appcontext.AppContext, moveI } shipments[i].MTOAgents = agents + //Pull the port location info back for _, serviceItem := range shipments[i].MTOServiceItems { if serviceItem.PODLocation != nil { loadErr := appCtx.DB().Load(serviceItem.PODLocation, "City", "Country", "UsPostRegionCity.UsPostRegion.State") diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx index 83b69434ec5..0badbd9682f 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx @@ -5,7 +5,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button } from '@trussworks/react-uswds'; import { AddressShape } from '../../../types/address'; -import { formatAddress, formatCityStateAndPostalCode } from '../../../utils/shipmentDisplay'; +import { formatAddress, formatCityStateAndPostalCode, formatCityStateAndZipCode } from '../../../utils/shipmentDisplay'; import DataTableWrapper from '../../DataTableWrapper/index'; import DataTable from '../../DataTable/index'; @@ -86,7 +86,7 @@ const ShipmentAddresses = ({ icon={} data-testid="pickupDestinationAddress" /> - + ); }; diff --git a/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx b/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx index f0c01c85530..20badc2b889 100644 --- a/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx +++ b/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx @@ -146,7 +146,7 @@ const ShipmentDetailsMain = ({ weightResult = primeEstimatedWeight; displayedPickupAddress = pickupAddress; displayedDeliveryAddress = destinationAddress || destinationDutyLocationAddress; - displayPoeLocation = poeLocation.portCode; + displayPoeLocation = poeLocation; break; case SHIPMENT_OPTIONS.NTS: pickupRequestedDate = requestedPickupDate; @@ -178,7 +178,7 @@ const ShipmentDetailsMain = ({ weightResult = primeEstimatedWeight; displayedPickupAddress = pickupAddress; displayedDeliveryAddress = destinationAddress || destinationDutyLocationAddress; - displayPoeLocation = poeLocation.portCode; + displayPoeLocation = poeLocation; break; } diff --git a/src/utils/shipmentDisplay.jsx b/src/utils/shipmentDisplay.jsx index ebde35e2071..d5c468e1de7 100644 --- a/src/utils/shipmentDisplay.jsx +++ b/src/utils/shipmentDisplay.jsx @@ -163,6 +163,18 @@ export function formatCityStateAndPostalCode(address) { return ''; } +/** + * @description This function is used to format the port in the + * ShipmentAddresses component. + * It displays only the city, state and zip code. + * */ +export function formatCityStateAndZipCode(port) { + if (port) { + return `${port.portCode} - ${port.city}, ${port.state} ${port.zip}`; + } + return ''; +} + export function getShipmentModificationType(shipment) { if (shipment.status === shipmentStatuses.CANCELED) { return shipmentModificationTypes.CANCELED; From 1c54b1d6bf1fc6f77591d36bd0f7ecb917a95718 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Mon, 23 Dec 2024 23:49:19 +0000 Subject: [PATCH 07/35] B-21507 Add Port Name and refactor format in shipment display --- .../Office/ShipmentAddresses/ShipmentAddresses.jsx | 8 ++++++-- .../Office/ShipmentDetails/ShipmentDetailsMain.jsx | 5 +++++ src/utils/shipmentDisplay.jsx | 6 +++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx index 0badbd9682f..8a4ce025f72 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx @@ -5,7 +5,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button } from '@trussworks/react-uswds'; import { AddressShape } from '../../../types/address'; -import { formatAddress, formatCityStateAndPostalCode, formatCityStateAndZipCode } from '../../../utils/shipmentDisplay'; +import { formatAddress, formatCityStateAndPostalCode, formatPortInfo } from '../../../utils/shipmentDisplay'; import DataTableWrapper from '../../DataTableWrapper/index'; import DataTable from '../../DataTable/index'; @@ -26,6 +26,7 @@ const ShipmentAddresses = ({ shipmentInfo, isMoveLocked, poeLocation, + podLocation, }) => { let pickupHeader; let destinationHeader; @@ -86,7 +87,10 @@ const ShipmentAddresses = ({ icon={} data-testid="pickupDestinationAddress" /> - + ); }; diff --git a/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx b/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx index 20badc2b889..c1914d2f9c1 100644 --- a/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx +++ b/src/components/Office/ShipmentDetails/ShipmentDetailsMain.jsx @@ -68,6 +68,7 @@ const ShipmentDetailsMain = ({ shipmentType, storageFacility, poeLocation, + podLocation, } = shipment; const { originDutyLocationAddress, destinationDutyLocationAddress } = dutyLocationAddresses; @@ -137,6 +138,7 @@ const ShipmentDetailsMain = ({ let plannedMoveDate; let actualMoveDate; let displayPoeLocation; + let displayPodLocation; switch (shipmentType) { case SHIPMENT_OPTIONS.HHG: @@ -147,6 +149,7 @@ const ShipmentDetailsMain = ({ displayedPickupAddress = pickupAddress; displayedDeliveryAddress = destinationAddress || destinationDutyLocationAddress; displayPoeLocation = poeLocation; + displayPodLocation = podLocation; break; case SHIPMENT_OPTIONS.NTS: pickupRequestedDate = requestedPickupDate; @@ -179,6 +182,7 @@ const ShipmentDetailsMain = ({ displayedPickupAddress = pickupAddress; displayedDeliveryAddress = destinationAddress || destinationDutyLocationAddress; displayPoeLocation = poeLocation; + displayPodLocation = podLocation; break; } @@ -265,6 +269,7 @@ const ShipmentDetailsMain = ({ handleShowDiversionModal={handleShowDiversionModal} isMoveLocked={isMoveLocked} poeLocation={displayPoeLocation} + podLocation={displayPodLocation} /> Date: Thu, 26 Dec 2024 15:00:32 +0000 Subject: [PATCH 08/35] Merge branch 'MAIN-B-21505' into MAIN-B-21507 --- swagger/prime_v3.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swagger/prime_v3.yaml b/swagger/prime_v3.yaml index f4d30feeb6f..eb7b469aedc 100644 --- a/swagger/prime_v3.yaml +++ b/swagger/prime_v3.yaml @@ -3118,7 +3118,7 @@ definitions: description: Port type A (Air), B (Border Crossing), S (Sea) enum: - A - - P + - B - S portCode: type: string From 5f72b9ae3adaaea9e9577895d81d792a4daf119b Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Thu, 26 Dec 2024 15:41:20 +0000 Subject: [PATCH 09/35] MAIN-B-21507 Consolidate getPoeLocation with getPodLocation for DRY code --- .../internal/payloads/model_to_payload.go | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go index 183cc92d56f..94f8c4e5bbb 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go @@ -1521,8 +1521,8 @@ func MTOShipment(storer storage.FileStorer, mtoShipment *models.MTOShipment, sit DeliveryAddressUpdate: ShipmentAddressUpdate(mtoShipment.DeliveryAddressUpdate), ShipmentLocator: handlers.FmtStringPtr(mtoShipment.ShipmentLocator), MarketCode: MarketCode(&mtoShipment.MarketCode), - PoeLocation: getPoeLocation(mtoShipment.MTOServiceItems), - PodLocation: getPodLocation(mtoShipment.MTOServiceItems), + PoeLocation: getPortLocation(mtoShipment.MTOServiceItems), + PodLocation: getPortLocation(mtoShipment.MTOServiceItems), } if mtoShipment.Distance != nil { @@ -2725,7 +2725,7 @@ func Port(portLocation *models.PortLocation) *ghcmessages.Port { } // Get POD/POE info from MTO shipment's service items -func getPoeLocation(mtoServiceItems models.MTOServiceItems) *ghcmessages.Port { +func getPortLocation(mtoServiceItems models.MTOServiceItems) *ghcmessages.Port { if mtoServiceItems == nil { return nil } @@ -2733,20 +2733,11 @@ func getPoeLocation(mtoServiceItems models.MTOServiceItems) *ghcmessages.Port { for _, mtoServiceItem := range mtoServiceItems { if mtoServiceItem.POELocation != nil { portLocation = Port(mtoServiceItem.POELocation) + break } - } - return portLocation -} - -// Get POD/POE info from MTO shipment's service items -func getPodLocation(mtoServiceItems models.MTOServiceItems) *ghcmessages.Port { - if mtoServiceItems == nil { - return nil - } - var portLocation *ghcmessages.Port - for _, mtoServiceItem := range mtoServiceItems { if mtoServiceItem.PODLocation != nil { portLocation = Port(mtoServiceItem.PODLocation) + break } } return portLocation From 2e95c4bdcd0442d0b9662d250a431fc74581ac1c Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Thu, 26 Dec 2024 15:51:58 +0000 Subject: [PATCH 10/35] B-21507 update comment --- pkg/handlers/ghcapi/internal/payloads/model_to_payload.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go index 94f8c4e5bbb..72298b7c54b 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go @@ -2709,7 +2709,7 @@ func ReServiceItems(reServiceItems models.ReServiceItems) ghcmessages.ReServiceI return payload } -// Convert a PortLocation model to Port message +// Port payload func Port(portLocation *models.PortLocation) *ghcmessages.Port { return &ghcmessages.Port{ ID: strfmt.UUID(portLocation.ID.String()), From a58ee66356defc369bcb457c33f9e946848a26e2 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Thu, 26 Dec 2024 20:08:32 +0000 Subject: [PATCH 11/35] B-21507 Add port tests to model to payload for ghcapi --- .../internal/payloads/model_to_payload.go | 3 + .../payloads/model_to_payload_test.go | 61 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go index 72298b7c54b..b83c51775a3 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go @@ -2711,6 +2711,9 @@ func ReServiceItems(reServiceItems models.ReServiceItems) ghcmessages.ReServiceI // Port payload func Port(portLocation *models.PortLocation) *ghcmessages.Port { + if portLocation == nil { + return nil + } return &ghcmessages.Port{ ID: strfmt.UUID(portLocation.ID.String()), PortType: portLocation.Port.PortType.String(), diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index ec3072d2ca0..1955a1c7b08 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -950,3 +950,64 @@ func (suite *PayloadsSuite) TestMTOServiceItemModel() { suite.Equal(handlers.FmtString(models.MarketOconus.FullString()), result.Market, "Expected Market to be OCONUS") }) } + +func (suite *PayloadsSuite) TestPort() { + + suite.Run("returns nil when PortLocation is nil", func() { + var portLocation *models.PortLocation = nil + result := Port(portLocation) + suite.Nil(result, "Expected result to be nil when Port Location is nil") + }) + + suite.Run("Success - Maps PortLocation to Port payload", func() { + // Arrange + portID, _ := uuid.NewV4() + portType := models.PortType("A") + portCode := "LAX" + portName := "Port of Los Angeles" + cityName := "Los Angeles" + countyName := "Los Angeles County" + stateName := "California" + zip := "90210" + countryName := "United States" + + mockPortLocation := &models.PortLocation{ + ID: portID, + Port: models.Port{ + PortType: portType, + PortCode: portCode, + PortName: portName, + }, + City: models.City{ + CityName: cityName, + }, + UsPostRegionCity: models.UsPostRegionCity{ + UsprcCountyNm: countyName, + UsPostRegion: models.UsPostRegion{ + State: models.State{ + StateName: stateName, + }, + }, + UsprZipID: zip, + }, + Country: models.Country{ + CountryName: countryName, + }, + } + + // Actual + result := Port(mockPortLocation) + + // Assert + suite.IsType(&ghcmessages.Port{}, result) + suite.Equal(strfmt.UUID(portID.String()), result.ID) + suite.Equal(portType.String(), result.PortType) + suite.Equal(portCode, result.PortCode) + suite.Equal(portName, result.PortName) + suite.Equal(cityName, result.City) + suite.Equal(countyName, result.County) + suite.Equal(stateName, result.State) + suite.Equal(zip, result.Zip) + suite.Equal(countryName, result.Country) + }) +} From 1b215b8bbb9a703209cc2511aed4722901bd683b Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Thu, 26 Dec 2024 20:20:51 +0000 Subject: [PATCH 12/35] B-21507 Restore FF for UB --- .envrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.envrc b/.envrc index 02c400ca703..3891c5b8d85 100644 --- a/.envrc +++ b/.envrc @@ -154,7 +154,7 @@ export FEATURE_FLAG_NTS=true export FEATURE_FLAG_NTSR=true export FEATURE_FLAG_BOAT=true export FEATURE_FLAG_MOBILE_HOME=true -export FEATURE_FLAG_UNACCOMPANIED_BAGGAGE=true +export FEATURE_FLAG_UNACCOMPANIED_BAGGAGE=false # Feature flag to allow AK to be entered as a state export FEATURE_FLAG_ENABLE_ALASKA=true From c6f0ec0f3aec58c588f4b1774998ef460f540e74 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Thu, 26 Dec 2024 21:00:59 +0000 Subject: [PATCH 13/35] B-21507 Fix getPortLocation function --- pkg/gen/ghcapi/embedded_spec.go | 408 +++++++++++++++++- pkg/gen/ghcmessages/port.go | 8 +- pkg/gen/primeapi/embedded_spec.go | 74 +++- pkg/gen/primev3api/embedded_spec.go | 34 +- .../internal/payloads/model_to_payload.go | 12 +- .../payloads/model_to_payload_test.go | 12 +- swagger/ghc.yaml | 175 +++++++- swagger/prime.yaml | 52 +++ swagger/prime_v3.yaml | 10 + 9 files changed, 753 insertions(+), 32 deletions(-) diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index 413f047e8be..082916278f4 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -36,6 +36,44 @@ func init() { }, "basePath": "/ghc/v1", "paths": { + "/addresses/zip-city-lookup/{search}": { + "get": { + "description": "Find by API using full/partial postal code or city name that returns an us_post_region_cities json object containing city, state, county and postal code.", + "tags": [ + "addresses" + ], + "summary": "Returns city, state, postal code, and county associated with the specified full/partial postal code or city and state string", + "operationId": "getLocationByZipCityState", + "parameters": [ + { + "type": "string", + "name": "search", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "the requested list of city, state, county, and postal code matches", + "schema": { + "$ref": "#/definitions/VLocations" + } + }, + "400": { + "$ref": "#/responses/InvalidRequest" + }, + "403": { + "$ref": "#/responses/PermissionDenied" + }, + "404": { + "$ref": "#/responses/NotFound" + }, + "500": { + "$ref": "#/responses/ServerError" + } + } + } + }, "/application_parameters/{parameterName}": { "get": { "description": "Searches for an application parameter by name, returns nil if not found", @@ -6513,6 +6551,11 @@ func init() { "title": "Address Line 3", "x-nullable": true, "example": "Montmârtre" + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" } } }, @@ -11360,6 +11403,11 @@ func init() { "title": "Address Line 3", "x-nullable": true, "example": "Montmârtre" + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" } } }, @@ -12251,7 +12299,7 @@ func init() { "type": "string", "enum": [ "A", - "P", + "B", "S" ] }, @@ -14795,6 +14843,151 @@ func init() { } } }, + "VLocation": { + "description": "A postal code, city, and state lookup", + "type": "object", + "properties": { + "city": { + "type": "string", + "title": "City", + "example": "Anytown" + }, + "county": { + "type": "string", + "title": "County", + "x-nullable": true, + "example": "LOS ANGELES" + }, + "postalCode": { + "type": "string", + "format": "zip", + "title": "ZIP", + "pattern": "^(\\d{5}?)$", + "example": "90210" + }, + "state": { + "type": "string", + "title": "State", + "enum": [ + "AL", + "AK", + "AR", + "AZ", + "CA", + "CO", + "CT", + "DC", + "DE", + "FL", + "GA", + "HI", + "IA", + "ID", + "IL", + "IN", + "KS", + "KY", + "LA", + "MA", + "MD", + "ME", + "MI", + "MN", + "MO", + "MS", + "MT", + "NC", + "ND", + "NE", + "NH", + "NJ", + "NM", + "NV", + "NY", + "OH", + "OK", + "OR", + "PA", + "RI", + "SC", + "SD", + "TN", + "TX", + "UT", + "VA", + "VT", + "WA", + "WI", + "WV", + "WY" + ], + "x-display-value": { + "AK": "AK", + "AL": "AL", + "AR": "AR", + "AZ": "AZ", + "CA": "CA", + "CO": "CO", + "CT": "CT", + "DC": "DC", + "DE": "DE", + "FL": "FL", + "GA": "GA", + "HI": "HI", + "IA": "IA", + "ID": "ID", + "IL": "IL", + "IN": "IN", + "KS": "KS", + "KY": "KY", + "LA": "LA", + "MA": "MA", + "MD": "MD", + "ME": "ME", + "MI": "MI", + "MN": "MN", + "MO": "MO", + "MS": "MS", + "MT": "MT", + "NC": "NC", + "ND": "ND", + "NE": "NE", + "NH": "NH", + "NJ": "NJ", + "NM": "NM", + "NV": "NV", + "NY": "NY", + "OH": "OH", + "OK": "OK", + "OR": "OR", + "PA": "PA", + "RI": "RI", + "SC": "SC", + "SD": "SD", + "TN": "TN", + "TX": "TX", + "UT": "UT", + "VA": "VA", + "VT": "VT", + "WA": "WA", + "WI": "WI", + "WV": "WV", + "WY": "WY" + } + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" + } + } + }, + "VLocations": { + "type": "array", + "items": { + "$ref": "#/definitions/VLocation" + } + }, "ValidationError": { "required": [ "invalid_fields" @@ -15131,6 +15324,9 @@ func init() { { "name": "transportationOffice" }, + { + "name": "addresses" + }, { "name": "uploads" }, @@ -15161,6 +15357,56 @@ func init() { }, "basePath": "/ghc/v1", "paths": { + "/addresses/zip-city-lookup/{search}": { + "get": { + "description": "Find by API using full/partial postal code or city name that returns an us_post_region_cities json object containing city, state, county and postal code.", + "tags": [ + "addresses" + ], + "summary": "Returns city, state, postal code, and county associated with the specified full/partial postal code or city and state string", + "operationId": "getLocationByZipCityState", + "parameters": [ + { + "type": "string", + "name": "search", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "the requested list of city, state, county, and postal code matches", + "schema": { + "$ref": "#/definitions/VLocations" + } + }, + "400": { + "description": "The request payload is invalid", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "403": { + "description": "The request was denied", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "404": { + "description": "The requested resource wasn't found", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "500": { + "description": "A server error occurred", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, "/application_parameters/{parameterName}": { "get": { "description": "Searches for an application parameter by name, returns nil if not found", @@ -23163,6 +23409,11 @@ func init() { "title": "Address Line 3", "x-nullable": true, "example": "Montmârtre" + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" } } }, @@ -28015,6 +28266,11 @@ func init() { "title": "Address Line 3", "x-nullable": true, "example": "Montmârtre" + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" } } }, @@ -28979,7 +29235,7 @@ func init() { "type": "string", "enum": [ "A", - "P", + "B", "S" ] }, @@ -31586,6 +31842,151 @@ func init() { } } }, + "VLocation": { + "description": "A postal code, city, and state lookup", + "type": "object", + "properties": { + "city": { + "type": "string", + "title": "City", + "example": "Anytown" + }, + "county": { + "type": "string", + "title": "County", + "x-nullable": true, + "example": "LOS ANGELES" + }, + "postalCode": { + "type": "string", + "format": "zip", + "title": "ZIP", + "pattern": "^(\\d{5}?)$", + "example": "90210" + }, + "state": { + "type": "string", + "title": "State", + "enum": [ + "AL", + "AK", + "AR", + "AZ", + "CA", + "CO", + "CT", + "DC", + "DE", + "FL", + "GA", + "HI", + "IA", + "ID", + "IL", + "IN", + "KS", + "KY", + "LA", + "MA", + "MD", + "ME", + "MI", + "MN", + "MO", + "MS", + "MT", + "NC", + "ND", + "NE", + "NH", + "NJ", + "NM", + "NV", + "NY", + "OH", + "OK", + "OR", + "PA", + "RI", + "SC", + "SD", + "TN", + "TX", + "UT", + "VA", + "VT", + "WA", + "WI", + "WV", + "WY" + ], + "x-display-value": { + "AK": "AK", + "AL": "AL", + "AR": "AR", + "AZ": "AZ", + "CA": "CA", + "CO": "CO", + "CT": "CT", + "DC": "DC", + "DE": "DE", + "FL": "FL", + "GA": "GA", + "HI": "HI", + "IA": "IA", + "ID": "ID", + "IL": "IL", + "IN": "IN", + "KS": "KS", + "KY": "KY", + "LA": "LA", + "MA": "MA", + "MD": "MD", + "ME": "ME", + "MI": "MI", + "MN": "MN", + "MO": "MO", + "MS": "MS", + "MT": "MT", + "NC": "NC", + "ND": "ND", + "NE": "NE", + "NH": "NH", + "NJ": "NJ", + "NM": "NM", + "NV": "NV", + "NY": "NY", + "OH": "OH", + "OK": "OK", + "OR": "OR", + "PA": "PA", + "RI": "RI", + "SC": "SC", + "SD": "SD", + "TN": "TN", + "TX": "TX", + "UT": "UT", + "VA": "VA", + "VT": "VT", + "WA": "WA", + "WI": "WI", + "WV": "WV", + "WY": "WY" + } + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" + } + } + }, + "VLocations": { + "type": "array", + "items": { + "$ref": "#/definitions/VLocation" + } + }, "ValidationError": { "required": [ "invalid_fields" @@ -31930,6 +32331,9 @@ func init() { { "name": "transportationOffice" }, + { + "name": "addresses" + }, { "name": "uploads" }, diff --git a/pkg/gen/ghcmessages/port.go b/pkg/gen/ghcmessages/port.go index a2fa6787aa0..5ffb0256db8 100644 --- a/pkg/gen/ghcmessages/port.go +++ b/pkg/gen/ghcmessages/port.go @@ -47,7 +47,7 @@ type Port struct { PortName string `json:"portName,omitempty"` // Port type A (Air), B (Border Crossing), S (Sea) - // Enum: [A P S] + // Enum: [A B S] PortType string `json:"portType,omitempty"` // US state @@ -119,7 +119,7 @@ var portTypePortTypePropEnum []interface{} func init() { var res []string - if err := json.Unmarshal([]byte(`["A","P","S"]`), &res); err != nil { + if err := json.Unmarshal([]byte(`["A","B","S"]`), &res); err != nil { panic(err) } for _, v := range res { @@ -132,8 +132,8 @@ const ( // PortPortTypeA captures enum value "A" PortPortTypeA string = "A" - // PortPortTypeP captures enum value "P" - PortPortTypeP string = "P" + // PortPortTypeB captures enum value "B" + PortPortTypeB string = "B" // PortPortTypeS captures enum value "S" PortPortTypeS string = "S" diff --git a/pkg/gen/primeapi/embedded_spec.go b/pkg/gen/primeapi/embedded_spec.go index d963da8870d..52039d783cc 100644 --- a/pkg/gen/primeapi/embedded_spec.go +++ b/pkg/gen/primeapi/embedded_spec.go @@ -355,7 +355,7 @@ func init() { }, "/mto-service-items/{mtoServiceItemID}": { "patch": { - "description": "Updates MTOServiceItems after creation. Not all service items or fields may be updated, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to update and the documentation will update with the new definition.\n\n* Addresses: To update a destination service item's SIT destination final address, update the shipment delivery address.\nFor approved shipments, please use [updateShipmentDestinationAddress](#mtoShipment/updateShipmentDestinationAddress).\nFor shipments not yet approved, please use [updateMTOShipmentAddress](#mtoShipment/updateMTOShipmentAddress).\n\n* SIT Service Items: Take note that when updating ` + "`" + `sitCustomerContacted` + "`" + `, ` + "`" + `sitDepartureDate` + "`" + `, or ` + "`" + `sitRequestedDelivery` + "`" + `, we want\nthose to be updated on ` + "`" + `DOASIT` + "`" + ` (for origin SIT) and ` + "`" + `DDASIT` + "`" + ` (for destination SIT). If updating those values in other service\nitems, the office users will not have as much attention to those values.\n\nTo create a service item, please use [createMTOServiceItem](#mtoServiceItem/createMTOServiceItem)) endpoint.\n\n* Resubmitting rejected SIT service items: This endpoint will handle the logic of changing the status of rejected SIT service items from\nREJECTED to SUBMITTED. Please provide the ` + "`" + `requestedApprovalsRequestedStatus: true` + "`" + ` when resubmitting as this will give attention to the TOO to\nreview the resubmitted SIT service item. Another note, ` + "`" + `updateReason` + "`" + ` must have a different value than the current ` + "`" + `reason` + "`" + ` value on the service item.\nIf this value is not updated, then an error will be sent back.\n\nThe following SIT service items can be resubmitted following a rejection:\n- DDASIT\n- DDDSIT\n- DDFSIT\n- DOASIT\n- DOPSIT\n- DOFSIT\n- DDSFSC\n- DOSFSC\n\nAt a MINIMUM, the payload for resubmitting a rejected SIT service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"reServiceCode\": \"DDFSIT\",\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemSIT\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n", + "description": "Updates MTOServiceItems after creation. Not all service items or fields may be updated, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to update and the documentation will update with the new definition.\n\n* Addresses: To update a destination service item's SIT destination final address, update the shipment delivery address.\nFor approved shipments, please use [updateShipmentDestinationAddress](#mtoShipment/updateShipmentDestinationAddress).\nFor shipments not yet approved, please use [updateMTOShipmentAddress](#mtoShipment/updateMTOShipmentAddress).\n\n* SIT Service Items: Take note that when updating ` + "`" + `sitCustomerContacted` + "`" + `, ` + "`" + `sitDepartureDate` + "`" + `, or ` + "`" + `sitRequestedDelivery` + "`" + `, we want\nthose to be updated on ` + "`" + `DOASIT` + "`" + ` (for origin SIT) and ` + "`" + `DDASIT` + "`" + ` (for destination SIT). If updating those values in other service\nitems, the office users will not have as much attention to those values.\n\nTo create a service item, please use [createMTOServiceItem](#mtoServiceItem/createMTOServiceItem)) endpoint.\n\n* Resubmitting rejected SIT service items: This endpoint will handle the logic of changing the status of rejected SIT service items from\nREJECTED to SUBMITTED. Please provide the ` + "`" + `requestedApprovalsRequestedStatus: true` + "`" + ` when resubmitting as this will give attention to the TOO to\nreview the resubmitted SIT service item. Another note, ` + "`" + `updateReason` + "`" + ` must have a different value than the current ` + "`" + `reason` + "`" + ` value on the service item.\nIf this value is not updated, then an error will be sent back.\n\nThe following SIT service items can be resubmitted following a rejection:\n- DDASIT\n- DDDSIT\n- DDFSIT\n- DOASIT\n- DOPSIT\n- DOFSIT\n- DDSFSC\n- DOSFSC\n\nAt a MINIMUM, the payload for resubmitting a rejected SIT service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"reServiceCode\": \"DDFSIT\",\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemSIT\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nThe following service items allow you to update the Port that the shipment will use:\n- PODFSC (Port of Debarkation can be updated)\n- POEFSC (Port of Embarkation can be updated)\n\nAt a MINIMUM, the payload for updating the port should contain the reServiceCode (PODFSC or POEFSC), modelType (UpdateMTOServiceItemInternationalPortFSC), portCode, and id for the service item.\nPlease see the example payload below:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"id\": \"1ed224b6-c65e-4616-b88e-8304d26c9562\",\n \"modelType\": \"UpdateMTOServiceItemInternationalPortFSC\",\n \"portCode\": \"SEA\",\n \"reServiceCode\": \"POEFSC\"\n}\n` + "`" + `` + "`" + `` + "`" + `\n", "consumes": [ "application/json" ], @@ -1362,6 +1362,11 @@ func init() { "title": "Address Line 3", "x-nullable": true, "example": "Montmârtre" + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" } } }, @@ -2338,8 +2343,33 @@ func init() { } ] }, + "MTOServiceItemInternationalFuelSurcharge": { + "description": "Describes a international Port of Embarkation/Debarkation fuel surcharge service item subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "properties": { + "portCode": { + "description": "A unique code for a Port", + "type": "string" + }, + "reServiceCode": { + "description": "A unique code for the service item. Indicates if the service is for Port of Embarkation (POEFSC) or Port of Debarkation (PODFSC).", + "type": "string", + "enum": [ + "PODFSC", + "POEFSC" + ] + } + } + } + ] + }, "MTOServiceItemModelType": { - "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n\nThe documentation will then update with the supported fields.\n", + "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "MTOServiceItemBasic", @@ -2347,7 +2377,8 @@ func init() { "MTOServiceItemDestSIT", "MTOServiceItemShuttle", "MTOServiceItemDomesticCrating", - "MTOServiceItemInternationalCrating" + "MTOServiceItemInternationalCrating", + "MTOSerivceItemInternationalFuelSurcharge" ] }, "MTOServiceItemOriginSIT": { @@ -4943,7 +4974,7 @@ func init() { }, "/mto-service-items/{mtoServiceItemID}": { "patch": { - "description": "Updates MTOServiceItems after creation. Not all service items or fields may be updated, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to update and the documentation will update with the new definition.\n\n* Addresses: To update a destination service item's SIT destination final address, update the shipment delivery address.\nFor approved shipments, please use [updateShipmentDestinationAddress](#mtoShipment/updateShipmentDestinationAddress).\nFor shipments not yet approved, please use [updateMTOShipmentAddress](#mtoShipment/updateMTOShipmentAddress).\n\n* SIT Service Items: Take note that when updating ` + "`" + `sitCustomerContacted` + "`" + `, ` + "`" + `sitDepartureDate` + "`" + `, or ` + "`" + `sitRequestedDelivery` + "`" + `, we want\nthose to be updated on ` + "`" + `DOASIT` + "`" + ` (for origin SIT) and ` + "`" + `DDASIT` + "`" + ` (for destination SIT). If updating those values in other service\nitems, the office users will not have as much attention to those values.\n\nTo create a service item, please use [createMTOServiceItem](#mtoServiceItem/createMTOServiceItem)) endpoint.\n\n* Resubmitting rejected SIT service items: This endpoint will handle the logic of changing the status of rejected SIT service items from\nREJECTED to SUBMITTED. Please provide the ` + "`" + `requestedApprovalsRequestedStatus: true` + "`" + ` when resubmitting as this will give attention to the TOO to\nreview the resubmitted SIT service item. Another note, ` + "`" + `updateReason` + "`" + ` must have a different value than the current ` + "`" + `reason` + "`" + ` value on the service item.\nIf this value is not updated, then an error will be sent back.\n\nThe following SIT service items can be resubmitted following a rejection:\n- DDASIT\n- DDDSIT\n- DDFSIT\n- DOASIT\n- DOPSIT\n- DOFSIT\n- DDSFSC\n- DOSFSC\n\nAt a MINIMUM, the payload for resubmitting a rejected SIT service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"reServiceCode\": \"DDFSIT\",\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemSIT\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n", + "description": "Updates MTOServiceItems after creation. Not all service items or fields may be updated, please see details below.\n\nThis endpoint supports different body definitions. In the modelType field below, select the modelType corresponding\n to the service item you wish to update and the documentation will update with the new definition.\n\n* Addresses: To update a destination service item's SIT destination final address, update the shipment delivery address.\nFor approved shipments, please use [updateShipmentDestinationAddress](#mtoShipment/updateShipmentDestinationAddress).\nFor shipments not yet approved, please use [updateMTOShipmentAddress](#mtoShipment/updateMTOShipmentAddress).\n\n* SIT Service Items: Take note that when updating ` + "`" + `sitCustomerContacted` + "`" + `, ` + "`" + `sitDepartureDate` + "`" + `, or ` + "`" + `sitRequestedDelivery` + "`" + `, we want\nthose to be updated on ` + "`" + `DOASIT` + "`" + ` (for origin SIT) and ` + "`" + `DDASIT` + "`" + ` (for destination SIT). If updating those values in other service\nitems, the office users will not have as much attention to those values.\n\nTo create a service item, please use [createMTOServiceItem](#mtoServiceItem/createMTOServiceItem)) endpoint.\n\n* Resubmitting rejected SIT service items: This endpoint will handle the logic of changing the status of rejected SIT service items from\nREJECTED to SUBMITTED. Please provide the ` + "`" + `requestedApprovalsRequestedStatus: true` + "`" + ` when resubmitting as this will give attention to the TOO to\nreview the resubmitted SIT service item. Another note, ` + "`" + `updateReason` + "`" + ` must have a different value than the current ` + "`" + `reason` + "`" + ` value on the service item.\nIf this value is not updated, then an error will be sent back.\n\nThe following SIT service items can be resubmitted following a rejection:\n- DDASIT\n- DDDSIT\n- DDFSIT\n- DOASIT\n- DOPSIT\n- DOFSIT\n- DDSFSC\n- DOSFSC\n\nAt a MINIMUM, the payload for resubmitting a rejected SIT service item must look like this:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"reServiceCode\": \"DDFSIT\",\n \"updateReason\": \"A reason that differs from the previous reason\",\n \"modelType\": \"UpdateMTOServiceItemSIT\",\n \"requestApprovalsRequestedStatus\": true\n}\n` + "`" + `` + "`" + `` + "`" + `\n\nThe following service items allow you to update the Port that the shipment will use:\n- PODFSC (Port of Debarkation can be updated)\n- POEFSC (Port of Embarkation can be updated)\n\nAt a MINIMUM, the payload for updating the port should contain the reServiceCode (PODFSC or POEFSC), modelType (UpdateMTOServiceItemInternationalPortFSC), portCode, and id for the service item.\nPlease see the example payload below:\n` + "`" + `` + "`" + `` + "`" + `json\n{\n \"id\": \"1ed224b6-c65e-4616-b88e-8304d26c9562\",\n \"modelType\": \"UpdateMTOServiceItemInternationalPortFSC\",\n \"portCode\": \"SEA\",\n \"reServiceCode\": \"POEFSC\"\n}\n` + "`" + `` + "`" + `` + "`" + `\n", "consumes": [ "application/json" ], @@ -6225,6 +6256,11 @@ func init() { "title": "Address Line 3", "x-nullable": true, "example": "Montmârtre" + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" } } }, @@ -7201,8 +7237,33 @@ func init() { } ] }, + "MTOServiceItemInternationalFuelSurcharge": { + "description": "Describes a international Port of Embarkation/Debarkation fuel surcharge service item subtype of a MTOServiceItem.", + "allOf": [ + { + "$ref": "#/definitions/MTOServiceItem" + }, + { + "type": "object", + "properties": { + "portCode": { + "description": "A unique code for a Port", + "type": "string" + }, + "reServiceCode": { + "description": "A unique code for the service item. Indicates if the service is for Port of Embarkation (POEFSC) or Port of Debarkation (PODFSC).", + "type": "string", + "enum": [ + "PODFSC", + "POEFSC" + ] + } + } + } + ] + }, "MTOServiceItemModelType": { - "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n\nThe documentation will then update with the supported fields.\n", + "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "MTOServiceItemBasic", @@ -7210,7 +7271,8 @@ func init() { "MTOServiceItemDestSIT", "MTOServiceItemShuttle", "MTOServiceItemDomesticCrating", - "MTOServiceItemInternationalCrating" + "MTOServiceItemInternationalCrating", + "MTOSerivceItemInternationalFuelSurcharge" ] }, "MTOServiceItemOriginSIT": { diff --git a/pkg/gen/primev3api/embedded_spec.go b/pkg/gen/primev3api/embedded_spec.go index c0990b8fa51..bb5a844cfe0 100644 --- a/pkg/gen/primev3api/embedded_spec.go +++ b/pkg/gen/primev3api/embedded_spec.go @@ -553,6 +553,11 @@ func init() { "title": "Address Line 3", "x-nullable": true, "example": "Montmârtre" + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" } } }, @@ -1632,7 +1637,7 @@ func init() { ] }, "MTOServiceItemModelType": { - "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n\nThe documentation will then update with the supported fields.\n", + "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "MTOServiceItemBasic", @@ -1640,7 +1645,8 @@ func init() { "MTOServiceItemDestSIT", "MTOServiceItemShuttle", "MTOServiceItemDomesticCrating", - "MTOServiceItemInternationalCrating" + "MTOServiceItemInternationalCrating", + "MTOSerivceItemInternationalFuelSurcharge" ] }, "MTOServiceItemOriginSIT": { @@ -2536,6 +2542,11 @@ func init() { "title": "Address Line 3", "x-nullable": true, "example": "Montmârtre" + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" } } }, @@ -3024,7 +3035,7 @@ func init() { "type": "string", "enum": [ "A", - "P", + "B", "S" ] }, @@ -4796,6 +4807,11 @@ func init() { "title": "Address Line 3", "x-nullable": true, "example": "Montmârtre" + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" } } }, @@ -5875,7 +5891,7 @@ func init() { ] }, "MTOServiceItemModelType": { - "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n\nThe documentation will then update with the supported fields.\n", + "description": "Describes all model sub-types for a MTOServiceItem model.\n\nUsing this list, choose the correct modelType in the dropdown, corresponding to the service item type.\n * DOFSIT, DOASIT - MTOServiceItemOriginSIT\n * DDFSIT, DDASIT - MTOServiceItemDestSIT\n * DOSHUT, DDSHUT - MTOServiceItemShuttle\n * DCRT, DUCRT - MTOServiceItemDomesticCrating\n * ICRT, IUCRT - MTOServiceItemInternationalCrating\n * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", "enum": [ "MTOServiceItemBasic", @@ -5883,7 +5899,8 @@ func init() { "MTOServiceItemDestSIT", "MTOServiceItemShuttle", "MTOServiceItemDomesticCrating", - "MTOServiceItemInternationalCrating" + "MTOServiceItemInternationalCrating", + "MTOSerivceItemInternationalFuelSurcharge" ] }, "MTOServiceItemOriginSIT": { @@ -6779,6 +6796,11 @@ func init() { "title": "Address Line 3", "x-nullable": true, "example": "Montmârtre" + }, + "usPostRegionCitiesID": { + "type": "string", + "format": "uuid", + "example": "c56a4180-65aa-42ec-a945-5fd21dec0538" } } }, @@ -7267,7 +7289,7 @@ func init() { "type": "string", "enum": [ "A", - "P", + "B", "S" ] }, diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go index b83c51775a3..973503d1686 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go @@ -1521,8 +1521,8 @@ func MTOShipment(storer storage.FileStorer, mtoShipment *models.MTOShipment, sit DeliveryAddressUpdate: ShipmentAddressUpdate(mtoShipment.DeliveryAddressUpdate), ShipmentLocator: handlers.FmtStringPtr(mtoShipment.ShipmentLocator), MarketCode: MarketCode(&mtoShipment.MarketCode), - PoeLocation: getPortLocation(mtoShipment.MTOServiceItems), - PodLocation: getPortLocation(mtoShipment.MTOServiceItems), + PoeLocation: getPortLocation(mtoShipment.MTOServiceItems, "POE"), + PodLocation: getPortLocation(mtoShipment.MTOServiceItems, "POD"), } if mtoShipment.Distance != nil { @@ -2728,19 +2728,17 @@ func Port(portLocation *models.PortLocation) *ghcmessages.Port { } // Get POD/POE info from MTO shipment's service items -func getPortLocation(mtoServiceItems models.MTOServiceItems) *ghcmessages.Port { +func getPortLocation(mtoServiceItems models.MTOServiceItems, portType string) *ghcmessages.Port { if mtoServiceItems == nil { return nil } var portLocation *ghcmessages.Port for _, mtoServiceItem := range mtoServiceItems { - if mtoServiceItem.POELocation != nil { + if mtoServiceItem.POELocation != nil && portType == "POE" { portLocation = Port(mtoServiceItem.POELocation) - break } - if mtoServiceItem.PODLocation != nil { + if mtoServiceItem.PODLocation != nil && portType == "POD" { portLocation = Port(mtoServiceItem.PODLocation) - break } } return portLocation diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index 1955a1c7b08..c3b0f1a2125 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -963,12 +963,12 @@ func (suite *PayloadsSuite) TestPort() { // Arrange portID, _ := uuid.NewV4() portType := models.PortType("A") - portCode := "LAX" - portName := "Port of Los Angeles" - cityName := "Los Angeles" - countyName := "Los Angeles County" - stateName := "California" - zip := "90210" + portCode := "PDX" + portName := "Portland Intl" + cityName := "Portland" + countyName := "Multhnomah" + stateName := "Oregon" + zip := "97220" countryName := "United States" mockPortLocation := &models.PortLocation{ diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index f91f7538d48..2f93154260b 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -38,6 +38,7 @@ tags: - name: ppm - name: tac - name: transportationOffice + - name: addresses - name: uploads - name: paymentRequests - name: reServiceItems @@ -4222,6 +4223,36 @@ paths: $ref: '#/responses/NotFound' '500': $ref: '#/responses/ServerError' + /addresses/zip-city-lookup/{search}: + get: + summary: >- + Returns city, state, postal code, and county associated with the + specified full/partial postal code or city and state string + description: >- + Find by API using full/partial postal code or city name that returns an + us_post_region_cities json object containing city, state, county and + postal code. + operationId: getLocationByZipCityState + tags: + - addresses + parameters: + - in: path + name: search + type: string + required: true + responses: + '200': + description: the requested list of city, state, county, and postal code matches + schema: + $ref: '#/definitions/VLocations' + '400': + $ref: '#/responses/InvalidRequest' + '403': + $ref: '#/responses/PermissionDenied' + '404': + $ref: '#/responses/NotFound' + '500': + $ref: '#/responses/ServerError' /uploads: post: summary: Create a new upload @@ -7975,6 +8006,10 @@ definitions: type: array items: $ref: '#/definitions/TransportationOffice' + VLocations: + type: array + items: + $ref: '#/definitions/VLocation' ReServiceItems: type: array items: @@ -8263,6 +8298,10 @@ definitions: title: isOconus x-nullable: true example: false + usPostRegionCitiesID: + type: string + format: uuid + example: c56a4180-65aa-42ec-a945-5fd21dec0538 required: - streetAddress1 - city @@ -8995,6 +9034,10 @@ definitions: title: County x-nullable: true example: LOS ANGELES + usPostRegionCitiesID: + type: string + format: uuid + example: c56a4180-65aa-42ec-a945-5fd21dec0538 required: - city - state @@ -9249,7 +9292,7 @@ definitions: description: Port type A (Air), B (Border Crossing), S (Sea) enum: - A - - P + - B - S portCode: type: string @@ -11521,6 +11564,136 @@ definitions: validHhgProgramCodeForLoa: type: boolean x-nullable: true + VLocation: + description: A postal code, city, and state lookup + type: object + properties: + city: + type: string + example: Anytown + title: City + state: + title: State + type: string + x-display-value: + AL: AL + AK: AK + AR: AR + AZ: AZ + CA: CA + CO: CO + CT: CT + DC: DC + DE: DE + FL: FL + GA: GA + HI: HI + IA: IA + ID: ID + IL: IL + IN: IN + KS: KS + KY: KY + LA: LA + MA: MA + MD: MD + ME: ME + MI: MI + MN: MN + MO: MO + MS: MS + MT: MT + NC: NC + ND: ND + NE: NE + NH: NH + NJ: NJ + NM: NM + NV: NV + NY: NY + OH: OH + OK: OK + OR: OR + PA: PA + RI: RI + SC: SC + SD: SD + TN: TN + TX: TX + UT: UT + VA: VA + VT: VT + WA: WA + WI: WI + WV: WV + WY: WY + enum: + - AL + - AK + - AR + - AZ + - CA + - CO + - CT + - DC + - DE + - FL + - GA + - HI + - IA + - ID + - IL + - IN + - KS + - KY + - LA + - MA + - MD + - ME + - MI + - MN + - MO + - MS + - MT + - NC + - ND + - NE + - NH + - NJ + - NM + - NV + - NY + - OH + - OK + - OR + - PA + - RI + - SC + - SD + - TN + - TX + - UT + - VA + - VT + - WA + - WI + - WV + - WY + postalCode: + type: string + format: zip + title: ZIP + example: '90210' + pattern: ^(\d{5}?)$ + county: + type: string + title: County + x-nullable: true + example: LOS ANGELES + usPostRegionCitiesID: + type: string + format: uuid + example: c56a4180-65aa-42ec-a945-5fd21dec0538 ReServiceItem: description: A Service Item which ties an ReService, Market, and Shipment Type together type: object diff --git a/swagger/prime.yaml b/swagger/prime.yaml index 41dbd01f69a..83ef52b06c7 100644 --- a/swagger/prime.yaml +++ b/swagger/prime.yaml @@ -1072,6 +1072,33 @@ paths: } ``` + + + The following service items allow you to update the Port that the + shipment will use: + + - PODFSC (Port of Debarkation can be updated) + + - POEFSC (Port of Embarkation can be updated) + + + At a MINIMUM, the payload for updating the port should contain the + reServiceCode (PODFSC or POEFSC), modelType + (UpdateMTOServiceItemInternationalPortFSC), portCode, and id for the + service item. + + Please see the example payload below: + + ```json + + { + "id": "1ed224b6-c65e-4616-b88e-8304d26c9562", + "modelType": "UpdateMTOServiceItemInternationalPortFSC", + "portCode": "SEA", + "reServiceCode": "POEFSC" + } + + ``` operationId: updateMTOServiceItem tags: - mtoServiceItem @@ -2234,6 +2261,25 @@ definitions: required: - reason - reServiceCode + MTOServiceItemInternationalFuelSurcharge: + description: >- + Describes a international Port of Embarkation/Debarkation fuel surcharge + service item subtype of a MTOServiceItem. + allOf: + - $ref: '#/definitions/MTOServiceItem' + - type: object + properties: + reServiceCode: + type: string + description: >- + A unique code for the service item. Indicates if the service is + for Port of Embarkation (POEFSC) or Port of Debarkation (PODFSC). + enum: + - PODFSC + - POEFSC + portCode: + description: A unique code for a Port + type: string MTOShipment: type: object properties: @@ -2905,6 +2951,10 @@ definitions: title: isOconus x-nullable: true example: false + usPostRegionCitiesID: + type: string + format: uuid + example: c56a4180-65aa-42ec-a945-5fd21dec0538 required: - streetAddress1 - city @@ -3393,6 +3443,7 @@ definitions: * DOSHUT, DDSHUT - MTOServiceItemShuttle * DCRT, DUCRT - MTOServiceItemDomesticCrating * ICRT, IUCRT - MTOServiceItemInternationalCrating + * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge The documentation will then update with the supported fields. type: string @@ -3403,6 +3454,7 @@ definitions: - MTOServiceItemShuttle - MTOServiceItemDomesticCrating - MTOServiceItemInternationalCrating + - MTOSerivceItemInternationalFuelSurcharge ServiceRequestDocument: properties: uploads: diff --git a/swagger/prime_v3.yaml b/swagger/prime_v3.yaml index eb7b469aedc..cb7c5a5d10a 100644 --- a/swagger/prime_v3.yaml +++ b/swagger/prime_v3.yaml @@ -1650,6 +1650,10 @@ definitions: title: isOconus x-nullable: true example: false + usPostRegionCitiesID: + type: string + format: uuid + example: c56a4180-65aa-42ec-a945-5fd21dec0538 required: - streetAddress1 - city @@ -2150,6 +2154,7 @@ definitions: * DOSHUT, DDSHUT - MTOServiceItemShuttle * DCRT, DUCRT - MTOServiceItemDomesticCrating * ICRT, IUCRT - MTOServiceItemInternationalCrating + * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge The documentation will then update with the supported fields. type: string @@ -2160,6 +2165,7 @@ definitions: - MTOServiceItemShuttle - MTOServiceItemDomesticCrating - MTOServiceItemInternationalCrating + - MTOSerivceItemInternationalFuelSurcharge ServiceRequestDocument: properties: uploads: @@ -2647,6 +2653,10 @@ definitions: title: County x-nullable: true example: LOS ANGELES + usPostRegionCitiesID: + type: string + format: uuid + example: c56a4180-65aa-42ec-a945-5fd21dec0538 required: - city - state From b778618f2b65e0f5e46a55a10384c03f99fa5dd9 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 27 Dec 2024 18:19:02 +0000 Subject: [PATCH 14/35] B-21507 Add PortLocationShape into address.js Add Poe/pod to PropTypes --- .../Office/ShipmentAddresses/ShipmentAddresses.jsx | 6 +++++- src/types/address.js | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx index 8a4ce025f72..ad5dcbe4743 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx @@ -4,7 +4,7 @@ import { PropTypes } from 'prop-types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button } from '@trussworks/react-uswds'; -import { AddressShape } from '../../../types/address'; +import { AddressShape, PortLocationShape } from '../../../types/address'; import { formatAddress, formatCityStateAndPostalCode, formatPortInfo } from '../../../utils/shipmentDisplay'; import DataTableWrapper from '../../DataTableWrapper/index'; import DataTable from '../../DataTable/index'; @@ -101,6 +101,8 @@ ShipmentAddresses.propTypes = { originDutyLocation: AddressShape, destinationDutyLocation: AddressShape, handleShowDiversionModal: PropTypes.func.isRequired, + poeLocation: PortLocationShape, + podLocation: PortLocationShape, shipmentInfo: PropTypes.shape({ id: PropTypes.string.isRequired, eTag: PropTypes.string.isRequired, @@ -114,6 +116,8 @@ ShipmentAddresses.defaultProps = { destinationAddress: {}, originDutyLocation: {}, destinationDutyLocation: {}, + poeLocation: null, + podLocation: null, }; export default ShipmentAddresses; diff --git a/src/types/address.js b/src/types/address.js index f7152df3fc6..0396874b0cb 100644 --- a/src/types/address.js +++ b/src/types/address.js @@ -43,3 +43,11 @@ export const W2AddressShape = shape({ postalCode: string, usPostRegionCitiesID: string, }); + +export const PortLocationShape = shape({ + portCode: string, + portName: string, + city: string, + state: string, + zip: string, +}); From ec804ce028e75eb662602b3ec185df0d9d93aaf2 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 27 Dec 2024 20:21:31 +0000 Subject: [PATCH 15/35] B-21507 Add tests for ShipmentAddresses.jsx Add tests for shipmentDisplay.jsx --- .../ShipmentAddresses.test.jsx | 4 ++++ src/utils/shipmentDisplay.test.jsx | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx index 9153061aafa..af6ec81cb13 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx @@ -42,6 +42,8 @@ const testProps = { shipmentLocator: 'ABCDEF-01', }, diversionReason: '', + poeLocation: null, + podLocation: null, }; const ppmShipment = { @@ -184,6 +186,8 @@ describe('ShipmentAddresses', () => { it('shows correct headings for HHG', () => { render(); expect(screen.getByText("Customer's addresses")).toBeInTheDocument(); + expect(screen.getByText('Port of Embark')).toBeInTheDocument(); + expect(screen.getByText('Port of Debark')).toBeInTheDocument(); }); it('shows correct headings for NTS', () => { diff --git a/src/utils/shipmentDisplay.test.jsx b/src/utils/shipmentDisplay.test.jsx index 2d36c3fdf24..c3718fec6b4 100644 --- a/src/utils/shipmentDisplay.test.jsx +++ b/src/utils/shipmentDisplay.test.jsx @@ -13,6 +13,7 @@ import { getShipmentModificationType, retrieveSAC, retrieveTAC, + formatPortInfo, } from './shipmentDisplay'; import { LOA_TYPE } from 'shared/constants'; @@ -348,4 +349,23 @@ describe('shipmentDisplay utils', () => { expect(shipmentType).toEqual(shipmentModificationTypes.DIVERSION); }); }); + + describe('formatPortInfo', () => { + it('formats port information correctly when all fields are provided', () => { + const port = { + portCode: 'PDX', + portName: 'PORTLAND INTL', + city: 'PORTLAND', + state: 'OREGON', + zip: '97220', + }; + const formattedPortInfo = formatPortInfo(port); + expect(formattedPortInfo).toEqual('PDX - PORTLAND INTL\nPORTLAND, OREGON 97220'); + }); + + it('returns an empty string when no port is provided', () => { + const formattedPortInfo = formatPortInfo(null); + expect(formattedPortInfo).toEqual(''); + }); + }); }); From 68bec57c213333331a9406414e52dac154fdce40 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 27 Dec 2024 21:53:04 +0000 Subject: [PATCH 16/35] B-21507 Refactor how dashes are shown for empty POD or POE --- .../Office/ShipmentAddresses/ShipmentAddresses.jsx | 8 ++------ src/utils/shipmentDisplay.jsx | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx index ad5dcbe4743..f3ab85975a1 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx @@ -4,7 +4,7 @@ import { PropTypes } from 'prop-types'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button } from '@trussworks/react-uswds'; -import { AddressShape, PortLocationShape } from '../../../types/address'; +import { AddressShape } from '../../../types/address'; import { formatAddress, formatCityStateAndPostalCode, formatPortInfo } from '../../../utils/shipmentDisplay'; import DataTableWrapper from '../../DataTableWrapper/index'; import DataTable from '../../DataTable/index'; @@ -89,7 +89,7 @@ const ShipmentAddresses = ({ /> ); @@ -101,8 +101,6 @@ ShipmentAddresses.propTypes = { originDutyLocation: AddressShape, destinationDutyLocation: AddressShape, handleShowDiversionModal: PropTypes.func.isRequired, - poeLocation: PortLocationShape, - podLocation: PortLocationShape, shipmentInfo: PropTypes.shape({ id: PropTypes.string.isRequired, eTag: PropTypes.string.isRequired, @@ -116,8 +114,6 @@ ShipmentAddresses.defaultProps = { destinationAddress: {}, originDutyLocation: {}, destinationDutyLocation: {}, - poeLocation: null, - podLocation: null, }; export default ShipmentAddresses; diff --git a/src/utils/shipmentDisplay.jsx b/src/utils/shipmentDisplay.jsx index 03c1dd24013..546fd1b7ff0 100644 --- a/src/utils/shipmentDisplay.jsx +++ b/src/utils/shipmentDisplay.jsx @@ -172,7 +172,7 @@ export function formatPortInfo(port) { if (port) { return `${port.portCode} - ${port.portName}\n${port.city}, ${port.state} ${port.zip}`; } - return ''; + return '-'; } export function getShipmentModificationType(shipment) { From 7bc337aacabceea462a7a04e3f2472b70ffdd4af Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 27 Dec 2024 22:05:12 +0000 Subject: [PATCH 17/35] B-21507 Rename Embark and Debark to Embarkation and Debarkation --- src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx index f3ab85975a1..876aca3a848 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx @@ -88,7 +88,7 @@ const ShipmentAddresses = ({ data-testid="pickupDestinationAddress" /> From 8fb5a07e5fa978bd950a7d8d32681da85465fee1 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 27 Dec 2024 22:07:16 +0000 Subject: [PATCH 18/35] B-21507 Refactor test for change of POE/POD header --- .../Office/ShipmentAddresses/ShipmentAddresses.test.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx index af6ec81cb13..9521d67fbbb 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx @@ -186,8 +186,8 @@ describe('ShipmentAddresses', () => { it('shows correct headings for HHG', () => { render(); expect(screen.getByText("Customer's addresses")).toBeInTheDocument(); - expect(screen.getByText('Port of Embark')).toBeInTheDocument(); - expect(screen.getByText('Port of Debark')).toBeInTheDocument(); + expect(screen.getByText('Port of Embarkation')).toBeInTheDocument(); + expect(screen.getByText('Port of Debarkation')).toBeInTheDocument(); }); it('shows correct headings for NTS', () => { From ab935f2f417eac476c659856c6bdfba5ca845a13 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 27 Dec 2024 22:23:15 +0000 Subject: [PATCH 19/35] B-21507 Remove unnecessary swagger definition for Port --- swagger/ghc.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index 2f93154260b..1426c305432 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -10685,8 +10685,6 @@ definitions: storageFacility: x-nullable: true $ref: '#/definitions/StorageFacility' - port: - $ref: '#/definitions/Port' ppmShipment: $ref: '#/definitions/PPMShipment' boatShipment: From 26245b953552aabf7578108a0b5347809b733d7a Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Thu, 2 Jan 2025 17:17:50 +0000 Subject: [PATCH 20/35] B-21507 Remove Port definition from MTOShipment.yaml --- swagger-def/definitions/MTOShipment.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/swagger-def/definitions/MTOShipment.yaml b/swagger-def/definitions/MTOShipment.yaml index ecb1b141630..d11a9ec4023 100644 --- a/swagger-def/definitions/MTOShipment.yaml +++ b/swagger-def/definitions/MTOShipment.yaml @@ -191,8 +191,6 @@ properties: storageFacility: x-nullable: true $ref: 'StorageFacility.yaml' - port: - $ref: 'Port.yaml' ppmShipment: $ref: 'PPMShipment.yaml' boatShipment: From 6b7a44dfa16f94589c566266b91f3d175a0be5d7 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Thu, 2 Jan 2025 17:24:51 +0000 Subject: [PATCH 21/35] B-21507 Fix typo for POD --- .../ghcapi/internal/payloads/model_to_payload_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index c3b0f1a2125..ee098c4edda 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -637,16 +637,16 @@ func (suite *PayloadsSuite) TestReServiceItems() { marketCodeInternational := models.MarketCodeInternational marketCodeDomestic := models.MarketCodeDomestic poefscReServiceCode := models.ReServiceCodePOEFSC - poedscReServiceCode := models.ReServiceCodePODFSC + podfscReServiceCode := models.ReServiceCodePODFSC poefscServiceName := "International POE Fuel Surcharge" - poedscServiceName := "International POD Fuel Surcharge" + podfscServiceName := "International POD Fuel Surcharge" poefscService := models.ReService{ Code: poefscReServiceCode, Name: poefscServiceName, } podfscService := models.ReService{ - Code: poedscReServiceCode, - Name: poedscServiceName, + Code: podfscReServiceCode, + Name: podfscServiceName, } hhgShipmentType := models.MTOShipmentTypeHHG ubShipmentType := models.MTOShipmentTypeUnaccompaniedBaggage From 65e8deb3615a27fbdded87bd344b7d5822104757 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 3 Jan 2025 14:09:21 +0000 Subject: [PATCH 22/35] B-21507 Refactor model to payload test to use factories Create test for MTO Shipment for POE and POD --- .../payloads/model_to_payload_test.go | 146 +++++++++++++----- 1 file changed, 104 insertions(+), 42 deletions(-) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index ee098c4edda..b60ebc43499 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -960,54 +960,116 @@ func (suite *PayloadsSuite) TestPort() { }) suite.Run("Success - Maps PortLocation to Port payload", func() { - // Arrange - portID, _ := uuid.NewV4() - portType := models.PortType("A") - portCode := "PDX" - portName := "Portland Intl" - cityName := "Portland" - countyName := "Multhnomah" - stateName := "Oregon" - zip := "97220" - countryName := "United States" - - mockPortLocation := &models.PortLocation{ - ID: portID, - Port: models.Port{ - PortType: portType, - PortCode: portCode, - PortName: portName, - }, - City: models.City{ - CityName: cityName, - }, - UsPostRegionCity: models.UsPostRegionCity{ - UsprcCountyNm: countyName, - UsPostRegion: models.UsPostRegion{ - State: models.State{ - StateName: stateName, - }, + // Use the factory to create a port location + portLocation := factory.FetchPortLocation(suite.DB(), []factory.Customization{ + { + Model: models.Port{ + PortCode: "PDX", }, - UsprZipID: zip, }, - Country: models.Country{ - CountryName: countryName, - }, - } + }, nil) // Actual - result := Port(mockPortLocation) + result := Port(&portLocation) // Assert suite.IsType(&ghcmessages.Port{}, result) - suite.Equal(strfmt.UUID(portID.String()), result.ID) - suite.Equal(portType.String(), result.PortType) - suite.Equal(portCode, result.PortCode) - suite.Equal(portName, result.PortName) - suite.Equal(cityName, result.City) - suite.Equal(countyName, result.County) - suite.Equal(stateName, result.State) - suite.Equal(zip, result.Zip) - suite.Equal(countryName, result.Country) + suite.Equal(strfmt.UUID(portLocation.ID.String()), result.ID) + suite.Equal(portLocation.Port.PortType.String(), result.PortType) + suite.Equal(portLocation.Port.PortCode, result.PortCode) + suite.Equal(portLocation.Port.PortName, result.PortName) + suite.Equal(portLocation.City.CityName, result.City) + suite.Equal(portLocation.UsPostRegionCity.UsprcCountyNm, result.County) + suite.Equal(portLocation.UsPostRegionCity.UsPostRegion.State.StateName, result.State) + suite.Equal(portLocation.UsPostRegionCity.UsprZipID, result.Zip) + suite.Equal(portLocation.Country.CountryName, result.Country) + }) +} + +func (suite *PayloadsSuite) TestMTOShipment_POE_POD_Locations() { + suite.Run("Only POE Location is set", func() { + // Create mock data for MTOServiceItems with POE and POD + poePortLocation := factory.FetchPortLocation(suite.DB(), []factory.Customization{ + { + Model: models.Port{ + PortCode: "PDX", + }, + }, + }, nil) + + poefscServiceItem := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: models.ReServiceCodePOEFSC, + Priority: 1, + }, + }, + { + Model: poePortLocation, + LinkOnly: true, + Type: &factory.PortLocations.PortOfEmbarkation, + }, + }, nil) + + mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + MTOServiceItems: models.MTOServiceItems{poefscServiceItem}, + }, + }, + }, nil) + + payload := MTOShipment(nil, &mtoShipment, nil) + + // Assertions + suite.NotNil(payload, "Expected payload to not be nil") + suite.NotNil(payload.PoeLocation, "Expected POELocation to not be nil") + suite.Equal("PDX", payload.PoeLocation.PortCode, "Expected POE Port Code to match") + suite.Equal("PORTLAND INTL", payload.PoeLocation.PortName, "Expected POE Port Name to match") + + suite.Nil(payload.PodLocation, "Expected PODLocation to be nil when POELocation is set") + }) + + suite.Run("Only POD Location is set", func() { + // Create mock data for MTOServiceItems with POE and POD + podPortLocation := factory.FetchPortLocation(suite.DB(), []factory.Customization{ + { + Model: models.Port{ + PortCode: "PDX", + }, + }, + }, nil) + + podfscServiceItem := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: models.ReServiceCodePODFSC, + Priority: 1, + }, + }, + { + Model: podPortLocation, + LinkOnly: true, + Type: &factory.PortLocations.PortOfDebarkation, + }, + }, nil) + + mtoShipment := factory.BuildMTOShipment(suite.DB(), []factory.Customization{ + { + Model: models.MTOShipment{ + MTOServiceItems: models.MTOServiceItems{podfscServiceItem}, + }, + }, + }, nil) + + payload := MTOShipment(nil, &mtoShipment, nil) + + // Assertions + suite.NotNil(payload, "Expected payload to not be nil") + suite.NotNil(payload.PodLocation, "Expected PODLocation to not be nil") + suite.Equal("PDX", payload.PodLocation.PortCode, "Expected POD Port Code to match") + suite.Equal("PORTLAND INTL", payload.PodLocation.PortName, "Expected POD Port Name to match") + + suite.Nil(payload.PoeLocation, "Expected PODLocation to be nil when PODLocation is set") }) } From db670f53051e850b2fe5f40dde3caa3d2a3ec295 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 3 Jan 2025 14:15:23 +0000 Subject: [PATCH 23/35] B-21507 Fix formatting --- pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index b60ebc43499..6a21c96a873 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -1026,7 +1026,6 @@ func (suite *PayloadsSuite) TestMTOShipment_POE_POD_Locations() { suite.NotNil(payload.PoeLocation, "Expected POELocation to not be nil") suite.Equal("PDX", payload.PoeLocation.PortCode, "Expected POE Port Code to match") suite.Equal("PORTLAND INTL", payload.PoeLocation.PortName, "Expected POE Port Name to match") - suite.Nil(payload.PodLocation, "Expected PODLocation to be nil when POELocation is set") }) @@ -1069,7 +1068,6 @@ func (suite *PayloadsSuite) TestMTOShipment_POE_POD_Locations() { suite.NotNil(payload.PodLocation, "Expected PODLocation to not be nil") suite.Equal("PDX", payload.PodLocation.PortCode, "Expected POD Port Code to match") suite.Equal("PORTLAND INTL", payload.PodLocation.PortName, "Expected POD Port Name to match") - suite.Nil(payload.PoeLocation, "Expected PODLocation to be nil when PODLocation is set") }) } From d33da9a27e1fafb3a038a857eeece8799347d590 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 3 Jan 2025 18:12:00 +0000 Subject: [PATCH 24/35] B-21507 Update shipmentDisplay.test so a dash is expected --- src/utils/shipmentDisplay.test.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/shipmentDisplay.test.jsx b/src/utils/shipmentDisplay.test.jsx index c3718fec6b4..4fa0ed8aa9e 100644 --- a/src/utils/shipmentDisplay.test.jsx +++ b/src/utils/shipmentDisplay.test.jsx @@ -363,9 +363,9 @@ describe('shipmentDisplay utils', () => { expect(formattedPortInfo).toEqual('PDX - PORTLAND INTL\nPORTLAND, OREGON 97220'); }); - it('returns an empty string when no port is provided', () => { + it('returns a dash when no port is provided', () => { const formattedPortInfo = formatPortInfo(null); - expect(formattedPortInfo).toEqual(''); + expect(formattedPortInfo).toEqual('-'); }); }); }); From 80aee2082ff7dbf535c8e761335000bae695ae13 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 3 Jan 2025 18:34:41 +0000 Subject: [PATCH 25/35] B-21507 Fix check-generated-code test --- pkg/gen/ghcapi/embedded_spec.go | 6 - pkg/gen/ghcmessages/m_t_o_shipment.go | 51 ------- swagger/ghc.yaml | 192 +++++++++++++------------- 3 files changed, 96 insertions(+), 153 deletions(-) diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index 082916278f4..090e0c3addf 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -9687,9 +9687,6 @@ func init() { "poeLocation": { "$ref": "#/definitions/Port" }, - "port": { - "$ref": "#/definitions/Port" - }, "ppmShipment": { "$ref": "#/definitions/PPMShipment" }, @@ -26549,9 +26546,6 @@ func init() { "poeLocation": { "$ref": "#/definitions/Port" }, - "port": { - "$ref": "#/definitions/Port" - }, "ppmShipment": { "$ref": "#/definitions/PPMShipment" }, diff --git a/pkg/gen/ghcmessages/m_t_o_shipment.go b/pkg/gen/ghcmessages/m_t_o_shipment.go index 144c129df34..793859afdfc 100644 --- a/pkg/gen/ghcmessages/m_t_o_shipment.go +++ b/pkg/gen/ghcmessages/m_t_o_shipment.go @@ -157,9 +157,6 @@ type MTOShipment struct { // poe location PoeLocation *Port `json:"poeLocation,omitempty"` - // port - Port *Port `json:"port,omitempty"` - // ppm shipment PpmShipment *PPMShipment `json:"ppmShipment,omitempty"` @@ -335,10 +332,6 @@ func (m *MTOShipment) Validate(formats strfmt.Registry) error { res = append(res, err) } - if err := m.validatePort(formats); err != nil { - res = append(res, err) - } - if err := m.validatePpmShipment(formats); err != nil { res = append(res, err) } @@ -757,25 +750,6 @@ func (m *MTOShipment) validatePoeLocation(formats strfmt.Registry) error { return nil } -func (m *MTOShipment) validatePort(formats strfmt.Registry) error { - if swag.IsZero(m.Port) { // not required - return nil - } - - if m.Port != nil { - if err := m.Port.Validate(formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("port") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("port") - } - return err - } - } - - return nil -} - func (m *MTOShipment) validatePpmShipment(formats strfmt.Registry) error { if swag.IsZero(m.PpmShipment) { // not required return nil @@ -1137,10 +1111,6 @@ func (m *MTOShipment) ContextValidate(ctx context.Context, formats strfmt.Regist res = append(res, err) } - if err := m.contextValidatePort(ctx, formats); err != nil { - res = append(res, err) - } - if err := m.contextValidatePpmShipment(ctx, formats); err != nil { res = append(res, err) } @@ -1408,27 +1378,6 @@ func (m *MTOShipment) contextValidatePoeLocation(ctx context.Context, formats st return nil } -func (m *MTOShipment) contextValidatePort(ctx context.Context, formats strfmt.Registry) error { - - if m.Port != nil { - - if swag.IsZero(m.Port) { // not required - return nil - } - - if err := m.Port.ContextValidate(ctx, formats); err != nil { - if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("port") - } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("port") - } - return err - } - } - - return nil -} - func (m *MTOShipment) contextValidatePpmShipment(ctx context.Context, formats strfmt.Registry) error { if m.PpmShipment != nil { diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index 1426c305432..b167a637b3c 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -9279,102 +9279,6 @@ definitions: given SIT service items for an instance of SIT (Either Origin or Destination), grouped by the date they went into SIT and service items limited explicitly to SIT related Re Service Codes. - Port: - description: A port that is used to move an international shipment. - type: object - properties: - id: - type: string - format: uuid - example: c56a4180-65aa-42ec-a945-5fd21dec0538 - portType: - type: string - description: Port type A (Air), B (Border Crossing), S (Sea) - enum: - - A - - B - - S - portCode: - type: string - description: 3 or 4 digit port code - example: '0431' - portName: - type: string - description: Name of the port - example: PORTLAND INTL - city: - type: string - example: PORTLAND - county: - type: string - example: MULTNOMAH - state: - type: string - description: US state - example: OR - enum: - - AL - - AK - - AR - - AZ - - CA - - CO - - CT - - DC - - DE - - FL - - GA - - HI - - IA - - ID - - IL - - IN - - KS - - KY - - LA - - MA - - MD - - ME - - MI - - MN - - MO - - MS - - MT - - NC - - ND - - NE - - NH - - NJ - - NM - - NV - - NY - - OH - - OK - - OR - - PA - - RI - - SC - - SD - - TN - - TX - - UT - - VA - - VT - - WA - - WI - - WV - - WY - zip: - type: string - format: zip - title: ZIP - example: '99501' - pattern: ^(\d{5}([\-]\d{4})?)$ - country: - type: string - example: US - pattern: ^[A-Z]{2}$ - description: Two-letter country code PPMShipmentStatus: description: | Status of the PPM Shipment: @@ -10483,6 +10387,102 @@ definitions: - originalAddress - newAddress - contractorRemarks + Port: + description: A port that is used to move an international shipment. + type: object + properties: + id: + type: string + format: uuid + example: c56a4180-65aa-42ec-a945-5fd21dec0538 + portType: + type: string + description: Port type A (Air), B (Border Crossing), S (Sea) + enum: + - A + - B + - S + portCode: + type: string + description: 3 or 4 digit port code + example: '0431' + portName: + type: string + description: Name of the port + example: PORTLAND INTL + city: + type: string + example: PORTLAND + county: + type: string + example: MULTNOMAH + state: + type: string + description: US state + example: OR + enum: + - AL + - AK + - AR + - AZ + - CA + - CO + - CT + - DC + - DE + - FL + - GA + - HI + - IA + - ID + - IL + - IN + - KS + - KY + - LA + - MA + - MD + - ME + - MI + - MN + - MO + - MS + - MT + - NC + - ND + - NE + - NH + - NJ + - NM + - NV + - NY + - OH + - OK + - OR + - PA + - RI + - SC + - SD + - TN + - TX + - UT + - VA + - VT + - WA + - WI + - WV + - WY + zip: + type: string + format: zip + title: ZIP + example: '99501' + pattern: ^(\d{5}([\-]\d{4})?)$ + country: + type: string + example: US + pattern: ^[A-Z]{2}$ + description: Two-letter country code MTOShipment: properties: moveTaskOrderID: From d9a309b1540e123a2fad02dabe376458325bcafa Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Fri, 3 Jan 2025 19:23:52 +0000 Subject: [PATCH 26/35] Run server_generate locally. --- pkg/gen/ghcapi/embedded_spec.go | 6 - swagger/ghc.yaml | 194 ++++++++++++++++---------------- 2 files changed, 96 insertions(+), 104 deletions(-) diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index df414676a4b..61bd52e4f5c 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -9992,9 +9992,6 @@ func init() { "poeLocation": { "$ref": "#/definitions/Port" }, - "port": { - "$ref": "#/definitions/Port" - }, "ppmShipment": { "$ref": "#/definitions/PPMShipment" }, @@ -27201,9 +27198,6 @@ func init() { "poeLocation": { "$ref": "#/definitions/Port" }, - "port": { - "$ref": "#/definitions/Port" - }, "ppmShipment": { "$ref": "#/definitions/PPMShipment" }, diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index 5e5525e6588..23c28fdb556 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -9521,102 +9521,6 @@ definitions: given SIT service items for an instance of SIT (Either Origin or Destination), grouped by the date they went into SIT and service items limited explicitly to SIT related Re Service Codes. - Port: - description: A port that is used to move an international shipment. - type: object - properties: - id: - type: string - format: uuid - example: c56a4180-65aa-42ec-a945-5fd21dec0538 - portType: - type: string - description: Port type A (Air), B (Border Crossing), S (Sea) - enum: - - A - - B - - S - portCode: - type: string - description: 3 or 4 digit port code - example: '0431' - portName: - type: string - description: Name of the port - example: PORTLAND INTL - city: - type: string - example: PORTLAND - county: - type: string - example: MULTNOMAH - state: - type: string - description: US state - example: OR - enum: - - AL - - AK - - AR - - AZ - - CA - - CO - - CT - - DC - - DE - - FL - - GA - - HI - - IA - - ID - - IL - - IN - - KS - - KY - - LA - - MA - - MD - - ME - - MI - - MN - - MO - - MS - - MT - - NC - - ND - - NE - - NH - - NJ - - NM - - NV - - NY - - OH - - OK - - OR - - PA - - RI - - SC - - SD - - TN - - TX - - UT - - VA - - VT - - WA - - WI - - WV - - WY - zip: - type: string - format: zip - title: ZIP - example: '99501' - pattern: ^(\d{5}([\-]\d{4})?)$ - country: - type: string - example: US - pattern: ^[A-Z]{2}$ - description: Two-letter country code PPMShipmentStatus: description: | Status of the PPM Shipment: @@ -10725,6 +10629,102 @@ definitions: - originalAddress - newAddress - contractorRemarks + Port: + description: A port that is used to move an international shipment. + type: object + properties: + id: + type: string + format: uuid + example: c56a4180-65aa-42ec-a945-5fd21dec0538 + portType: + type: string + description: Port type A (Air), B (Border Crossing), S (Sea) + enum: + - A + - B + - S + portCode: + type: string + description: 3 or 4 digit port code + example: '0431' + portName: + type: string + description: Name of the port + example: PORTLAND INTL + city: + type: string + example: PORTLAND + county: + type: string + example: MULTNOMAH + state: + type: string + description: US state + example: OR + enum: + - AL + - AK + - AR + - AZ + - CA + - CO + - CT + - DC + - DE + - FL + - GA + - HI + - IA + - ID + - IL + - IN + - KS + - KY + - LA + - MA + - MD + - ME + - MI + - MN + - MO + - MS + - MT + - NC + - ND + - NE + - NH + - NJ + - NM + - NV + - NY + - OH + - OK + - OR + - PA + - RI + - SC + - SD + - TN + - TX + - UT + - VA + - VT + - WA + - WI + - WV + - WY + zip: + type: string + format: zip + title: ZIP + example: '99501' + pattern: ^(\d{5}([\-]\d{4})?)$ + country: + type: string + example: US + pattern: ^[A-Z]{2}$ + description: Two-letter country code MTOShipment: properties: moveTaskOrderID: @@ -10927,8 +10927,6 @@ definitions: storageFacility: x-nullable: true $ref: '#/definitions/StorageFacility' - port: - $ref: '#/definitions/Port' ppmShipment: $ref: '#/definitions/PPMShipment' boatShipment: From 124d4e918b9397cfede4e7b816adf2cc2125158f Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Mon, 6 Jan 2025 17:12:39 +0000 Subject: [PATCH 27/35] B-21507 Consolidate payload functions for Ports Refactor model_to_payload tests for updated Port function --- .../internal/payloads/model_to_payload.go | 52 +++++++++---------- .../payloads/model_to_payload_test.go | 20 +++++-- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go index 973503d1686..47fb77b86b3 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go @@ -1521,8 +1521,8 @@ func MTOShipment(storer storage.FileStorer, mtoShipment *models.MTOShipment, sit DeliveryAddressUpdate: ShipmentAddressUpdate(mtoShipment.DeliveryAddressUpdate), ShipmentLocator: handlers.FmtStringPtr(mtoShipment.ShipmentLocator), MarketCode: MarketCode(&mtoShipment.MarketCode), - PoeLocation: getPortLocation(mtoShipment.MTOServiceItems, "POE"), - PodLocation: getPortLocation(mtoShipment.MTOServiceItems, "POD"), + PoeLocation: Port(mtoShipment.MTOServiceItems, "POE"), + PodLocation: Port(mtoShipment.MTOServiceItems, "POD"), } if mtoShipment.Distance != nil { @@ -2709,37 +2709,33 @@ func ReServiceItems(reServiceItems models.ReServiceItems) ghcmessages.ReServiceI return payload } -// Port payload -func Port(portLocation *models.PortLocation) *ghcmessages.Port { - if portLocation == nil { - return nil - } - return &ghcmessages.Port{ - ID: strfmt.UUID(portLocation.ID.String()), - PortType: portLocation.Port.PortType.String(), - PortCode: portLocation.Port.PortCode, - PortName: portLocation.Port.PortName, - City: portLocation.City.CityName, - County: portLocation.UsPostRegionCity.UsprcCountyNm, - State: portLocation.UsPostRegionCity.UsPostRegion.State.StateName, - Zip: portLocation.UsPostRegionCity.UsprZipID, - Country: portLocation.Country.CountryName, - } -} - -// Get POD/POE info from MTO shipment's service items -func getPortLocation(mtoServiceItems models.MTOServiceItems, portType string) *ghcmessages.Port { +func Port(mtoServiceItems models.MTOServiceItems, portType string) *ghcmessages.Port { if mtoServiceItems == nil { return nil } - var portLocation *ghcmessages.Port + for _, mtoServiceItem := range mtoServiceItems { - if mtoServiceItem.POELocation != nil && portType == "POE" { - portLocation = Port(mtoServiceItem.POELocation) + var portLocation *models.PortLocation + if portType == "POE" && mtoServiceItem.POELocation != nil { + portLocation = mtoServiceItem.POELocation } - if mtoServiceItem.PODLocation != nil && portType == "POD" { - portLocation = Port(mtoServiceItem.PODLocation) + if portType == "POD" && mtoServiceItem.PODLocation != nil { + portLocation = mtoServiceItem.PODLocation + } + + if portLocation != nil { + return &ghcmessages.Port{ + ID: strfmt.UUID(portLocation.ID.String()), + PortType: portLocation.Port.PortType.String(), + PortCode: portLocation.Port.PortCode, + PortName: portLocation.Port.PortName, + City: portLocation.City.CityName, + County: portLocation.UsPostRegionCity.UsprcCountyNm, + State: portLocation.UsPostRegionCity.UsPostRegion.State.StateName, + Zip: portLocation.UsPostRegionCity.UsprZipID, + Country: portLocation.Country.CountryName, + } } } - return portLocation + return nil } diff --git a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go index 6a21c96a873..ff6a37444fa 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload_test.go @@ -954,8 +954,8 @@ func (suite *PayloadsSuite) TestMTOServiceItemModel() { func (suite *PayloadsSuite) TestPort() { suite.Run("returns nil when PortLocation is nil", func() { - var portLocation *models.PortLocation = nil - result := Port(portLocation) + var mtoServiceItems models.MTOServiceItems = nil + result := Port(mtoServiceItems, "POE") suite.Nil(result, "Expected result to be nil when Port Location is nil") }) @@ -969,8 +969,22 @@ func (suite *PayloadsSuite) TestPort() { }, }, nil) + mtoServiceItem := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: models.ReServiceCodePOEFSC, + }, + }, + { + Model: portLocation, + LinkOnly: true, + Type: &factory.PortLocations.PortOfEmbarkation, + }, + }, nil) + // Actual - result := Port(&portLocation) + mtoServiceItems := models.MTOServiceItems{mtoServiceItem} + result := Port(mtoServiceItems, "POE") // Assert suite.IsType(&ghcmessages.Port{}, result) From a77c1e9e096c1e3b68d78e933ba1cc70df3ba74c Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Mon, 6 Jan 2025 21:34:00 +0000 Subject: [PATCH 28/35] B-21507 Use 'else if' to improve efficiency --- migrations/app/migrations_manifest.txt | 2 +- pkg/handlers/ghcapi/internal/payloads/model_to_payload.go | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/migrations/app/migrations_manifest.txt b/migrations/app/migrations_manifest.txt index 18c13cdaa73..a5330171a14 100644 --- a/migrations/app/migrations_manifest.txt +++ b/migrations/app/migrations_manifest.txt @@ -1052,9 +1052,9 @@ 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 -20241218201833_add_PPPO_BASE_ELIZABETH.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/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go index 47fb77b86b3..71f9188f076 100644 --- a/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go +++ b/pkg/handlers/ghcapi/internal/payloads/model_to_payload.go @@ -2718,8 +2718,7 @@ func Port(mtoServiceItems models.MTOServiceItems, portType string) *ghcmessages. var portLocation *models.PortLocation if portType == "POE" && mtoServiceItem.POELocation != nil { portLocation = mtoServiceItem.POELocation - } - if portType == "POD" && mtoServiceItem.PODLocation != nil { + } else if portType == "POD" && mtoServiceItem.PODLocation != nil { portLocation = mtoServiceItem.PODLocation } From f0d0742558eba5654097d69bcd895854be9772f9 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Tue, 7 Jan 2025 18:07:03 +0000 Subject: [PATCH 29/35] B-21507 Add poe location to ShipmentDetails.stories.jsx --- .../Office/ShipmentDetails/ShipmentDetails.stories.jsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/components/Office/ShipmentDetails/ShipmentDetails.stories.jsx b/src/components/Office/ShipmentDetails/ShipmentDetails.stories.jsx index 107bed9636c..15d814d367a 100644 --- a/src/components/Office/ShipmentDetails/ShipmentDetails.stories.jsx +++ b/src/components/Office/ShipmentDetails/ShipmentDetails.stories.jsx @@ -109,6 +109,13 @@ const shipment = { serviceOrderNumber: '1234', tacType: LOA_TYPE.HHG, sacType: LOA_TYPE.NTS, + poeLocation: { + portCode: 'PDX', + portName: 'PORTLAND INTL', + city: 'PORTLAND', + state: 'OREGON', + zip: '97220', + }, }; const order = { From 4ed67d02f7a5025a66ff7e1b2f98e8ca112d1313 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Tue, 7 Jan 2025 18:19:23 +0000 Subject: [PATCH 30/35] B-21507 Hide POE/POD Location UI if there isn't a value --- .../Office/ShipmentAddresses/ShipmentAddresses.jsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx index 876aca3a848..af0f44a383c 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx @@ -87,10 +87,12 @@ const ShipmentAddresses = ({ icon={} data-testid="pickupDestinationAddress" /> - + {(poeLocation || podLocation) && ( + + )} ); }; From 17cb068b9723c6c21b68250971a438eb0ac55d0c Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Tue, 7 Jan 2025 20:33:42 +0000 Subject: [PATCH 31/35] B-21507 Move port location formatter to formatters.js Add toTitleCase function to formatters.js Update test files --- .../ShipmentAddresses/ShipmentAddresses.jsx | 3 +- .../ShipmentAddresses.test.jsx | 2 - src/utils/formatters.js | 28 ++++++++++ src/utils/formatters.test.js | 51 +++++++++++++++++++ src/utils/shipmentDisplay.jsx | 12 ----- src/utils/shipmentDisplay.test.jsx | 20 -------- 6 files changed, 81 insertions(+), 35 deletions(-) diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx index af0f44a383c..3fe5d3e849e 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.jsx @@ -5,12 +5,13 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Button } from '@trussworks/react-uswds'; import { AddressShape } from '../../../types/address'; -import { formatAddress, formatCityStateAndPostalCode, formatPortInfo } from '../../../utils/shipmentDisplay'; +import { formatAddress, formatCityStateAndPostalCode } from '../../../utils/shipmentDisplay'; import DataTableWrapper from '../../DataTableWrapper/index'; import DataTable from '../../DataTable/index'; import styles from './ShipmentAddresses.module.scss'; +import { formatPortInfo } from 'utils/formatters'; import { shipmentStatuses } from 'constants/shipments'; import { ShipmentOptionsOneOf, ShipmentStatusesOneOf } from 'types/shipment'; import { SHIPMENT_OPTIONS } from 'shared/constants'; diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx index 9521d67fbbb..2f35934a6c0 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx @@ -186,8 +186,6 @@ describe('ShipmentAddresses', () => { it('shows correct headings for HHG', () => { render(); expect(screen.getByText("Customer's addresses")).toBeInTheDocument(); - expect(screen.getByText('Port of Embarkation')).toBeInTheDocument(); - expect(screen.getByText('Port of Debarkation')).toBeInTheDocument(); }); it('shows correct headings for NTS', () => { diff --git a/src/utils/formatters.js b/src/utils/formatters.js index b0eee711141..c2e209377c7 100644 --- a/src/utils/formatters.js +++ b/src/utils/formatters.js @@ -583,3 +583,31 @@ export const constructSCOrderOconusFields = (values) => { null, }; }; + +/** + * @description Converts a string to title case (capitalizes the first letter of each word) + * @param {string} str - The input string to format. + * @returns {string} - the formatted string in the title case. + * */ +export function toTitleCase(str) { + if (!str) return ''; + return str + .toLowerCase() + .split(' ') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); +} + +/** + * @description This function is used to format the port in the + * ShipmentAddresses component. + * It displays only the port code, port name, city, state and zip code. + * */ +export function formatPortInfo(port) { + if (port) { + const formattedCity = toTitleCase(port.city); + const formattedState = toTitleCase(port.state); + return `${port.portCode} - ${port.portName}\n${formattedCity}, ${formattedState} ${port.zip}`; + } + return '-'; +} diff --git a/src/utils/formatters.test.js b/src/utils/formatters.test.js index 481cea6cf7a..e6629944ba8 100644 --- a/src/utils/formatters.test.js +++ b/src/utils/formatters.test.js @@ -433,3 +433,54 @@ describe('constructSCOrderOconusFields', () => { }); }); }); + +describe('formatPortInfo', () => { + it('formats port information correctly when all fields are provided', () => { + const values = { + portCode: 'PDX', + portName: 'PORTLAND INTL', + city: 'PORTLAND', + state: 'OREGON', + zip: '97220', + }; + const result = formatters.formatPortInfo(values); + expect(result).toEqual('PDX - PORTLAND INTL\nPortland, Oregon 97220'); + }); + + it('returns a dash when no port is provided', () => { + const result = formatters.formatPortInfo(null); + expect(result).toEqual('-'); + }); +}); + +describe('toTitleCase', () => { + it('correctly formats a lowercase string', () => { + const values = 'portland oregon'; + const result = formatters.toTitleCase(values); + expect(result).toEqual('Portland Oregon'); + }); + + it('correctly formats an uppercase string', () => { + const values = 'PORTLAND OREGON'; + const result = formatters.toTitleCase(values); + expect(result).toEqual('Portland Oregon'); + }); + + it('return an empty string when given an empty string', () => { + const values = ''; + const result = formatters.toTitleCase(values); + expect(result).toEqual(''); + }); + + it('return an empty string when given when input is null', () => { + const values = null; + const result = formatters.toTitleCase(values); + expect(result).toEqual(''); + }); + + it('does not alter strings that are already in title case', () => { + const values = 'Portland Oregon'; + const result = formatters.toTitleCase(values); + expect(result).toEqual('Portland Oregon'); + }); +}); diff --git a/src/utils/shipmentDisplay.jsx b/src/utils/shipmentDisplay.jsx index 546fd1b7ff0..ebde35e2071 100644 --- a/src/utils/shipmentDisplay.jsx +++ b/src/utils/shipmentDisplay.jsx @@ -163,18 +163,6 @@ export function formatCityStateAndPostalCode(address) { return ''; } -/** - * @description This function is used to format the port in the - * ShipmentAddresses component. - * It displays only the port code, port name, city, state and zip code. - * */ -export function formatPortInfo(port) { - if (port) { - return `${port.portCode} - ${port.portName}\n${port.city}, ${port.state} ${port.zip}`; - } - return '-'; -} - export function getShipmentModificationType(shipment) { if (shipment.status === shipmentStatuses.CANCELED) { return shipmentModificationTypes.CANCELED; diff --git a/src/utils/shipmentDisplay.test.jsx b/src/utils/shipmentDisplay.test.jsx index 4fa0ed8aa9e..2d36c3fdf24 100644 --- a/src/utils/shipmentDisplay.test.jsx +++ b/src/utils/shipmentDisplay.test.jsx @@ -13,7 +13,6 @@ import { getShipmentModificationType, retrieveSAC, retrieveTAC, - formatPortInfo, } from './shipmentDisplay'; import { LOA_TYPE } from 'shared/constants'; @@ -349,23 +348,4 @@ describe('shipmentDisplay utils', () => { expect(shipmentType).toEqual(shipmentModificationTypes.DIVERSION); }); }); - - describe('formatPortInfo', () => { - it('formats port information correctly when all fields are provided', () => { - const port = { - portCode: 'PDX', - portName: 'PORTLAND INTL', - city: 'PORTLAND', - state: 'OREGON', - zip: '97220', - }; - const formattedPortInfo = formatPortInfo(port); - expect(formattedPortInfo).toEqual('PDX - PORTLAND INTL\nPORTLAND, OREGON 97220'); - }); - - it('returns a dash when no port is provided', () => { - const formattedPortInfo = formatPortInfo(null); - expect(formattedPortInfo).toEqual('-'); - }); - }); }); From 502e892e4ba1c41506b960deca1be3d13ebbce14 Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Tue, 7 Jan 2025 21:59:43 +0000 Subject: [PATCH 32/35] B-21507 Start adding test to mto_shipment_fetcher_test.go --- .../mto_shipment/mto_shipment_fetcher_test.go | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/pkg/services/mto_shipment/mto_shipment_fetcher_test.go b/pkg/services/mto_shipment/mto_shipment_fetcher_test.go index 97fc19ca4ea..deb334f4cfe 100644 --- a/pkg/services/mto_shipment/mto_shipment_fetcher_test.go +++ b/pkg/services/mto_shipment/mto_shipment_fetcher_test.go @@ -216,7 +216,7 @@ func (suite *MTOShipmentServiceSuite) TestListMTOShipments() { }, }, []factory.Trait{factory.GetTraitShipmentAddressUpdateRequested}) - serviceItem := testdatagen.MakeMTOServiceItemDomesticCrating(suite.DB(), testdatagen.Assertions{ + serviceItemDCRT := testdatagen.MakeMTOServiceItemDomesticCrating(suite.DB(), testdatagen.Assertions{ ReService: models.ReService{ Code: models.ReServiceCodeDCRT, }, @@ -224,6 +224,27 @@ func (suite *MTOShipmentServiceSuite) TestListMTOShipments() { Move: move, }) + portLocation := factory.FetchPortLocation(suite.DB(), []factory.Customization{ + { + Model: models.Port{ + PortCode: "PDX", + }, + }, + }, nil) + + serviceItemPort := factory.BuildMTOServiceItem(nil, []factory.Customization{ + { + Model: models.ReService{ + Code: models.ReServiceCodePOEFSC, + }, + }, + { + Model: portLocation, + LinkOnly: true, + Type: &factory.PortLocations.PortOfEmbarkation, + }, + }, nil) + agents := factory.BuildMTOAgent(suite.DB(), []factory.Customization{ { Model: shipment, @@ -253,7 +274,8 @@ func (suite *MTOShipmentServiceSuite) TestListMTOShipments() { actualShipment := mtoShipments[0] - suite.Equal(serviceItem.ReService.Code, actualShipment.MTOServiceItems[0].ReService.Code) + suite.Equal(serviceItemDCRT.ReService.Code, actualShipment.MTOServiceItems[0].ReService.Code) + suite.Equal(serviceItemPort.ReService.Code, actualShipment.MTOServiceItems[0].ReService.Code) suite.Equal(agents.ID.String(), actualShipment.MTOAgents[0].ID.String()) suite.Equal(shipment.PickupAddress.ID.String(), actualShipment.PickupAddress.ID.String()) suite.Equal(secondaryPickupAddress.ID.String(), actualShipment.SecondaryPickupAddress.ID.String()) From f960e09cb4291db062a22b3008a24b441ffd07ce Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Wed, 8 Jan 2025 15:03:08 +0000 Subject: [PATCH 33/35] B-21507 Fix serviceItemPortFSC to link to shipment model and pass DB argument --- pkg/services/mto_shipment/mto_shipment_fetcher_test.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/pkg/services/mto_shipment/mto_shipment_fetcher_test.go b/pkg/services/mto_shipment/mto_shipment_fetcher_test.go index deb334f4cfe..8a96b1ef739 100644 --- a/pkg/services/mto_shipment/mto_shipment_fetcher_test.go +++ b/pkg/services/mto_shipment/mto_shipment_fetcher_test.go @@ -232,7 +232,7 @@ func (suite *MTOShipmentServiceSuite) TestListMTOShipments() { }, }, nil) - serviceItemPort := factory.BuildMTOServiceItem(nil, []factory.Customization{ + serviceItemPortFSC := factory.BuildMTOServiceItem(suite.DB(), []factory.Customization{ { Model: models.ReService{ Code: models.ReServiceCodePOEFSC, @@ -243,6 +243,10 @@ func (suite *MTOShipmentServiceSuite) TestListMTOShipments() { LinkOnly: true, Type: &factory.PortLocations.PortOfEmbarkation, }, + { + Model: shipment, + LinkOnly: true, + }, }, nil) agents := factory.BuildMTOAgent(suite.DB(), []factory.Customization{ @@ -275,7 +279,7 @@ func (suite *MTOShipmentServiceSuite) TestListMTOShipments() { actualShipment := mtoShipments[0] suite.Equal(serviceItemDCRT.ReService.Code, actualShipment.MTOServiceItems[0].ReService.Code) - suite.Equal(serviceItemPort.ReService.Code, actualShipment.MTOServiceItems[0].ReService.Code) + suite.Equal(serviceItemPortFSC.ReService.Code, actualShipment.MTOServiceItems[1].ReService.Code) suite.Equal(agents.ID.String(), actualShipment.MTOAgents[0].ID.String()) suite.Equal(shipment.PickupAddress.ID.String(), actualShipment.PickupAddress.ID.String()) suite.Equal(secondaryPickupAddress.ID.String(), actualShipment.SecondaryPickupAddress.ID.String()) From d2e43bc33de1261b23af1b2c23b8b0a1c91865ab Mon Sep 17 00:00:00 2001 From: msaki-caci Date: Wed, 8 Jan 2025 15:43:21 +0000 Subject: [PATCH 34/35] B-21507 Update test on ShipmentAddresses.test.jsx --- .../ShipmentAddresses.test.jsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx b/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx index 2f35934a6c0..e99661d1032 100644 --- a/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx +++ b/src/components/Office/ShipmentAddresses/ShipmentAddresses.test.jsx @@ -119,6 +119,17 @@ const cancellationRequestedShipment = { }, }; +const shipmentWithPort = { + ...testProps, + poeLocation: { + portCode: 'PDX', + portName: 'PORTLAND INTL', + city: 'PORTLAND', + state: 'OREGON', + zip: '97220', + }, +}; + describe('ShipmentAddresses', () => { it('calls props.handleShowDiversionModal on request diversion button click', async () => { render( @@ -235,4 +246,10 @@ describe('ShipmentAddresses', () => { const requestDiversionBtn = screen.getByRole('button', { name: 'Request Diversion' }); expect(requestDiversionBtn).toBeDisabled(); }); + + it('renders port of embarkation and debarkation if one is set', async () => { + render(); + expect(screen.getByText('Port of Embarkation')).toBeInTheDocument(); + expect(screen.getByText('Port of Debarkation')).toBeInTheDocument(); + }); }); From 398055105c3d779e40365e40e8f860821de0de86 Mon Sep 17 00:00:00 2001 From: Logan Cunningham <148146808+loganwc@users.noreply.github.com> Date: Wed, 8 Jan 2025 13:26:18 -0600 Subject: [PATCH 35/35] B 21445 INT too bulk data (#14494) * added TOO query and handler for bulk management: * fixed query to meet hidden AC --- pkg/handlers/ghcapi/queues.go | 21 +++++++++ pkg/handlers/ghcapi/queues_test.go | 65 ++++++++++++++++++++++++++ pkg/services/move.go | 1 + pkg/services/move/move_fetcher.go | 47 +++++++++++++++++++ pkg/services/move/move_fetcher_test.go | 61 ++++++++++++++++++++++++ 5 files changed, 195 insertions(+) diff --git a/pkg/handlers/ghcapi/queues.go b/pkg/handlers/ghcapi/queues.go index e132e7942ba..ab48a061fc1 100644 --- a/pkg/handlers/ghcapi/queues.go +++ b/pkg/handlers/ghcapi/queues.go @@ -737,6 +737,27 @@ func (h GetBulkAssignmentDataHandler) Handle( return queues.NewGetBulkAssignmentDataInternalServerError(), err } + officeUserData = payloads.BulkAssignmentData(appCtx, moves, officeUsers, officeUser.TransportationOffice.ID) + case string(models.QueueTypeTaskOrder): + // fetch the TOOs who work at their office + officeUsers, err := h.OfficeUserFetcherPop.FetchOfficeUsersWithWorkloadByRoleAndOffice( + appCtx, + roles.RoleTypeTOO, + officeUser.TransportationOfficeID, + ) + if err != nil { + appCtx.Logger().Error("Error retreiving office users", zap.Error(err)) + return queues.NewGetBulkAssignmentDataInternalServerError(), err + } + // fetch the moves available to be assigned to their office users + moves, err := h.MoveFetcherBulkAssignment.FetchMovesForBulkAssignmentTaskOrder( + appCtx, officeUser.TransportationOffice.Gbloc, officeUser.TransportationOffice.ID, + ) + if err != nil { + appCtx.Logger().Error("Error retreiving moves", zap.Error(err)) + return queues.NewGetBulkAssignmentDataInternalServerError(), err + } + officeUserData = payloads.BulkAssignmentData(appCtx, moves, officeUsers, officeUser.TransportationOffice.ID) } return queues.NewGetBulkAssignmentDataOK().WithPayload(&officeUserData), nil diff --git a/pkg/handlers/ghcapi/queues_test.go b/pkg/handlers/ghcapi/queues_test.go index 631ccb1e52a..e0fb5a4007f 100644 --- a/pkg/handlers/ghcapi/queues_test.go +++ b/pkg/handlers/ghcapi/queues_test.go @@ -1884,4 +1884,69 @@ func (suite *HandlerSuite) TestGetBulkAssignmentDataHandler() { suite.Len(payload.AvailableOfficeUsers, 1) suite.Len(payload.BulkAssignmentMoveIDs, 1) }) + suite.Run("TOO: returns properly formatted bulk assignment data", func() { + transportationOffice := factory.BuildTransportationOffice(suite.DB(), nil, nil) + + officeUser := factory.BuildOfficeUserWithPrivileges(suite.DB(), []factory.Customization{ + { + Model: models.OfficeUser{ + Email: "officeuser1@example.com", + Active: true, + }, + }, + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CounselingOffice, + }, + { + Model: models.User{ + Privileges: []models.Privilege{ + { + PrivilegeType: models.PrivilegeTypeSupervisor, + }, + }, + Roles: []roles.Role{ + { + RoleType: roles.RoleTypeTOO, + }, + }, + }, + }, + }, nil) + + // move to appear in the return + factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + }, + }, + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CounselingOffice, + }, + }, nil) + + request := httptest.NewRequest("GET", "/queues/bulk-assignment", nil) + request = suite.AuthenticateOfficeRequest(request, officeUser) + params := queues.GetBulkAssignmentDataParams{ + HTTPRequest: request, + QueueType: models.StringPointer("TASK_ORDER"), + } + handlerConfig := suite.HandlerConfig() + handler := GetBulkAssignmentDataHandler{ + handlerConfig, + officeusercreator.NewOfficeUserFetcherPop(), + movefetcher.NewMoveFetcherBulkAssignment(), + } + response := handler.Handle(params) + suite.IsNotErrResponse(response) + suite.IsType(&queues.GetBulkAssignmentDataOK{}, response) + payload := response.(*queues.GetBulkAssignmentDataOK).Payload + suite.NoError(payload.Validate(strfmt.Default)) + suite.Len(payload.AvailableOfficeUsers, 1) + suite.Len(payload.BulkAssignmentMoveIDs, 1) + }) } diff --git a/pkg/services/move.go b/pkg/services/move.go index 237e360fe3f..8ddda83a8ec 100644 --- a/pkg/services/move.go +++ b/pkg/services/move.go @@ -31,6 +31,7 @@ type MoveFetcher interface { type MoveFetcherBulkAssignment interface { FetchMovesForBulkAssignmentCounseling(appCtx appcontext.AppContext, gbloc string, officeId uuid.UUID) ([]models.MoveWithEarliestDate, error) + FetchMovesForBulkAssignmentTaskOrder(appCtx appcontext.AppContext, gbloc string, officeId uuid.UUID) ([]models.MoveWithEarliestDate, error) } //go:generate mockery --name MoveSearcher diff --git a/pkg/services/move/move_fetcher.go b/pkg/services/move/move_fetcher.go index f4fc42dea57..a1ec1d8bbed 100644 --- a/pkg/services/move/move_fetcher.go +++ b/pkg/services/move/move_fetcher.go @@ -165,3 +165,50 @@ func (f moveFetcherBulkAssignment) FetchMovesForBulkAssignmentCounseling(appCtx return moves, nil } + +func (f moveFetcherBulkAssignment) FetchMovesForBulkAssignmentTaskOrder(appCtx appcontext.AppContext, gbloc string, officeId uuid.UUID) ([]models.MoveWithEarliestDate, error) { + var moves []models.MoveWithEarliestDate + + err := appCtx.DB(). + RawQuery(`SELECT + moves.id, + MIN(LEAST( + COALESCE(mto_shipments.requested_pickup_date, '9999-12-31'), + COALESCE(mto_shipments.requested_delivery_date, '9999-12-31'), + COALESCE(ppm_shipments.expected_departure_date, '9999-12-31') + )) AS earliest_date + FROM moves + INNER JOIN orders ON orders.id = moves.orders_id + INNER JOIN service_members ON orders.service_member_id = service_members.id + INNER JOIN mto_shipments ON mto_shipments.move_id = moves.id + LEFT JOIN ppm_shipments ON ppm_shipments.shipment_id = mto_shipments.id + LEFT JOIN move_to_gbloc ON move_to_gbloc.move_id = moves.id + WHERE + (moves.status IN ('APPROVALS REQUESTED', 'SUBMITTED', 'SERVICE COUNSELING COMPLETED')) + AND moves.show = $1 + AND moves.too_assigned_id IS NULL + AND (orders.orders_type NOT IN ($2, $3, $4)) + AND service_members.affiliation != 'MARINES' + AND ((mto_shipments.shipment_type != $5 AND move_to_gbloc.gbloc = $6) OR (mto_shipments.shipment_type = $7 AND orders.gbloc = $8)) + GROUP BY moves.id + ORDER BY earliest_date ASC`, + models.BoolPointer(true), + internalmessages.OrdersTypeBLUEBARK, + internalmessages.OrdersTypeWOUNDEDWARRIOR, + internalmessages.OrdersTypeSAFETY, + models.MTOShipmentTypeHHGOutOfNTSDom, + gbloc, + models.MTOShipmentTypeHHGOutOfNTSDom, + gbloc). + All(&moves) + + if err != nil { + return nil, fmt.Errorf("error fetching moves for office: %s with error %w", officeId, err) + } + + if len(moves) < 1 { + return nil, nil + } + + return moves, nil +} diff --git a/pkg/services/move/move_fetcher_test.go b/pkg/services/move/move_fetcher_test.go index 381199013cd..92fb23751bb 100644 --- a/pkg/services/move/move_fetcher_test.go +++ b/pkg/services/move/move_fetcher_test.go @@ -433,4 +433,65 @@ func (suite *MoveServiceSuite) TestMoveFetcherBulkAssignment() { // Orders type isn't WW, BB, or Safety suite.Equal(assignedMove.Orders.OrdersType, internalmessages.OrdersTypePERMANENTCHANGEOFSTATION) }) + + suite.Run("TOO: Returns moves that fulfill the query criteria", func() { + moveFetcher := NewMoveFetcherBulkAssignment() + transportationOffice := factory.BuildTransportationOffice(suite.DB(), nil, nil) + officeUser := factory.BuildOfficeUserWithRoles(suite.DB(), []factory.Customization{ + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CounselingOffice, + }, + }, []roles.RoleType{roles.RoleTypeTOO}) + + factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusAPPROVALSREQUESTED, + }, + }, + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CounselingOffice, + }, + }, nil) + + factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusServiceCounselingCompleted, + }, + }, + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CounselingOffice, + }, + }, nil) + + marine := models.AffiliationMARINES + factory.BuildMoveWithShipment(suite.DB(), []factory.Customization{ + { + Model: models.Move{ + Status: models.MoveStatusServiceCounselingCompleted, + }, + }, + { + Model: transportationOffice, + LinkOnly: true, + Type: &factory.TransportationOffices.CounselingOffice, + }, + { + Model: models.ServiceMember{ + Affiliation: &marine, + }, + }, + }, nil) + + moves, err := moveFetcher.FetchMovesForBulkAssignmentTaskOrder(suite.AppContextForTest(), "KKFA", officeUser.TransportationOffice.ID) + suite.FatalNoError(err) + suite.Equal(2, len(moves)) + }) }