From 3e184f52b56d0b6a96b70ec38dcd4ff57ed3457c Mon Sep 17 00:00:00 2001 From: loganwc Date: Tue, 17 Dec 2024 16:14:54 -0600 Subject: [PATCH 01/12] add key to column button wrapper --- src/pages/Office/PaymentRequestQueue/PaymentRequestQueue.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Office/PaymentRequestQueue/PaymentRequestQueue.jsx b/src/pages/Office/PaymentRequestQueue/PaymentRequestQueue.jsx index e93cba3ff65..3523419616b 100644 --- a/src/pages/Office/PaymentRequestQueue/PaymentRequestQueue.jsx +++ b/src/pages/Office/PaymentRequestQueue/PaymentRequestQueue.jsx @@ -157,7 +157,7 @@ export const columns = (moveLockFlag, isQueueManagementEnabled, showBranchFilter {row.assignedTo ? `${row.assignedTo?.lastName}, ${row.assignedTo?.firstName}` : ''} ) : ( -
+
{ From 13a53ce330c8278f6d5805dc211d752c81666360 Mon Sep 17 00:00:00 2001 From: loganwc Date: Wed, 18 Dec 2024 16:50:29 +0000 Subject: [PATCH 02/12] add key to sc and too queue assigned column button wrapper --- src/pages/Office/MoveQueue/MoveQueue.jsx | 2 +- .../ServicesCounselingQueue/ServicesCounselingQueue.jsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/Office/MoveQueue/MoveQueue.jsx b/src/pages/Office/MoveQueue/MoveQueue.jsx index 0deb6a7e6c5..65dd072279d 100644 --- a/src/pages/Office/MoveQueue/MoveQueue.jsx +++ b/src/pages/Office/MoveQueue/MoveQueue.jsx @@ -158,7 +158,7 @@ export const columns = (moveLockFlag, isQueueManagementEnabled, showBranchFilter {row.assignedTo ? `${row.assignedTo?.lastName}, ${row.assignedTo?.firstName}` : ''}
) : ( -
+
handleQueueAssignment(row.id, e.target.value, roleTypes.TOO)} diff --git a/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx b/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx index 190a4095fd3..c71f307e548 100644 --- a/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx +++ b/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx @@ -202,7 +202,7 @@ export const counselingColumns = (moveLockFlag, originLocationList, supervisor, return !row?.assignable ? (
{row.assignedTo ? `${row.assignedTo?.lastName}, ${row.assignedTo?.firstName}` : ''}
) : ( -
+
handleQueueAssignment(row.id, e.target.value, roleTypes.SERVICES_COUNSELOR)} @@ -396,7 +396,7 @@ export const closeoutColumns = ( return !row?.assignable ? (
{row.assignedTo ? `${row.assignedTo?.lastName}, ${row.assignedTo?.firstName}` : ''}
) : ( -
+
handleQueueAssignment(row.id, e.target.value, roleTypes.SERVICES_COUNSELOR)} From 3873375a2bf5c86854d1f468c3ecc44342e41e11 Mon Sep 17 00:00:00 2001 From: loganwc Date: Wed, 18 Dec 2024 19:46:43 +0000 Subject: [PATCH 03/12] use row.id instead of entire obj --- src/pages/Office/MoveQueue/MoveQueue.jsx | 2 +- src/pages/Office/PaymentRequestQueue/PaymentRequestQueue.jsx | 2 +- .../ServicesCounselingQueue/ServicesCounselingQueue.jsx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/Office/MoveQueue/MoveQueue.jsx b/src/pages/Office/MoveQueue/MoveQueue.jsx index 65dd072279d..c98bb1995f1 100644 --- a/src/pages/Office/MoveQueue/MoveQueue.jsx +++ b/src/pages/Office/MoveQueue/MoveQueue.jsx @@ -158,7 +158,7 @@ export const columns = (moveLockFlag, isQueueManagementEnabled, showBranchFilter {row.assignedTo ? `${row.assignedTo?.lastName}, ${row.assignedTo?.firstName}` : ''}
) : ( -
+
handleQueueAssignment(row.id, e.target.value, roleTypes.TOO)} diff --git a/src/pages/Office/PaymentRequestQueue/PaymentRequestQueue.jsx b/src/pages/Office/PaymentRequestQueue/PaymentRequestQueue.jsx index 3523419616b..4252100344f 100644 --- a/src/pages/Office/PaymentRequestQueue/PaymentRequestQueue.jsx +++ b/src/pages/Office/PaymentRequestQueue/PaymentRequestQueue.jsx @@ -157,7 +157,7 @@ export const columns = (moveLockFlag, isQueueManagementEnabled, showBranchFilter {row.assignedTo ? `${row.assignedTo?.lastName}, ${row.assignedTo?.firstName}` : ''}
) : ( -
+
{ diff --git a/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx b/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx index c71f307e548..51ba0324c12 100644 --- a/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx +++ b/src/pages/Office/ServicesCounselingQueue/ServicesCounselingQueue.jsx @@ -202,7 +202,7 @@ export const counselingColumns = (moveLockFlag, originLocationList, supervisor, return !row?.assignable ? (
{row.assignedTo ? `${row.assignedTo?.lastName}, ${row.assignedTo?.firstName}` : ''}
) : ( -
+
handleQueueAssignment(row.id, e.target.value, roleTypes.SERVICES_COUNSELOR)} @@ -396,7 +396,7 @@ export const closeoutColumns = ( return !row?.assignable ? (
{row.assignedTo ? `${row.assignedTo?.lastName}, ${row.assignedTo?.firstName}` : ''}
) : ( -
+
handleQueueAssignment(row.id, e.target.value, roleTypes.SERVICES_COUNSELOR)} From 677299fd12cd7eec72b0cef7d18753524de65148 Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Fri, 27 Dec 2024 22:54:26 +0000 Subject: [PATCH 04/12] B-22133 show edit button for port fsc service items --- src/constants/serviceItems.js | 6 ++- .../PrimeUI/MoveTaskOrder/MoveDetails.jsx | 4 +- .../MoveTaskOrder/MoveDetails.test.jsx | 48 ++++++++++++++++++- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/constants/serviceItems.js b/src/constants/serviceItems.js index 7a1a0f76502..cb8e35c95bf 100644 --- a/src/constants/serviceItems.js +++ b/src/constants/serviceItems.js @@ -165,7 +165,7 @@ const SERVICE_ITEMS_ALLOWED_WEIGHT_BILLED_PARAM = [ SERVICE_ITEM_CODES.FSC, ]; -const SIT_SERVICE_ITEMS_ALLOWED_UPDATE = [ +const SERVICE_ITEMS_ALLOWED_UPDATE = [ SERVICE_ITEM_CODES.DDDSIT, SERVICE_ITEM_CODES.DDASIT, SERVICE_ITEM_CODES.DOASIT, @@ -174,6 +174,8 @@ const SIT_SERVICE_ITEMS_ALLOWED_UPDATE = [ SERVICE_ITEM_CODES.DDFSIT, SERVICE_ITEM_CODES.DOSFSC, SERVICE_ITEM_CODES.DDSFSC, + SERVICE_ITEM_CODES.PODFSC, + SERVICE_ITEM_CODES.POEFSC, ]; /** @@ -228,5 +230,5 @@ export { allowedServiceItemCalculations, SERVICE_ITEM_STATUSES, SERVICE_ITEMS_ALLOWED_WEIGHT_BILLED_PARAM, - SIT_SERVICE_ITEMS_ALLOWED_UPDATE, + SERVICE_ITEMS_ALLOWED_UPDATE, }; diff --git a/src/pages/PrimeUI/MoveTaskOrder/MoveDetails.jsx b/src/pages/PrimeUI/MoveTaskOrder/MoveDetails.jsx index 92f5ec9bd55..45881d58602 100644 --- a/src/pages/PrimeUI/MoveTaskOrder/MoveDetails.jsx +++ b/src/pages/PrimeUI/MoveTaskOrder/MoveDetails.jsx @@ -21,7 +21,7 @@ import { usePrimeSimulatorGetMove } from 'hooks/queries'; import { completeCounseling, deleteShipment, downloadMoveOrder } from 'services/primeApi'; import { setFlashMessage as setFlashMessageAction } from 'store/flash/actions'; import scrollToTop from 'shared/scrollToTop'; -import { SIT_SERVICE_ITEMS_ALLOWED_UPDATE } from 'constants/serviceItems'; +import { SERVICE_ITEMS_ALLOWED_UPDATE } from 'constants/serviceItems'; import { MoveOrderDocumentType } from 'shared/constants'; import { CHECK_SPECIAL_ORDERS_TYPES, SPECIAL_ORDERS_TYPES } from 'constants/orders'; @@ -257,7 +257,7 @@ const MoveDetails = ({ setFlashMessage }) => { {serviceItem.reServiceCode} - {serviceItem.reServiceName}
- {SIT_SERVICE_ITEMS_ALLOWED_UPDATE.includes(serviceItem.reServiceCode) ? ( + {SERVICE_ITEMS_ALLOWED_UPDATE.includes(serviceItem.reServiceCode) ? ( { ); }); - it('shows edit button next to the right destination SIT service items', async () => { + it('shows edit button next to the right service items', async () => { usePrimeSimulatorGetMove.mockReturnValue(moveReturnValue); renderWithProviders(); // Check for Edit buttons const editButtons = screen.getAllByRole('link', { name: 'Edit' }); - expect(editButtons).toHaveLength(3); + expect(editButtons).toHaveLength(5); }); }); }); From 5de680ae93e1e68998e6bd444c41574e4027a650 Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Thu, 2 Jan 2025 15:13:50 +0000 Subject: [PATCH 05/12] B-22133 adds port fsc prime ui --- pkg/gen/primev3api/embedded_spec.go | 50 ++ pkg/gen/primev3messages/m_t_o_service_item.go | 6 + ...rvice_item_international_fuel_surcharge.go | 575 ++++++++++++++++++ .../primeapiv3/payloads/model_to_payload.go | 13 + ...dateInternationalFuelSurcharge.module.scss | 12 + ...UIUpdateInternationalFuelSurchargeForm.jsx | 102 ++++ ...ateInternationalFuelSurchargeForm.test.jsx | 101 +++ .../PrimeUIUpdateSitServiceItem.jsx | 21 + swagger-def/prime_v3.yaml | 2 + swagger/prime_v3.yaml | 19 + 10 files changed, 901 insertions(+) create mode 100644 pkg/gen/primev3messages/m_t_o_service_item_international_fuel_surcharge.go create mode 100644 src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurcharge.module.scss create mode 100644 src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx create mode 100644 src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx diff --git a/pkg/gen/primev3api/embedded_spec.go b/pkg/gen/primev3api/embedded_spec.go index bb5a844cfe0..f68a9ea6ebd 100644 --- a/pkg/gen/primev3api/embedded_spec.go +++ b/pkg/gen/primev3api/embedded_spec.go @@ -1636,6 +1636,31 @@ 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 * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", @@ -5890,6 +5915,31 @@ 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 * PODFSC, POEFSC - MTOSerivceItemInternationalFuelSurcharge\n\nThe documentation will then update with the supported fields.\n", "type": "string", diff --git a/pkg/gen/primev3messages/m_t_o_service_item.go b/pkg/gen/primev3messages/m_t_o_service_item.go index 9559114c004..d6861255a80 100644 --- a/pkg/gen/primev3messages/m_t_o_service_item.go +++ b/pkg/gen/primev3messages/m_t_o_service_item.go @@ -279,6 +279,12 @@ func unmarshalMTOServiceItem(data []byte, consumer runtime.Consumer) (MTOService return nil, err } return &result, nil + case "MTOServiceItemInternationalFuelSurcharge": + var result MTOServiceItemInternationalFuelSurcharge + if err := consumer.Consume(buf2, &result); err != nil { + return nil, err + } + return &result, nil case "MTOServiceItemOriginSIT": var result MTOServiceItemOriginSIT if err := consumer.Consume(buf2, &result); err != nil { diff --git a/pkg/gen/primev3messages/m_t_o_service_item_international_fuel_surcharge.go b/pkg/gen/primev3messages/m_t_o_service_item_international_fuel_surcharge.go new file mode 100644 index 00000000000..73d7c4e4c0b --- /dev/null +++ b/pkg/gen/primev3messages/m_t_o_service_item_international_fuel_surcharge.go @@ -0,0 +1,575 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package primev3messages + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "bytes" + "context" + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// MTOServiceItemInternationalFuelSurcharge Describes a international Port of Embarkation/Debarkation fuel surcharge service item subtype of a MTOServiceItem. +// +// swagger:model MTOServiceItemInternationalFuelSurcharge +type MTOServiceItemInternationalFuelSurcharge struct { + eTagField string + + idField strfmt.UUID + + lockedPriceCentsField *int64 + + moveTaskOrderIdField *strfmt.UUID + + mtoShipmentIdField strfmt.UUID + + reServiceNameField string + + rejectionReasonField *string + + serviceRequestDocumentsField ServiceRequestDocuments + + statusField MTOServiceItemStatus + + // A unique code for a Port + PortCode string `json:"portCode,omitempty"` + + // 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] + ReServiceCode string `json:"reServiceCode,omitempty"` +} + +// ETag gets the e tag of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) ETag() string { + return m.eTagField +} + +// SetETag sets the e tag of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetETag(val string) { + m.eTagField = val +} + +// ID gets the id of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) ID() strfmt.UUID { + return m.idField +} + +// SetID sets the id of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetID(val strfmt.UUID) { + m.idField = val +} + +// LockedPriceCents gets the locked price cents of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) LockedPriceCents() *int64 { + return m.lockedPriceCentsField +} + +// SetLockedPriceCents sets the locked price cents of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetLockedPriceCents(val *int64) { + m.lockedPriceCentsField = val +} + +// ModelType gets the model type of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) ModelType() MTOServiceItemModelType { + return "MTOServiceItemInternationalFuelSurcharge" +} + +// SetModelType sets the model type of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetModelType(val MTOServiceItemModelType) { +} + +// MoveTaskOrderID gets the move task order ID of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) MoveTaskOrderID() *strfmt.UUID { + return m.moveTaskOrderIdField +} + +// SetMoveTaskOrderID sets the move task order ID of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetMoveTaskOrderID(val *strfmt.UUID) { + m.moveTaskOrderIdField = val +} + +// MtoShipmentID gets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) MtoShipmentID() strfmt.UUID { + return m.mtoShipmentIdField +} + +// SetMtoShipmentID sets the mto shipment ID of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetMtoShipmentID(val strfmt.UUID) { + m.mtoShipmentIdField = val +} + +// ReServiceName gets the re service name of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) ReServiceName() string { + return m.reServiceNameField +} + +// SetReServiceName sets the re service name of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetReServiceName(val string) { + m.reServiceNameField = val +} + +// RejectionReason gets the rejection reason of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) RejectionReason() *string { + return m.rejectionReasonField +} + +// SetRejectionReason sets the rejection reason of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetRejectionReason(val *string) { + m.rejectionReasonField = val +} + +// ServiceRequestDocuments gets the service request documents of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) ServiceRequestDocuments() ServiceRequestDocuments { + return m.serviceRequestDocumentsField +} + +// SetServiceRequestDocuments sets the service request documents of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetServiceRequestDocuments(val ServiceRequestDocuments) { + m.serviceRequestDocumentsField = val +} + +// Status gets the status of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) Status() MTOServiceItemStatus { + return m.statusField +} + +// SetStatus sets the status of this subtype +func (m *MTOServiceItemInternationalFuelSurcharge) SetStatus(val MTOServiceItemStatus) { + m.statusField = val +} + +// UnmarshalJSON unmarshals this object with a polymorphic type from a JSON structure +func (m *MTOServiceItemInternationalFuelSurcharge) UnmarshalJSON(raw []byte) error { + var data struct { + + // A unique code for a Port + PortCode string `json:"portCode,omitempty"` + + // 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] + ReServiceCode string `json:"reServiceCode,omitempty"` + } + buf := bytes.NewBuffer(raw) + dec := json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&data); err != nil { + return err + } + + var base struct { + /* Just the base type fields. Used for unmashalling polymorphic types.*/ + + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + } + buf = bytes.NewBuffer(raw) + dec = json.NewDecoder(buf) + dec.UseNumber() + + if err := dec.Decode(&base); err != nil { + return err + } + + var result MTOServiceItemInternationalFuelSurcharge + + result.eTagField = base.ETag + + result.idField = base.ID + + result.lockedPriceCentsField = base.LockedPriceCents + + if base.ModelType != result.ModelType() { + /* Not the type we're looking for. */ + return errors.New(422, "invalid modelType value: %q", base.ModelType) + } + result.moveTaskOrderIdField = base.MoveTaskOrderID + + result.mtoShipmentIdField = base.MtoShipmentID + + result.reServiceNameField = base.ReServiceName + + result.rejectionReasonField = base.RejectionReason + + result.serviceRequestDocumentsField = base.ServiceRequestDocuments + + result.statusField = base.Status + + result.PortCode = data.PortCode + result.ReServiceCode = data.ReServiceCode + + *m = result + + return nil +} + +// MarshalJSON marshals this object with a polymorphic type to a JSON structure +func (m MTOServiceItemInternationalFuelSurcharge) MarshalJSON() ([]byte, error) { + var b1, b2, b3 []byte + var err error + b1, err = json.Marshal(struct { + + // A unique code for a Port + PortCode string `json:"portCode,omitempty"` + + // 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] + ReServiceCode string `json:"reServiceCode,omitempty"` + }{ + + PortCode: m.PortCode, + + ReServiceCode: m.ReServiceCode, + }) + if err != nil { + return nil, err + } + b2, err = json.Marshal(struct { + ETag string `json:"eTag,omitempty"` + + ID strfmt.UUID `json:"id,omitempty"` + + LockedPriceCents *int64 `json:"lockedPriceCents,omitempty"` + + ModelType MTOServiceItemModelType `json:"modelType"` + + MoveTaskOrderID *strfmt.UUID `json:"moveTaskOrderID"` + + MtoShipmentID strfmt.UUID `json:"mtoShipmentID,omitempty"` + + ReServiceName string `json:"reServiceName,omitempty"` + + RejectionReason *string `json:"rejectionReason,omitempty"` + + ServiceRequestDocuments ServiceRequestDocuments `json:"serviceRequestDocuments,omitempty"` + + Status MTOServiceItemStatus `json:"status,omitempty"` + }{ + + ETag: m.ETag(), + + ID: m.ID(), + + LockedPriceCents: m.LockedPriceCents(), + + ModelType: m.ModelType(), + + MoveTaskOrderID: m.MoveTaskOrderID(), + + MtoShipmentID: m.MtoShipmentID(), + + ReServiceName: m.ReServiceName(), + + RejectionReason: m.RejectionReason(), + + ServiceRequestDocuments: m.ServiceRequestDocuments(), + + Status: m.Status(), + }) + if err != nil { + return nil, err + } + + return swag.ConcatJSON(b1, b2, b3), nil +} + +// Validate validates this m t o service item international fuel surcharge +func (m *MTOServiceItemInternationalFuelSurcharge) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMoveTaskOrderID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMtoShipmentID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateServiceRequestDocuments(formats); err != nil { + res = append(res, err) + } + + if err := m.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := m.validateReServiceCode(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) 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 +} + +func (m *MTOServiceItemInternationalFuelSurcharge) validateMoveTaskOrderID(formats strfmt.Registry) error { + + if err := validate.Required("moveTaskOrderID", "body", m.MoveTaskOrderID()); err != nil { + return err + } + + if err := validate.FormatOf("moveTaskOrderID", "body", "uuid", m.MoveTaskOrderID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) validateMtoShipmentID(formats strfmt.Registry) error { + + if swag.IsZero(m.MtoShipmentID()) { // not required + return nil + } + + if err := validate.FormatOf("mtoShipmentID", "body", "uuid", m.MtoShipmentID().String(), formats); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) validateServiceRequestDocuments(formats strfmt.Registry) error { + + if swag.IsZero(m.ServiceRequestDocuments()) { // not required + return nil + } + + if err := m.ServiceRequestDocuments().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) validateStatus(formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +var mTOServiceItemInternationalFuelSurchargeTypeReServiceCodePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["PODFSC","POEFSC"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + mTOServiceItemInternationalFuelSurchargeTypeReServiceCodePropEnum = append(mTOServiceItemInternationalFuelSurchargeTypeReServiceCodePropEnum, v) + } +} + +// property enum +func (m *MTOServiceItemInternationalFuelSurcharge) validateReServiceCodeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, mTOServiceItemInternationalFuelSurchargeTypeReServiceCodePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) validateReServiceCode(formats strfmt.Registry) error { + + if swag.IsZero(m.ReServiceCode) { // not required + return nil + } + + // value enum + if err := m.validateReServiceCodeEnum("reServiceCode", "body", m.ReServiceCode); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this m t o service item international fuel surcharge based on the context it is used +func (m *MTOServiceItemInternationalFuelSurcharge) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateETag(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateID(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateReServiceName(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateRejectionReason(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateServiceRequestDocuments(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateStatus(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) contextValidateETag(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "eTag", "body", string(m.ETag())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) contextValidateID(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "id", "body", strfmt.UUID(m.ID())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) contextValidateModelType(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ModelType().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("modelType") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("modelType") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) contextValidateReServiceName(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "reServiceName", "body", string(m.ReServiceName())); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) contextValidateRejectionReason(ctx context.Context, formats strfmt.Registry) error { + + if err := validate.ReadOnly(ctx, "rejectionReason", "body", m.RejectionReason()); err != nil { + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) contextValidateServiceRequestDocuments(ctx context.Context, formats strfmt.Registry) error { + + if err := m.ServiceRequestDocuments().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("serviceRequestDocuments") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("serviceRequestDocuments") + } + return err + } + + return nil +} + +func (m *MTOServiceItemInternationalFuelSurcharge) contextValidateStatus(ctx context.Context, formats strfmt.Registry) error { + + if swag.IsZero(m.Status()) { // not required + return nil + } + + if err := m.Status().ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *MTOServiceItemInternationalFuelSurcharge) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *MTOServiceItemInternationalFuelSurcharge) UnmarshalBinary(b []byte) error { + var res MTOServiceItemInternationalFuelSurcharge + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/handlers/primeapiv3/payloads/model_to_payload.go b/pkg/handlers/primeapiv3/payloads/model_to_payload.go index f4cd6ab2609..d5cfb359355 100644 --- a/pkg/handlers/primeapiv3/payloads/model_to_payload.go +++ b/pkg/handlers/primeapiv3/payloads/model_to_payload.go @@ -803,6 +803,19 @@ func MTOServiceItem(mtoServiceItem *models.MTOServiceItem) primev3messages.MTOSe EstimatedWeight: handlers.FmtPoundPtr(mtoServiceItem.EstimatedWeight), ActualWeight: handlers.FmtPoundPtr(mtoServiceItem.ActualWeight), } + + case models.ReServiceCodePODFSC, models.ReServiceCodePOEFSC: + var portCode string + if mtoServiceItem.POELocation != nil { + portCode = mtoServiceItem.POELocation.Port.PortCode + } else if mtoServiceItem.PODLocation != nil { + portCode = mtoServiceItem.PODLocation.Port.PortCode + } + payload = &primev3messages.MTOServiceItemInternationalFuelSurcharge{ + ReServiceCode: string(mtoServiceItem.ReService.Code), + PortCode: portCode, + } + default: // otherwise, basic service item payload = &primev3messages.MTOServiceItemBasic{ diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurcharge.module.scss b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurcharge.module.scss new file mode 100644 index 00000000000..985dcabf2b0 --- /dev/null +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurcharge.module.scss @@ -0,0 +1,12 @@ +@import 'shared/styles/basics'; +@import 'shared/styles/colors'; + +.IntlFsc { + + .intlFscHeader { + text-align: center; + } + + @include u-margin-bottom(4); + + } diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx new file mode 100644 index 00000000000..5092ae351a6 --- /dev/null +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -0,0 +1,102 @@ +import React from 'react'; +import { Formik } from 'formik'; +import { useNavigate, useParams, generatePath } from 'react-router-dom'; +import { FormGroup } from '@trussworks/react-uswds'; +import classnames from 'classnames'; + +import styles from './PrimeUIUpdateInternationalFuelSurcharge.module.scss'; + +import SectionWrapper from 'components/Customer/SectionWrapper'; +import formStyles from 'styles/form.module.scss'; +import { Form } from 'components/form/Form'; +import TextField from 'components/form/fields/TextField/TextField'; +import WizardNavigation from 'components/Customer/WizardNavigation/WizardNavigation'; +import descriptionListStyles from 'styles/descriptionList.module.scss'; +import { primeSimulatorRoutes } from 'constants/routes'; +import { SERVICE_ITEM_STATUSES } from 'constants/serviceItems'; + +const PrimeUIUpdateInternationalFuelSurchargeForm = ({ initialValues, onSubmit, serviceItem, port }) => { + const { moveCodeOrID } = useParams(); + const navigate = useNavigate(); + + const handleClose = () => { + navigate(generatePath(primeSimulatorRoutes.VIEW_MOVE_PATH, { moveCodeOrID })); + }; + + return ( + + {({ handleSubmit }) => ( +
+ +
+

Update International Fuel Surcharge Service Item

+ +
+ Here you can update specific fields for an International Fuel Surcharge service item.
+ At this time, only the following values can be updated:
{' '} + + Port Code
+
+
+
+ +

+ {serviceItem.reServiceCode} - {serviceItem.reServiceName} +

+
+
+
ID:
+
{serviceItem.id}
+
+
+
MTO ID:
+
{serviceItem.moveTaskOrderID}
+
+
+
Shipment ID:
+
{serviceItem.mtoShipmentID}
+
+
+
Status:
+
{serviceItem.status}
+
+
+
Port:
+
{port && port.portName}
+
+
+
Port Location:
+
+ {port && port.city}, {port && port.state} {port && port.zip} +
+
+
+ {serviceItem.status === SERVICE_ITEM_STATUSES.APPROVED && ( + + )} +
+ +
+
+
+ )} +
+ ); +}; + +export default PrimeUIUpdateInternationalFuelSurchargeForm; diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx new file mode 100644 index 00000000000..f87bd27d8cc --- /dev/null +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx @@ -0,0 +1,101 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import PrimeUIUpdateInternationalFuelSurchargeForm from './PrimeUIUpdateInternationalFuelSurchargeForm'; + +import { renderWithProviders } from 'testUtils'; +import { primeSimulatorRoutes } from 'constants/routes'; + +const originSitInitialValues = { + sitDepartureDate: '01 Nov 2023', + sitRequestedDelivery: '01 Dec 2023', + sitCustomerContacted: '15 Oct 2023', + mtoServiceItemID: '45fe9475-d592-48f5-896a-45d4d6eb7e76', + reServiceCode: 'DOPSIT', +}; + +const serviceItem = { + reServiceCode: 'POEFSC', + reServiceName: 'International POE Fuel Surcharge', +}; + +const port = { + city: 'SEATTLE', + country: 'UNITED STATES', + county: 'KING', + id: '48569958-2889-41e5-8101-82c56ec48430', + portCode: 'SEA', + portName: 'SEATTLE TACOMA INTL', + portType: 'A', + state: 'WASHINGTON', + zip: '98158', +}; + +// Mock the react-router-dom functions +const mockNavigate = jest.fn(); +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useNavigate: () => mockNavigate, + useParams: jest.fn().mockReturnValue({ moveCodeOrID: ':moveCodeOrID' }), +})); + +describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { + it('renders the address change request form', async () => { + renderWithProviders( + , + ); + + expect( + screen.getByRole('heading', { name: 'Update International Fuel Surcharge Service Item', level: 2 }), + ).toBeInTheDocument(); + expect( + screen.getByRole('heading', { name: 'POEFSC - International POE Fuel Surcharge', level: 3 }), + ).toBeInTheDocument(); + expect(screen.getByText('Port:')).toBeInTheDocument(); + expect(screen.getByText('SEATTLE TACOMA INTL')).toBeInTheDocument(); + expect(screen.getByText('SEATTLE, WASHINGTON 98158')).toBeInTheDocument(); + expect(screen.getByRole('button', { name: 'Save' })).toBeEnabled(); + expect(screen.getByRole('button', { name: 'Cancel' })).toBeEnabled(); + }); + + it('fires off onSubmit function when save button is clicked', async () => { + const onSubmitMock = jest.fn(); + renderWithProviders( + , + ); + + const saveButton = await screen.findByRole('button', { name: 'Save' }); + + await userEvent.click(saveButton); + + expect(onSubmitMock).toHaveBeenCalled(); + }); + + it('directs the user back to the move page when cancel button is clicked', async () => { + renderWithProviders( + , + ); + + const cancelButton = await screen.findByRole('button', { name: 'Cancel' }); + + await userEvent.click(cancelButton); + + expect(mockNavigate).toHaveBeenCalledWith(primeSimulatorRoutes.VIEW_MOVE_PATH); + }); +}); diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx index 0a39bc1e6a3..4ff8a1a3651 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx @@ -6,6 +6,7 @@ import { connect } from 'react-redux'; import PrimeUIUpdateOriginSITForm from './PrimeUIUpdateOriginSITForm'; import PrimeUIUpdateDestSITForm from './PrimeUIUpdateDestSITForm'; +import PrimeUIUpdateInternationalFuelSurchargeForm from './PrimeUIUpdateInternationalFuelSurchargeForm'; import { updateMTOServiceItem } from 'services/primeApi'; import scrollToTop from 'shared/scrollToTop'; @@ -67,7 +68,18 @@ const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { if (isError) return ; const serviceItem = moveTaskOrder?.mtoServiceItems.find((s) => s?.id === mtoServiceItemId); + const mtoShipment = moveTaskOrder?.mtoShipments.find((s) => s.id === serviceItem.mtoShipmentID); const { modelType } = serviceItem; + let port; + if (modelType === 'MTOServiceItemInternationalFuelSurcharge') { + if (mtoShipment.portOfEmbarkation) { + port = mtoShipment.portOfEmbarkation; + } else if (mtoShipment.portOfDebarkation) { + port = mtoShipment.portOfDebarkation; + } else { + port = null; + } + } const initialValues = { sitDepartureDate: formatDateWithUTC(serviceItem.sitDepartureDate, 'YYYY-MM-DD', 'DD MMM YYYY') || '', @@ -76,6 +88,7 @@ const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { mtoServiceItemID: serviceItem.id, reServiceCode: serviceItem.reServiceCode, eTag: serviceItem.eTag, + portCode: port?.portCode, }; // sending the data submitted in the form to the API @@ -136,6 +149,14 @@ const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { onSubmit={onSubmit} /> ) : null} + {modelType === 'MTOServiceItemInternationalFuelSurcharge' ? ( + + ) : null} diff --git a/swagger-def/prime_v3.yaml b/swagger-def/prime_v3.yaml index 344db2011d1..7b9be659619 100644 --- a/swagger-def/prime_v3.yaml +++ b/swagger-def/prime_v3.yaml @@ -348,6 +348,8 @@ definitions: $ref: 'definitions/prime/MTOServiceItemOriginSIT.yaml' MTOServiceItemShuttle: # spectral oas2-unused-definition is OK here due to polymorphism $ref: 'definitions/prime/MTOServiceItemShuttle.yaml' + MTOServiceItemInternationalFuelSurcharge: # spectral oas2-unused-definition is OK here due to polymorphism + $ref: 'definitions/prime/MTOServiceItemInternationalFuelSurcharge.yaml' CreateMTOShipment: type: object properties: diff --git a/swagger/prime_v3.yaml b/swagger/prime_v3.yaml index cb7c5a5d10a..925437e9091 100644 --- a/swagger/prime_v3.yaml +++ b/swagger/prime_v3.yaml @@ -663,6 +663,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 CreateMTOShipment: type: object properties: From 061525e1f767882227e08720f1581e73a971c1c5 Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Thu, 2 Jan 2025 18:22:07 +0000 Subject: [PATCH 06/12] B-22133 make generic for reuse --- src/pages/Office/index.jsx | 8 +- ...eItem.jsx => PrimeUIUpdateServiceItem.jsx} | 106 +++++++++++------- .../PrimeUpdateSitServiceItem.test.jsx | 2 +- 3 files changed, 67 insertions(+), 49 deletions(-) rename src/pages/PrimeUI/UpdateServiceItems/{PrimeUIUpdateSitServiceItem.jsx => PrimeUIUpdateServiceItem.jsx} (64%) diff --git a/src/pages/Office/index.jsx b/src/pages/Office/index.jsx index 4ca83220d96..38d974c414c 100644 --- a/src/pages/Office/index.jsx +++ b/src/pages/Office/index.jsx @@ -82,9 +82,7 @@ const PrimeSimulatorUploadServiceRequestDocuments = lazy(() => import('pages/PrimeUI/UploadServiceRequestDocuments/UploadServiceRequestDocuments'), ); const PrimeSimulatorCreateServiceItem = lazy(() => import('pages/PrimeUI/CreateServiceItem/CreateServiceItem')); -const PrimeSimulatorUpdateSitServiceItem = lazy(() => - import('pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem'), -); +const PrimeSimulatorUpdateServiceItem = lazy(() => import('pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem')); const PrimeUIShipmentUpdateAddress = lazy(() => import('pages/PrimeUI/Shipment/PrimeUIShipmentUpdateAddress')); const PrimeUIShipmentUpdateReweigh = lazy(() => import('pages/PrimeUI/Shipment/PrimeUIShipmentUpdateReweigh')); const PrimeSimulatorCreateSITExtensionRequest = lazy(() => @@ -510,11 +508,11 @@ export class OfficeApp extends Component { } /> - + } /> diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx similarity index 64% rename from src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx rename to src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx index 4ff8a1a3651..923f92c8e7a 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateSitServiceItem.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx @@ -20,18 +20,18 @@ import { primeSimulatorRoutes } from 'constants/routes'; import { formatDateForSwagger, formatDateWithUTC } from 'shared/dates'; import { SERVICE_ITEM_STATUSES } from 'constants/serviceItems'; -const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { +const PrimeUIUpdateServiceItem = ({ setFlashMessage }) => { const [errorMessage, setErrorMessage] = useState(); const navigate = useNavigate(); const { moveCodeOrID, mtoServiceItemId } = useParams(); const { moveTaskOrder, isLoading, isError } = usePrimeSimulatorGetMove(moveCodeOrID); /* istanbul ignore next */ - const { mutate: createUpdateSITServiceItemRequestMutation } = useMutation(updateMTOServiceItem, { + const { mutate: createUpdateServiceItemRequestMutation } = useMutation(updateMTOServiceItem, { onSuccess: () => { setFlashMessage( - `UPDATE_SIT_SERVICE_ITEM_REQUEST_SUCCESS${moveCodeOrID}`, + `UPDATE_SERVICE_ITEM_REQUEST_SUCCESS${moveCodeOrID}`, 'success', - 'Successfully updated SIT service item', + 'Successfully updated service item', '', true, ); @@ -68,10 +68,12 @@ const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { if (isError) return ; const serviceItem = moveTaskOrder?.mtoServiceItems.find((s) => s?.id === mtoServiceItemId); - const mtoShipment = moveTaskOrder?.mtoShipments.find((s) => s.id === serviceItem.mtoShipmentID); const { modelType } = serviceItem; + let initialValues; + let onSubmit; let port; if (modelType === 'MTOServiceItemInternationalFuelSurcharge') { + const mtoShipment = moveTaskOrder?.mtoShipments.find((s) => s.id === serviceItem.mtoShipmentID); if (mtoShipment.portOfEmbarkation) { port = mtoShipment.portOfEmbarkation; } else if (mtoShipment.portOfDebarkation) { @@ -79,46 +81,64 @@ const PrimeUIUpdateSitServiceItem = ({ setFlashMessage }) => { } else { port = null; } - } - - const initialValues = { - sitDepartureDate: formatDateWithUTC(serviceItem.sitDepartureDate, 'YYYY-MM-DD', 'DD MMM YYYY') || '', - sitRequestedDelivery: formatDateWithUTC(serviceItem.sitRequestedDelivery, 'YYYY-MM-DD', 'DD MMM YYYY') || '', - sitCustomerContacted: formatDateWithUTC(serviceItem.sitCustomerContacted, 'YYYY-MM-DD', 'DD MMM YYYY') || '', - mtoServiceItemID: serviceItem.id, - reServiceCode: serviceItem.reServiceCode, - eTag: serviceItem.eTag, - portCode: port?.portCode, - }; - - // sending the data submitted in the form to the API - // if any of the dates are skipped or not filled with values, we'll just make them null - const onSubmit = (values) => { - const { - sitCustomerContacted, - sitDepartureDate, - sitRequestedDelivery, - updateReason, - mtoServiceItemID, - reServiceCode, - eTag, - } = values; - - const body = { - sitDepartureDate: sitDepartureDate === 'Invalid date' ? null : formatDateForSwagger(sitDepartureDate), - sitRequestedDelivery: sitRequestedDelivery === 'Invalid date' ? null : formatDateForSwagger(sitRequestedDelivery), - sitCustomerContacted: sitCustomerContacted === 'Invalid date' ? null : formatDateForSwagger(sitCustomerContacted), - reServiceCode, - modelType: 'UpdateMTOServiceItemSIT', + initialValues = { + mtoServiceItemID: serviceItem.id, + reServiceCode: serviceItem.reServiceCode, + eTag: serviceItem.eTag, + portCode: port?.portCode, }; - if (serviceItem?.status === SERVICE_ITEM_STATUSES.REJECTED) { - body.requestApprovalsRequestedStatus = true; - body.updateReason = updateReason; - } + onSubmit = (values) => { + const { eTag, mtoServiceItemID, portCode, reServiceCode } = values; + + const body = { + portCode, + reServiceCode, + modelType: 'UpdateMTOServiceItemInternationalPortFSC', + }; + + createUpdateServiceItemRequestMutation({ mtoServiceItemID, eTag, body }); + }; + } else if (modelType === 'MTOServiceItemOriginSIT' || modelType === 'MTOServiceItemDestSIT') { + initialValues = { + sitDepartureDate: formatDateWithUTC(serviceItem.sitDepartureDate, 'YYYY-MM-DD', 'DD MMM YYYY') || '', + sitRequestedDelivery: formatDateWithUTC(serviceItem.sitRequestedDelivery, 'YYYY-MM-DD', 'DD MMM YYYY') || '', + sitCustomerContacted: formatDateWithUTC(serviceItem.sitCustomerContacted, 'YYYY-MM-DD', 'DD MMM YYYY') || '', + mtoServiceItemID: serviceItem.id, + reServiceCode: serviceItem.reServiceCode, + eTag: serviceItem.eTag, + }; + // sending the data submitted in the form to the API + // if any of the dates are skipped or not filled with values, we'll just make them null + onSubmit = (values) => { + const { + sitCustomerContacted, + sitDepartureDate, + sitRequestedDelivery, + updateReason, + mtoServiceItemID, + reServiceCode, + eTag, + } = values; + + const body = { + sitDepartureDate: sitDepartureDate === 'Invalid date' ? null : formatDateForSwagger(sitDepartureDate), + sitRequestedDelivery: + sitRequestedDelivery === 'Invalid date' ? null : formatDateForSwagger(sitRequestedDelivery), + sitCustomerContacted: + sitCustomerContacted === 'Invalid date' ? null : formatDateForSwagger(sitCustomerContacted), + reServiceCode, + modelType: 'UpdateMTOServiceItemSIT', + }; + + if (serviceItem?.status === SERVICE_ITEM_STATUSES.REJECTED) { + body.requestApprovalsRequestedStatus = true; + body.updateReason = updateReason; + } - createUpdateSITServiceItemRequestMutation({ mtoServiceItemID, eTag, body }); - }; + createUpdateServiceItemRequestMutation({ mtoServiceItemID, eTag, body }); + }; + } return (
@@ -169,4 +189,4 @@ const mapDispatchToProps = { setFlashMessage: setFlashMessageAction, }; -export default connect(() => ({}), mapDispatchToProps)(PrimeUIUpdateSitServiceItem); +export default connect(() => ({}), mapDispatchToProps)(PrimeUIUpdateServiceItem); diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUpdateSitServiceItem.test.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUpdateSitServiceItem.test.jsx index 1f397cb700f..e7f21f94309 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUpdateSitServiceItem.test.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUpdateSitServiceItem.test.jsx @@ -1,7 +1,7 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; -import PrimeUIUpdateSitServiceItem from './PrimeUIUpdateSitServiceItem'; +import PrimeUIUpdateSitServiceItem from './PrimeUIUpdateServiceItem'; import { MockProviders, ReactQueryWrapper } from 'testUtils'; import { primeSimulatorRoutes } from 'constants/routes'; From c76ea0130351453a1d41ec17b625f86656909cf1 Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Thu, 2 Jan 2025 21:04:59 +0000 Subject: [PATCH 07/12] B-22133 jest stuff --- ...UIUpdateInternationalFuelSurchargeForm.jsx | 33 ++++++---- ...ateInternationalFuelSurchargeForm.test.jsx | 60 +++++++++++++++---- 2 files changed, 70 insertions(+), 23 deletions(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index 5092ae351a6..92ff9925869 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { Formik } from 'formik'; +import * as Yup from 'yup'; import { useNavigate, useParams, generatePath } from 'react-router-dom'; import { FormGroup } from '@trussworks/react-uswds'; import classnames from 'classnames'; @@ -24,7 +25,16 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ initialValues, onSubmit, }; return ( - + {({ handleSubmit }) => (
@@ -71,17 +81,16 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ initialValues, onSubmit,
- {serviceItem.status === SERVICE_ITEM_STATUSES.APPROVED && ( - - )} + ({ })); describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { - it('renders the address change request form', async () => { + it('renders the international fuel surcharge form', async () => { renderWithProviders( { const onSubmitMock = jest.fn(); renderWithProviders( , ); - + const portCodeInput = screen.getByLabelText(/Port Code/); + await userEvent.type(portCodeInput, 'SEA'); const saveButton = await screen.findByRole('button', { name: 'Save' }); await userEvent.click(saveButton); @@ -82,10 +82,48 @@ describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { expect(onSubmitMock).toHaveBeenCalled(); }); + it('does not fire off onSubmit function when save button is clicked and port code is empty', async () => { + const onSubmitMock = jest.fn(); + renderWithProviders( + , + ); + const portCodeInput = screen.getByLabelText(/Port Code/); + await userEvent.clear(portCodeInput, ''); + const saveButton = await screen.findByRole('button', { name: 'Save' }); + + await userEvent.click(saveButton); + + expect(onSubmitMock).not.toHaveBeenCalled(); + }); + + it('does not fire off onSubmit function when save button is clicked and port code is fewer than 3 characters', async () => { + const onSubmitMock = jest.fn(); + renderWithProviders( + , + ); + const portCodeInput = screen.getByLabelText(/Port Code/); + await userEvent.clear(portCodeInput, '12'); + const saveButton = await screen.findByRole('button', { name: 'Save' }); + + await userEvent.click(saveButton); + + expect(onSubmitMock).not.toHaveBeenCalled(); + }); + it('directs the user back to the move page when cancel button is clicked', async () => { renderWithProviders( Date: Thu, 2 Jan 2025 21:43:18 +0000 Subject: [PATCH 08/12] B-22133 move port stuff out of common area --- ...UIUpdateInternationalFuelSurchargeForm.jsx | 31 +++++++- ...ateInternationalFuelSurchargeForm.test.jsx | 79 ++++++++++--------- .../PrimeUIUpdateServiceItem.jsx | 37 +-------- 3 files changed, 75 insertions(+), 72 deletions(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index 92ff9925869..5b31672c1c3 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -16,7 +16,7 @@ import descriptionListStyles from 'styles/descriptionList.module.scss'; import { primeSimulatorRoutes } from 'constants/routes'; import { SERVICE_ITEM_STATUSES } from 'constants/serviceItems'; -const PrimeUIUpdateInternationalFuelSurchargeForm = ({ initialValues, onSubmit, serviceItem, port }) => { +const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, moveTaskOrder, mtoServiceItemId }) => { const { moveCodeOrID } = useParams(); const navigate = useNavigate(); @@ -24,6 +24,35 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ initialValues, onSubmit, navigate(generatePath(primeSimulatorRoutes.VIEW_MOVE_PATH, { moveCodeOrID })); }; + const serviceItem = moveTaskOrder?.mtoServiceItems.find((s) => s?.id === mtoServiceItemId); + const mtoShipment = moveTaskOrder?.mtoShipments.find((s) => s.id === serviceItem.mtoShipmentID); + let port; + if (mtoShipment.portOfEmbarkation) { + port = mtoShipment.portOfEmbarkation; + } else if (mtoShipment.portOfDebarkation) { + port = mtoShipment.portOfDebarkation; + } else { + port = null; + } + const initialValues = { + mtoServiceItemID: serviceItem.id, + reServiceCode: serviceItem.reServiceCode, + eTag: serviceItem.eTag, + portCode: port?.portCode, + }; + + const onSubmit = (values) => { + const { eTag, mtoServiceItemID, portCode, reServiceCode } = values; + + const body = { + portCode, + reServiceCode, + modelType: 'UpdateMTOServiceItemInternationalPortFSC', + }; + + onUpdateServiceItem({ mtoServiceItemID, eTag, body }); + }; + return ( ({ @@ -43,10 +54,9 @@ describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { it('renders the international fuel surcharge form', async () => { renderWithProviders( , ); @@ -63,14 +73,12 @@ describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { expect(screen.getByRole('button', { name: 'Cancel' })).toBeEnabled(); }); - it('fires off onSubmit function when save button is clicked', async () => { - const onSubmitMock = jest.fn(); + it('fires off onUpdateServiceItemMock function when save button is clicked', async () => { renderWithProviders( , ); const portCodeInput = screen.getByLabelText(/Port Code/); @@ -79,54 +87,49 @@ describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { await userEvent.click(saveButton); - expect(onSubmitMock).toHaveBeenCalled(); + expect(onUpdateServiceItemMock).toHaveBeenCalled(); }); - it('does not fire off onSubmit function when save button is clicked and port code is empty', async () => { - const onSubmitMock = jest.fn(); + it('does not fire off onUpdateServiceItemMock function when save button is clicked and port code is empty', async () => { renderWithProviders( , ); const portCodeInput = screen.getByLabelText(/Port Code/); await userEvent.clear(portCodeInput, ''); const saveButton = await screen.findByRole('button', { name: 'Save' }); + onUpdateServiceItemMock.mockClear(); await userEvent.click(saveButton); - - expect(onSubmitMock).not.toHaveBeenCalled(); + expect(onUpdateServiceItemMock).not.toHaveBeenCalled(); }); - it('does not fire off onSubmit function when save button is clicked and port code is fewer than 3 characters', async () => { - const onSubmitMock = jest.fn(); + it('does not fire off onUpdateServiceItemMock function when save button is clicked and port code is fewer than 3 characters', async () => { renderWithProviders( , ); const portCodeInput = screen.getByLabelText(/Port Code/); await userEvent.clear(portCodeInput, '12'); const saveButton = await screen.findByRole('button', { name: 'Save' }); + onUpdateServiceItemMock.mockClear(); await userEvent.click(saveButton); - - expect(onSubmitMock).not.toHaveBeenCalled(); + expect(onUpdateServiceItemMock).not.toHaveBeenCalled(); }); it('directs the user back to the move page when cancel button is clicked', async () => { renderWithProviders( , ); diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx index 923f92c8e7a..387981922c4 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateServiceItem.jsx @@ -71,35 +71,7 @@ const PrimeUIUpdateServiceItem = ({ setFlashMessage }) => { const { modelType } = serviceItem; let initialValues; let onSubmit; - let port; - if (modelType === 'MTOServiceItemInternationalFuelSurcharge') { - const mtoShipment = moveTaskOrder?.mtoShipments.find((s) => s.id === serviceItem.mtoShipmentID); - if (mtoShipment.portOfEmbarkation) { - port = mtoShipment.portOfEmbarkation; - } else if (mtoShipment.portOfDebarkation) { - port = mtoShipment.portOfDebarkation; - } else { - port = null; - } - initialValues = { - mtoServiceItemID: serviceItem.id, - reServiceCode: serviceItem.reServiceCode, - eTag: serviceItem.eTag, - portCode: port?.portCode, - }; - - onSubmit = (values) => { - const { eTag, mtoServiceItemID, portCode, reServiceCode } = values; - - const body = { - portCode, - reServiceCode, - modelType: 'UpdateMTOServiceItemInternationalPortFSC', - }; - - createUpdateServiceItemRequestMutation({ mtoServiceItemID, eTag, body }); - }; - } else if (modelType === 'MTOServiceItemOriginSIT' || modelType === 'MTOServiceItemDestSIT') { + if (modelType === 'MTOServiceItemOriginSIT' || modelType === 'MTOServiceItemDestSIT') { initialValues = { sitDepartureDate: formatDateWithUTC(serviceItem.sitDepartureDate, 'YYYY-MM-DD', 'DD MMM YYYY') || '', sitRequestedDelivery: formatDateWithUTC(serviceItem.sitRequestedDelivery, 'YYYY-MM-DD', 'DD MMM YYYY') || '', @@ -171,10 +143,9 @@ const PrimeUIUpdateServiceItem = ({ setFlashMessage }) => { ) : null} {modelType === 'MTOServiceItemInternationalFuelSurcharge' ? ( ) : null} From b8e5a42a4b1e12e679a37fcd543aee0acb04f3f1 Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Thu, 2 Jan 2025 22:51:52 +0000 Subject: [PATCH 09/12] B-22133 don't show random comma --- .../PrimeUIUpdateInternationalFuelSurchargeForm.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index 5b31672c1c3..a68f99f71dd 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -106,7 +106,8 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move
Port Location:
- {port && port.city}, {port && port.state} {port && port.zip} + {port && port.city} + {port && port.city && ','} {port && port.state} {port && port.zip}
From f6a9c0c5f4e27b44846155079060ccc5c05a634b Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Fri, 3 Jan 2025 21:29:46 +0000 Subject: [PATCH 10/12] B-22133 provide flexibility for input --- .../PrimeUIUpdateInternationalFuelSurchargeForm.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index a68f99f71dd..ea6e8ea5ea1 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -45,7 +45,7 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move const { eTag, mtoServiceItemID, portCode, reServiceCode } = values; const body = { - portCode, + portCode: portCode.toUpperCase(), reServiceCode, modelType: 'UpdateMTOServiceItemInternationalPortFSC', }; From 0c48d41a9e10453be8af1dedaec651c5bdce468f Mon Sep 17 00:00:00 2001 From: Brian Manley Date: Fri, 3 Jan 2025 21:43:46 +0000 Subject: [PATCH 11/12] B-22133 formik way of doing things --- .../PrimeUIUpdateInternationalFuelSurchargeForm.jsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index ea6e8ea5ea1..dc02c9c2423 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -45,7 +45,7 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move const { eTag, mtoServiceItemID, portCode, reServiceCode } = values; const body = { - portCode: portCode.toUpperCase(), + portCode, reServiceCode, modelType: 'UpdateMTOServiceItemInternationalPortFSC', }; @@ -64,7 +64,7 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move .max(4, 'Port Code must be 3-4 characters.'), })} > - {({ handleSubmit }) => ( + {({ handleSubmit, setFieldValue }) => (
@@ -120,6 +120,9 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move labelHint="Required" maxLength="4" isDisabled={serviceItem.status !== SERVICE_ITEM_STATUSES.APPROVED} + onBlur={(e) => { + setFieldValue('portCode', e.target.value.toUpperCase()); + }} /> Date: Fri, 3 Jan 2025 22:15:20 +0000 Subject: [PATCH 12/12] B-22133 test uppercase --- ...meUIUpdateInternationalFuelSurchargeForm.jsx | 2 +- ...pdateInternationalFuelSurchargeForm.test.jsx | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx index dc02c9c2423..63014e86300 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.jsx @@ -120,7 +120,7 @@ const PrimeUIUpdateInternationalFuelSurchargeForm = ({ onUpdateServiceItem, move labelHint="Required" maxLength="4" isDisabled={serviceItem.status !== SERVICE_ITEM_STATUSES.APPROVED} - onBlur={(e) => { + onChange={(e) => { setFieldValue('portCode', e.target.value.toUpperCase()); }} /> diff --git a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx index d76306cf7b1..78461a6e840 100644 --- a/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx +++ b/src/pages/PrimeUI/UpdateServiceItems/PrimeUIUpdateInternationalFuelSurchargeForm.test.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { screen } from '@testing-library/react'; +import { screen, fireEvent } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import PrimeUIUpdateInternationalFuelSurchargeForm from './PrimeUIUpdateInternationalFuelSurchargeForm'; @@ -90,6 +90,21 @@ describe('PrimeUIUpdateInternationalFuelSurchargeForm', () => { expect(onUpdateServiceItemMock).toHaveBeenCalled(); }); + it('port code value is set to uppercase when user types in a value', async () => { + renderWithProviders( + , + ); + const portCodeInput = screen.getByLabelText(/Port Code/); + expect(portCodeInput).toHaveValue('SEA'); + fireEvent.change(portCodeInput, { target: { value: 'pdx' } }); + + expect(portCodeInput).toHaveValue('PDX'); + }); + it('does not fire off onUpdateServiceItemMock function when save button is clicked and port code is empty', async () => { renderWithProviders(