Skip to content

Commit

Permalink
Merge pull request #133 from bahmni-msf/AP-74
Browse files Browse the repository at this point in the history
Vineela, Bindu, Kirity| AP-74 | Duplicate appointments created when trying to create a single appointment
  • Loading branch information
buvaneswari-arun committed Nov 9, 2020
2 parents 652d55a + 1a4a9ef commit 27def50
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 12 deletions.
14 changes: 13 additions & 1 deletion ui/react-components/components/AddAppointment/AddAppointment.jsx
Expand Up @@ -110,6 +110,7 @@ const AddAppointment = props => {
const [errors, setErrors] = useState(initialErrorsState);
const [showSuccessPopup, setShowSuccessPopup] = useState(false);
const [serviceErrorMessage, setServiceErrorMessage] = useState('');
const [disableSaveButton, setDisableSaveButton] = useState(false);

useEffect(() => {
if (appointmentDetails.occurrences === undefined)
Expand Down Expand Up @@ -246,6 +247,7 @@ const AddAppointment = props => {


const save = async appointmentRequest => {
setDisableSaveButton(true);
if (appConfig.enableAppointmentRequests) {
await checkAndUpdateAppointmentStatus(appointmentRequest, false);
}
Expand All @@ -259,10 +261,12 @@ const AddAppointment = props => {
setServiceErrorMessageFromResponse(response.data);
resetServiceErrorMessage();
}
setDisableSaveButton(false);
};

const checkAndSave = async () => {
if (isValidAppointment()) {
setDisableSaveButton(true);
const appointment = getAppointmentRequest();
const response = await getAppointmentConflicts(appointment);
const status = response.status;
Expand All @@ -275,6 +279,7 @@ const AddAppointment = props => {
setServiceErrorMessageFromResponse(response.data);
resetServiceErrorMessage();
}
setDisableSaveButton(false);
}
};

Expand All @@ -284,6 +289,7 @@ const AddAppointment = props => {
};

const saveRecurringAppointments = async recurringAppointmentRequest => {
setDisableSaveButton(true);
if (appConfig.enableAppointmentRequests) {
await checkAndUpdateAppointmentStatus(recurringAppointmentRequest, true);
}
Expand All @@ -302,12 +308,14 @@ const AddAppointment = props => {
setServiceErrorMessageFromResponse(response.data);
resetServiceErrorMessage();
}
setDisableSaveButton(false);
};



const checkAndSaveRecurringAppointments = async () => {
if (isValidRecurringAppointment()) {
setDisableSaveButton(true);
const recurringRequest = getRecurringAppointmentRequest();
const response = await getRecurringAppointmentsConflicts(recurringRequest);
const status = response.status;
Expand All @@ -320,6 +328,7 @@ const AddAppointment = props => {
setServiceErrorMessageFromResponse(response.data);
resetServiceErrorMessage();
}
setDisableSaveButton(false);
}
};

Expand Down Expand Up @@ -549,7 +558,9 @@ const AddAppointment = props => {
<AppointmentEditorFooter
errorMessage={serviceErrorMessage}
checkAndSave={isRecurringAppointment() ? checkAndSaveRecurringAppointments : checkAndSave}
cancelConfirmationMessage={CANCEL_CONFIRMATION_MESSAGE_ADD}/>
cancelConfirmationMessage={CANCEL_CONFIRMATION_MESSAGE_ADD}
disableSaveAndUpdateButton={disableSaveButton}
/>
{conflicts &&
<CustomPopup style={conflictsPopup} open={true}
closeOnDocumentClick={false}
Expand All @@ -558,6 +569,7 @@ const AddAppointment = props => {
popupContent={<Conflicts saveAnyway={saveAppointments}
modifyInformation={() => setConflicts(undefined)}
conflicts={conflicts} service={appointmentDetails.service}
disableSaveAnywayButton={disableSaveButton}
isRecurring={appointmentDetails.isRecurring}/>}/>}
{showSuccessPopup ? React.cloneElement(savePopup, {
open: true,
Expand Down
Expand Up @@ -20,7 +20,7 @@ import ErrorMessage from "../ErrorMessage/ErrorMessage.jsx";

const AppointmentEditorFooter = props => {

const {checkAndSave, isEdit, isOptionsRequired, disableUpdateButton, cancelConfirmationMessage, errorMessage} = props;
const {checkAndSave, isEdit, isOptionsRequired, disableSaveAndUpdateButton, cancelConfirmationMessage, errorMessage} = props;
const[showUpdateButtons, setShowUpdateButtons] = useState(false);

const getUpdateButtons =() =>{
Expand All @@ -45,14 +45,14 @@ const AppointmentEditorFooter = props => {
{isEdit
? <button className={classNames(button, save)}
onClick={() => isOptionsRequired ? getUpdateButtons() : checkAndSave(undefined)}
disabled={disableUpdateButton}
disabled={disableSaveAndUpdateButton}
data-testid="check-and-save">
<i className={classNames("fa", "fa-check")}/>
<span>
<FormattedMessage id={'APPOINTMENT_UPDATE_LABEL'} defaultMessage={'Update'}/>
</span>
</button>
: <button className={classNames(button, save)} onClick={checkAndSave} data-testid="check-and-save">
: <button className={classNames(button, save)} onClick={checkAndSave} data-testid="check-and-save" disabled={disableSaveAndUpdateButton}>
<i className={classNames("fa", "fa-check")}/>
<span>
<FormattedMessage id={'APPOINTMENT_CREATE_CHECK_AND_SAVE'} defaultMessage={'Check and Save'}/>
Expand All @@ -70,7 +70,7 @@ AppointmentEditorFooter.propTypes = {
checkAndSave: PropTypes.func,
isEdit: PropTypes.bool,
isOptionsRequired: PropTypes.bool,
disableUpdateButton: PropTypes.bool,
disableSaveAndUpdateButton: PropTypes.bool,
cancelConfirmationMessage: PropTypes.shape({
translationKey: PropTypes.string.isRequired,
defaultMessage: PropTypes.string.isRequired
Expand Down
Expand Up @@ -55,15 +55,23 @@ describe('Appointment editor Footer Search', () => {
});

it('should disable update button', () => {
const {container, getByText, getByTestId} = renderWithReactIntl(<AppointmentEditorFooter {...cancelConfirmationMessage} isEdit={true} disableUpdateButton={true} />);
const {container, getByText, getByTestId} = renderWithReactIntl(<AppointmentEditorFooter {...cancelConfirmationMessage} isEdit={true} disableSaveAndUpdateButton={true} />);
const update = getByTestId('check-and-save');
expect(update.disabled).toBe(true);
});

it('should not disable update button', () => {
const {container, getByText, getByTestId} = renderWithReactIntl(<AppointmentEditorFooter {...cancelConfirmationMessage} isEdit={true} disableUpdateButton={false} />);
const {container, getByText, getByTestId} = renderWithReactIntl(<AppointmentEditorFooter {...cancelConfirmationMessage} isEdit={true} disableSaveAndUpdateButton={false} />);
const update = getByTestId('check-and-save');
expect(update.disabled).toBe(false);
});

it('should disable check and save button on click of the button', () => {
const {getByTestId} = renderWithReactIntl(<AppointmentEditorFooter {...cancelConfirmationMessage} checkAndSave={() => jest.fn()} disableSaveAndUpdateButton={true} />);
const checkAndSave = getByTestId('check-and-save');
fireEvent.click(checkAndSave);
expect(checkAndSave.disabled).toBe(true);
});


});
5 changes: 3 additions & 2 deletions ui/react-components/components/Conflicts/Conflicts.jsx
Expand Up @@ -18,7 +18,7 @@ const Conflicts = props => {
<ConflictsBody conflicts={props.conflicts} service={props.service} isRecurring={props.isRecurring}/>
</div>
<div data-testid="conflicts-footer">
<ConflictsFooter saveAnyway={props.saveAnyway} modifyInformation={props.modifyInformation}/>
<ConflictsFooter saveAnyway={props.saveAnyway} modifyInformation={props.modifyInformation} disableSaveAnywayButton={props.disableSaveAnywayButton}/>
</div>
</div>
)
Expand All @@ -27,6 +27,7 @@ Conflicts.proptypes = {
saveAnyway: PropTypes.func.isRequired,
modifyInformation: PropTypes.func.isRequired,
conflicts: PropTypes.object.isRequired,
service: PropTypes.object.isRequired
service: PropTypes.object.isRequired,
disableSaveAnywayButton: PropTypes.bool
};
export default injectIntl(useFocusLock(Conflicts));
Expand Up @@ -10,7 +10,7 @@ const ConflictsFooter = props => {
<div className={classNames(footer, conflictsFooter)}>
<div className={classNames(footerElements)}>
<button className={classNames(button)} data-testid="conflictsSaveAnyway" onClick={props.saveAnyway}
tabIndex={3}>
tabIndex={3} disabled={props.disableSaveAnywayButton}>
<i className={classNames("fa", "fa-check")}/>
<span>
<FormattedMessage id={'APPOINTMENT_SAVE_ANYWAY'} defaultMessage={'Save Anyway'}/>
Expand All @@ -30,7 +30,8 @@ const ConflictsFooter = props => {
};
ConflictsFooter.propTypes = {
saveAnyway: PropTypes.func,
modifyInformation: PropTypes.func
modifyInformation: PropTypes.func,
disableSaveAnywayButton: PropTypes.bool
};

export default injectIntl(ConflictsFooter);
Expand Up @@ -36,4 +36,12 @@ describe('ConflictsFooter', () => {

expect(modifyInformationSpy).toHaveBeenCalled();
});

it('should disable Save Anyway button on click of the button', () => {
const saveAnywaySpy = jest.fn();
const {getByText, getByTestId} = renderWithReactIntl(<ConflictsFooter saveAnyway={saveAnywaySpy} disableSaveAnywayButton={true} />);
const saveAnywayButton = getByTestId('conflictsSaveAnyway');
fireEvent.click(saveAnywayButton);
expect(saveAnywayButton.disabled).toBe(true);
});
});
Expand Up @@ -126,6 +126,7 @@ const EditAppointment = props => {
const [serviceErrorMessage, setServiceErrorMessage] = useState('');
const [existingProvidersUuids, setExistingProvidersUuids] = useState([]);
const [appointmentTimeBeforeEdit, setAppointmentTimeBeforeEdit] = useState({});
const [disableUpdateButton, setDisableUpdateButton] = useState(false);

const isRecurringAppointment = () => appointmentDetails.appointmentType === RECURRING_APPOINTMENT_TYPE;
const isWalkInAppointment = () => appointmentDetails.appointmentType === WALK_IN_APPOINTMENT_TYPE;
Expand Down Expand Up @@ -225,6 +226,7 @@ const EditAppointment = props => {

const checkAndSave = async () => {
if (isValidAppointment()) {
setDisableUpdateButton(true);
const appointment = getAppointmentRequest();
const response = await getAppointmentConflicts(appointment);
const status = response.status;
Expand All @@ -237,6 +239,7 @@ const EditAppointment = props => {
setServiceErrorMessageFromResponse(response.data);
resetServiceErrorMessage();
}
setDisableUpdateButton(false);
}
};

Expand Down Expand Up @@ -266,6 +269,7 @@ const EditAppointment = props => {
};

const save = async appointmentRequest => {
setDisableUpdateButton(true);
if (appConfig.enableAppointmentRequests) {
await checkAndUpdateAppointmentStatus(appointmentRequest, false);
}
Expand All @@ -280,9 +284,11 @@ const EditAppointment = props => {
setServiceErrorMessageFromResponse(response.data);
resetServiceErrorMessage();
}
setDisableUpdateButton(false);
};

const updateAllAppointments = async recurringAppointmentRequest => {
setDisableUpdateButton(true);
if (appConfig.enableAppointmentRequests) {
await checkAndUpdateAppointmentStatus(recurringAppointmentRequest, true);
}
Expand All @@ -297,10 +303,12 @@ const EditAppointment = props => {
setServiceErrorMessageFromResponse(response.data);
resetServiceErrorMessage();
}
setDisableUpdateButton(false);
};

const checkAndUpdateRecurringAppointments = async (applyForAllInd) => {
if (isValidRecurringAppointment()) {
setDisableUpdateButton(true);
const recurringRequest = getRecurringAppointmentRequest(applyForAllInd);
const response = applyForAllInd ? await getRecurringAppointmentsConflicts(recurringRequest) :
await getAppointmentConflicts(recurringRequest.appointmentRequest);
Expand All @@ -314,6 +322,7 @@ const EditAppointment = props => {
setServiceErrorMessageFromResponse(response.data);
resetServiceErrorMessage();
}
setDisableUpdateButton(false);
}
};

Expand Down Expand Up @@ -593,7 +602,7 @@ const EditAppointment = props => {
checkAndSave={applyForAllInd => updateAppointments(applyForAllInd)}
isEdit={true}
isOptionsRequired={isRecurringAppointment() && isApplicableForAll()}
disableUpdateButton={isStartDateModified() && (isEndDateModified() || isOccurrencesModified())}
disableSaveAndUpdateButton={disableUpdateButton || (isStartDateModified() && (isEndDateModified() || isOccurrencesModified()))}
cancelConfirmationMessage={CANCEL_CONFIRMATION_MESSAGE_EDIT}
/>
{conflicts &&
Expand All @@ -603,6 +612,7 @@ const EditAppointment = props => {
onClose={() => setConflicts(undefined)}
popupContent={<Conflicts saveAnyway={saveAppointments}
modifyInformation={() => setConflicts(undefined)}
disableSaveAnywayButton={disableUpdateButton}
conflicts={conflicts} service={appointmentDetails.service}/>}/>}
{showUpdateSuccessPopup ? React.cloneElement(updateSuccessPopup, {
open: true,
Expand Down

0 comments on commit 27def50

Please sign in to comment.