Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

UIOR-1325 UIOR-1351 Add submit actions for PO and PO Line forms #1692

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## 7.1.0 (IN PROGRESS)

* Display the “Record deleted” label in version history only if the UUID no longer exists. Refs UIOR-1355.
* Add the "Save & keep editing" button to the PO form. Refs UIOR-1325.
* Add the "Save & keep editing" button to the PO Line form. Refs UIOR-1351.

## [7.0.4](https://github.com/folio-org/ui-orders/tree/v7.0.4) (2024-12-31)
[Full Changelog](https://github.com/folio-org/ui-orders/compare/v7.0.3...v7.0.4)
Expand Down
2 changes: 2 additions & 0 deletions src/common/constants/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,5 @@ export const CENTRAL_ORDERING_DEFAULT_RECEIVING_SEARCH = {
centralDefault: 'Central default',
activeAffiliationDefault: 'Active affiliation default',
};

export const SUBMIT_ACTION_FIELD = '__submitAction__';
7 changes: 6 additions & 1 deletion src/common/hooks/useOrder/useOrder.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ export const useOrder = (orderId) => {
query: `id==${orderId}`,
};

const { isLoading, data } = useQuery(
const {
data,
isLoading,
refetch,
} = useQuery(
['ui-orders', 'order', orderId],
async () => {
try {
Expand All @@ -29,5 +33,6 @@ export const useOrder = (orderId) => {
return ({
order: data,
isLoading,
refetch,
});
};
32 changes: 22 additions & 10 deletions src/common/hooks/useOrderLine/useOrderLine.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,32 @@ import {

import { LINES_API } from '@folio/stripes-acq-components';

export const useOrderLine = (lineId) => {
const ky = useOkapiKy();
const [namespace] = useNamespace({ key: 'order-versions' });
export const useOrderLine = (lineId, options = {}) => {
const {
enabled = true,
tenantId,
...queryOptions
} = options;

const { isLoading, data } = useQuery(
[namespace, lineId],
async () => ky.get(`${LINES_API}/${lineId}`).json(),
{
enabled: Boolean(lineId),
},
);
const [namespace] = useNamespace({ key: 'purchase-order-line' });
const ky = useOkapiKy({ tenant: tenantId });

const {
data,
isFetching,
isLoading,
refetch,
} = useQuery({
queryKey: [namespace, lineId, tenantId],
queryFn: ({ signal }) => ky.get(`${LINES_API}/${lineId}`, { signal }).json(),
enabled: enabled && Boolean(lineId),
...queryOptions,
});

return ({
orderLine: data,
isFetching,
isLoading,
refetch,
});
};
100 changes: 74 additions & 26 deletions src/components/LayerCollection/LayerPO.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import get from 'lodash/get';
import PropTypes from 'prop-types';
import { get } from 'lodash';
import {
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import { FormattedMessage } from 'react-intl';

import { LoadingView } from '@folio/stripes/components';
import {
stripesConnect,
} from '@folio/stripes/core';
import { stripesConnect } from '@folio/stripes/core';
import {
baseManifest,
ORDER_STATUSES,
Expand All @@ -16,9 +19,15 @@ import {
useShowCallout,
} from '@folio/stripes-acq-components';

import { SUBMIT_ACTION_FIELD } from '../../common/constants';
import {
createOrEditOrderResource,
} from '../Utils/orderResource';
useHandleOrderUpdateError,
useOrder,
} from '../../common/hooks';
import { SUBMIT_ACTION } from '../PurchaseOrder/constants';
import POForm from '../PurchaseOrder/POForm';
import { UpdateOrderErrorModal } from '../PurchaseOrder/UpdateOrderErrorModal';
import { createOrEditOrderResource } from '../Utils/orderResource';
import {
ADDRESSES,
ORDER,
Expand All @@ -27,9 +36,6 @@ import {
ORDER_TEMPLATES,
USERS,
} from '../Utils/resources';
import { useHandleOrderUpdateError } from '../../common/hooks/useHandleOrderUpdateError';
import POForm from '../PurchaseOrder/POForm';
import { UpdateOrderErrorModal } from '../PurchaseOrder/UpdateOrderErrorModal';

const NEW_ORDER = {
reEncumber: true,
Expand All @@ -53,8 +59,17 @@ function LayerPO({
const [isLoading, setIsLoading] = useState(true);
const [updateOrderError, setUpdateOrderError] = useState();
const [isErrorsModalOpened, toggleErrorsModal] = useModalToggle();
const order = id ? resources?.order?.records[0] : NEW_ORDER;

const instanceId = location.state?.instanceId;
const instanceTenantId = location.state?.instanceTenantId;

const {
order: fetchedOrder,
isLoading: isOrderLoading,
refetch,
} = useOrder(id);

const order = id ? fetchedOrder : NEW_ORDER;

useEffect(() => {
memoizedMutator.orderNumber.reset();
Expand All @@ -73,33 +88,56 @@ function LayerPO({
setUpdateOrderError(errors);
}, [toggleErrorsModal]);

const updatePO = useCallback(values => {
const updatePO = useCallback((values) => {
setIsLoading(true);
setSavingValues(values);

return createOrEditOrderResource(values, memoizedMutator.order)
.then(savedOrder => {
const { [SUBMIT_ACTION_FIELD]: submitAction, ...data } = values;

setSavingValues(data);

return createOrEditOrderResource(data, mutator.order)
.then((savedOrder) => {
sendCallout({
message: <FormattedMessage id="ui-orders.order.save.success" values={{ orderNumber: savedOrder.poNumber }} />,
});
history.push({
pathname: instanceId ? `/orders/view/${savedOrder.id}/po-line/create` : `/orders/view/${savedOrder.id}`,
search: location.search,
state: instanceId ? { instanceId, instanceTenantId: location.state?.instanceTenantId } : {},
});

return savedOrder;
})
.then(async (savedOrder) => {
setSavingValues(null);

switch (submitAction) {
case SUBMIT_ACTION.saveAndKeepEditing:
await refetch();

history.push({
pathname: `/orders/edit/${savedOrder.id}`,
search: location.search,
});
break;
case SUBMIT_ACTION.saveAndClose:
default:
history.push({
pathname: instanceId ? `/orders/view/${savedOrder.id}/po-line/create` : `/orders/view/${savedOrder.id}`,
search: location.search,
state: instanceId ? { instanceId, instanceTenantId } : {},
});
break;
}
})
.catch(async e => {
setIsLoading(false);
await handleErrorResponse(e, openOrderErrorModalShow);
});
})
.finally(() => setIsLoading(false));
}, [
handleErrorResponse,
history,
instanceId,
location.search,
location.state?.instanceTenantId,
memoizedMutator.order,
instanceTenantId,
mutator.order,
openOrderErrorModalShow,
refetch,
sendCallout,
]);

Expand All @@ -116,7 +154,14 @@ function LayerPO({
[history, id, location.search, instanceId],
);

if (isLoading || !order) return <LoadingView dismissible onClose={onCancel} />;
if (isLoading || isOrderLoading || !order) {
return (
<LoadingView
dismissible
onClose={onCancel}
/>
);
}

const { poNumber, poNumberPrefix, poNumberSuffix } = order;
const generatedNumber = get(resources, 'orderNumber.records.0.poNumber');
Expand Down Expand Up @@ -152,7 +197,10 @@ function LayerPO({
}

LayerPO.manifest = Object.freeze({
order: ORDER,
order: {
...ORDER,
fetch: false,
},
addresses: ADDRESSES,
users: {
...USERS,
Expand Down
48 changes: 38 additions & 10 deletions src/components/LayerCollection/LayerPO.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { MemoryRouter } from 'react-router';

import { render, screen, waitFor } from '@folio/jest-config-stripes/testing-library/react';
import {
render,
screen,
waitFor,
} from '@folio/jest-config-stripes/testing-library/react';
import { ORDER_TYPES } from '@folio/stripes-acq-components';

import {
Expand All @@ -12,23 +16,26 @@ import {
history,
location,
} from 'fixtures/routerMocks';
import { SUBMIT_ACTION_FIELD } from '../../common/constants';
import { useOrder } from '../../common/hooks';
import { SUBMIT_ACTION } from '../PurchaseOrder/constants';
import POForm from '../PurchaseOrder/POForm';
import LayerPO from './LayerPO';

jest.mock('../../common/hooks', () => ({
...jest.requireActual('../../common/hooks'),
useOrder: jest.fn(),
}));
jest.mock('../PurchaseOrder/POForm', () => jest.fn().mockReturnValue('POForm'));

const defaultProps = {
resourses: {
order: {
records: [order],
},
orderNumber: {
records: [{ poNumber: '10000' }],
},
},
mutator: {
order: {
GET: jest.fn().mockResolvedValue([order]),
POST: jest.fn().mockResolvedValue([order]),
PUT: jest.fn().mockResolvedValue([order]),
},
Expand Down Expand Up @@ -73,9 +80,14 @@ const renderLayerPO = (props = {}) => render(

describe('LayerPO', () => {
beforeEach(() => {
defaultProps.mutator.order.POST.mockClear();
history.push.mockClear();
POForm.mockClear();
useOrder.mockReturnValue({
order,
refetch: jest.fn(),
});
});

afterEach(() => {
jest.clearAllMocks();
});

it('should render PO form', async () => {
Expand All @@ -101,7 +113,22 @@ describe('LayerPO', () => {
orderType: ORDER_TYPES.ongoing,
}));

expect(history.push).toHaveBeenCalled();
expect(history.push).toHaveBeenCalledWith(expect.objectContaining({
pathname: expect.stringMatching(/orders\/view/),
}));
});

it('should keep edit form opened if saveAndKeepEditing action was selected', async () => {
renderLayerPO();

await waitFor(() => POForm.mock.calls[0][0].onSubmit({
orderType: ORDER_TYPES.ongoing,
[SUBMIT_ACTION_FIELD]: SUBMIT_ACTION.saveAndKeepEditing,
}));

expect(history.push).toHaveBeenCalledWith(expect.objectContaining({
pathname: expect.stringMatching(/orders\/edit/),
}));
});

describe('Create from inventory', () => {
Expand All @@ -120,6 +147,7 @@ describe('LayerPO', () => {

await waitFor(() => POForm.mock.calls[0][0].onSubmit({
orderType: ORDER_TYPES.ongoing,
[SUBMIT_ACTION_FIELD]: SUBMIT_ACTION.saveAndClose,
}));

expect(history.push).toHaveBeenCalledWith(expect.objectContaining({
Expand All @@ -130,7 +158,7 @@ describe('LayerPO', () => {
});

it('should throw an error if the order update was failed ', async () => {
defaultProps.mutator.order.POST.mockRejectedValue({});
defaultProps.mutator.order.POST.mockRejectedValueOnce({});

renderLayerPO();

Expand Down
Loading
Loading