diff --git a/client/src/scenes/MemberPracticeSummaryReport/index.js b/client/src/scenes/MemberPracticeSummaryReport/index.js index 003aafb..fcec497 100644 --- a/client/src/scenes/MemberPracticeSummaryReport/index.js +++ b/client/src/scenes/MemberPracticeSummaryReport/index.js @@ -1,22 +1,92 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; -import { Container, Button, Loader } from 'semantic-ui-react'; +import { Container, Button, Loader, Input, Message, Grid } from 'semantic-ui-react'; import MainMenu from '../../components/MainMenu'; import { fetchMemberPracticeSummaryReport } from '../../store/actions'; class MemberPracticeSummaryReport extends Component { + + constructor(props) { + super(props); + + this.state = { + year: new Date().getFullYear(), + stateError: null, + } + } + + onGenerateReportClick = () => { + const {fetchMemberPracticeSummaryReport} = this.props; + const { year } = this.state; + + const currentYear = new Date().getFullYear(); + const parsedYear = parseInt(year); + + if (!parsedYear || isNaN(parsedYear)){ + this.setState({stateError: 'Year is not a number'}); + return; + } + + if (parsedYear > currentYear){ + this.setState({stateError: 'Selected year cannot be greater than current year'}); + return; + } + + fetchMemberPracticeSummaryReport(year); + }; + + onYearInputChange = (event, data) => { + let newYear = parseInt(data.value) + if (!newYear || isNaN(newYear)){ + newYear = new Date().getFullYear(); + } + this.setState({year: newYear, stateError: null}) + }; + render () { - const { fetchMemberPracticeSummaryReport, pendingReport } = this.props; + const { pendingReport, fetchReportError } = this.props; + const { year, stateError } = this.state; + + let error; + error = stateError ? stateError : null; + error = fetchReportError ? fetchReportError : error; + return (

Member Practice Summary Report



+ + + + + + + + + + {error && + + + + Error +
+

{error}

+
+
+
+ } +
-
); } @@ -24,10 +94,11 @@ class MemberPracticeSummaryReport extends Component { const mapStateToProps = (state) => ({ pendingReport: state.memberPracticeSummaryReport.pending, + fetchReportError: state.memberPracticeSummaryReport.error, }); const mapDispatchToProps = (dispatch) => ({ - fetchMemberPracticeSummaryReport: () => fetchMemberPracticeSummaryReport(dispatch), + fetchMemberPracticeSummaryReport: (year) => fetchMemberPracticeSummaryReport(dispatch, year), }); export default connect(mapStateToProps, mapDispatchToProps)(MemberPracticeSummaryReport); diff --git a/client/src/store/actions/integrationActions.js b/client/src/store/actions/integrationActions.js index a8bdb5d..d2b4d1f 100644 --- a/client/src/store/actions/integrationActions.js +++ b/client/src/store/actions/integrationActions.js @@ -113,15 +113,24 @@ export const checkProcessing = (dispatch) => { }); }; -export const fetchMemberPracticeSummaryReport = (dispatch) => { +export const fetchMemberPracticeSummaryReport = (dispatch, year) => { dispatch({type: FETCH_MEMBER_PRACTICE_SUMMARY_REPORT_PENDING}); - API.get('integration/report/practiceSummary', { + API.get(`integration/report/practiceSummary/${year}`, { responseType: 'blob', }) .then(response => { dispatch({type: FETCH_MEMBER_PRACTICE_SUMMARY_REPORT_SUCCESS, payload: response}); }) .catch(error => { - dispatch({type: FETCH_MEMBER_PRACTICE_SUMMARY_REPORT_FAILED, payload: error.response}); + let errorMessage = 'Error generating Member Practice Summary Report'; + switch (error.response.status) { + case 400: + errorMessage = 'Year cannot be greater than current year and it has to be a number'; + break; + case 500: + default: + break; + } + dispatch({type: FETCH_MEMBER_PRACTICE_SUMMARY_REPORT_FAILED, payload: errorMessage}); }); }; diff --git a/controllers/integration.js b/controllers/integration.js index 5a8b354..c703d47 100644 --- a/controllers/integration.js +++ b/controllers/integration.js @@ -1,5 +1,7 @@ 'use strict'; +const moment = require('moment-timezone'); + const { getMappingsFromDatabase, fetchOffices, fetchResources, saveNewMappingToDatabase } = require('../services/officeRnD/resources'); const { getAllIncidents, getMemberPracticeSummaryReport } = require('../services/integration/reports'); const { getMembersFeesForDateRange } = require('../services/integration/invoiceIntegration'); @@ -7,6 +9,8 @@ const { deleteFeesFromORD, addFeesToORD } = require('../services/officeRnD/fees' const { checkBookingChanges } = require('../services/integration/checkBookingChange'); const { checkIfProcessing } = require('../services/integration/processingStatus'); +const { UI_TIMEZONE } = require('../constants/constants'); + const getKnownOfficeResourceMappings = (req, res) => { const dataToFetch = [getMappingsFromDatabase(), fetchOffices(), fetchResources() ]; @@ -127,7 +131,22 @@ const checkProcessingStatus = (req, res) => { }; const getPracticeSummaryReport = (req, res) => { - getMemberPracticeSummaryReport() + const year = req.params.year; + + const currentYear = moment.tz(UI_TIMEZONE).year(); + const parsedYear = parseInt(year); + + if (!parsedYear || isNaN(parsedYear)){ + res.status(400).send('Year is not a number'); + return; + } + + if (parsedYear > currentYear){ + res.status(400).send('Selected year cannot be greater than current year'); + return; + } + + getMemberPracticeSummaryReport(parsedYear) .then((result) => { const pathToDownloadFile = `${__dirname}/../${result.reportPath}`; res.download(pathToDownloadFile); diff --git a/routes/index.js b/routes/index.js index 47f0b46..27add39 100644 --- a/routes/index.js +++ b/routes/index.js @@ -33,7 +33,7 @@ router.post('/integration/addFees', addFees); router.get('/integration/processing', checkProcessingStatus); -router.get('/integration/report/practiceSummary', getPracticeSummaryReport); +router.get('/integration/report/practiceSummary/:year', getPracticeSummaryReport); diff --git a/services/integration/reports.js b/services/integration/reports.js index 4a4f054..8633f4b 100644 --- a/services/integration/reports.js +++ b/services/integration/reports.js @@ -318,10 +318,8 @@ const getAllIncidents = (dateRange, memberIds) => { }); }; -const getMemberPracticeSummaryReport = (res) => { +const getMemberPracticeSummaryReport = (year) => { return new Promise((resolve, reject) => { - const year = moment.tz(UI_TIMEZONE).year(); - const asyncJobs = [checkBookingChanges(), getAllBookingsForYear(year), fetchAllMembers()]; Promise.all(asyncJobs)