diff --git a/pkg/gen/ghcapi/embedded_spec.go b/pkg/gen/ghcapi/embedded_spec.go index 0fa6c815434..0a825214bc7 100644 --- a/pkg/gen/ghcapi/embedded_spec.go +++ b/pkg/gen/ghcapi/embedded_spec.go @@ -5001,6 +5001,9 @@ func init() { "x-nullable": true, "$ref": "#/definitions/DeptIndicator" }, + "grade": { + "$ref": "#/definitions/Grade" + }, "issueDate": { "description": "The date and time that these orders were cut.", "type": "string", @@ -9554,6 +9557,9 @@ func init() { "x-nullable": true, "$ref": "#/definitions/DeptIndicator" }, + "grade": { + "$ref": "#/definitions/Grade" + }, "issueDate": { "description": "The date and time that these orders were cut.", "type": "string", @@ -16570,6 +16576,9 @@ func init() { "x-nullable": true, "$ref": "#/definitions/DeptIndicator" }, + "grade": { + "$ref": "#/definitions/Grade" + }, "issueDate": { "description": "The date and time that these orders were cut.", "type": "string", @@ -21181,6 +21190,9 @@ func init() { "x-nullable": true, "$ref": "#/definitions/DeptIndicator" }, + "grade": { + "$ref": "#/definitions/Grade" + }, "issueDate": { "description": "The date and time that these orders were cut.", "type": "string", diff --git a/pkg/gen/ghcmessages/counseling_update_order_payload.go b/pkg/gen/ghcmessages/counseling_update_order_payload.go index 76c1981cdf0..a03a99a22de 100644 --- a/pkg/gen/ghcmessages/counseling_update_order_payload.go +++ b/pkg/gen/ghcmessages/counseling_update_order_payload.go @@ -23,6 +23,9 @@ type CounselingUpdateOrderPayload struct { // department indicator DepartmentIndicator *DeptIndicator `json:"departmentIndicator,omitempty"` + // grade + Grade *Grade `json:"grade,omitempty"` + // Orders date // // The date and time that these orders were cut. @@ -89,6 +92,10 @@ func (m *CounselingUpdateOrderPayload) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateGrade(formats); err != nil { + res = append(res, err) + } + if err := m.validateIssueDate(formats); err != nil { res = append(res, err) } @@ -154,6 +161,25 @@ func (m *CounselingUpdateOrderPayload) validateDepartmentIndicator(formats strfm return nil } +func (m *CounselingUpdateOrderPayload) validateGrade(formats strfmt.Registry) error { + if swag.IsZero(m.Grade) { // not required + return nil + } + + if m.Grade != nil { + if err := m.Grade.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("grade") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("grade") + } + return err + } + } + + return nil +} + func (m *CounselingUpdateOrderPayload) validateIssueDate(formats strfmt.Registry) error { if err := validate.Required("issueDate", "body", m.IssueDate); err != nil { @@ -324,6 +350,10 @@ func (m *CounselingUpdateOrderPayload) ContextValidate(ctx context.Context, form res = append(res, err) } + if err := m.contextValidateGrade(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateNtsSac(ctx, formats); err != nil { res = append(res, err) } @@ -371,6 +401,27 @@ func (m *CounselingUpdateOrderPayload) contextValidateDepartmentIndicator(ctx co return nil } +func (m *CounselingUpdateOrderPayload) contextValidateGrade(ctx context.Context, formats strfmt.Registry) error { + + if m.Grade != nil { + + if swag.IsZero(m.Grade) { // not required + return nil + } + + if err := m.Grade.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("grade") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("grade") + } + return err + } + } + + return nil +} + func (m *CounselingUpdateOrderPayload) contextValidateNtsSac(ctx context.Context, formats strfmt.Registry) error { if swag.IsZero(m.NtsSac) { // not required diff --git a/pkg/gen/ghcmessages/update_order_payload.go b/pkg/gen/ghcmessages/update_order_payload.go index 08cb3953bcd..f5a09ceb70d 100644 --- a/pkg/gen/ghcmessages/update_order_payload.go +++ b/pkg/gen/ghcmessages/update_order_payload.go @@ -23,6 +23,9 @@ type UpdateOrderPayload struct { // department indicator DepartmentIndicator *DeptIndicator `json:"departmentIndicator,omitempty"` + // grade + Grade *Grade `json:"grade,omitempty"` + // Orders date // // The date and time that these orders were cut. @@ -92,6 +95,10 @@ func (m *UpdateOrderPayload) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateGrade(formats); err != nil { + res = append(res, err) + } + if err := m.validateIssueDate(formats); err != nil { res = append(res, err) } @@ -157,6 +164,25 @@ func (m *UpdateOrderPayload) validateDepartmentIndicator(formats strfmt.Registry return nil } +func (m *UpdateOrderPayload) validateGrade(formats strfmt.Registry) error { + if swag.IsZero(m.Grade) { // not required + return nil + } + + if m.Grade != nil { + if err := m.Grade.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("grade") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("grade") + } + return err + } + } + + return nil +} + func (m *UpdateOrderPayload) validateIssueDate(formats strfmt.Registry) error { if err := validate.Required("issueDate", "body", m.IssueDate); err != nil { @@ -327,6 +353,10 @@ func (m *UpdateOrderPayload) ContextValidate(ctx context.Context, formats strfmt res = append(res, err) } + if err := m.contextValidateGrade(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateNtsSac(ctx, formats); err != nil { res = append(res, err) } @@ -374,6 +404,27 @@ func (m *UpdateOrderPayload) contextValidateDepartmentIndicator(ctx context.Cont return nil } +func (m *UpdateOrderPayload) contextValidateGrade(ctx context.Context, formats strfmt.Registry) error { + + if m.Grade != nil { + + if swag.IsZero(m.Grade) { // not required + return nil + } + + if err := m.Grade.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("grade") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("grade") + } + return err + } + } + + return nil +} + func (m *UpdateOrderPayload) contextValidateNtsSac(ctx context.Context, formats strfmt.Registry) error { if swag.IsZero(m.NtsSac) { // not required diff --git a/pkg/services/order/order_updater.go b/pkg/services/order/order_updater.go index 7041cb9eee4..8f42fec6ca0 100644 --- a/pkg/services/order/order_updater.go +++ b/pkg/services/order/order_updater.go @@ -228,6 +228,19 @@ func orderFromTOOPayload(_ appcontext.AppContext, existingOrder models.Order, pa order.AmendedOrdersAcknowledgedAt = &acknowledgedAt } + if payload.Grade != nil { + order.Grade = (*internalmessages.OrderPayGrade)(payload.Grade) + // Calculate new DBWeightAuthorized based on the new grade + weightAllotment := models.GetWeightAllotment(*order.Grade) + weight := weightAllotment.TotalWeightSelf + // Payload does not have this information, retrieve dependents from the existing order + if existingOrder.HasDependents && *order.Entitlement.DependentsAuthorized { + // Only utilize dependent weight authorized if dependents are both present and authorized + weight = weightAllotment.TotalWeightSelfPlusDependents + } + order.Entitlement.DBAuthorizedWeight = &weight + } + return order } @@ -348,6 +361,19 @@ func orderFromCounselingPayload(existingOrder models.Order, payload ghcmessages. order.OrdersType = internalmessages.OrdersType(*payload.OrdersType) } + if payload.Grade != nil { + order.Grade = (*internalmessages.OrderPayGrade)(payload.Grade) + // Calculate new DBWeightAuthorized based on the new grade + weightAllotment := models.GetWeightAllotment(*order.Grade) + weight := weightAllotment.TotalWeightSelf + // Payload does not have this information, retrieve dependents from the existing order + if existingOrder.HasDependents && *order.Entitlement.DependentsAuthorized { + // Only utilize dependent weight authorized if dependents are both present and authorized + weight = weightAllotment.TotalWeightSelfPlusDependents + } + order.Entitlement.DBAuthorizedWeight = &weight + } + return order } diff --git a/pkg/services/order/order_updater_test.go b/pkg/services/order/order_updater_test.go index 8cf2a862d8d..bf756fa7681 100644 --- a/pkg/services/order/order_updater_test.go +++ b/pkg/services/order/order_updater_test.go @@ -437,6 +437,7 @@ func (suite *OrderServiceSuite) TestUpdateOrderAsCounselor() { reportByDate := strfmt.Date(time.Now().Add(72 * time.Hour)) deptIndicator := ghcmessages.DeptIndicatorCOASTGUARD ordersTypeDetail := ghcmessages.OrdersTypeDetail("INSTRUCTION_20_WEEKS") + grade := ghcmessages.GradeO5 body := ghcmessages.CounselingUpdateOrderPayload{ IssueDate: &dateIssued, @@ -449,6 +450,7 @@ func (suite *OrderServiceSuite) TestUpdateOrderAsCounselor() { OrdersTypeDetail: &ordersTypeDetail, Tac: handlers.FmtString("E19A"), Sac: nullable.NewString("987654321"), + Grade: &grade, } eTag := etag.GenerateEtag(order.UpdatedAt) @@ -471,6 +473,7 @@ func (suite *OrderServiceSuite) TestUpdateOrderAsCounselor() { suite.EqualValues(body.DepartmentIndicator, updatedOrder.DepartmentIndicator) suite.EqualValues(body.Tac, updatedOrder.TAC) suite.EqualValues(body.Sac.Value, updatedOrder.SAC) + suite.Equal(*updatedOrder.Entitlement.DBAuthorizedWeight, 16000) }) suite.Run("Rolls back transaction if Order is invalid", func() { diff --git a/playwright/tests/office/qaecsr/csrFlows.spec.js b/playwright/tests/office/qaecsr/csrFlows.spec.js index 765d44530f1..6d9df692eb9 100644 --- a/playwright/tests/office/qaecsr/csrFlows.spec.js +++ b/playwright/tests/office/qaecsr/csrFlows.spec.js @@ -136,6 +136,7 @@ test.describe('Customer Support User Flows', () => { await expect(page.locator('select[name="ordersTypeDetail"]')).toBeDisabled(); await expect(page.locator('input[name="tac"]')).toBeDisabled(); await expect(page.locator('input[name="sac"]')).toBeDisabled(); + await expect(page.locator('select[name="payGrade"]')).toBeDisabled(); // no save button should exist await expect(page.getByRole('button', { name: 'Save' })).toHaveCount(0); }); @@ -157,11 +158,9 @@ test.describe('Customer Support User Flows', () => { await expect(page.locator('input[name="storageInTransit"]')).toBeDisabled(); await expect(page.locator('input[name="organizationalClothingAndIndividualEquipment"]')).toBeDisabled(); - // read only grade and authorized weight + // read only authorized weight await expect(page.locator('select[name=agency]')).toBeDisabled(); await expect(page.locator('select[name=agency]')).toBeDisabled(); - await expect(page.locator('select[name="grade"]')).toBeDisabled(); - await expect(page.locator('select[name="grade"]')).toBeDisabled(); await expect(page.locator('input[name="dependentsAuthorized"]')).toBeDisabled(); // no save button should exist diff --git a/src/components/Office/AllowancesDetailForm/AllowancesDetailForm.jsx b/src/components/Office/AllowancesDetailForm/AllowancesDetailForm.jsx index 1c9517b02fa..c377d812389 100644 --- a/src/components/Office/AllowancesDetailForm/AllowancesDetailForm.jsx +++ b/src/components/Office/AllowancesDetailForm/AllowancesDetailForm.jsx @@ -10,7 +10,7 @@ import { EntitlementShape } from 'types/order'; import { formatWeight } from 'utils/formatters'; import Hint from 'components/Hint'; -const AllowancesDetailForm = ({ header, entitlements, payGradeOptions, branchOptions, formIsDisabled }) => { +const AllowancesDetailForm = ({ header, entitlements, branchOptions, formIsDisabled }) => { return (
{header &&

{header}

} @@ -71,15 +71,6 @@ const AllowancesDetailForm = ({ header, entitlements, payGradeOptions, branchOpt showDropdownPlaceholderText={false} isDisabled={formIsDisabled} /> - ({ const { Formik } = jest.requireActual('formik'); -const payGradeOptions = [ - { key: 'E_1', value: 'E-1' }, - { key: 'E_2', value: 'E-2' }, - { key: 'E_3', value: 'E-3' }, - { key: 'E_4', value: 'E-4' }, - { key: 'E_5', value: 'E-5' }, - { key: 'E_6', value: 'E-6' }, - { key: 'E_7', value: 'E-7' }, - { key: 'E_8', value: 'E-8' }, - { key: 'E_9', value: 'E-9' }, -]; - const branchOptions = [ { key: 'Army', value: 'Army' }, { key: 'Navy', value: 'Navy' }, @@ -83,11 +71,7 @@ describe('AllowancesDetailForm', () => { it('renders the form', async () => { render( - + , ); @@ -99,11 +83,7 @@ describe('AllowancesDetailForm', () => { it('renders the pro-gear hints', async () => { render( - + , ); @@ -114,12 +94,7 @@ describe('AllowancesDetailForm', () => { it('renders the title header', async () => { render( - + , ); diff --git a/src/components/Office/DefinitionLists/AllowancesList.jsx b/src/components/Office/DefinitionLists/AllowancesList.jsx index 8f05352bbd1..c444824b635 100644 --- a/src/components/Office/DefinitionLists/AllowancesList.jsx +++ b/src/components/Office/DefinitionLists/AllowancesList.jsx @@ -6,7 +6,7 @@ import styles from './OfficeDefinitionLists.module.scss'; import descriptionListStyles from 'styles/descriptionList.module.scss'; import { formatWeight } from 'utils/formatters'; -import friendlyBranchGrade from 'utils/branchGradeFormatters'; +import { ORDERS_BRANCH_OPTIONS } from 'constants/orders'; const AllowancesList = ({ info, showVisualCues }) => { const visualCuesStyle = classNames(descriptionListStyles.row, { @@ -17,8 +17,8 @@ const AllowancesList = ({ info, showVisualCues }) => {
-
Branch, pay grade
-
{friendlyBranchGrade(info.branch, info.grade)}
+
Branch
+
{info.branch ? ORDERS_BRANCH_OPTIONS[info.branch] : ''}
Weight allowance
diff --git a/src/components/Office/DefinitionLists/AllowancesList.test.jsx b/src/components/Office/DefinitionLists/AllowancesList.test.jsx index a9612bf88b0..e72b9fd320b 100644 --- a/src/components/Office/DefinitionLists/AllowancesList.test.jsx +++ b/src/components/Office/DefinitionLists/AllowancesList.test.jsx @@ -17,9 +17,9 @@ const info = { }; describe('AllowancesList', () => { - it('renders formatted branch and grade', () => { + it('renders formatted branch', () => { render(); - expect(screen.getByText('Navy, E-6')).toBeInTheDocument(); + expect(screen.getByText('Navy')).toBeInTheDocument(); }); it('renders formatted weight allowance', () => { diff --git a/src/components/Office/DefinitionLists/OrdersList.jsx b/src/components/Office/DefinitionLists/OrdersList.jsx index b84f6470fb4..4b49c27a906 100644 --- a/src/components/Office/DefinitionLists/OrdersList.jsx +++ b/src/components/Office/DefinitionLists/OrdersList.jsx @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import styles from './OfficeDefinitionLists.module.scss'; +import { ORDERS_PAY_GRADE_OPTIONS } from 'constants/orders'; import { OrdersInfoShape } from 'types/order'; import { formatDate } from 'shared/dates'; import descriptionListStyles from 'styles/descriptionList.module.scss'; @@ -41,6 +42,17 @@ const OrdersList = ({ ordersInfo, showMissingWarnings }) => {
{reportDateRowLabel}
{formatDate(ordersInfo.reportByDate, 'DD MMM YYYY')}
+ +
+
Pay grade
+
+ {!ordersInfo.payGrade ? missingText : ORDERS_PAY_GRADE_OPTIONS[ordersInfo.payGrade]} +
+
Current duty location
{ordersInfo.currentDutyLocation?.name}
diff --git a/src/components/Office/DefinitionLists/OrdersList.stories.jsx b/src/components/Office/DefinitionLists/OrdersList.stories.jsx index 9c4186ad6f9..e74dd904ae0 100644 --- a/src/components/Office/DefinitionLists/OrdersList.stories.jsx +++ b/src/components/Office/DefinitionLists/OrdersList.stories.jsx @@ -24,6 +24,7 @@ export const Basic = () => ( sacSDN: text('ordersInfo.sacSDN', '999 999999 999'), NTSsac: text('ordersInfo.NTSsac', '999 999999 999'), NTStac: text('ordersInfo.NTStac', '9999'), + payGrade: text('ordersInfo.payGrade', 'E_5'), }} />
@@ -46,6 +47,7 @@ export const AsServiceCounselor = () => ( sacSDN: '', NTSsac: '', NTStac: '', + payGrade: text('ordersInfo.payGrade', 'E_5'), }} />
@@ -68,6 +70,7 @@ export const AsServiceCounselorProcessingRetirement = () => ( sacSDN: '', NTSsac: '', NTStac: '', + payGrade: text('ordersInfo.payGrade', 'E_5'), }} />
@@ -90,6 +93,7 @@ export const AsServiceCounselorProcessingSeparation = () => ( sacSDN: '', NTSsac: '', NTStac: '', + payGrade: text('ordersInfo.payGrade', 'E_5'), }} /> @@ -111,6 +115,7 @@ export const AsTOO = () => ( sacSDN: '', NTSsac: '', NTStac: '', + payGrade: text('ordersInfo.payGrade', 'E_5'), }} /> @@ -132,6 +137,7 @@ export const AsTOOProcessingRetirement = () => ( sacSDN: '', NTSsac: '', NTStac: '', + payGrade: text('ordersInfo.payGrade', 'E_5'), }} /> @@ -153,6 +159,7 @@ export const AsTOOProcessingSeparation = () => ( sacSDN: '', NTSsac: '', NTStac: '', + payGrade: text('ordersInfo.payGrade', 'E_5'), }} /> diff --git a/src/components/Office/DefinitionLists/OrdersList.test.jsx b/src/components/Office/DefinitionLists/OrdersList.test.jsx index ec36c4cbc1b..cf442cf241e 100644 --- a/src/components/Office/DefinitionLists/OrdersList.test.jsx +++ b/src/components/Office/DefinitionLists/OrdersList.test.jsx @@ -14,6 +14,7 @@ const ordersInfo = { ordersTypeDetail: 'HHG_PERMITTED', tacMDC: '9999', sacSDN: '999 999999 999', + payGrade: 'E_7', }; // what ordersInfo from above should be rendered as @@ -28,6 +29,7 @@ const expectedRenderedOrdersInfo = { ordersTypeDetail: 'Shipment of HHG Permitted', tacMDC: '9999', sacSDN: '999 999999 999', + payGrade: 'E-7', }; const ordersInfoMissing = { @@ -41,6 +43,7 @@ const ordersInfoMissing = { ordersTypeDetail: '', tacMDC: '', sacSDN: '999 999999 999', + payGrade: '', }; describe('OrdersList', () => { @@ -58,6 +61,7 @@ describe('OrdersList', () => { expect(screen.getByTestId('ordersType').textContent).toEqual('Missing'); expect(screen.getByTestId('ordersTypeDetail').textContent).toEqual('Missing'); expect(screen.getByTestId('tacMDC').textContent).toEqual('Missing'); + expect(screen.getByTestId('payGrade').textContent).toEqual('Missing'); }); it('renders missing orders info as dashes if showMissingWarnings is false', () => { @@ -67,5 +71,6 @@ describe('OrdersList', () => { expect(screen.getByTestId('ordersType').textContent).toEqual('—'); expect(screen.getByTestId('ordersTypeDetail').textContent).toEqual('—'); expect(screen.getByTestId('tacMDC').textContent).toEqual('—'); + expect(screen.getByTestId('payGrade').textContent).toEqual('—'); }); }); diff --git a/src/components/Office/OrdersDetailForm/OrdersDetailForm.jsx b/src/components/Office/OrdersDetailForm/OrdersDetailForm.jsx index de0d051c509..5b375fa179c 100644 --- a/src/components/Office/OrdersDetailForm/OrdersDetailForm.jsx +++ b/src/components/Office/OrdersDetailForm/OrdersDetailForm.jsx @@ -27,6 +27,7 @@ const OrdersDetailForm = ({ showOrdersAcknowledgement, ordersType, setFieldValue, + payGradeOptions, formIsDisabled, }) => { const [formOrdersType, setFormOrdersType] = useState(ordersType); @@ -48,6 +49,15 @@ const OrdersDetailForm = ({ placeholder={isRetirementOrSeparation ? 'Enter a city or ZIP' : 'Start typing a duty location...'} isDisabled={formIsDisabled} /> + {showDepartmentIndicator && ( @@ -161,6 +171,7 @@ OrdersDetailForm.propTypes = { showOrdersAcknowledgement: bool, ordersType: string.isRequired, setFieldValue: func.isRequired, + payGradeOptions: DropdownArrayOf, formIsDisabled: bool, }; @@ -179,6 +190,7 @@ OrdersDetailForm.defaultProps = { showNTSTac: true, showNTSSac: true, showOrdersAcknowledgement: false, + payGradeOptions: null, formIsDisabled: false, }; diff --git a/src/components/Office/OrdersDetailForm/OrdersDetailForm.stories.jsx b/src/components/Office/OrdersDetailForm/OrdersDetailForm.stories.jsx index a39bd80d0ab..74c9b2d1565 100644 --- a/src/components/Office/OrdersDetailForm/OrdersDetailForm.stories.jsx +++ b/src/components/Office/OrdersDetailForm/OrdersDetailForm.stories.jsx @@ -4,7 +4,7 @@ import { Formik } from 'formik'; import OrdersDetailForm from 'components/Office/OrdersDetailForm/OrdersDetailForm'; import { dropdownInputOptions } from 'utils/formatters'; -import { ORDERS_TYPE_OPTIONS, ORDERS_TYPE_DETAILS_OPTIONS } from 'constants/orders'; +import { ORDERS_TYPE_OPTIONS, ORDERS_TYPE_DETAILS_OPTIONS, ORDERS_PAY_GRADE_OPTIONS } from 'constants/orders'; import { DEPARTMENT_INDICATOR_OPTIONS } from 'constants/departmentIndicators'; const originDutyLocation = { @@ -41,6 +41,7 @@ const newDutyLocation = { const deptIndicatorOptions = dropdownInputOptions(DEPARTMENT_INDICATOR_OPTIONS); const ordersTypeOptions = dropdownInputOptions(ORDERS_TYPE_OPTIONS); const ordersTypeDetailOptions = dropdownInputOptions(ORDERS_TYPE_DETAILS_OPTIONS); +const payGradeOptions = dropdownInputOptions(ORDERS_PAY_GRADE_OPTIONS); export default { title: 'Office Components/OrdersDetailForm', @@ -86,6 +87,8 @@ export const EmptyValues = () => ( ordersTypeDetailOptions={ordersTypeDetailOptions} ordersType={ORDERS_TYPE_OPTIONS.PERMANENT_CHANGE_OF_STATION} setFieldValue={Formik.setFieldValue} + payGrade={ORDERS_PAY_GRADE_OPTIONS.E_1} + payGradeOptions={payGradeOptions} /> @@ -135,6 +138,7 @@ export const InitialValues = () => { ordersTypeDetailOptions={ordersTypeDetailOptions} showOrdersAcknowledgement setFieldValue={formik.setFieldValue} + payGradeOptions={payGradeOptions} /> ); @@ -186,6 +190,7 @@ export const FieldsHidden = (args) => { ordersTypeOptions={ordersTypeOptions} ordersTypeDetailOptions={ordersTypeDetailOptions} setFieldValue={formik.setFieldValue} + payGradeOptions={payGradeOptions} {...args} /> @@ -224,6 +229,7 @@ export const Retiree = () => ( ordersTypeDetailOptions={ordersTypeDetailOptions} ordersType="RETIREMENT" setFieldValue={formik.setFieldValue} + payGradeOptions={payGradeOptions} /> ); @@ -260,6 +266,7 @@ export const Separatee = () => ( ordersTypeDetailOptions={ordersTypeDetailOptions} ordersType="SEPARATION" setFieldValue={formik.setFieldValue} + payGradeOptions={payGradeOptions} /> ); diff --git a/src/components/Office/OrdersDetailForm/OrdersDetailForm.test.jsx b/src/components/Office/OrdersDetailForm/OrdersDetailForm.test.jsx index 0319cc92faf..64ee66772e4 100644 --- a/src/components/Office/OrdersDetailForm/OrdersDetailForm.test.jsx +++ b/src/components/Office/OrdersDetailForm/OrdersDetailForm.test.jsx @@ -7,7 +7,7 @@ import OrdersDetailForm from './OrdersDetailForm'; import { DEPARTMENT_INDICATOR_OPTIONS } from 'constants/departmentIndicators'; import { dropdownInputOptions } from 'utils/formatters'; -import { ORDERS_TYPE_OPTIONS, ORDERS_TYPE_DETAILS_OPTIONS } from 'constants/orders'; +import { ORDERS_TYPE_OPTIONS, ORDERS_TYPE_DETAILS_OPTIONS, ORDERS_PAY_GRADE_OPTIONS } from 'constants/orders'; const dutyLocation = { address: { @@ -42,6 +42,8 @@ const initialValues = { const deptOptions = dropdownInputOptions(DEPARTMENT_INDICATOR_OPTIONS); const ordersTypeOptions = dropdownInputOptions(ORDERS_TYPE_OPTIONS); const ordersTypeDetailOptions = dropdownInputOptions(ORDERS_TYPE_DETAILS_OPTIONS); +const payGradeOptions = dropdownInputOptions(ORDERS_PAY_GRADE_OPTIONS); + const defaultProps = { deptIndicatorOptions: deptOptions, ordersTypeOptions, @@ -50,6 +52,7 @@ const defaultProps = { validateTac: jest.fn, ordersType: 'PERMANENT_CHANGE_OF_STATION', setFieldValue: jest.fn, + payGradeOptions, }; function renderOrdersDetailForm(props) { diff --git a/src/pages/Office/MoveAllowances/MoveAllowances.jsx b/src/pages/Office/MoveAllowances/MoveAllowances.jsx index c12251d008a..2aad30cc0b8 100644 --- a/src/pages/Office/MoveAllowances/MoveAllowances.jsx +++ b/src/pages/Office/MoveAllowances/MoveAllowances.jsx @@ -16,14 +16,12 @@ import { updateAllowance } from 'services/ghcApi'; import LoadingPlaceholder from 'shared/LoadingPlaceholder'; import SomethingWentWrong from 'shared/SomethingWentWrong'; import { useOrdersDocumentQueries } from 'hooks/queries'; -import { ORDERS_BRANCH_OPTIONS, ORDERS_PAY_GRADE_OPTIONS } from 'constants/orders'; +import { ORDERS_BRANCH_OPTIONS } from 'constants/orders'; import { dropdownInputOptions } from 'utils/formatters'; import { ORDERS } from 'constants/queryKeys'; import { permissionTypes } from 'constants/permissions'; import Restricted from 'components/Restricted/Restricted'; -const payGradeDropdownOptions = dropdownInputOptions(ORDERS_PAY_GRADE_OPTIONS); - const branchDropdownOption = dropdownInputOptions(ORDERS_BRANCH_OPTIONS); const validationSchema = Yup.object({ @@ -171,18 +169,13 @@ const MoveAllowances = () => { fallback={ } > - + diff --git a/src/pages/Office/MoveAllowances/MoveAllowances.test.jsx b/src/pages/Office/MoveAllowances/MoveAllowances.test.jsx index 8cfe6589316..b9ff87d66e5 100644 --- a/src/pages/Office/MoveAllowances/MoveAllowances.test.jsx +++ b/src/pages/Office/MoveAllowances/MoveAllowances.test.jsx @@ -150,7 +150,6 @@ describe('MoveAllowances page', () => { expect(screen.getByTestId('proGearWeightSpouseInput')).toHaveDisplayValue('500'); expect(screen.getByTestId('rmeInput')).toHaveDisplayValue('1,000'); expect(screen.getByTestId('branchInput')).toHaveDisplayValue('Army'); - expect(screen.getByTestId('payGradeInput')).toHaveDisplayValue('E-1'); expect(screen.getByTestId('sitInput')).toHaveDisplayValue('2'); expect(screen.getByLabelText('OCIE authorized (Army only)')).toBeChecked(); diff --git a/src/pages/Office/MoveDetails/MoveDetails.jsx b/src/pages/Office/MoveDetails/MoveDetails.jsx index f301ffcfba2..3fa46b26971 100644 --- a/src/pages/Office/MoveDetails/MoveDetails.jsx +++ b/src/pages/Office/MoveDetails/MoveDetails.jsx @@ -248,6 +248,7 @@ const MoveDetails = ({ sacSDN: order.sac, NTStac: order.ntsTac, NTSsac: order.ntsSac, + payGrade: order.grade, }; const allowancesInfo = { branch: customer.agency, diff --git a/src/pages/Office/Orders/Orders.jsx b/src/pages/Office/Orders/Orders.jsx index d98dd30a15b..17c23678adc 100644 --- a/src/pages/Office/Orders/Orders.jsx +++ b/src/pages/Office/Orders/Orders.jsx @@ -16,7 +16,7 @@ import SomethingWentWrong from 'shared/SomethingWentWrong'; import OrdersDetailForm from 'components/Office/OrdersDetailForm/OrdersDetailForm'; import { formatSwaggerDate, dropdownInputOptions } from 'utils/formatters'; import { DEPARTMENT_INDICATOR_OPTIONS } from 'constants/departmentIndicators'; -import { ORDERS_TYPE_DETAILS_OPTIONS, ORDERS_TYPE_OPTIONS } from 'constants/orders'; +import { ORDERS_PAY_GRADE_OPTIONS, ORDERS_TYPE_DETAILS_OPTIONS, ORDERS_TYPE_OPTIONS } from 'constants/orders'; import { ORDERS } from 'constants/queryKeys'; import { useOrdersDocumentQueries } from 'hooks/queries'; import { TAC_VALIDATION_ACTIONS, reducer, initialState } from 'reducers/tacValidation'; @@ -27,6 +27,7 @@ import { permissionTypes } from 'constants/permissions'; const deptIndicatorDropdownOptions = dropdownInputOptions(DEPARTMENT_INDICATOR_OPTIONS); const ordersTypeDropdownOptions = dropdownInputOptions(ORDERS_TYPE_OPTIONS); const ordersTypeDetailsDropdownOptions = dropdownInputOptions(ORDERS_TYPE_DETAILS_OPTIONS); +const payGradeDropdownOptions = dropdownInputOptions(ORDERS_PAY_GRADE_OPTIONS); const Orders = () => { const navigate = useNavigate(); @@ -146,7 +147,9 @@ const Orders = () => { proGearWeightSpouse, requiredMedicalEquipmentWeight, organizationalClothingAndIndividualEquipment, + grade: values.payGrade, }; + mutateOrders({ orderID: orderId, ifMatchETag: order.eTag, body }); }; @@ -170,6 +173,7 @@ const Orders = () => { ntsTac: order?.ntsTac, ntsSac: order?.ntsSac, ordersAcknowledgement: !!amendedOrdersAcknowledgedAt, + payGrade: order?.grade, }; return ( @@ -225,6 +229,7 @@ const Orders = () => { showOrdersAcknowledgement={hasAmendedOrders} ordersType={order.order_type} setFieldValue={formik.setFieldValue} + payGradeOptions={payGradeDropdownOptions} formIsDisabled /> } @@ -240,6 +245,7 @@ const Orders = () => { showOrdersAcknowledgement={hasAmendedOrders} ordersType={order.order_type} setFieldValue={formik.setFieldValue} + payGradeOptions={payGradeDropdownOptions} /> diff --git a/src/pages/Office/Orders/Orders.test.jsx b/src/pages/Office/Orders/Orders.test.jsx index fc4421c7bf2..d6a46bd30e3 100644 --- a/src/pages/Office/Orders/Orders.test.jsx +++ b/src/pages/Office/Orders/Orders.test.jsx @@ -152,6 +152,7 @@ describe('Orders page', () => { expect(await screen.findByLabelText('Current duty location')).toBeInTheDocument(); expect(screen.getByTestId('ntsTacInput')).toHaveValue('1111'); expect(screen.getByTestId('ntsSacInput')).toHaveValue('2222'); + expect(screen.getByTestId('payGradeInput')).toHaveDisplayValue('E-1'); }); }); diff --git a/src/pages/Office/ServicesCounselingMoveAllowances/ServicesCounselingMoveAllowances.jsx b/src/pages/Office/ServicesCounselingMoveAllowances/ServicesCounselingMoveAllowances.jsx index 3c4dcc18816..e8d3bd08693 100644 --- a/src/pages/Office/ServicesCounselingMoveAllowances/ServicesCounselingMoveAllowances.jsx +++ b/src/pages/Office/ServicesCounselingMoveAllowances/ServicesCounselingMoveAllowances.jsx @@ -11,7 +11,7 @@ import AllowancesDetailForm from '../../../components/Office/AllowancesDetailFor import styles from 'styles/documentViewerWithSidebar.module.scss'; import { milmoveLogger } from 'utils/milmoveLog'; -import { ORDERS_BRANCH_OPTIONS, ORDERS_PAY_GRADE_OPTIONS } from 'constants/orders'; +import { ORDERS_BRANCH_OPTIONS } from 'constants/orders'; import { ORDERS } from 'constants/queryKeys'; import { servicesCounselingRoutes } from 'constants/routes'; import { useOrdersDocumentQueries } from 'hooks/queries'; @@ -20,8 +20,6 @@ import { dropdownInputOptions } from 'utils/formatters'; import LoadingPlaceholder from 'shared/LoadingPlaceholder'; import SomethingWentWrong from 'shared/SomethingWentWrong'; -const payGradeDropdownOptions = dropdownInputOptions(ORDERS_PAY_GRADE_OPTIONS); - const branchDropdownOption = dropdownInputOptions(ORDERS_BRANCH_OPTIONS); const validationSchema = Yup.object({ @@ -156,7 +154,6 @@ const ServicesCounselingMoveAllowances = () => {
diff --git a/src/pages/Office/ServicesCounselingMoveAllowances/ServicesCounselingMoveAllowances.test.jsx b/src/pages/Office/ServicesCounselingMoveAllowances/ServicesCounselingMoveAllowances.test.jsx index 682601cd43c..c2cb6443422 100644 --- a/src/pages/Office/ServicesCounselingMoveAllowances/ServicesCounselingMoveAllowances.test.jsx +++ b/src/pages/Office/ServicesCounselingMoveAllowances/ServicesCounselingMoveAllowances.test.jsx @@ -151,7 +151,6 @@ describe('MoveAllowances page', () => { expect(screen.getByTestId('proGearWeightSpouseInput')).toHaveDisplayValue('500'); expect(screen.getByTestId('rmeInput')).toHaveDisplayValue('1,000'); expect(screen.getByTestId('branchInput')).toHaveDisplayValue('Army'); - expect(screen.getByTestId('payGradeInput')).toHaveDisplayValue('E-1'); expect(screen.getByTestId('sitInput')).toHaveDisplayValue('2'); expect(screen.getByLabelText('OCIE authorized (Army only)')).toBeChecked(); diff --git a/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.jsx b/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.jsx index c0235a11cac..a143c4da477 100644 --- a/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.jsx +++ b/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.jsx @@ -310,6 +310,7 @@ const ServicesCounselingMoveDetails = ({ infoSavedAlert, setUnapprovedShipmentCo sacSDN: order.sac, NTStac: order.ntsTac, NTSsac: order.ntsSac, + payGrade: order.grade, }; const ordersLOA = { tac: order.tac, diff --git a/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.test.jsx b/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.test.jsx index 3bf39ebe33d..e58a9ca1ebc 100644 --- a/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.test.jsx +++ b/src/pages/Office/ServicesCounselingMoveDetails/ServicesCounselingMoveDetails.test.jsx @@ -740,7 +740,7 @@ describe('MoveDetails page', () => { renderComponent(); expect(await screen.findByRole('heading', { name: 'Allowances', level: 2 })).toBeInTheDocument(); - expect(screen.getByText('Branch, pay grade')).toBeInTheDocument(); + expect(screen.getByText('Branch')).toBeInTheDocument(); }); it('allows the service counselor to use the modal as expected', async () => { diff --git a/src/pages/Office/ServicesCounselingOrders/ServicesCounselingOrders.jsx b/src/pages/Office/ServicesCounselingOrders/ServicesCounselingOrders.jsx index 4573d938bb2..c9b07f2704f 100644 --- a/src/pages/Office/ServicesCounselingOrders/ServicesCounselingOrders.jsx +++ b/src/pages/Office/ServicesCounselingOrders/ServicesCounselingOrders.jsx @@ -12,7 +12,7 @@ import styles from 'styles/documentViewerWithSidebar.module.scss'; import { milmoveLogger } from 'utils/milmoveLog'; import OrdersDetailForm from 'components/Office/OrdersDetailForm/OrdersDetailForm'; import { DEPARTMENT_INDICATOR_OPTIONS } from 'constants/departmentIndicators'; -import { ORDERS_TYPE_DETAILS_OPTIONS, ORDERS_TYPE_OPTIONS } from 'constants/orders'; +import { ORDERS_TYPE_DETAILS_OPTIONS, ORDERS_TYPE_OPTIONS, ORDERS_PAY_GRADE_OPTIONS } from 'constants/orders'; import { ORDERS } from 'constants/queryKeys'; import { servicesCounselingRoutes } from 'constants/routes'; import { useOrdersDocumentQueries } from 'hooks/queries'; @@ -26,6 +26,7 @@ import { LOA_TYPE } from 'shared/constants'; const deptIndicatorDropdownOptions = dropdownInputOptions(DEPARTMENT_INDICATOR_OPTIONS); const ordersTypeDropdownOptions = dropdownInputOptions(ORDERS_TYPE_OPTIONS); const ordersTypeDetailsDropdownOptions = dropdownInputOptions(ORDERS_TYPE_DETAILS_OPTIONS); +const payGradeDropdownOptions = dropdownInputOptions(ORDERS_PAY_GRADE_OPTIONS); const ServicesCounselingOrders = () => { const navigate = useNavigate(); @@ -126,6 +127,7 @@ const ServicesCounselingOrders = () => { issueDate: formatSwaggerDate(values.issueDate), reportByDate: formatSwaggerDate(values.reportByDate), ordersType: values.ordersType, + grade: values.payGrade, }; mutateOrders({ orderID: orderId, ifMatchETag: order.eTag, body }); }; @@ -143,6 +145,7 @@ const ServicesCounselingOrders = () => { sac: order?.sac, ntsTac: order?.ntsTac, ntsSac: order?.ntsSac, + payGrade: order?.grade, }; const tacWarningMsg = @@ -188,6 +191,7 @@ const ServicesCounselingOrders = () => { ntsTacWarning={ntsTacWarning} validateHHGTac={handleHHGTacValidation} validateNTSTac={handleNTSTacValidation} + payGradeOptions={payGradeDropdownOptions} />
diff --git a/src/pages/Office/ServicesCounselingOrders/ServicesCounselingOrders.test.jsx b/src/pages/Office/ServicesCounselingOrders/ServicesCounselingOrders.test.jsx index 0a01bdeacca..dab006ef0b9 100644 --- a/src/pages/Office/ServicesCounselingOrders/ServicesCounselingOrders.test.jsx +++ b/src/pages/Office/ServicesCounselingOrders/ServicesCounselingOrders.test.jsx @@ -202,6 +202,7 @@ describe('Orders page', () => { expect(screen.getByTestId('hhgSacInput')).toHaveValue('E2P3'); expect(screen.getByTestId('ntsTacInput')).toHaveValue('1111'); expect(screen.getByTestId('ntsSacInput')).toHaveValue('R6X1'); + expect(screen.getByTestId('payGradeInput')).toHaveValue('E_1'); }); }); diff --git a/swagger-def/ghc.yaml b/swagger-def/ghc.yaml index e2db26aad5a..2b30d4b323f 100644 --- a/swagger-def/ghc.yaml +++ b/swagger-def/ghc.yaml @@ -3878,6 +3878,8 @@ definitions: title: NTS SAC example: 'N002214CSW32Y9' $ref: definitions/NullableString.yaml + grade: + $ref: '#/definitions/Grade' required: - issueDate - reportByDate @@ -3944,6 +3946,8 @@ definitions: description: Confirmation that the new amended orders were reviewed after previously approving the original orders type: boolean x-nullable: true + grade: + $ref: '#/definitions/Grade' required: - issueDate - reportByDate diff --git a/swagger/ghc.yaml b/swagger/ghc.yaml index accd7cf75cb..1733b23b912 100644 --- a/swagger/ghc.yaml +++ b/swagger/ghc.yaml @@ -4021,6 +4021,8 @@ definitions: title: NTS SAC example: N002214CSW32Y9 $ref: '#/definitions/NullableString' + grade: + $ref: '#/definitions/Grade' required: - issueDate - reportByDate @@ -4089,6 +4091,8 @@ definitions: previously approving the original orders type: boolean x-nullable: true + grade: + $ref: '#/definitions/Grade' required: - issueDate - reportByDate