diff --git a/src/components/Office/RequestedShipments/ApprovedRequestedShipments.jsx b/src/components/Office/RequestedShipments/ApprovedRequestedShipments.jsx index 4f271725818..236f4821ea1 100644 --- a/src/components/Office/RequestedShipments/ApprovedRequestedShipments.jsx +++ b/src/components/Office/RequestedShipments/ApprovedRequestedShipments.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import * as PropTypes from 'prop-types'; import { generatePath, useParams, useNavigate } from 'react-router-dom'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -86,16 +86,30 @@ const ApprovedRequestedShipments = ({ const dutyLocationPostal = { postalCode: ordersInfo.newDutyLocation?.address?.postalCode }; - const [enableBoat, setEnableBoat] = React.useState(false); - const [enableMobileHome, setEnableMobileHome] = React.useState(false); - React.useEffect(() => { + const [enableBoat, setEnableBoat] = useState(false); + const [enableMobileHome, setEnableMobileHome] = useState(false); + const [enableUB, setEnableUB] = useState(false); + const [isOconusMove, setIsOconusMove] = useState(false); + + useEffect(() => { const fetchData = async () => { setEnableBoat(await isBooleanFlagEnabled(FEATURE_FLAG_KEYS.BOAT)); setEnableMobileHome(await isBooleanFlagEnabled(FEATURE_FLAG_KEYS.MOBILE_HOME)); + setEnableUB(await isBooleanFlagEnabled(FEATURE_FLAG_KEYS.UNACCOMPANIED_BAGGAGE)); }; fetchData(); }, []); + const { newDutyLocation, currentDutyLocation } = ordersInfo; + useEffect(() => { + // Check if duty locations on the orders qualify as OCONUS to conditionally render the UB shipment option + if (currentDutyLocation?.address?.isOconus || newDutyLocation?.address?.isOconus) { + setIsOconusMove(true); + } else { + setIsOconusMove(false); + } + }, [currentDutyLocation, newDutyLocation, isOconusMove, enableUB]); + const allowedShipmentOptions = () => { return ( <> @@ -107,6 +121,7 @@ const ApprovedRequestedShipments = ({ {enableBoat && } {enableMobileHome && } + {enableUB && isOconusMove && } ); }; diff --git a/src/components/Office/RequestedShipments/RequestedShipments.test.jsx b/src/components/Office/RequestedShipments/RequestedShipments.test.jsx index d231e042a58..55b512970d0 100644 --- a/src/components/Office/RequestedShipments/RequestedShipments.test.jsx +++ b/src/components/Office/RequestedShipments/RequestedShipments.test.jsx @@ -502,6 +502,7 @@ describe('RequestedShipments', () => { SHIPMENT_OPTIONS_URL.NTSrelease, SHIPMENT_OPTIONS_URL.MOBILE_HOME, SHIPMENT_OPTIONS_URL.BOAT, + SHIPMENT_OPTIONS_URL.UNACCOMPANIED_BAGGAGE, ], ])('selects the %s option and navigates to the matching form for that shipment type', async (shipmentType) => { render( diff --git a/src/components/Office/RequestedShipments/SubmittedRequestedShipments.jsx b/src/components/Office/RequestedShipments/SubmittedRequestedShipments.jsx index c83d4eddc81..93c119cf16e 100644 --- a/src/components/Office/RequestedShipments/SubmittedRequestedShipments.jsx +++ b/src/components/Office/RequestedShipments/SubmittedRequestedShipments.jsx @@ -65,15 +65,28 @@ const SubmittedRequestedShipments = ({ const [filteredShipments, setFilteredShipments] = useState([]); const [enableBoat, setEnableBoat] = useState(false); const [enableMobileHome, setEnableMobileHome] = useState(false); + const [enableUB, setEnableUB] = useState(false); + const [isOconusMove, setIsOconusMove] = useState(false); useEffect(() => { const fetchData = async () => { setEnableBoat(await isBooleanFlagEnabled(FEATURE_FLAG_KEYS.BOAT)); setEnableMobileHome(await isBooleanFlagEnabled(FEATURE_FLAG_KEYS.MOBILE_HOME)); + setEnableUB(await isBooleanFlagEnabled(FEATURE_FLAG_KEYS.UNACCOMPANIED_BAGGAGE)); }; fetchData(); }, []); + const { newDutyLocation, currentDutyLocation } = ordersInfo; + useEffect(() => { + // Check if duty locations on the orders qualify as OCONUS to conditionally render the UB shipment option + if (currentDutyLocation?.address?.isOconus || newDutyLocation?.address?.isOconus) { + setIsOconusMove(true); + } else { + setIsOconusMove(false); + } + }, [currentDutyLocation, newDutyLocation, isOconusMove, enableUB]); + const filterPrimeShipments = mtoShipments.filter((shipment) => !shipment.usesExternalVendor); const filterShipments = (formikShipmentIds) => { @@ -126,6 +139,7 @@ const SubmittedRequestedShipments = ({ {enableBoat && } {enableMobileHome && } + {enableUB && isOconusMove && } ); }; diff --git a/src/components/Office/ShipmentForm/ShipmentForm.jsx b/src/components/Office/ShipmentForm/ShipmentForm.jsx index 62c73213119..22d079956d6 100644 --- a/src/components/Office/ShipmentForm/ShipmentForm.jsx +++ b/src/components/Office/ShipmentForm/ShipmentForm.jsx @@ -890,7 +890,7 @@ const ShipmentForm = (props) => {
- {isTOO && !isHHG && !isPPM && !isBoat && !isMobileHome && } + {isTOO && !isHHG && !isPPM && !isBoat && !isMobileHome && !isUB && } {isNTSR && } diff --git a/src/components/Office/ShipmentForm/ShipmentForm.test.jsx b/src/components/Office/ShipmentForm/ShipmentForm.test.jsx index 6c00f05cdd0..dfe5b1d89a1 100644 --- a/src/components/Office/ShipmentForm/ShipmentForm.test.jsx +++ b/src/components/Office/ShipmentForm/ShipmentForm.test.jsx @@ -212,7 +212,7 @@ const defaultProps = { serviceMember: { weightAllotment: { totalWeightSelf: 5000, - ubAllowance: 400, + unaccompaniedBaggageAllowance: 400, }, agency: '', }, diff --git a/src/components/ShipmentTag/ShipmentTag.module.scss b/src/components/ShipmentTag/ShipmentTag.module.scss index 85d03da1b77..b7fe8f59acd 100644 --- a/src/components/ShipmentTag/ShipmentTag.module.scss +++ b/src/components/ShipmentTag/ShipmentTag.module.scss @@ -34,4 +34,7 @@ &.MobileHome { background-color: $accent-mobile-home; } + &.UB { + background-color: $accent-ub; + } } diff --git a/src/pages/Office/AddShipment/AddShipment.jsx b/src/pages/Office/AddShipment/AddShipment.jsx index 7c545dc86cb..c5cb50d3541 100644 --- a/src/pages/Office/AddShipment/AddShipment.jsx +++ b/src/pages/Office/AddShipment/AddShipment.jsx @@ -27,6 +27,8 @@ const AddShipment = () => { shipmentType = SHIPMENT_OPTIONS.BOAT; } else if (shipmentType === SHIPMENT_OPTIONS_URL.MOBILE_HOME) { shipmentType = SHIPMENT_OPTIONS.MOBILE_HOME; + } else if (shipmentType === SHIPMENT_OPTIONS_URL.UNACCOMPANIED_BAGGAGE) { + shipmentType = SHIPMENT_OPTIONS.UNACCOMPANIED_BAGGAGE; } else { shipmentType = SHIPMENT_OPTIONS[shipmentType]; } diff --git a/src/pages/Office/ServicesCounselingAddShipment/ServicesCounselingAddShipment.jsx b/src/pages/Office/ServicesCounselingAddShipment/ServicesCounselingAddShipment.jsx index 39292f6c722..b279fbe7c56 100644 --- a/src/pages/Office/ServicesCounselingAddShipment/ServicesCounselingAddShipment.jsx +++ b/src/pages/Office/ServicesCounselingAddShipment/ServicesCounselingAddShipment.jsx @@ -27,6 +27,8 @@ const ServicesCounselingAddShipment = () => { shipmentType = SHIPMENT_OPTIONS.BOAT; } else if (shipmentType === SHIPMENT_OPTIONS_URL.MOBILE_HOME) { shipmentType = SHIPMENT_OPTIONS.MOBILE_HOME; + } else if (shipmentType === SHIPMENT_OPTIONS_URL.UNACCOMPANIED_BAGGAGE) { + shipmentType = SHIPMENT_OPTIONS.UNACCOMPANIED_BAGGAGE; } else { shipmentType = SHIPMENT_OPTIONS[shipmentType]; } diff --git a/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.jsx b/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.jsx index 9ba42961d5e..2b39fc3aa53 100644 --- a/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.jsx +++ b/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.jsx @@ -76,6 +76,8 @@ const ServicesCounselingMoveDetails = ({ const [isCancelMoveModalVisible, setIsCancelMoveModalVisible] = useState(false); const [enableBoat, setEnableBoat] = useState(false); const [enableMobileHome, setEnableMobileHome] = useState(false); + const [enableUB, setEnableUB] = useState(false); + const [isOconusMove, setIsOconusMove] = useState(false); const { upload, amendedUpload } = useOrdersDocumentQueries(moveCode); const [errorMessage, setErrorMessage] = useState(null); const documentsForViewer = Object.values(upload || {}) @@ -90,7 +92,7 @@ const ServicesCounselingMoveDetails = ({ const validOrdersDocuments = Object.values(orderDocuments || {})?.filter((file) => !file.deletedAt); - const { customer, entitlement: allowances } = order; + const { customer, entitlement: allowances, originDutyLocation, destinationDutyLocation } = order; const moveWeightTotal = calculateWeightRequested(mtoShipments); @@ -169,10 +171,20 @@ const ServicesCounselingMoveDetails = ({ const fetchData = async () => { setEnableBoat(await isBooleanFlagEnabled(FEATURE_FLAG_KEYS.BOAT)); setEnableMobileHome(await isBooleanFlagEnabled(FEATURE_FLAG_KEYS.MOBILE_HOME)); + setEnableUB(await isBooleanFlagEnabled(FEATURE_FLAG_KEYS.UNACCOMPANIED_BAGGAGE)); }; fetchData(); }, []); + useEffect(() => { + // Check if either currentDutyLocation or newDutyLocation is OCONUS to conditionally render the UB shipment option + if (originDutyLocation?.address?.isOconus || destinationDutyLocation?.address?.isOconus) { + setIsOconusMove(true); + } else { + setIsOconusMove(false); + } + }, [originDutyLocation, destinationDutyLocation, isOconusMove, enableUB]); + // for now we are only showing dest type on retiree and separatee orders const isRetirementOrSeparation = order.order_type === ORDERS_TYPE.RETIREMENT || order.order_type === ORDERS_TYPE.SEPARATION; @@ -624,6 +636,7 @@ const ServicesCounselingMoveDetails = ({ {enableBoat && } {enableMobileHome && } + {enableUB && isOconusMove && } ); }; diff --git a/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.test.jsx b/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.test.jsx index bef3fb51b59..1bd3e48d601 100644 --- a/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.test.jsx +++ b/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.test.jsx @@ -16,6 +16,7 @@ import { useMoveDetailsQueries, useOrdersDocumentQueries } from 'hooks/queries'; import { formatDateWithUTC } from 'shared/dates'; import { MockProviders } from 'testUtils'; import { updateMTOShipment, updateMoveStatusServiceCounselingCompleted } from 'services/ghcApi'; +import { isBooleanFlagEnabled } from 'utils/featureFlags'; const mockRequestedMoveCode = 'LR4T8V'; const mockRoutingParams = { moveCode: mockRequestedMoveCode }; @@ -38,6 +39,11 @@ jest.mock('services/ghcApi', () => ({ updateMoveStatusServiceCounselingCompleted: jest.fn(), })); +jest.mock('utils/featureFlags', () => ({ + ...jest.requireActual('utils/featureFlags'), + isBooleanFlagEnabled: jest.fn().mockImplementation(() => Promise.resolve(false)), +})); + const mtoShipments = [ { customerRemarks: 'please treat gently', @@ -256,6 +262,7 @@ const newMoveDetailsQuery = { city: 'Fort Knox', state: 'KY', postalCode: '40121', + isOconus: true, }, }, destinationDutyLocation: { @@ -1127,40 +1134,42 @@ describe('MoveDetails page', () => { }); describe('shows the dropdown and navigates to each option', () => { - it.each([[SHIPMENT_OPTIONS_URL.HHG], [SHIPMENT_OPTIONS_URL.NTS], [SHIPMENT_OPTIONS_URL.NTSrelease]])( - 'selects the %s option and navigates to the matching form for that shipment type', - async (shipmentType) => { - render( - - - , - , - ); - - const path = `../${generatePath(servicesCounselingRoutes.SHIPMENT_ADD_PATH, { - moveCode: mockRequestedMoveCode, - shipmentType, - })}`; + it.each([ + [SHIPMENT_OPTIONS_URL.HHG], + [SHIPMENT_OPTIONS_URL.NTS], + [SHIPMENT_OPTIONS_URL.NTSrelease], + [SHIPMENT_OPTIONS_URL.UNACCOMPANIED_BAGGAGE], + ])('selects the %s option and navigates to the matching form for that shipment type', async (shipmentType) => { + isBooleanFlagEnabled.mockImplementation(() => Promise.resolve(true)); + render( + + + , + ); - const buttonDropdown = await screen.findByRole('combobox'); + const path = `../${generatePath(servicesCounselingRoutes.SHIPMENT_ADD_PATH, { + moveCode: mockRequestedMoveCode, + shipmentType, + })}`; - expect(buttonDropdown).toBeInTheDocument(); + const buttonDropdown = await screen.findByRole('combobox'); - await userEvent.selectOptions(buttonDropdown, shipmentType); + expect(buttonDropdown).toBeInTheDocument(); - await waitFor(() => { - expect(mockNavigate).toHaveBeenCalledWith(path); - }); - }, - ); + await userEvent.selectOptions(buttonDropdown, shipmentType); + + await waitFor(() => { + expect(mockNavigate).toHaveBeenCalledWith(path); + }); + }); }); it('shows the edit shipment buttons', async () => {