From 7640a91ea0d71fadd33cde8a09c9d800790c05fd Mon Sep 17 00:00:00 2001 From: Yury Saukou Date: Thu, 5 Dec 2024 18:44:31 +0400 Subject: [PATCH 1/5] UIORGS-442 Add claiming to organization integration details --- CHANGELOG.md | 1 + .../OrganizationIntegrationCreate.js | 6 + .../EdiForm/EdiForm.js | 55 ++------ .../FtpForm/FtpForm.js | 19 ++- .../IntegrationInfoForm.js | 132 +++++++++++++++++- .../OrganizationIntegrationForm.js | 17 ++- .../EdiView/EdiView.js | 19 +-- .../IntegrationInfoView.js | 75 +++++++++- .../OrganizationIntegrationView.js | 15 +- src/OrganizationIntegration/constants.js | 15 ++ src/OrganizationIntegration/utils.js | 71 +++++++++- translations/ui-organizations/en.json | 7 + 12 files changed, 348 insertions(+), 84 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b26a0a90..26bba0ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * *BREAKING* Display all versions in change log in fourth pane. Refs UIORGS-355. * Show in version history record view, which fields have been edited. Refs UIORGS-356. * Adapt organization metadata fields to version history mechanism. Refs UIORGS-359. +* Add claiming to organization integration details. Refs UIORGS-442. ## [5.2.0](https://github.com/folio-org/ui-organizations/tree/v5.2.0) (2024-10-31) [Full Changelog](https://github.com/folio-org/ui-organizations/compare/v5.1.1...v5.2.0) diff --git a/src/OrganizationIntegration/OrganizationIntegrationCreate/OrganizationIntegrationCreate.js b/src/OrganizationIntegration/OrganizationIntegrationCreate/OrganizationIntegrationCreate.js index 46d0a37b..2ce8fe34 100644 --- a/src/OrganizationIntegration/OrganizationIntegrationCreate/OrganizationIntegrationCreate.js +++ b/src/OrganizationIntegration/OrganizationIntegrationCreate/OrganizationIntegrationCreate.js @@ -17,9 +17,12 @@ import { import { EDI_CODE_TYPES, + FILE_FORMAT, FTP_TYPES, + TRANSMISSION_METHOD, TRANSMISSION_MODES, CONNECTION_MODES, + INTEGRATION_TYPE, } from '../constants'; import { buildAvailableAccounts, @@ -38,6 +41,9 @@ const buildInitialValues = (organization, withMigration) => { exportTypeSpecificParameters: { vendorEdiOrdersExportConfig: { vendorId: organization.id, + integrationType: INTEGRATION_TYPE.claiming, + transmissionMethod: TRANSMISSION_METHOD.fileDownLoad, + fileFormat: FILE_FORMAT.csv, ediConfig: { vendorEdiCode: edi.vendorEdiCode, vendorEdiType: edi.vendorEdiType || EDI_CODE_TYPES[0].value, diff --git a/src/OrganizationIntegration/OrganizationIntegrationForm/EdiForm/EdiForm.js b/src/OrganizationIntegration/OrganizationIntegrationForm/EdiForm/EdiForm.js index 89027b65..bdca5176 100644 --- a/src/OrganizationIntegration/OrganizationIntegrationForm/EdiForm/EdiForm.js +++ b/src/OrganizationIntegration/OrganizationIntegrationForm/EdiForm/EdiForm.js @@ -1,7 +1,10 @@ -import React, { useMemo } from 'react'; import PropTypes from 'prop-types'; +import { useMemo } from 'react'; +import { + Field, + useForm, +} from 'react-final-form'; import { FormattedMessage } from 'react-intl'; -import { Field, useForm } from 'react-final-form'; import { Accordion, @@ -13,33 +16,23 @@ import { TextArea, TextField, } from '@folio/stripes/components'; -import { - validateRequired, -} from '@folio/stripes-acq-components'; +import { validateRequired } from '@folio/stripes-acq-components'; import { EDI_CODE_TYPES, EDI_NAMING_TOKENS, } from '../../constants'; import { - getAccountOptions, getAcqMethodOptions, + isFileFormatEDI, } from '../../utils'; -export const EdiForm = ({ - acqMethods = [], - accounts = [], -}) => { +export const EdiForm = ({ acqMethods }) => { const { getState } = useForm(); const acqMethodOptions = useMemo(() => getAcqMethodOptions(acqMethods), [acqMethods]); - const accountOptions = useMemo(() => getAccountOptions(accounts), [accounts]); - const isDefaultConfig = getState() - ?.values - ?.exportTypeSpecificParameters - ?.vendorEdiOrdersExportConfig - ?.isDefaultConfig; + const isFormatEDI = isFileFormatEDI(getState()?.values); return ( } > - { - !isDefaultConfig && ( - - } - name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.ediConfig.accountNoList" - component={Select} - dataOptions={accountOptions} - fullWidth - multiple - required - validate={validateRequired} - /> - - ) - } - } name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.ediConfig.vendorEdiCode" - required - validate={validateRequired} + required={isFormatEDI} + validate={isFormatEDI ? validateRequired : undefined} /> @@ -124,8 +96,8 @@ export const EdiForm = ({ id="libEdiCode" label={} name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.ediConfig.libEdiCode" - required - validate={validateRequired} + required={isFormatEDI} + validate={isFormatEDI ? validateRequired : undefined} /> @@ -226,5 +198,4 @@ export const EdiForm = ({ EdiForm.propTypes = { acqMethods: PropTypes.arrayOf(PropTypes.object), - accounts: PropTypes.arrayOf(PropTypes.string), }; diff --git a/src/OrganizationIntegration/OrganizationIntegrationForm/FtpForm/FtpForm.js b/src/OrganizationIntegration/OrganizationIntegrationForm/FtpForm/FtpForm.js index 74bcdd55..a4e8bafc 100644 --- a/src/OrganizationIntegration/OrganizationIntegrationForm/FtpForm/FtpForm.js +++ b/src/OrganizationIntegration/OrganizationIntegrationForm/FtpForm/FtpForm.js @@ -1,6 +1,8 @@ -import React from 'react'; import { FormattedMessage } from 'react-intl'; -import { Field } from 'react-final-form'; +import { + Field, + useForm, +} from 'react-final-form'; import { Accordion, @@ -24,8 +26,13 @@ import { TRANSMISSION_MODES, CONNECTION_MODES, } from '../../constants'; +import { isTransmissionMethodFTP } from '../../utils'; export const FtpForm = () => { + const { getState } = useForm(); + + const isMethodFTP = isTransmissionMethodFTP(getState()?.values); + return ( { label={} name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.ediFtp.serverAddress" type="text" - validate={validateURLRequired} + validate={isMethodFTP ? validateURLRequired : undefined} component={TextField} fullWidth - required + required={isMethodFTP} validateFields={[]} /> @@ -139,9 +146,9 @@ export const FtpForm = () => { type="number" component={TextField} fullWidth - required + required={isMethodFTP} validateFields={[]} - validate={validateRequired} + validate={isMethodFTP ? validateRequired : undefined} /> { + const intl = useIntl(); + const { + batch, + change, + getState, + } = useForm(); + + const formValues = getState()?.values; + + const isFormatEDI = isFileFormatEDI(formValues); + const isOrderingType = isOrderingIntegration(formValues); + + const isDefaultConfig = formValues + ?.exportTypeSpecificParameters + ?.vendorEdiOrdersExportConfig + ?.isDefaultConfig; + + const accountOptions = useMemo(() => getAccountOptions(accounts), [accounts]); + + const integrationTypeOptions = useMemo(() => getIntegrationTypeOptions(intl), [intl]); + const transmissionMethodOptions = useMemo(() => getTransmissionMethodOptions(intl), [intl]); + const fileFormatOptions = useMemo(() => getFileFormatOptions(), []); + + const handleIntegrationTypeChange = ({ target: { value } }) => { + batch(() => { + change('exportTypeSpecificParameters.vendorEdiOrdersExportConfig.integrationType', value); + + switch (value) { + case INTEGRATION_TYPE.ordering: { + change('exportTypeSpecificParameters.vendorEdiOrdersExportConfig.transmissionMethod', TRANSMISSION_METHOD.ftp); + change('exportTypeSpecificParameters.vendorEdiOrdersExportConfig.fileFormat', FILE_FORMAT.edi); + break; + } + case INTEGRATION_TYPE.claiming: { + change('exportTypeSpecificParameters.vendorEdiOrdersExportConfig.ediSchedule', null); + break; + } + default: break; + } + }); + }; -export const IntegrationInfoForm = ({ defaultIntegration }) => { return ( { /> + + + } + name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.integrationType" + onChange={handleIntegrationTypeChange} + required + /> + + + } + name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.transmissionMethod" + required + /> + + + } + name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.fileFormat" + required + /> + + { + !isDefaultConfig && ( + + } + name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.ediConfig.accountNoList" + component={Select} + dataOptions={accountOptions} + fullWidth + multiple + required={isFormatEDI} + validate={isFormatEDI ? validateRequired : undefined} + /> + + ) + } + ); }; IntegrationInfoForm.propTypes = { + accounts: PropTypes.arrayOf(PropTypes.string), defaultIntegration: PropTypes.object, }; diff --git a/src/OrganizationIntegration/OrganizationIntegrationForm/OrganizationIntegrationForm.js b/src/OrganizationIntegration/OrganizationIntegrationForm/OrganizationIntegrationForm.js index c2b7561c..e17811d7 100644 --- a/src/OrganizationIntegration/OrganizationIntegrationForm/OrganizationIntegrationForm.js +++ b/src/OrganizationIntegration/OrganizationIntegrationForm/OrganizationIntegrationForm.js @@ -28,6 +28,7 @@ import { } from '@folio/stripes-acq-components'; import { ORGANIZATIONS_ROUTE } from '../../common/constants'; +import { isClaimingIntegration } from '../utils'; import { IntegrationInfoForm } from './IntegrationInfoForm'; import { EdiForm } from './EdiForm'; import { FtpForm } from './FtpForm'; @@ -37,6 +38,7 @@ const OrganizationIntegrationForm = ({ acqMethods, accounts, defaultIntegration, + form: { getState }, onClose, paneTitle, handleSubmit, @@ -107,6 +109,8 @@ const OrganizationIntegrationForm = ({ }, ]; + const isClaimingType = isClaimingIntegration(getState()?.values); + return ( - - - + + - + {!isClaimingType && } @@ -163,6 +167,9 @@ OrganizationIntegrationForm.propTypes = { acqMethods: PropTypes.arrayOf(PropTypes.object), accounts: PropTypes.arrayOf(PropTypes.string), defaultIntegration: PropTypes.object, + form: PropTypes.shape({ + getState: PropTypes.func.isRequired, + }).isRequired, handleSubmit: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired, paneTitle: PropTypes.node.isRequired, diff --git a/src/OrganizationIntegration/OrganizationIntegrationView/EdiView/EdiView.js b/src/OrganizationIntegration/OrganizationIntegrationView/EdiView/EdiView.js index 665e657f..d1d07798 100644 --- a/src/OrganizationIntegration/OrganizationIntegrationView/EdiView/EdiView.js +++ b/src/OrganizationIntegration/OrganizationIntegrationView/EdiView/EdiView.js @@ -1,5 +1,5 @@ -import React, { useMemo } from 'react'; import PropTypes from 'prop-types'; +import { useMemo } from 'react'; import { FormattedMessage } from 'react-intl'; import { @@ -23,29 +23,12 @@ const EdiView = ({ .join(', '); }, [vendorEdiOrdersExportConfig.ediConfig?.defaultAcquisitionMethods, acqMethods]); - const isDefaultConfig = vendorEdiOrdersExportConfig?.isDefaultConfig; - return ( } > - { - !isDefaultConfig && ( - - } - value={vendorEdiOrdersExportConfig.ediConfig?.accountNoList?.join(', ')} - /> - - ) - } - { + const isDefaultConfig = integrationConfig?.isDefaultConfig; + + const integrationType = useMemo(() => { + const translationKey = Object.entries(INTEGRATION_TYPE).find(([, value]) => { + return value === integrationConfig?.integrationType; + })?.[0]; + + return translationKey + ? + : integrationConfig?.integrationType; + }, [integrationConfig?.integrationType]); + + const transmissionMethod = useMemo(() => { + const translationKey = Object.entries(TRANSMISSION_METHOD).find(([, value]) => { + return value === integrationConfig?.transmissionMethod; + })?.[0]; + + return translationKey + ? + : integrationConfig?.transmissionMethod; + }, [integrationConfig?.transmissionMethod]); + return ( { /> + + + } + value={integrationType} + /> + + + + } + value={transmissionMethod} + /> + + + + } + value={integrationConfig.fileFormat} + /> + + + { + !isDefaultConfig && ( + + } + value={integrationConfig.ediConfig?.accountNoList?.join(', ')} + /> + + ) + } + ); }; diff --git a/src/OrganizationIntegration/OrganizationIntegrationView/OrganizationIntegrationView.js b/src/OrganizationIntegration/OrganizationIntegrationView/OrganizationIntegrationView.js index f58b0b1d..f134e1e4 100644 --- a/src/OrganizationIntegration/OrganizationIntegrationView/OrganizationIntegrationView.js +++ b/src/OrganizationIntegration/OrganizationIntegrationView/OrganizationIntegrationView.js @@ -34,6 +34,7 @@ import { useIntegrationConfig, useIntegrationConfigMutation, } from '../../common/hooks'; +import { isClaimingIntegration } from '../utils'; import { IntegrationInfoView } from './IntegrationInfoView'; import { EdiView } from './EdiView'; import { FtpView } from './FtpView'; @@ -51,6 +52,8 @@ const OrganizationIntegrationView = ({ orgId }) => { const { integrationConfig, isLoading } = useIntegrationConfig(id); const { acqMethods, isLoading: isAcqMethodsLoading } = useAcqMethods(); + const isClaimingType = isClaimingIntegration(integrationConfig); + const onEdit = useCallback( () => { history.push({ @@ -208,11 +211,13 @@ const OrganizationIntegrationView = ({ orgId }) => { ?.ediFtp} /> - + {!isClaimingType && ( + + )} diff --git a/src/OrganizationIntegration/constants.js b/src/OrganizationIntegration/constants.js index f4b9fa8d..5d96627f 100644 --- a/src/OrganizationIntegration/constants.js +++ b/src/OrganizationIntegration/constants.js @@ -37,3 +37,18 @@ export const EDI_NAMING_TOKENS = { jobID: 'jobID', numberSequence: 'numberSequence', }; + +export const INTEGRATION_TYPE = { + claiming: 'Claiming', + ordering: 'Ordering', +}; + +export const TRANSMISSION_METHOD = { + fileDownLoad: 'File download', + ftp: 'FTP', +}; + +export const FILE_FORMAT = { + csv: 'CSV', + edi: 'EDI', +}; diff --git a/src/OrganizationIntegration/utils.js b/src/OrganizationIntegration/utils.js index bb5cde75..5f002641 100644 --- a/src/OrganizationIntegration/utils.js +++ b/src/OrganizationIntegration/utils.js @@ -1,7 +1,12 @@ import { flow, join, map, pick, values } from 'lodash/fp'; import moment from 'moment-timezone'; -import { EDI_NAMING_TOKENS } from './constants'; +import { + EDI_NAMING_TOKENS, + FILE_FORMAT, + INTEGRATION_TYPE, + TRANSMISSION_METHOD, +} from './constants'; export const buildAvailableAccounts = (organization, integrations, currentIntegration) => { const accounts = organization.accounts.map(({ accountNo }) => accountNo); @@ -65,3 +70,67 @@ export const getDefaultEdiNamingConvention = () => ( join('-'), )(EDI_NAMING_TOKENS) ); + +export const getIntegrationTypeOptions = (intl) => { + return Object.entries(INTEGRATION_TYPE).map(([key, value]) => ({ + label: intl.formatMessage({ id: `ui-organizations.integration.info.integrationType.${key}` }), + value, + })); +}; + +export const getTransmissionMethodOptions = (intl) => { + return Object.entries(TRANSMISSION_METHOD).map(([key, value]) => ({ + label: intl.formatMessage({ id: `ui-organizations.integration.info.transmissionMethod.${key}` }), + value, + })); +}; + +export const getFileFormatOptions = () => { + return Object.values(FILE_FORMAT).map((value) => ({ + label: value, + value, + })); +}; + +export const isFileFormat = (config, type) => { + const integrationType = config + ?.exportTypeSpecificParameters + ?.vendorEdiOrdersExportConfig + ?.fileFormat; + + return integrationType === type; +}; + +export const isFileFormatEDI = (config) => { + return isFileFormat(config, FILE_FORMAT.edi); +}; + +export const isTransmissionMethod = (config, type) => { + const transmissionMethod = config + ?.exportTypeSpecificParameters + ?.vendorEdiOrdersExportConfig + ?.transmissionMethod; + + return transmissionMethod === type; +}; + +export const isTransmissionMethodFTP = (config) => { + return isTransmissionMethod(config, TRANSMISSION_METHOD.ftp); +}; + +export const isIntegrationType = (config, type) => { + const integrationType = config + ?.exportTypeSpecificParameters + ?.vendorEdiOrdersExportConfig + ?.integrationType; + + return integrationType === type; +}; + +export const isClaimingIntegration = (config) => { + return isIntegrationType(config, INTEGRATION_TYPE.claiming); +}; + +export const isOrderingIntegration = (config) => { + return isIntegrationType(config, INTEGRATION_TYPE.ordering); +}; diff --git a/translations/ui-organizations/en.json b/translations/ui-organizations/en.json index 083d0197..4260e74a 100644 --- a/translations/ui-organizations/en.json +++ b/translations/ui-organizations/en.json @@ -371,6 +371,13 @@ "integration.info.configName": "Integration name", "integration.info.configDescription": "Description", "integration.info.isDefaultConfig": "Default integration", + "integration.info.integrationType": "Integration type", + "integration.info.integrationType.claiming": "Claiming", + "integration.info.integrationType.ordering": "Ordering", + "integration.info.transmissionMethod": "Transmission method", + "integration.info.transmissionMethod.fileDownLoad": "File download", + "integration.info.transmissionMethod.ftp": "FTP", + "integration.info.fileFormat": "File format", "integration.edi": "EDI configuration", "integration.edi.accountNumbers": "Account numbers", "integration.edi.defaultAcquisitionMethods": "Automate order export for acquisition methods", From 4ee10e3b08f8bf3bb5820fdd3dcedafd573b7028 Mon Sep 17 00:00:00 2001 From: Yury Saukou Date: Thu, 5 Dec 2024 20:18:59 +0400 Subject: [PATCH 2/5] update snapshots --- .../OrganizationIntegrationForm.test.js.snap | 382 ++++++++++++------ .../OrganizationIntegrationView.test.js.snap | 111 ++++- 2 files changed, 341 insertions(+), 152 deletions(-) diff --git a/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap b/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap index 5fe6df20..75ffc77c 100644 --- a/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap +++ b/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap @@ -287,6 +287,206 @@ exports[`OrganizationIntegrationForm should render correct form structure 1`] = +
+
+
+ +
+ + + Icon + +
+
+
+
+
+
+ +
+ + + Icon + +
+
+
+
+
+
+ +
+ + + Icon + +
+
+
+
+
+
+ +
+ +
+
+
+
+
@@ -352,56 +552,6 @@ exports[`OrganizationIntegrationForm should render correct form structure 1`] =
-
-
- -
- -
-
-
-
@@ -421,9 +571,9 @@ exports[`OrganizationIntegrationForm should render correct form structure 1`] = > @@ -495,9 +638,9 @@ exports[`OrganizationIntegrationForm should render correct form structure 1`] = > @@ -592,9 +728,9 @@ exports[`OrganizationIntegrationForm should render correct form structure 1`] = >