Skip to content

Commit

Permalink
OM-109: voucher searcher and form
Browse files Browse the repository at this point in the history
  • Loading branch information
olewandowski1 committed Dec 28, 2023
1 parent 5b6637c commit 7d7fe39
Show file tree
Hide file tree
Showing 7 changed files with 236 additions and 96 deletions.
32 changes: 32 additions & 0 deletions src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ const WORKER_VOUCHER_PROJECTION = (modulesManager) => [
`policyholder ${modulesManager.getProjection('policyHolder.PolicyHolderPicker.projection')}`,
];

const VOUCHER_PRICE_PROJECTION = () => [
'id',
'uuid',
'key',
'value',
'dateValidFrom',
'dateValidTo',
'isDeleted',
];

function formatGraphQLDateRanges(dateRanges) {
const rangeStrings = dateRanges.map((range) => `{ startDate: "${range.startDate}", endDate: "${range.endDate}" }`);
return `[${rangeStrings.join(', ')}]`;
Expand Down Expand Up @@ -213,3 +223,25 @@ export function fetchMutation(clientMutationId) {
{ clientMutationId },
);
}

export function fetchVoucherPrices(params) {
const payload = formatPageQueryWithCount('businessConfig', params, VOUCHER_PRICE_PROJECTION());
return graphql(payload, ACTION_TYPE.SEARCH_VOUCHER_PRICES);
}

export function deleteVoucherPrice(voucherPriceUuid, clientMutationLabel) {
const voucherPricesUuids = `ids: ["${voucherPriceUuid}"]`;
const mutation = formatMutation('deleteBusinessConfig', voucherPricesUuids, clientMutationLabel);
const requestedDateTime = new Date();

return graphql(
mutation.payload,
[REQUEST(ACTION_TYPE.MUTATION), SUCCESS(ACTION_TYPE.DELETE_VOUCHER_PRICE), ERROR(ACTION_TYPE.MUTATION)],
{
actionType: ACTION_TYPE.DELETE_VOUCHER_PRICE,
clientMutationId: mutation.clientMutationId,
clientMutationLabel,
requestedDateTime,
},
);
}
81 changes: 54 additions & 27 deletions src/components/VoucherPriceFilter.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,73 @@
import React from 'react';
import _debounce from 'lodash/debounce';

import { Grid, Typography, Divider } from '@material-ui/core';
import { Grid } from '@material-ui/core';
import { makeStyles } from '@material-ui/styles';

import { PublishedComponent } from '@openimis/fe-core';
import { PublishedComponent, TextInput } from '@openimis/fe-core';
import {
DATE_TIME_SUFFIX, DEFAULT_DEBOUNCE_TIME, EMPTY_STRING, STARTS_WITH_LOOKUP,
} from '../constants';

export const useStyles = makeStyles((theme) => ({
item: theme.paper.item,
}));

function VoucherPriceFilter({ filters, onChangeFilters, formatMessage }) {
function VoucherPriceFilter({ filters, onChangeFilters }) {
const classes = useStyles();

const debouncedOnChangeFilters = _debounce(onChangeFilters, DEFAULT_DEBOUNCE_TIME);

const filterValue = (filterName) => filters?.[filterName]?.value;
const filterTextFieldValue = (filterName) => filters?.[filterName]?.value ?? EMPTY_STRING;

return (
<>
<Grid xs={12}>
<Typography variant="subtitle1" style={{ padding: '4px' }}>
{formatMessage('workerVoucher.priceManagement.tip')}
</Typography>
<Divider />
<Grid container className={classes.form}>
<Grid item xs={3} className={classes.item}>
<TextInput
module="workerVoucher"
label="searcher.price"
value={filterTextFieldValue('value')}
onChange={(price) => debouncedOnChangeFilters([
{
id: 'value',
value: price,
filter: `value_${STARTS_WITH_LOOKUP}: "${price}"`,
},
])}
/>
</Grid>
<Grid item xs={3} className={classes.item}>
<PublishedComponent
pubRef="core.DatePicker"
module="workerVoucher"
label="validFrom"
value={filterValue('dateValidFrom_Gte')}
onChange={(validFrom) => onChangeFilters([
{
id: 'dateValidFrom_Gte',
value: validFrom,
filter: `dateValidFrom_Gte: "${validFrom}${DATE_TIME_SUFFIX}"`,
},
])}
/>
</Grid>
<Grid container className={classes.form}>
<Grid item xs={3} className={classes.item}>
<PublishedComponent
pubRef="core.DatePicker"
module="workerVoucher"
label="filter.date"
value={filterValue('date')}
// TODO: Adjust filters
onChange={(date) => onChangeFilters([
{
id: 'date',
value: date,
filter: `date: "${date}"`,
},
])}
/>
</Grid>
<Grid item xs={3} className={classes.item}>
<PublishedComponent
pubRef="core.DatePicker"
module="workerVoucher"
label="validTo"
value={filterValue('dateValidTo_Lte')}
onChange={(validTo) => onChangeFilters([
{
id: 'dateValidTo_Lte',
value: validTo,
filter: `dateValidTo_Lte: "${validTo}${DATE_TIME_SUFFIX}"`,
},
])}
/>
</Grid>
</>
</Grid>

);
}
Expand Down
76 changes: 42 additions & 34 deletions src/components/VoucherPriceManagementForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
} from '@openimis/fe-core';
import PriceManagementForm from './PriceManagementForm';
import VoucherPriceSearcher from './VoucherPriceSearcher';
import { fetchMutation, manageVoucherPrice } from '../actions';
import { MODULE_NAME, VOUCHER_PRICE_MANAGEMENT_BUSINESS_KEY } from '../constants';
import { fetchMutation, fetchVoucherPrices, manageVoucherPrice } from '../actions';
import { DEFAULT_VOUCHER_PRICE_FILTERS, MODULE_NAME, VOUCHER_PRICE_MANAGEMENT_BUSINESS_KEY } from '../constants';

