Skip to content

Commit

Permalink
UINV-470: add selected version view
Browse files Browse the repository at this point in the history
  • Loading branch information
alisher-epam committed Nov 19, 2024
1 parent 9feae21 commit c937b30
Show file tree
Hide file tree
Showing 24 changed files with 597 additions and 244 deletions.
10 changes: 8 additions & 2 deletions src/common/components/ApprovedBy/ApprovedBy.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@ import { stripesConnect } from '@folio/stripes/core';
import {
baseManifest,
USERS_API,
VersionKeyValue,
} from '@folio/stripes-acq-components';

import { getUserName } from '../../utils';

export const ApprovedBy = ({ approvedByUserId, resources }) => {
export const ApprovedBy = ({ approvedByUserId, isVersionView, name, resources }) => {
const { failed, records } = resources.approvedByUser || {};
const approvedByUser = failed ? null : get(records, '0');
const value = approvedByUserId ? getUserName(approvedByUser) : <NoValue />;

const KeyValueComponent = isVersionView ? VersionKeyValue : KeyValue;

return (
<KeyValue
<KeyValueComponent
name={name}
label={<FormattedMessage id="ui-invoice.invoice.approvedBy" />}
value={value}
/>
Expand All @@ -37,6 +41,8 @@ ApprovedBy.manifest = Object.freeze({

ApprovedBy.propTypes = {
approvedByUserId: PropTypes.string,
isVersionView: PropTypes.bool,
name: PropTypes.string,
resources: PropTypes.shape({
approvedByUser: PropTypes.object,
}).isRequired,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';

import { AmountWithCurrencyField } from '@folio/stripes-acq-components';
import {
AmountWithCurrencyField,
VersionKeyValue,
} from '@folio/stripes-acq-components';
import { KeyValue } from '@folio/stripes/components';
import { useStripes } from '@folio/stripes/core';

import { useExchangeCalculation } from '../../hooks';

export const CalculatedExchangeAmount = ({ currency, exchangeRate, total }) => {
export const CalculatedExchangeAmount = ({
currency,
exchangeRate,
isVersionView = false,
name,
total,
}) => {
const stripes = useStripes();
const systemCurrency = stripes.currency;
const enabled = Boolean(systemCurrency !== currency && total);
Expand All @@ -19,22 +28,29 @@ export const CalculatedExchangeAmount = ({ currency, exchangeRate, total }) => {
to: systemCurrency,
}, { enabled });

const KeyValueComponent = isVersionView ? VersionKeyValue : KeyValue;

if (!enabled) {
return null;
}

return (
<KeyValue label={<FormattedMessage id="ui-invoice.invoice.details.information.calculatedTotalExchangeAmount" />}>
<KeyValueComponent
name={name}
label={<FormattedMessage id="ui-invoice.invoice.details.information.calculatedTotalExchangeAmount" />}
>
<AmountWithCurrencyField
amount={exchangedAmount || total}
currency={systemCurrency}
/>
</KeyValue>
</KeyValueComponent>
);
};

CalculatedExchangeAmount.propTypes = {
currency: PropTypes.string,
exchangeRate: PropTypes.number,
isVersionView: PropTypes.bool,
name: PropTypes.string,
total: PropTypes.number,
};
10 changes: 8 additions & 2 deletions src/common/components/FiscalYearValue/FiscalYearValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,22 @@ import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';

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

export const FiscalYearValue = ({ isVersionView, name, value }) => {
const KeyValueComponent = isVersionView ? VersionKeyValue : KeyValue;

export const FiscalYearValue = ({ value }) => {
return (
<KeyValue
<KeyValueComponent
name={name}
label={<FormattedMessage id="ui-invoice.invoice.details.information.fiscalYear" />}
value={value}
/>
);
};

FiscalYearValue.propTypes = {
isVersionView: PropTypes.bool,
name: PropTypes.string,
value: PropTypes.string,
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Loading } from '@folio/stripes/components';
import { useFiscalYear } from '../../hooks';
import { FiscalYearValue } from './FiscalYearValue';

export const FiscalYearValueContainer = ({ fiscalYearId }) => {
export const FiscalYearValueContainer = ({ fiscalYearId, ...rest }) => {
const {
fiscalYear,
isLoading,
Expand All @@ -14,7 +14,7 @@ export const FiscalYearValueContainer = ({ fiscalYearId }) => {
if (isLoading) return <Loading />;

return (
<FiscalYearValue value={fiscalYear.code} />
<FiscalYearValue {...rest} value={fiscalYear.code} />
);
};

Expand Down
20 changes: 15 additions & 5 deletions src/common/components/Status/StatusValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,26 @@ import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';

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

import { getInvoiceStatusLabel } from '../../utils';

const StatusValue = ({ value }) => (
<KeyValue label={<FormattedMessage id="ui-invoice.invoice.details.information.status" />}>
<FormattedMessage id={getInvoiceStatusLabel({ status: value })} />
</KeyValue>
);
const StatusValue = ({ isVersionView, name, value }) => {
const KeyValueComponent = isVersionView ? VersionKeyValue : KeyValue;

return (
<KeyValueComponent
label={<FormattedMessage id="ui-invoice.invoice.details.information.status" />}
name={name}
>
<FormattedMessage id={getInvoiceStatusLabel({ status: value })} />
</KeyValueComponent>
);
};

StatusValue.propTypes = {
isVersionView: PropTypes.bool,
name: PropTypes.string,
value: PropTypes.string.isRequired,
};

Expand Down
9 changes: 6 additions & 3 deletions src/common/hooks/useOrderLines/useOrderLines.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const buildQueryByOrderId = (itemsChunk) => {
};

export const useOrderLines = (orderIds, options = {}) => {
const { enabled = true, buildQuery = buildQueryByOrderId, ...otherOptions } = options;
const ky = useOkapiKy();
const [namespace] = useNamespace({ key: 'order-lines' });

Expand All @@ -31,10 +32,12 @@ export const useOrderLines = (orderIds, options = {}) => {
.then(({ poLines }) => poLines)
.catch(() => []),
orderIds,
buildQueryByOrderId,

buildQuery,
),
{ enabled: Boolean(orderIds?.length), ...options },
{
enabled: enabled && Boolean(orderIds?.length),
...otherOptions,
},
);

return ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import {
filter,
flow,
get,
keyBy,
uniq,
} from 'lodash/fp';
import get from 'lodash/get';
import keyBy from 'lodash/keyBy';
import uniq from 'lodash/uniq';
import { useMemo } from 'react';
import { useIntl } from 'react-intl';
import { useQuery } from 'react-query';
Expand All @@ -16,39 +12,16 @@ import {
import { getFullName } from '@folio/stripes/util';
import {
ACQUISITIONS_UNITS_API,
CONFIG_ADDRESSES,
CONFIG_API,
LIMIT_MAX,
MODULE_TENANT,
fetchExportDataByIds,
fetchOrganizationsByIds,
getAddresses,
useUsersBatch,
} from '@folio/stripes-acq-components';

import { useInvoice } from '../useInvoice';
import { getTenantAddresses, getVersionMetadata } from './utils';

const getUniqItems = (arr) => (
flow(
uniq,
filter(Boolean),
)(arr)
);

export const getTenantAddresses = (ky) => async () => {
const searchParams = {
limit: LIMIT_MAX,
query: `(module=${MODULE_TENANT} and configName=${CONFIG_ADDRESSES})`,
};

return ky.get(CONFIG_API, { searchParams }).json();
};

export const getVersionMetadata = (version, entity) => ({
...get(entity, 'metadata', {}),
updatedByUserId: version?.userId,
updatedDate: version?.actionDate,
});
const DEFAULT_VALUE = [];

export const useSelectedInvoiceVersion = ({ versionId, versions, snapshotPath }, options = {}) => {
const intl = useIntl();
Expand All @@ -60,26 +33,26 @@ export const useSelectedInvoiceVersion = ({ versionId, versions, snapshotPath },
versions?.find(({ id }) => id === versionId)
), [versionId, versions]);
const versionSnapshot = useMemo(() => (
get(snapshotPath, currentVersion)
get(currentVersion, snapshotPath)
), [snapshotPath, currentVersion]);

const {
invoice,
isLoading: isInvoiceLoading,
} = useInvoice(currentVersion?.id);
} = useInvoice(currentVersion?.invoiceId);

const metadata = useMemo(() => getVersionMetadata(currentVersion, invoice), [currentVersion, invoice]);
const assignedToId = versionSnapshot?.assignedTo;
const createdByUserId = metadata?.createdByUserId;
const vendorId = versionSnapshot?.vendor;
const updatedByUserId = metadata?.updatedByUserId;
const vendorId = versionSnapshot?.vendorId;
const billToId = versionSnapshot?.billTo;

const versionUserIds = useMemo(() => getUniqItems([assignedToId, createdByUserId]), [assignedToId, createdByUserId]);
const versionUserIds = useMemo(() => uniq([updatedByUserId, createdByUserId]), [updatedByUserId, createdByUserId]);
const {
users,
users = DEFAULT_VALUE,
isLoading: isUsersLoading,
} = useUsersBatch(versionUserIds);
const versionUsersMap = keyBy('id', users);
const versionUsersMap = keyBy(users, 'id');

const {
isLoading: isVersionDataLoading,
Expand All @@ -88,32 +61,32 @@ export const useSelectedInvoiceVersion = ({ versionId, versions, snapshotPath },
[namespace, versionId, versionSnapshot?.id],
async () => {
const organizationIds = [vendorId];
const acqUnitsIds = versionSnapshot?.acqUnitIds || [];
const acqUnitsIds = versionSnapshot?.acqUnitIds || DEFAULT_VALUE;

const [
organizationsMap,
acqUnitsMap,
addressesMap,
] = await Promise.all([
fetchOrganizationsByIds(ky)(organizationIds).then(keyBy('id')),
fetchExportDataByIds({ ky, ids: acqUnitsIds, api: ACQUISITIONS_UNITS_API, records: 'acquisitionsUnits' })(acqUnitsIds).then(keyBy('id')),
fetchOrganizationsByIds(ky)(organizationIds).then(({ organizations }) => keyBy(organizations, 'id')),
fetchExportDataByIds({
ky,
ids: acqUnitsIds,
api: ACQUISITIONS_UNITS_API,
records: 'acquisitionsUnits',
}).then(data => keyBy(data, 'id')),
getTenantAddresses(ky)()
.then(({ configs }) => getAddresses(configs))
.then(keyBy('id')),
.then(data => keyBy(data, 'id')),
]);

const assignedTo = versionUsersMap[assignedToId]
? getFullName(versionUsersMap[assignedToId])
: deletedRecordLabel;

const createdByUser = versionUsersMap[createdByUserId]
? getFullName(versionUsersMap[createdByUserId])
: deletedRecordLabel;

return {
...versionSnapshot,
acqUnits: acqUnitsIds.map(acqUnitsId => acqUnitsMap[acqUnitsId]?.name || deletedRecordLabel).join(', '),
assignedTo: assignedToId && assignedTo,
vendor: organizationsMap[vendorId]?.name || deletedRecordLabel,
createdByUser: createdByUserId && createdByUser,
billTo: billToId && (addressesMap[billToId]?.address || deletedRecordLabel),
Expand All @@ -133,8 +106,8 @@ export const useSelectedInvoiceVersion = ({ versionId, versions, snapshotPath },

const isLoading = (
isInvoiceLoading
|| isUsersLoading
|| isVersionDataLoading
|| isUsersLoading
);

return {
Expand Down
23 changes: 23 additions & 0 deletions src/common/hooks/useSelectedInvoiceVersion/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import get from 'lodash/get';

import {
CONFIG_ADDRESSES,
CONFIG_API,
LIMIT_MAX,
MODULE_TENANT,
} from '@folio/stripes-acq-components';

export const getTenantAddresses = (ky) => async () => {
const searchParams = {
limit: LIMIT_MAX,
query: `(module=${MODULE_TENANT} and configName=${CONFIG_ADDRESSES})`,
};

return ky.get(CONFIG_API, { searchParams }).json();
};

export const getVersionMetadata = (version, entity) => ({
...get(entity, 'metadata', {}),
updatedByUserId: version?.userId,
updatedDate: version?.actionDate,
});
10 changes: 8 additions & 2 deletions src/invoices/InvoiceDetails/BatchGroupValue/BatchGroupValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import {
KeyValue,
Loading,
} from '@folio/stripes/components';
import { VersionKeyValue } from '@folio/stripes-acq-components';

import { batchGroupByPropResource } from '../../../common/resources';

export const BatchGroupValue = ({ id, label, mutator }) => {
export const BatchGroupValue = ({ id, isVersionView, name, label, mutator }) => {
const [batchGroup, setBatchGroup] = useState();

useEffect(
Expand All @@ -29,13 +30,16 @@ export const BatchGroupValue = ({ id, label, mutator }) => {
[id],
);

const KeyValueComponent = isVersionView ? VersionKeyValue : KeyValue;

if (!batchGroup) {
return <Loading />;
}

return (
<KeyValue
<KeyValueComponent
label={label}
name={name}
value={batchGroup.name}
/>
);
Expand All @@ -47,8 +51,10 @@ BatchGroupValue.manifest = Object.freeze({

BatchGroupValue.propTypes = {
id: PropTypes.string,
isVersionView: PropTypes.bool,
label: PropTypes.node.isRequired,
mutator: PropTypes.object.isRequired,
name: PropTypes.string,
};

export default stripesConnect(BatchGroupValue);
Loading

0 comments on commit c937b30

Please sign in to comment.