diff --git a/client/src/components/MemberIncidentsTables/components/SingleIncidentsTable.js b/client/src/components/MemberIncidentsTables/components/SingleIncidentsTable.js
index 5c1d91e..98e778a 100644
--- a/client/src/components/MemberIncidentsTables/components/SingleIncidentsTable.js
+++ b/client/src/components/MemberIncidentsTables/components/SingleIncidentsTable.js
@@ -4,33 +4,48 @@ import ReactTable from 'react-table';
import 'react-table/react-table.css';
import { NavLink } from 'react-router-dom';
-import {incidentsReportHeaderTitles} from '../../../constants/menuItems';
+import {incidentsReportHeaderTitles} from '../../../constants/constants';
import {
+ incidentTableTypes,
incidentDescriptions,
incidentLevelDescriptions,
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, UNLOCKED_INCIDENT_STANDALONE, UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE
} from '../../../constants/enums';
+import { doorLockRelatedWithReservationIncidentHeaders, standaloneDoorLockIncidentHeaders, bookingChangeIncidentHeaders } from '../../../constants/constants';
const SingleIncidentsTable = props => {
- const { loading, title, openMemberSummaryOnMemberClick, showBookingTimes, showDoorLockEntryTimes, hideMemberName } = props;
+ const {
+ loading,
+ title,
+ openMemberSummaryOnMemberClick,
+ hideMemberName,
+ tableType
+ } = props;
const incidents = props.incidents ? props.incidents : [];
-
const columns = [];
- if (incidents && incidents.length > 0){
- const incidentHeaders = Object.keys(incidentsReportHeaderTitles);
- incidentHeaders.forEach((header) => {
+ if (incidents && incidents.length > 0){
+ let tableHeaders;
+ switch (tableType) {
+ case incidentTableTypes.INCIDENTS_RELATED_TO_RESERVATIONS:
+ tableHeaders = doorLockRelatedWithReservationIncidentHeaders;
+ break;
+ case incidentTableTypes.STANDALONE_INCIDENTS:
+ tableHeaders = standaloneDoorLockIncidentHeaders;
+ break;
+ case incidentTableTypes.BOOKING_CHANGE_INCIDENTS:
+ tableHeaders = bookingChangeIncidentHeaders;
+ break;
+ default:
+ break;
+ }
+
+ tableHeaders.forEach((header) => {
const columnTitle = incidentsReportHeaderTitles[header];
let showColumn = true;
- if ((header === 'bookingStart' || header === 'bookingEnd') && !showBookingTimes){
- showColumn = false;
- }
- if ((header === 'unlockTimestamp' || header === 'lockTimestamp') && !showDoorLockEntryTimes){
- showColumn = false;
- }
if (header === 'memberName' && hideMemberName){
showColumn = false;
}
@@ -55,6 +70,16 @@ const SingleIncidentsTable = props => {
urlValue = `/practice-summary-report/${memberId}`;
cellValue = props.value;
break;
+ case 'reservation':
+ const bookingStart = props.row['_original'].bookingStart;
+ const bookingEnd = props.row['_original'].bookingEnd;
+ cellValue = `${bookingStart}\n${bookingEnd}`;
+ break;
+ case 'doorLockTimestamps':
+ const unlockTimestamp = props.row['_original'].unlockTimestamp;
+ const lockTimestamp = props.row['_original'].lockTimestamp;
+ cellValue = `${unlockTimestamp ? unlockTimestamp : '---'}\n${lockTimestamp ? lockTimestamp : '---'}`;
+ break;
case 'incidentType':
cellValue = incidentDescriptions[props.value];
break;
@@ -85,6 +110,16 @@ const SingleIncidentsTable = props => {
cellValue = `$ ${totalFeeFormatted}`;
columnContentsAlignment = columnAlignments.right;
break;
+ case 'oldReservation':
+ const oldBookingStart = props.row['_original'].oldBookingStart;
+ const oldBookingEnd = props.row['_original'].oldBookingEnd;
+ cellValue = `${oldBookingStart}\n${oldBookingEnd}`;
+ break;
+ case 'newReservation':
+ const newBookingStart = props.row['_original'].newBookingStart;
+ const newBookingEnd = props.row['_original'].newBookingEnd;
+ cellValue = `${newBookingStart}\n${newBookingEnd}`;
+ break;
default:
cellValue = props.value;
}
@@ -92,7 +127,7 @@ const SingleIncidentsTable = props => {
if (openMemberSummaryOnMemberClick && urlValue){
return {cellValue}
}else{
- return
{cellValue}
+ return {cellValue}
}
}
});
diff --git a/client/src/components/MemberIncidentsTables/index.js b/client/src/components/MemberIncidentsTables/index.js
index ed05541..a4d7c67 100644
--- a/client/src/components/MemberIncidentsTables/index.js
+++ b/client/src/components/MemberIncidentsTables/index.js
@@ -3,7 +3,8 @@ import {Accordion, Label} from 'semantic-ui-react';
import SingleIncidentsTable from './components/SingleIncidentsTable';
import {
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, UNLOCKED_INCIDENT_STANDALONE, UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
- UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE
+ UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE, BOOKING_MOVED_TO_ANOTHER_DAY, BOOKING_SHORTENED,
+ incidentTableTypes
} from '../../constants/enums';
export default function MemberIncidentsTables (props) {
@@ -11,6 +12,7 @@ export default function MemberIncidentsTables (props) {
const incidentsRelatedToReservations = [];
const standaloneIncidents = [];
+ const bookingChangeIncidents = [];
if (Array.isArray(incidents)){
incidents.forEach((incident) => {
@@ -25,6 +27,12 @@ export default function MemberIncidentsTables (props) {
case UNSCHEDULED_INCIDENT_STANDALONE:
standaloneIncidents.push(incident);
break;
+ case BOOKING_MOVED_TO_ANOTHER_DAY:
+ case BOOKING_SHORTENED:
+ bookingChangeIncidents.push(incident);
+ break;
+ default:
+ break;
}
}
});
@@ -35,8 +43,8 @@ export default function MemberIncidentsTables (props) {
loading={pendingIncidents}
incidents={incidentsRelatedToReservations}
openMemberSummaryOnMemberClick
- showBookingTimes
hideMemberName={hideMemberName}
+ tableType={incidentTableTypes.INCIDENTS_RELATED_TO_RESERVATIONS}
/>
);
@@ -45,8 +53,17 @@ export default function MemberIncidentsTables (props) {
loading={pendingIncidents}
incidents={standaloneIncidents}
openMemberSummaryOnMemberClick
- showDoorLockEntryTimes
hideMemberName={hideMemberName}
+ tableType={incidentTableTypes.STANDALONE_INCIDENTS}
+ />
+ );
+
+ const bookingChangeIncidentsTable = (
+
);
@@ -63,7 +80,8 @@ export default function MemberIncidentsTables (props) {
},
{
key: 'reservation-modification-incidents',
- title: {content: },
+ title: {content: },
+ content: { content: bookingChangeIncidentsTable },
}
];
diff --git a/client/src/constants/constants.js b/client/src/constants/constants.js
index ed5633b..22e9725 100644
--- a/client/src/constants/constants.js
+++ b/client/src/constants/constants.js
@@ -1 +1,48 @@
export const defaultDateFormat = 'YYYY-MM-DD';
+
+export const doorLockRelatedWithReservationIncidentHeaders = [
+ 'officeName',
+ 'resourceName',
+ 'memberName',
+ 'reservation',
+ 'incidentType',
+ 'feeDescription',
+ 'totalChargeFee'
+];
+export const standaloneDoorLockIncidentHeaders = [
+ 'officeName',
+ 'resourceName',
+ 'memberName',
+ 'doorLockTimestamps',
+ 'incidentType',
+ 'feeDescription',
+ 'totalChargeFee'
+];
+export const bookingChangeIncidentHeaders = [
+ 'officeName',
+ 'resourceName',
+ 'memberName',
+ 'incidentTimestamp',
+ 'oldReservation',
+ 'newReservation',
+ 'incidentType',
+ 'totalChargeFee',
+];
+
+export const incidentsReportHeaderTitles = {
+ officeName: 'Office',
+ resourceName: 'Room',
+ bookingStart: 'Reservation Start',
+ bookingEnd: 'Reservation End',
+ reservation: 'Reservation start/end',
+ doorLockTimestamps: 'Door unlock/lock',
+ unlockTimestamp: 'Unlock Time',
+ lockTimestamp: 'Lock Time',
+ oldReservation: 'Old Reservation',
+ newReservation: 'New Reservation',
+ incidentTimestamp: 'Incident Time',
+ memberName: 'Member Name',
+ incidentType: 'Incident Type',
+ feeDescription: 'Fee description',
+ totalChargeFee: 'Total Fee',
+};
diff --git a/client/src/constants/enums.js b/client/src/constants/enums.js
index 2a3f642..6a5c48b 100644
--- a/client/src/constants/enums.js
+++ b/client/src/constants/enums.js
@@ -4,6 +4,8 @@ export const UNSCHEDULED_INCIDENT_BEFORE_RESERVATION = 3;
export const UNSCHEDULED_INCIDENT_AFTER_RESERVATION = 4;
export const UNLOCKED_INCIDENT_STANDALONE = 5;
export const UNSCHEDULED_INCIDENT_STANDALONE = 6;
+export const BOOKING_MOVED_TO_ANOTHER_DAY = 7;
+export const BOOKING_SHORTENED = 8;
export const incidentDescriptions = {};
incidentDescriptions[UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION] = 'User left door unlocked';
@@ -11,6 +13,8 @@ incidentDescriptions[UNSCHEDULED_INCIDENT_BEFORE_RESERVATION] = 'Unscheduled use
incidentDescriptions[UNSCHEDULED_INCIDENT_AFTER_RESERVATION] = 'Unscheduled use - after';
incidentDescriptions[UNLOCKED_INCIDENT_STANDALONE] = 'User left door unlocked';
incidentDescriptions[UNSCHEDULED_INCIDENT_STANDALONE] = 'Unscheduled use';
+incidentDescriptions[BOOKING_MOVED_TO_ANOTHER_DAY] = 'Reservation moved to another day';
+incidentDescriptions[BOOKING_SHORTENED] = 'Reservation shortened';
export const incidentLevelDescriptions = {
UNLOCKED_0: 'First month',
@@ -20,3 +24,9 @@ export const incidentLevelDescriptions = {
UNLOCKED_4: 'Fifth month',
UNLOCKED_5: 'Sixth month',
};
+
+export const incidentTableTypes = {
+ INCIDENTS_RELATED_TO_RESERVATIONS: 1,
+ STANDALONE_INCIDENTS: 2,
+ BOOKING_CHANGE_INCIDENTS: 3,
+};
diff --git a/client/src/constants/menuItems.js b/client/src/constants/menuItems.js
index 8a83cfc..63cac6d 100644
--- a/client/src/constants/menuItems.js
+++ b/client/src/constants/menuItems.js
@@ -39,16 +39,3 @@ export const mainMenuItems = [
component: UploadDLockData,
},
];
-
-export const incidentsReportHeaderTitles = {
- officeName: 'Office',
- resourceName: 'Room',
- bookingStart: 'Reservation Start',
- bookingEnd: 'Reservation End',
- unlockTimestamp: 'Unlock Time',
- lockTimestamp: 'Lock Time',
- memberName: 'Member Name',
- incidentType: 'Incident Type',
- feeDescription: 'Fee description',
- totalChargeFee: 'Total Fee',
-};
diff --git a/client/src/scenes/PracticeSummaryReport/components/MemberSummary.js b/client/src/scenes/PracticeSummaryReport/components/MemberSummary.js
index 212d173..c6e6af0 100644
--- a/client/src/scenes/PracticeSummaryReport/components/MemberSummary.js
+++ b/client/src/scenes/PracticeSummaryReport/components/MemberSummary.js
@@ -4,7 +4,8 @@ import { Loader, Grid } from 'semantic-ui-react';
import {
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION,
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION,
- UNSCHEDULED_INCIDENT_AFTER_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE, UNLOCKED_INCIDENT_STANDALONE
+ UNSCHEDULED_INCIDENT_AFTER_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE, UNLOCKED_INCIDENT_STANDALONE,
+ BOOKING_MOVED_TO_ANOTHER_DAY, BOOKING_SHORTENED,
} from '../../../constants/enums';
const MemberSummary = props => {
@@ -13,6 +14,7 @@ const MemberSummary = props => {
let totalUnscheduledFees = 0;
let totalUnlockedFees = 0;
+ let totalBookingChangeFees = 0;
incidents.forEach((incident) => {
switch (incident.incidentType) {
@@ -25,15 +27,20 @@ const MemberSummary = props => {
case UNLOCKED_INCIDENT_STANDALONE:
totalUnlockedFees += parseFloat(incident.incidentPrice);
break;
+ case BOOKING_MOVED_TO_ANOTHER_DAY:
+ case BOOKING_SHORTENED:
+ totalBookingChangeFees += parseFloat(incident.totalChargeFee);
+ break;
default:
break;
}
});
- const grandTotal = totalUnlockedFees + totalUnscheduledFees;
+ const grandTotal = totalUnlockedFees + totalUnscheduledFees + totalBookingChangeFees;
const formattedUnscheduledFees = `$ ${totalUnscheduledFees.toFixed(2)}`;
const formattedUnlockedFees = `$ ${totalUnlockedFees.toFixed(2)}`;
+ const formattedBookingChangeFees = `$ ${totalBookingChangeFees.toFixed(2)}`;
const formattedGrandTotalFee = `$ ${grandTotal.toFixed(2)}`;
return (
@@ -44,7 +51,7 @@ const MemberSummary = props => {
!loading &&
-
+
Unscheduled incidents total :
@@ -52,7 +59,7 @@ const MemberSummary = props => {
-
+
Unlocked incidents total :
@@ -60,7 +67,15 @@ const MemberSummary = props => {
-
+
+ Booking change charges total :
+
+
+ {formattedBookingChangeFees}
+
+
+
+
Grand Total :
diff --git a/services/integration/reports.js b/services/integration/reports.js
index 8a76cac..07c6f02 100644
--- a/services/integration/reports.js
+++ b/services/integration/reports.js
@@ -247,7 +247,38 @@ const getAllIncidents = (dateRange, memberId) => {
});
});
- allIncidents.push(...bookingChangeIncidents);
+ bookingChangeIncidents.forEach((bookingChangeIncident) => {
+ const {
+ id,
+ memberId,
+ resourceId,
+ oldBookingStart,
+ oldBookingEnd,
+ newBookingStart,
+ newBookingEnd,
+ incidentType,
+ chargeFee,
+ createdAt,
+ } = bookingChangeIncident;
+ const memberName = membersMap[memberId].name;
+ const resource = resourcesMap[resourceId];
+ const resourceName = resource.resourceName;
+ const officeName = officesMap[resource.officeId].officeName;
+ allIncidents.push({
+ incidentId: id,
+ memberId,
+ memberName,
+ resourceName,
+ officeName,
+ oldBookingStart: formatTime(oldBookingStart),
+ oldBookingEnd: formatTime(oldBookingEnd),
+ newBookingStart: formatTime(newBookingStart),
+ newBookingEnd: formatTime(newBookingEnd),
+ incidentType,
+ totalChargeFee: chargeFee,
+ incidentTimestamp: formatTime(createdAt),
+ });
+ });
resolve(allIncidents);
})