export const useStyles = makeStyles((theme) => ({
paper: { ...theme.paper.paper, margin: '10px 0 0 0' },
Expand All @@ -33,25 +33,29 @@ function VoucherPriceManagementForm() {
const classes = useStyles();
const { formatMessage, formatMessageWithValues } = useTranslations(MODULE_NAME, modulesManager);
const [priceManagement, setPriceManagement] = useState({});
const [priceManagementLoading, setPriceManagementLoading] = useState(false);
const { mutation, submittingMutation } = useSelector((state) => state.workerVoucher);
const {
voucherPrices,
voucherPricesTotalCount,
voucherPricesPageInfo,
fetchedVoucherPrices,
errorVoucherPrices,
} = useSelector((state) => state.workerVoucher);

const priceManagementBlocked = (priceManagement) => !priceManagement?.price
|| !priceManagement?.validFrom
|| !priceManagement?.validTo
|| priceManagementLoading;
|| !priceManagement?.validTo;

const fetchVoucherPrices = async (params) => {
const fetchPrices = async (params) => {
try {
// TODO: Fetch vouchers
console.log(params);
const queryParams = [...params, `key: "${VOUCHER_PRICE_MANAGEMENT_BUSINESS_KEY}"`];
dispatch(fetchVoucherPrices(queryParams));
} catch (error) {
throw new Error(`[VOUCHER_PRICE_SEARCHER]: Fetching voucher prices failed. ${error}`);
}
};

const onPriceManagementChange = async () => {
setPriceManagementLoading(true);
try {
const { payload } = await dispatch(
manageVoucherPrice(
Expand All @@ -70,26 +74,30 @@ function VoucherPriceManagementForm() {
if (currentMutation.error) {
const errorDetails = JSON.parse(currentMutation.error);

dispatch(coreAlert(
formatMessage('workerVoucher.menu.priceManagement'),
formatMessage(errorDetails?.detail || 'NOT_FOUND'),
));
dispatch(
coreAlert(
formatMessage('menu.priceManagement'),
formatMessage(errorDetails?.detail || 'NOT_FOUND'),
),
);
return;
}

dispatch(coreAlert(
formatMessage('workerVoucher.menu.priceManagement'),
formatMessageWithValues('workerVoucher.priceManagement.success', {
price: priceManagement.price,
dateFrom: priceManagement.validFrom,
dateTo: priceManagement.validTo,
}),
));
dispatch(
coreAlert(
formatMessage('menu.priceManagement'),
formatMessageWithValues('priceManagement.success', {
price: priceManagement.price,
dateFrom: priceManagement.validFrom,
dateTo: priceManagement.validTo,
}),
),
);

setPriceManagement({});
await fetchPrices(DEFAULT_VOUCHER_PRICE_FILTERS);
} catch (error) {
throw new Error(`[VOUCHER_PRICE_MANAGEMENT]: Price change failed. ${error}`);
} finally {
setPriceManagementLoading(false);
}
};

Expand All @@ -110,12 +118,12 @@ function VoucherPriceManagementForm() {
<Paper className={classes.paper}>
<Grid xs={12}>
<Grid container className={classes.paperHeaderTitle}>
<Typography variant="h5">{formatMessage('workerVoucher.menu.priceManagement')}</Typography>
<Typography variant="h5">{formatMessage('menu.priceManagement')}</Typography>
<Tooltip
title={
priceManagementBlocked(priceManagement)
? formatMessage('workerVoucher.vouchers.required')
: formatMessage('workerVoucher.priceManagement')
? formatMessage('vouchers.required')
: formatMessage('priceManagement')
}
>
<span>
Expand All @@ -125,7 +133,7 @@ function VoucherPriceManagementForm() {
onClick={onPriceManagementChange}
disabled={priceManagementBlocked(priceManagement)}
>
<Typography variant="subtitle1">{formatMessage('workerVoucher.priceManagement')}</Typography>
<Typography variant="subtitle1">{formatMessage('priceManagement')}</Typography>
</Button>
</span>
</Tooltip>
Expand All @@ -134,7 +142,7 @@ function VoucherPriceManagementForm() {
<Divider />
<Grid>
<Typography variant="subtitle1" style={{ padding: '4px' }}>
{formatMessage('workerVoucher.priceManagement.subtitle')}
{formatMessage('priceManagement.subtitle')}
</Typography>
</Grid>
<Divider />
Expand All @@ -148,12 +156,12 @@ function VoucherPriceManagementForm() {
</Grid>
</Grid>
<VoucherPriceSearcher
fetch={fetchVoucherPrices}
items={[{}]}
fetchedItems={false}
voucherPricesTotalCount={0}
itemsPageInfo={{}}
errorItems={null}
fetch={fetchPrices}
items={voucherPrices}
fetchedItems={fetchedVoucherPrices}
voucherPricesTotalCount={voucherPricesTotalCount}
itemsPageInfo={voucherPricesPageInfo}
errorItems={errorVoucherPrices}
/>
</>
);
Expand Down
Loading

0 comments on commit 7d7fe39

Please sign in to comment.