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

UIREC-411: ECS - fix user with no affiliation to the location in POL can not add pieces to the receiving title related to that POL #598

Merged
merged 9 commits into from
Oct 16, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
* Action menu should be closed after 'Save and create another' action. Refs UIREC-399.
* Update `consortium-search` interface. Refs UIREC-405.
* cleanup permissions for ui-receiving. Refs UIREC-410.
* ECS - fix user with no affiliation to the location in POL can not add pieces to the receiving title related to that POL. Refs UIREC-411.

## [5.0.5](https://github.com/folio-org/ui-receiving/tree/v5.0.5) (2024-08-05)
[Full Changelog](https://github.com/folio-org/ui-receiving/compare/v5.0.4...v5.0.5)
Expand Down
33 changes: 13 additions & 20 deletions src/Piece/PieceForm/PieceForm.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import uniq from 'lodash/uniq';
import PropTypes from 'prop-types';
import {
useCallback,
Expand Down Expand Up @@ -34,7 +33,10 @@ import {
useModalToggle,
} from '@folio/stripes-acq-components';

import { useHoldingsAndLocations } from '../../common/hooks';
import {
useHoldingsAndLocations,
useReceivingTenantIdsAndLocations,
} from '../../common/hooks';
import {
getClaimingIntervalFromDate,
setLocationValueFormMutator,
Expand Down Expand Up @@ -100,36 +102,27 @@ const PieceForm = ({
receivingTenantId,
} = formValues;

const receivingTenantIds = useMemo(() => {
const receivingTenants = useMemo(() => {
if (poLine?.locations?.length) {
return uniq([
...poLine.locations.map(({ tenantId }) => tenantId),
receivingTenantId,
].filter(Boolean));
return poLine.locations.map(({ tenantId }) => tenantId);
}

return [];
}, [receivingTenantId, poLine?.locations]);

const additionalLocations = useMemo(() => {
const locationIds = locationId ? [locationId] : [];
const tenantLocationIdsMap = receivingTenantId ? { [receivingTenantId]: locationIds } : {};
}, [poLine?.locations]);

return {
additionalLocationIds: locationIds,
additionalTenantLocationIdsMap: tenantLocationIdsMap,
};
}, [locationId, receivingTenantId]);
const receivingTenantIdsAndLocations = useReceivingTenantIdsAndLocations({
receivingTenantIds: receivingTenants,
currentReceivingTenantId: receivingTenantId,
currentLocationId: locationId,
});

const {
locations,
locationIds,
isFetching,
} = useHoldingsAndLocations({
instanceId,
receivingTenantIds,
tenantId: receivingTenantId,
...additionalLocations,
...receivingTenantIdsAndLocations,
});

useEffect(() => {
Expand Down
28 changes: 21 additions & 7 deletions src/Piece/PieceForm/PieceForm.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ import {
INVENTORY_RECORDS_TYPE,
PIECE_FORMAT,
PIECE_STATUS,
useCurrentUserTenants,
} from '@folio/stripes-acq-components';

import { renderWithRouter } from '../../../test/jest/helpers';
import { usePieceStatusChangeLog } from '../hooks';
import PieceForm from './PieceForm';

jest.mock('@folio/stripes-acq-components', () => {
return {
...jest.requireActual('@folio/stripes-acq-components'),
FieldInventory: jest.fn().mockReturnValue('FieldInventory'),
useCentralOrderingContext: jest.fn(),
};
});
jest.mock('@folio/stripes-acq-components', () => ({
...jest.requireActual('@folio/stripes-acq-components'),
FieldInventory: jest.fn().mockReturnValue('FieldInventory'),
useCentralOrderingContext: jest.fn(),
useCurrentUserTenants: jest.fn(),
}));
jest.mock('../../common/components/LineLocationsView/LineLocationsView', () => jest.fn().mockReturnValue('LineLocationsView'));
jest.mock('../hooks', () => ({
...jest.requireActual('../hooks'),
Expand Down Expand Up @@ -66,6 +66,16 @@ const userData = {
firstName: 'John',
},
};
const tenants = [{
id: 'tenantId1',
name: 'tenantName1',
isPrimary: true,
},
{
id: 'tenantId1',
name: 'tenantName1',
isPrimary: false,
}];
const logs = [
{
eventDate: '2023-12-26T14:08:19.402Z',
Expand Down Expand Up @@ -106,6 +116,10 @@ describe('PieceForm', () => {
usePieceStatusChangeLog
.mockClear()
.mockReturnValue({ data: logs });

useCurrentUserTenants
.mockClear()
.mockReturnValue(tenants);
});

it('should display the piece form', () => {
Expand Down
16 changes: 16 additions & 0 deletions src/Piece/PieceForm/PieceFormContainer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
useAcqRestrictions,
useLocationsQuery,
useOrderLine,
useCurrentUserTenants,
} from '@folio/stripes-acq-components';

import { renderWithRouter } from '../../../test/jest/helpers';
Expand All @@ -29,6 +30,7 @@ jest.mock('@folio/stripes-acq-components', () => ({
useAcqRestrictions: jest.fn(),
useLocationsQuery: jest.fn(),
useOrderLine: jest.fn(),
useCurrentUserTenants: jest.fn(),
}));
jest.mock('../../common/components/LineLocationsView/LineLocationsView', () => jest.fn().mockReturnValue('LineLocationsView'));
jest.mock('../../common/hooks', () => ({
Expand Down Expand Up @@ -85,6 +87,17 @@ const title = {
poLineId: orderLine.id,
};

const tenants = [{
id: 'tenantId1',
name: 'tenantName1',
isPrimary: true,
},
{
id: 'tenantId1',
name: 'tenantName1',
isPrimary: false,
}];

const restrictions = {};

const defaultProps = {
Expand Down Expand Up @@ -143,6 +156,9 @@ describe('PieceFormContainer', () => {
useUnreceive
.mockClear()
.mockReturnValue({ unreceive: unreceiveMock });
useCurrentUserTenants
.mockClear()
.mockReturnValue(tenants);
});

it('should display the piece form', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import {
TextField,
} from '@folio/stripes/components';

import { useHoldingsAndLocations } from '../../common/hooks';
import {
useHoldingsAndLocations,
useReceivingTenantIdsAndLocations,
} from '../../common/hooks';
import { useReceivingSearchContext } from '../../contexts';
import { PIECE_FORM_FIELD_NAMES } from '../constants';
import {
Expand All @@ -38,12 +41,18 @@ export const TitleBindPiecesCreateItemForm = ({

const { locationId, tenantId: receivingTenantId } = bindItemValues;

const additionalLocationIds = locationId ? [locationId] : [];
const additionalTenantLocationIdsMap = receivingTenantId ? { [receivingTenantId]: additionalLocationIds } : {};
const {
additionalLocationIds,
additionalTenantLocationIdsMap,
tenantId,
} = useReceivingTenantIdsAndLocations({
currentLocationId: locationId,
currentReceivingTenantId: receivingTenantId,
});

const { locations, isFetching } = useHoldingsAndLocations({
instanceId,
tenantId: bindItemValues.tenantId,
tenantId,
additionalLocationIds,
additionalTenantLocationIdsMap,
});
Expand Down
16 changes: 9 additions & 7 deletions src/TitleReceive/TitleReceiveContainer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import uniq from 'lodash/uniq';
import {
useCallback,
useMemo,
Expand All @@ -19,6 +18,7 @@ import {
import {
useHoldingsAndLocations,
useReceive,
useReceivingTenantIdsAndLocations,
useTitleHydratedPieces,
} from '../common/hooks';
import {
Expand Down Expand Up @@ -59,16 +59,18 @@ function TitleReceiveContainer({ history, location, match }) {

const { receive } = useReceive();

const receivingTenantIds = useMemo(() => {
const receivingTenants = useMemo(() => {
if (pieces?.length) {
return uniq([
...pieces.map(({ receivingTenantId }) => receivingTenantId),
targetTenantId,
].filter(Boolean));
return pieces.map(({ receivingTenantId }) => receivingTenantId);
}

return [];
}, [pieces, targetTenantId]);
}, [pieces]);

const { receivingTenantIds } = useReceivingTenantIdsAndLocations({
receivingTenantIds: receivingTenants,
currentReceivingTenantId: targetTenantId,
});

const { locations, isFetching } = useHoldingsAndLocations({
instanceId,
Expand Down
1 change: 1 addition & 0 deletions src/TitleReceive/TitleReceiveContainer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ jest.mock('../common/hooks', () => ({
useHoldingsAndLocations: jest.fn().mockReturnValue({ locations: [] }),
useReceive: jest.fn().mockReturnValue({}),
useTitleHydratedPieces: jest.fn(),
useReceivingTenantIdsAndLocations: jest.fn().mockReturnValue({}),
}));
jest.mock('./TitleReceive', () => jest.fn().mockReturnValue('TitleReceive'));

Expand Down
6 changes: 3 additions & 3 deletions src/common/components/LineLocationsView/LineLocationsView.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
const LineLocationsView = ({
crossTenant = false,
instanceId,
poLine,
poLine = {},
locations,
}) => {
const intl = useIntl();
Expand All @@ -27,14 +27,14 @@ const LineLocationsView = ({
const locationsToDisplay = useMemo(() => {
const locationsMap = locations.reduce((acc, l) => ({ ...acc, [l.id]: l }), {});
const holdingsMap = holdings.reduce((acc, h) => ({ ...acc, [h.id]: h }), {});
const lineLocations = poLine.locations.map(({ holdingId, locationId }) => (
const lineLocations = poLine.locations?.map(({ holdingId, locationId }) => (
holdingId
? holdings.length && holdingsMap[holdingId] && getHoldingLocationName(holdingsMap[holdingId], locationsMap, intl.formatMessage({ id: 'ui-receiving.titles.invalidReference' }))
: (locationsMap[locationId]?.name && `${locationsMap[locationId].name} (${locationsMap[locationId].code})`) || ''
));

return lineLocations.filter(Boolean).join(', ');
}, [holdings, intl, locations, poLine.locations]);
}, [holdings, intl, locations, poLine?.locations]);

return (
<>
Expand Down
1 change: 1 addition & 0 deletions src/common/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export * from './usePieces';
export * from './usePiecesExpect';
export * from './usePiecesRequests';
export * from './useReceive';
export * from './useReceivingTenantIdsAndLocations';
export * from './useTitle';
export * from './useTitleHydratedPieces';
export * from './useUnreceive';
43 changes: 43 additions & 0 deletions src/common/hooks/useReceivingTenantIdsAndLocations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import uniq from 'lodash/uniq';
import { useMemo } from 'react';

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

export const useReceivingTenantIdsAndLocations = ({
currentReceivingTenantId,
currentLocationId: locationId,
receivingTenantIds = [],
}) => {
const currentUserTenants = useCurrentUserTenants();

const receivingTenants = useMemo(() => {
if (receivingTenantIds.length) {
const currentUserTenantIds = currentUserTenants?.map(({ id: tenantId }) => tenantId);

// should get unique tenantIds from poLine locations and filter out tenantIds where the current user has assigned
return uniq([
...receivingTenantIds,
currentReceivingTenantId,
].filter((tenantId) => currentUserTenantIds.includes(tenantId))
.filter(Boolean));
}

return [];
}, [receivingTenantIds, currentUserTenants, currentReceivingTenantId]);

const additionalLocations = useMemo(() => {
const locationIds = locationId ? [locationId] : [];
const tenantLocationIdsMap = currentReceivingTenantId ? { [currentReceivingTenantId]: locationIds } : {};

return {
additionalLocationIds: locationIds,
additionalTenantLocationIdsMap: tenantLocationIdsMap,
};
}, [locationId, currentReceivingTenantId]);

return {
receivingTenantIds: receivingTenants,
tenantId: currentReceivingTenantId,
...additionalLocations,
};
};
Loading