Fixed column names and the report
This commit is contained in:
@@ -0,0 +1,119 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Loader } from 'semantic-ui-react';
|
||||||
|
import ReactTable from 'react-table';
|
||||||
|
import 'react-table/react-table.css';
|
||||||
|
import { NavLink } from 'react-router-dom';
|
||||||
|
|
||||||
|
import {incidentsReportHeaderTitles} from '../../../constants/menuItems';
|
||||||
|
import {
|
||||||
|
incidentDescriptions,
|
||||||
|
incidentLevelDescriptions,
|
||||||
|
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, UNLOCKED_INCIDENT_STANDALONE, UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
|
||||||
|
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE
|
||||||
|
} from '../../../constants/enums';
|
||||||
|
|
||||||
|
|
||||||
|
const SingleIncidentsTable = props => {
|
||||||
|
const { loading, title, openMemberSummaryOnMemberClick, showBookingTimes, showDoorLockEntryTimes, hideMemberName } = props;
|
||||||
|
const incidents = props.incidents ? props.incidents : [];
|
||||||
|
|
||||||
|
const columns = [];
|
||||||
|
if (incidents && incidents.length > 0){
|
||||||
|
const incidentHeaders = Object.keys(incidentsReportHeaderTitles);
|
||||||
|
|
||||||
|
incidentHeaders.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (columnTitle && showColumn){
|
||||||
|
const columnAlignments = {
|
||||||
|
left: 'left',
|
||||||
|
right: 'right',
|
||||||
|
};
|
||||||
|
let columnContentsAlignment = columnAlignments.left;
|
||||||
|
|
||||||
|
columns.push({
|
||||||
|
Header: incidentsReportHeaderTitles[header],
|
||||||
|
accessor: header,
|
||||||
|
Cell: props => {
|
||||||
|
let cellValue = '';
|
||||||
|
let urlValue = undefined;
|
||||||
|
|
||||||
|
switch (props.column.id) {
|
||||||
|
case 'memberName':
|
||||||
|
const memberId = props.row['_original'].memberId;
|
||||||
|
urlValue = `/practice-summary-report/${memberId}`;
|
||||||
|
cellValue = props.value;
|
||||||
|
break;
|
||||||
|
case 'incidentType':
|
||||||
|
cellValue = incidentDescriptions[props.value];
|
||||||
|
break;
|
||||||
|
case 'incidentLevel':
|
||||||
|
cellValue = incidentLevelDescriptions[props.value];
|
||||||
|
break;
|
||||||
|
case 'feeDescription':
|
||||||
|
const { incidentType, incidentLevel, timeIntervalsToCharge } = props.row['_original'];
|
||||||
|
|
||||||
|
switch (incidentType) {
|
||||||
|
case UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
|
||||||
|
case UNLOCKED_INCIDENT_STANDALONE:
|
||||||
|
cellValue = `${incidentLevelDescriptions[incidentLevel]}`;
|
||||||
|
break;
|
||||||
|
case UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
|
||||||
|
case UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
|
||||||
|
case UNSCHEDULED_INCIDENT_STANDALONE:
|
||||||
|
cellValue = `${timeIntervalsToCharge} x 5 min`;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cellValue = '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'totalChargeFee':
|
||||||
|
const totalFee = props.value ? props.value : props.row['_original'].incidentPrice;
|
||||||
|
const totalFeeFormatted = parseFloat(totalFee).toFixed(2);
|
||||||
|
cellValue = `$ ${totalFeeFormatted}`;
|
||||||
|
columnContentsAlignment = columnAlignments.right;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cellValue = props.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (openMemberSummaryOnMemberClick && urlValue){
|
||||||
|
return <NavLink to={urlValue}>{cellValue}</NavLink>
|
||||||
|
}else{
|
||||||
|
return <div style={{ textAlign: columnContentsAlignment }}>{cellValue}</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h4>{title}</h4>
|
||||||
|
<Loader active={loading} />
|
||||||
|
{
|
||||||
|
!loading && incidents &&
|
||||||
|
<ReactTable
|
||||||
|
data={incidents}
|
||||||
|
multiSort={false}
|
||||||
|
columns={columns}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SingleIncidentsTable;
|
||||||
78
client/src/components/MemberIncidentsTables/index.js
Normal file
78
client/src/components/MemberIncidentsTables/index.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import React from 'react';
|
||||||
|
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
|
||||||
|
} from '../../constants/enums';
|
||||||
|
|
||||||
|
export default function MemberIncidentsTables (props) {
|
||||||
|
const { pendingIncidents, incidents, hideMemberName } = props;
|
||||||
|
|
||||||
|
const incidentsRelatedToReservations = [];
|
||||||
|
const standaloneIncidents = [];
|
||||||
|
|
||||||
|
if (Array.isArray(incidents)){
|
||||||
|
incidents.forEach((incident) => {
|
||||||
|
if (incident && incident.incidentType){
|
||||||
|
switch (incident.incidentType) {
|
||||||
|
case UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
|
||||||
|
case UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
|
||||||
|
case UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
|
||||||
|
incidentsRelatedToReservations.push(incident);
|
||||||
|
break;
|
||||||
|
case UNLOCKED_INCIDENT_STANDALONE:
|
||||||
|
case UNSCHEDULED_INCIDENT_STANDALONE:
|
||||||
|
standaloneIncidents.push(incident);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const incidentsRelatedToReservationsTable = (
|
||||||
|
<SingleIncidentsTable
|
||||||
|
loading={pendingIncidents}
|
||||||
|
incidents={incidentsRelatedToReservations}
|
||||||
|
openMemberSummaryOnMemberClick
|
||||||
|
showBookingTimes
|
||||||
|
hideMemberName={hideMemberName}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const standaloneIncidentsTable = (
|
||||||
|
<SingleIncidentsTable
|
||||||
|
loading={pendingIncidents}
|
||||||
|
incidents={standaloneIncidents}
|
||||||
|
openMemberSummaryOnMemberClick
|
||||||
|
showDoorLockEntryTimes
|
||||||
|
hideMemberName={hideMemberName}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const accordionPanels = [
|
||||||
|
{
|
||||||
|
key: 'related-door-lock-incidents',
|
||||||
|
title : { content: <Label color='blue' content={'Door Lock Charges - Related to reservations'} /> },
|
||||||
|
content: { content : incidentsRelatedToReservationsTable },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'standalone-door-lock-incidents',
|
||||||
|
title : { content: <Label color='blue' content={'Door Lock Charges - Standalone'} /> },
|
||||||
|
content: { content: standaloneIncidentsTable },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'reservation-modification-incidents',
|
||||||
|
title: {content: <Label color='blue' content={'Cancellation charges'}/>},
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Accordion
|
||||||
|
panels={accordionPanels}
|
||||||
|
exclusive={false}
|
||||||
|
defaultActiveIndex={[0]}
|
||||||
|
fluid
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,10 +1,16 @@
|
|||||||
|
|
||||||
export const UNLOCKED_INCIDENT = 2;
|
export const UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION = 2;
|
||||||
export const UNSCHEDULED_INCIDENT = 3;
|
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 incidentDescriptions = {};
|
export const incidentDescriptions = {};
|
||||||
incidentDescriptions[UNLOCKED_INCIDENT] = 'User left door unlocked';
|
incidentDescriptions[UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION] = 'User left door unlocked';
|
||||||
incidentDescriptions[UNSCHEDULED_INCIDENT] = 'Unscheduled use';
|
incidentDescriptions[UNSCHEDULED_INCIDENT_BEFORE_RESERVATION] = 'Unscheduled use - before';
|
||||||
|
incidentDescriptions[UNSCHEDULED_INCIDENT_AFTER_RESERVATION] = 'Unscheduled use - after';
|
||||||
|
incidentDescriptions[UNLOCKED_INCIDENT_STANDALONE] = 'User left door unlocked';
|
||||||
|
incidentDescriptions[UNSCHEDULED_INCIDENT_STANDALONE] = 'Unscheduled use';
|
||||||
|
|
||||||
export const incidentLevelDescriptions = {
|
export const incidentLevelDescriptions = {
|
||||||
UNLOCKED_0: 'First month',
|
UNLOCKED_0: 'First month',
|
||||||
@@ -13,5 +19,4 @@ export const incidentLevelDescriptions = {
|
|||||||
UNLOCKED_3: 'Fourth month',
|
UNLOCKED_3: 'Fourth month',
|
||||||
UNLOCKED_4: 'Fifth month',
|
UNLOCKED_4: 'Fifth month',
|
||||||
UNLOCKED_5: 'Sixth month',
|
UNLOCKED_5: 'Sixth month',
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ export const incidentsReportHeaderTitles = {
|
|||||||
resourceName: 'Room',
|
resourceName: 'Room',
|
||||||
bookingStart: 'Reservation Start',
|
bookingStart: 'Reservation Start',
|
||||||
bookingEnd: 'Reservation End',
|
bookingEnd: 'Reservation End',
|
||||||
|
unlockTimestamp: 'Unlock Time',
|
||||||
|
lockTimestamp: 'Lock Time',
|
||||||
memberName: 'Member Name',
|
memberName: 'Member Name',
|
||||||
incidentType: 'Incident Type',
|
incidentType: 'Incident Type',
|
||||||
feeDescription: 'Fee description',
|
feeDescription: 'Fee description',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { Container } from 'semantic-ui-react';
|
|||||||
|
|
||||||
import MainMenu from '../../components/MainMenu';
|
import MainMenu from '../../components/MainMenu';
|
||||||
import DateRangePicker from '../../components/DateRangePicker';
|
import DateRangePicker from '../../components/DateRangePicker';
|
||||||
import MemberIncidentsTable from '../../components/MemberIncidentsTable';
|
import MemberIncidentsTables from '../../components/MemberIncidentsTables';
|
||||||
|
|
||||||
import { fetchIncidents } from '../../store/actions';
|
import { fetchIncidents } from '../../store/actions';
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ class IncidentsReport extends Component {
|
|||||||
<hr/>
|
<hr/>
|
||||||
<DateRangePicker buttonLabel="Show report" onDatesUpdate={this.onDatesUpdate.bind(this)} />
|
<DateRangePicker buttonLabel="Show report" onDatesUpdate={this.onDatesUpdate.bind(this)} />
|
||||||
<br/>
|
<br/>
|
||||||
<MemberIncidentsTable loading={pendingIncidents} incidents={incidents} openMemberSummaryOnMemberClick />
|
<MemberIncidentsTables pendingIncidents={pendingIncidents} incidents={incidents} />
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class MemberSelector extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
const { members } = this.props;
|
const { members, defaultMemberId } = this.props;
|
||||||
|
|
||||||
const dropdownOptions = members && Array.isArray(members) ? members.map(member => ({
|
const dropdownOptions = members && Array.isArray(members) ? members.map(member => ({
|
||||||
key: member.memberId,
|
key: member.memberId,
|
||||||
@@ -41,6 +41,7 @@ class MemberSelector extends Component {
|
|||||||
search
|
search
|
||||||
fluid
|
fluid
|
||||||
onChange={this.onMemberSelectionChange.bind(this)}
|
onChange={this.onMemberSelectionChange.bind(this)}
|
||||||
|
value={defaultMemberId ? defaultMemberId : null}
|
||||||
/>
|
/>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Loader, Grid } from 'semantic-ui-react';
|
import { Loader, Grid } from 'semantic-ui-react';
|
||||||
|
|
||||||
import { UNSCHEDULED_INCIDENT, UNLOCKED_INCIDENT } from '../../../constants/enums';
|
import {
|
||||||
|
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION,
|
||||||
|
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION,
|
||||||
|
UNSCHEDULED_INCIDENT_AFTER_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE, UNLOCKED_INCIDENT_STANDALONE
|
||||||
|
} from '../../../constants/enums';
|
||||||
|
|
||||||
const MemberSummary = props => {
|
const MemberSummary = props => {
|
||||||
const { loading } = props;
|
const { loading } = props;
|
||||||
@@ -12,10 +16,13 @@ const MemberSummary = props => {
|
|||||||
|
|
||||||
incidents.forEach((incident) => {
|
incidents.forEach((incident) => {
|
||||||
switch (incident.incidentType) {
|
switch (incident.incidentType) {
|
||||||
case UNSCHEDULED_INCIDENT:
|
case UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
|
||||||
|
case UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
|
||||||
|
case UNSCHEDULED_INCIDENT_STANDALONE:
|
||||||
totalUnscheduledFees += parseFloat(incident.totalChargeFee);
|
totalUnscheduledFees += parseFloat(incident.totalChargeFee);
|
||||||
break;
|
break;
|
||||||
case UNLOCKED_INCIDENT:
|
case UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
|
||||||
|
case UNLOCKED_INCIDENT_STANDALONE:
|
||||||
totalUnlockedFees += parseFloat(incident.incidentPrice);
|
totalUnlockedFees += parseFloat(incident.incidentPrice);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import MainMenu from '../../components/MainMenu';
|
|||||||
import DateRangePicker from '../../components/DateRangePicker';
|
import DateRangePicker from '../../components/DateRangePicker';
|
||||||
import MemberSelector from './components/MemberSelector';
|
import MemberSelector from './components/MemberSelector';
|
||||||
import MemberSummary from './components/MemberSummary';
|
import MemberSummary from './components/MemberSummary';
|
||||||
import MemberIncidentsTable from '../../components/MemberIncidentsTable';
|
import MemberIncidentsTables from '../../components/MemberIncidentsTables';
|
||||||
|
|
||||||
import { fetchMemberIncidents } from '../../store/actions';
|
import { fetchMemberIncidents } from '../../store/actions';
|
||||||
|
|
||||||
@@ -40,6 +40,7 @@ class PracticeSummaryReport extends Component {
|
|||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { memberIncidents, loading } = this.props;
|
const { memberIncidents, loading } = this.props;
|
||||||
|
const { memberId } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
@@ -49,7 +50,7 @@ class PracticeSummaryReport extends Component {
|
|||||||
<Grid stackable columns="equal">
|
<Grid stackable columns="equal">
|
||||||
<Grid.Row>
|
<Grid.Row>
|
||||||
<Grid.Column>
|
<Grid.Column>
|
||||||
<MemberSelector onMemberSelect={this.onMemberSelectionUpdate.bind(this)} />
|
<MemberSelector onMemberSelect={this.onMemberSelectionUpdate.bind(this)} defaultMemberId={memberId} />
|
||||||
</Grid.Column>
|
</Grid.Column>
|
||||||
<Grid.Column>
|
<Grid.Column>
|
||||||
<DateRangePicker inlineButton onDatesUpdate={this.onDateRangeUpdate.bind(this)}/>
|
<DateRangePicker inlineButton onDatesUpdate={this.onDateRangeUpdate.bind(this)}/>
|
||||||
@@ -66,11 +67,7 @@ class PracticeSummaryReport extends Component {
|
|||||||
<Grid.Row/>
|
<Grid.Row/>
|
||||||
<Grid.Row>
|
<Grid.Row>
|
||||||
<Grid.Column>
|
<Grid.Column>
|
||||||
<MemberIncidentsTable
|
<MemberIncidentsTables incidents={memberIncidents} pendingIncidents={loading} hideMemberName/>
|
||||||
title="Detail list"
|
|
||||||
incidents={memberIncidents}
|
|
||||||
loading={loading}
|
|
||||||
/>
|
|
||||||
</Grid.Column>
|
</Grid.Column>
|
||||||
</Grid.Row>
|
</Grid.Row>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -61,8 +61,11 @@ const integrationServiceErrors = {
|
|||||||
|
|
||||||
const incidentType = {
|
const incidentType = {
|
||||||
NOT_AN_INCIDENT: 1,
|
NOT_AN_INCIDENT: 1,
|
||||||
UNLOCKED_INCIDENT: 2,
|
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION: 2,
|
||||||
UNSCHEDULED_INCIDENT: 3,
|
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION: 3,
|
||||||
|
UNSCHEDULED_INCIDENT_AFTER_RESERVATION: 4,
|
||||||
|
UNLOCKED_INCIDENT_STANDALONE: 5,
|
||||||
|
UNSCHEDULED_INCIDENT_STANDALONE: 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
const UI_TIMEZONE = process.env.UI_TIMEZONE || 'America/Los_Angeles';
|
const UI_TIMEZONE = process.env.UI_TIMEZONE || 'America/Los_Angeles';
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface, Sequelize) => {
|
||||||
|
return queryInterface.addColumn('unlockedIncidents', 'unlockTimestamp', {
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
after: 'bookingEnd'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface, Sequelize) => {
|
||||||
|
return queryInterface.removeColumn('unlockedIncidents', 'unlockTimestamp');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface, Sequelize) => {
|
||||||
|
return queryInterface.sequelize.transaction((t) => {
|
||||||
|
return Promise.all([
|
||||||
|
queryInterface.addColumn('unscheduledIncidents', 'unlockTimestamp', {
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
after: 'bookingEnd'
|
||||||
|
}),
|
||||||
|
queryInterface.addColumn('unscheduledIncidents', 'lockTimestamp', {
|
||||||
|
type: Sequelize.DATE,
|
||||||
|
after: 'unlockTimestamp'
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: (queryInterface, Sequelize) => {
|
||||||
|
return queryInterface.sequelize.transaction((t) => {
|
||||||
|
return Promise.all([
|
||||||
|
queryInterface.removeColumn('unscheduledIncidents', 'lockTimestamp'),
|
||||||
|
queryInterface.removeColumn('unscheduledIncidents', 'unlockTimestamp')
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -21,6 +21,7 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
incidentLevelPrice: DataTypes.FLOAT,
|
incidentLevelPrice: DataTypes.FLOAT,
|
||||||
|
unlockTimestamp: DataTypes.DATE,
|
||||||
}, {});
|
}, {});
|
||||||
unlockedIncident.associate = function(models) {
|
unlockedIncident.associate = function(models) {
|
||||||
// associations can be defined here
|
// associations can be defined here
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ module.exports = (sequelize, DataTypes) => {
|
|||||||
chargePrice: DataTypes.FLOAT,
|
chargePrice: DataTypes.FLOAT,
|
||||||
timeIntervalsToCharge: DataTypes.INTEGER,
|
timeIntervalsToCharge: DataTypes.INTEGER,
|
||||||
totalChargeFee: DataTypes.FLOAT,
|
totalChargeFee: DataTypes.FLOAT,
|
||||||
|
unlockTimestamp: DataTypes.DATE,
|
||||||
|
lockTimestamp: DataTypes.DATE,
|
||||||
}, {});
|
}, {});
|
||||||
unscheduledIncident.associate = function(models) {
|
unscheduledIncident.associate = function(models) {
|
||||||
// associations can be defined here
|
// associations can be defined here
|
||||||
|
|||||||
@@ -188,8 +188,6 @@ const getUnlockEntryForReservation = (reservation, previousReservation) => {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const { memberId, resourceId } = reservation;
|
const { memberId, resourceId } = reservation;
|
||||||
|
|
||||||
const attributes = ['memberName', 'event', 'timestamp', 'resourceId'];
|
|
||||||
|
|
||||||
const previousReservationEndMoment = previousReservation && previousReservation.end ?
|
const previousReservationEndMoment = previousReservation && previousReservation.end ?
|
||||||
moment.utc(previousReservation.end) : null;
|
moment.utc(previousReservation.end) : null;
|
||||||
const reservationStartMoment = moment.utc(reservation.start);
|
const reservationStartMoment = moment.utc(reservation.start);
|
||||||
@@ -214,7 +212,6 @@ const getUnlockEntryForReservation = (reservation, previousReservation) => {
|
|||||||
const order = [['timestamp', 'DESC']];
|
const order = [['timestamp', 'DESC']];
|
||||||
|
|
||||||
db.doorLockEvent.findAll({
|
db.doorLockEvent.findAll({
|
||||||
attributes,
|
|
||||||
where: filters,
|
where: filters,
|
||||||
order,
|
order,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ const { getUnlockEntryForReservation, getLockEntryForReservation, getEntriesBetw
|
|||||||
const { getAllFinishedBookings, getFirstPreviousBooking, getFirstNextBooking } = require('../officeRnD/bookings');
|
const { getAllFinishedBookings, getFirstPreviousBooking, getFirstNextBooking } = require('../officeRnD/bookings');
|
||||||
|
|
||||||
const getSortedIncidentsForMember = (memberId) => {
|
const getSortedIncidentsForMember = (memberId) => {
|
||||||
const attributes = ['bookingStart', 'incidentLevel', 'incidentLevelPrice'];
|
const attributes = ['bookingStart', 'incidentLevel', 'incidentLevelPrice', 'unlockTimestamp'];
|
||||||
const filters = {
|
const filters = {
|
||||||
memberId
|
memberId
|
||||||
};
|
};
|
||||||
const order = [['bookingStart', 'DESC']];
|
const order = [['unlockTimestamp', 'DESC']];
|
||||||
|
|
||||||
return db.unlockedIncident.findAll({
|
return db.unlockedIncident.findAll({
|
||||||
attributes,
|
attributes,
|
||||||
@@ -24,9 +24,8 @@ const getSortedIncidentsForMember = (memberId) => {
|
|||||||
const insertUnscheduledIncidents = (incidents) => {
|
const insertUnscheduledIncidents = (incidents) => {
|
||||||
const asyncJobs = [];
|
const asyncJobs = [];
|
||||||
incidents.forEach((incident) => {
|
incidents.forEach((incident) => {
|
||||||
const { reservation, lockEntry, chargePrice, timeIntervalsToCharge, totalChargeFee } = incident;
|
const { reservation, unlockTimestamp, lockTimestamp, memberId, resourceId, chargePrice, timeIntervalsToCharge, totalChargeFee } = incident;
|
||||||
const { reservationId, memberId, resourceId, start, end } = reservation;
|
const { reservationId, start, end } = reservation;
|
||||||
const { timestamp, event } = lockEntry;
|
|
||||||
|
|
||||||
const incidentForDB = {
|
const incidentForDB = {
|
||||||
reservationId,
|
reservationId,
|
||||||
@@ -34,11 +33,13 @@ const insertUnscheduledIncidents = (incidents) => {
|
|||||||
resourceId,
|
resourceId,
|
||||||
bookingStart: start,
|
bookingStart: start,
|
||||||
bookingEnd: end,
|
bookingEnd: end,
|
||||||
doorLockEventTimestamp: timestamp,
|
doorLockEventTimestamp: null,
|
||||||
doorLockEventType: event,
|
doorLockEventType: null,
|
||||||
chargePrice,
|
chargePrice,
|
||||||
timeIntervalsToCharge,
|
timeIntervalsToCharge,
|
||||||
totalChargeFee,
|
totalChargeFee,
|
||||||
|
unlockTimestamp,
|
||||||
|
lockTimestamp,
|
||||||
};
|
};
|
||||||
|
|
||||||
asyncJobs.push(db.unscheduledIncident.findOrCreate({
|
asyncJobs.push(db.unscheduledIncident.findOrCreate({
|
||||||
@@ -48,8 +49,8 @@ const insertUnscheduledIncidents = (incidents) => {
|
|||||||
resourceId,
|
resourceId,
|
||||||
bookingStart: start,
|
bookingStart: start,
|
||||||
bookingEnd: end,
|
bookingEnd: end,
|
||||||
doorLockEventTimestamp: timestamp,
|
unlockTimestamp,
|
||||||
doorLockEventType: event
|
lockTimestamp,
|
||||||
},
|
},
|
||||||
defaults: {...incidentForDB},
|
defaults: {...incidentForDB},
|
||||||
}));
|
}));
|
||||||
@@ -61,36 +62,50 @@ const insertUnscheduledIncidents = (incidents) => {
|
|||||||
const insertUnlockedIncidents = (incidents) => {
|
const insertUnlockedIncidents = (incidents) => {
|
||||||
const asyncJobs = [];
|
const asyncJobs = [];
|
||||||
incidents.forEach((incident) => {
|
incidents.forEach((incident) => {
|
||||||
const { reservationId, memberId, resourceId, bookingStart, bookingEnd } = incident;
|
const { reservation, memberId, resourceId, unlockTimestamp, incidentLevel, incidentLevelPrice } = incident;
|
||||||
|
const { reservationId, start, end} = reservation;
|
||||||
|
|
||||||
|
const incidentForDB = {
|
||||||
|
reservationId,
|
||||||
|
memberId,
|
||||||
|
resourceId,
|
||||||
|
bookingStart: start,
|
||||||
|
bookingEnd: end,
|
||||||
|
unlockTimestamp,
|
||||||
|
incidentLevel,
|
||||||
|
incidentLevelPrice,
|
||||||
|
};
|
||||||
|
|
||||||
asyncJobs.push(db.unlockedIncident.findOrCreate({
|
asyncJobs.push(db.unlockedIncident.findOrCreate({
|
||||||
where: {
|
where: {
|
||||||
reservationId,
|
reservationId,
|
||||||
memberId,
|
memberId,
|
||||||
resourceId,
|
resourceId,
|
||||||
bookingStart,
|
bookingStart: start,
|
||||||
bookingEnd,
|
bookingEnd: end,
|
||||||
|
unlockTimestamp,
|
||||||
|
incidentLevel,
|
||||||
},
|
},
|
||||||
defaults: {...incident},
|
defaults: {...incidentForDB},
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all(asyncJobs);
|
return Promise.all(asyncJobs);
|
||||||
};
|
};
|
||||||
|
|
||||||
const setUnlockedIncidentsLevel = (incidentReservations) => {
|
const setUnlockedIncidentsLevel = (incidents) => {
|
||||||
return new Promise ((resolve, reject) => {
|
return new Promise ((resolve, reject) => {
|
||||||
const sortingFunction = (reservationA, reservationB) => {
|
const sortingFunction = (incidentA, incidentB) => {
|
||||||
const sortCondition = moment.utc(reservationA.start).isBefore(moment.utc(reservationB.start));
|
const sortCondition = moment.utc(incidentA.unlockTimestamp).isBefore(moment.utc(incidentB.unlockTimestamp));
|
||||||
return sortCondition ? -1 : 1;
|
return sortCondition ? -1 : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
incidentReservations.sort(sortingFunction);
|
incidents.sort(sortingFunction);
|
||||||
|
|
||||||
const membersLastIncident = {};
|
const membersLastIncident = {};
|
||||||
|
|
||||||
incidentReservations.forEach((reservation) => {
|
incidents.forEach((incident) => {
|
||||||
membersLastIncident[reservation.memberId] = {
|
membersLastIncident[incident.memberId] = {
|
||||||
incidentLevel: null,
|
incidentLevel: null,
|
||||||
incidentTimestamp: null,
|
incidentTimestamp: null,
|
||||||
};
|
};
|
||||||
@@ -108,59 +123,58 @@ const setUnlockedIncidentsLevel = (incidentReservations) => {
|
|||||||
if (lastIncident) {
|
if (lastIncident) {
|
||||||
membersLastIncident[lastIncident.memberId] = {
|
membersLastIncident[lastIncident.memberId] = {
|
||||||
incidentLevel: lastIncident.incidentLevel,
|
incidentLevel: lastIncident.incidentLevel,
|
||||||
incidentTimestamp: lastIncident.bookingStart,
|
incidentTimestamp: lastIncident.unlockTimestamp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const incidentsWithLevel = [];
|
const incidentsWithLevel = [];
|
||||||
|
|
||||||
incidentReservations.forEach((reservation) => {
|
incidents.forEach((incident) => {
|
||||||
const memberLastIncident = membersLastIncident[reservation.memberId];
|
const memberLastIncident = membersLastIncident[incident.memberId];
|
||||||
|
|
||||||
const incident = {
|
const formattedIncident = {
|
||||||
reservationId: reservation.reservationId,
|
reservation: incident.reservation,
|
||||||
memberId: reservation.memberId,
|
memberId: incident.memberId,
|
||||||
resourceId: reservation.resourceId,
|
resourceId: incident.resourceId,
|
||||||
bookingStart: reservation.start,
|
|
||||||
bookingEnd: reservation.end,
|
|
||||||
incidentLevel: undefined,
|
incidentLevel: undefined,
|
||||||
incidentLevelPrice: undefined,
|
incidentLevelPrice: undefined,
|
||||||
|
unlockTimestamp: incident.unlockTimestamp,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!memberLastIncident.incidentLevel) {
|
if (!memberLastIncident.incidentLevel) {
|
||||||
incident.incidentLevel = unlockedIncidentLevelsPrices.UNLOCKED_0.title;
|
formattedIncident.incidentLevel = unlockedIncidentLevelsPrices.UNLOCKED_0.title;
|
||||||
incident.incidentLevelPrice = unlockedIncidentLevelsPrices.UNLOCKED_0.price;
|
formattedIncident.incidentLevelPrice = unlockedIncidentLevelsPrices.UNLOCKED_0.price;
|
||||||
} else {
|
} else {
|
||||||
const lastIncidentTime = moment.utc(memberLastIncident.incidentTimestamp).startOf('month');
|
const lastIncidentTime = moment.utc(memberLastIncident.incidentTimestamp).startOf('month');
|
||||||
const currentIncidentTime = moment.utc(reservation.start).startOf('month');
|
const currentIncidentTime = moment.utc(incident.unlockTimestamp).startOf('month');
|
||||||
const timeDiff = Math.abs(lastIncidentTime.diff(currentIncidentTime, 'months'));
|
const timeDiff = Math.abs(lastIncidentTime.diff(currentIncidentTime, 'months'));
|
||||||
|
|
||||||
if (timeDiff >= (parseInt(process.env.UNLOCK_STREAK_REPAIR_AFTER) || 6)){
|
if (timeDiff >= (parseInt(process.env.UNLOCK_STREAK_REPAIR_AFTER) || 6)){
|
||||||
incident.incidentLevel = unlockedIncidentLevelsPrices.UNLOCKED_0.title;
|
formattedIncident.incidentLevel = unlockedIncidentLevelsPrices.UNLOCKED_0.title;
|
||||||
incident.incidentLevelPrice = unlockedIncidentLevelsPrices.UNLOCKED_0.price;
|
formattedIncident.incidentLevelPrice = unlockedIncidentLevelsPrices.UNLOCKED_0.price;
|
||||||
} else {
|
} else {
|
||||||
const lastIncidentLevelId = unlockedIncidentLevelsPrices[memberLastIncident.incidentLevel].id;
|
const lastIncidentLevelId = unlockedIncidentLevelsPrices[memberLastIncident.incidentLevel].id;
|
||||||
const maxId = 5;
|
const maxId = 5;
|
||||||
|
|
||||||
if ((lastIncidentLevelId && (lastIncidentLevelId >= maxId)) || (timeDiff === 0)){
|
if ((lastIncidentLevelId && (lastIncidentLevelId >= maxId)) || (timeDiff === 0)){
|
||||||
incident.incidentLevel = memberLastIncident.incidentLevel;
|
formattedIncident.incidentLevel = memberLastIncident.incidentLevel;
|
||||||
incident.incidentLevelPrice = unlockedIncidentLevelsPrices[incident.incidentLevel].price;
|
formattedIncident.incidentLevelPrice = unlockedIncidentLevelsPrices[formattedIncident.incidentLevel].price;
|
||||||
} else {
|
} else {
|
||||||
const nextId = lastIncidentLevelId + 1;
|
const nextId = lastIncidentLevelId + 1;
|
||||||
Object.keys(unlockedIncidentLevelsPrices).forEach((key) => {
|
Object.keys(unlockedIncidentLevelsPrices).forEach((key) => {
|
||||||
if (unlockedIncidentLevelsPrices[key].id === nextId){
|
if (unlockedIncidentLevelsPrices[key].id === nextId){
|
||||||
incident.incidentLevel = unlockedIncidentLevelsPrices[key].title;
|
formattedIncident.incidentLevel = unlockedIncidentLevelsPrices[key].title;
|
||||||
incident.incidentLevelPrice = unlockedIncidentLevelsPrices[key].price
|
formattedIncident.incidentLevelPrice = unlockedIncidentLevelsPrices[key].price
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memberLastIncident.incidentLevel = incident.incidentLevel;
|
memberLastIncident.incidentLevel = formattedIncident.incidentLevel;
|
||||||
memberLastIncident.incidentTimestamp = incident.bookingStart;
|
memberLastIncident.incidentTimestamp = formattedIncident.unlockTimestamp;
|
||||||
|
|
||||||
incidentsWithLevel.push(incident);
|
incidentsWithLevel.push(formattedIncident);
|
||||||
});
|
});
|
||||||
|
|
||||||
resolve(incidentsWithLevel);
|
resolve(incidentsWithLevel);
|
||||||
@@ -318,17 +332,18 @@ const getIncidentData = (reservation) => {
|
|||||||
if (!pairUnlockEntry){
|
if (!pairUnlockEntry){
|
||||||
pairUnlockEntry = entry;
|
pairUnlockEntry = entry;
|
||||||
}else{
|
}else{
|
||||||
const virtualReservation = {
|
const emptyReservation = {
|
||||||
reservationId: '',
|
reservationId: null,
|
||||||
start: pairUnlockEntry.timestamp,
|
start: null,
|
||||||
end: pairUnlockEntry.timestamp,
|
end: null,
|
||||||
memberId: pairUnlockEntry.memberId,
|
|
||||||
resourceId,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
incidents.push({
|
incidents.push({
|
||||||
incidentType: incidentType.UNLOCKED_INCIDENT,
|
incidentType: incidentType.UNLOCKED_INCIDENT_STANDALONE,
|
||||||
reservation: virtualReservation,
|
reservation: emptyReservation,
|
||||||
|
unlockTimestamp: pairUnlockEntry.timestamp,
|
||||||
|
memberId: pairUnlockEntry.memberId,
|
||||||
|
resourceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
pairLockEntry = null;
|
pairLockEntry = null;
|
||||||
@@ -338,12 +353,10 @@ const getIncidentData = (reservation) => {
|
|||||||
case doorLockEvents.USER_LOCKED:
|
case doorLockEvents.USER_LOCKED:
|
||||||
if (pairUnlockEntry && !pairLockEntry){
|
if (pairUnlockEntry && !pairLockEntry){
|
||||||
pairLockEntry = entry;
|
pairLockEntry = entry;
|
||||||
const virtualReservation = {
|
const emptyReservation = {
|
||||||
reservationId: '',
|
reservationId: null,
|
||||||
start: pairUnlockEntry.timestamp,
|
start: null,
|
||||||
end: pairLockEntry.timestamp,
|
end: null,
|
||||||
memberId: pairUnlockEntry.memberId,
|
|
||||||
resourceId,
|
|
||||||
};
|
};
|
||||||
const unlockMoment = moment.utc(pairUnlockEntry.timestamp);
|
const unlockMoment = moment.utc(pairUnlockEntry.timestamp);
|
||||||
const lockMoment = moment.utc(pairLockEntry.timestamp);
|
const lockMoment = moment.utc(pairLockEntry.timestamp);
|
||||||
@@ -352,9 +365,12 @@ const getIncidentData = (reservation) => {
|
|||||||
const totalChargeFee = timeIntervalsToCharge * UNSCHEDULED_CHARGE_PRICE;
|
const totalChargeFee = timeIntervalsToCharge * UNSCHEDULED_CHARGE_PRICE;
|
||||||
if (timeIntervalsToCharge > 0){
|
if (timeIntervalsToCharge > 0){
|
||||||
incidents.push({
|
incidents.push({
|
||||||
incidentType: incidentType.UNSCHEDULED_INCIDENT,
|
incidentType: incidentType.UNSCHEDULED_INCIDENT_STANDALONE,
|
||||||
reservation: virtualReservation,
|
reservation: emptyReservation,
|
||||||
doorLockEntry: pairLockEntry,
|
unlockTimestamp: pairUnlockEntry.timestamp,
|
||||||
|
lockTimestamp: pairLockEntry.timestamp,
|
||||||
|
memberId: pairUnlockEntry.memberId,
|
||||||
|
resourceId,
|
||||||
chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
||||||
timeIntervalsToCharge,
|
timeIntervalsToCharge,
|
||||||
totalChargeFee,
|
totalChargeFee,
|
||||||
@@ -384,9 +400,12 @@ const getIncidentData = (reservation) => {
|
|||||||
// 1. Check if member entered before reservation start time
|
// 1. Check if member entered before reservation start time
|
||||||
if (unlockEntry && chargeBefore && !previousReservationIsBackToBack) {
|
if (unlockEntry && chargeBefore && !previousReservationIsBackToBack) {
|
||||||
incidents.push({
|
incidents.push({
|
||||||
incidentType: incidentType.UNSCHEDULED_INCIDENT,
|
incidentType: incidentType.UNSCHEDULED_INCIDENT_BEFORE_RESERVATION,
|
||||||
reservation,
|
reservation,
|
||||||
doorLockEntry: unlockEntry,
|
unlockTimestamp: unlockEntry.timestamp,
|
||||||
|
lockTimestamp: null,
|
||||||
|
memberId: reservation.memberId,
|
||||||
|
resourceId: reservation.resourceId,
|
||||||
chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
||||||
timeIntervalsToCharge: timeIntervalsToChargeBefore,
|
timeIntervalsToCharge: timeIntervalsToChargeBefore,
|
||||||
totalChargeFee: totalChargeFeeBefore,
|
totalChargeFee: totalChargeFeeBefore,
|
||||||
@@ -396,9 +415,12 @@ const getIncidentData = (reservation) => {
|
|||||||
// 2. Check if member left after reservation end time
|
// 2. Check if member left after reservation end time
|
||||||
if (lockEntry && chargeAfter && !nextReservationIsBackToBack) {
|
if (lockEntry && chargeAfter && !nextReservationIsBackToBack) {
|
||||||
incidents.push({
|
incidents.push({
|
||||||
incidentType: incidentType.UNSCHEDULED_INCIDENT,
|
incidentType: incidentType.UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
|
||||||
reservation,
|
reservation,
|
||||||
doorLockEntry: lockEntry,
|
unlockTimestamp: null,
|
||||||
|
lockTimestamp: lockEntry.timestamp,
|
||||||
|
memberId: reservation.memberId,
|
||||||
|
resourceId: reservation.resourceId,
|
||||||
chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
||||||
timeIntervalsToCharge: timeIntervalsToChargeAfter,
|
timeIntervalsToCharge: timeIntervalsToChargeAfter,
|
||||||
totalChargeFee: totalChargeFeeAfter,
|
totalChargeFee: totalChargeFeeAfter,
|
||||||
@@ -407,10 +429,20 @@ const getIncidentData = (reservation) => {
|
|||||||
|
|
||||||
// 3. Check if member forgot to lock the door
|
// 3. Check if member forgot to lock the door
|
||||||
if (!lockEntry && !nextReservationIsBackToBack){
|
if (!lockEntry && !nextReservationIsBackToBack){
|
||||||
|
const emptyReservation = {
|
||||||
|
reservationId: null,
|
||||||
|
start: null,
|
||||||
|
end: null,
|
||||||
|
};
|
||||||
|
|
||||||
if (unlockEntry){
|
if (unlockEntry){
|
||||||
|
|
||||||
incidents.push({
|
incidents.push({
|
||||||
incidentType: incidentType.UNLOCKED_INCIDENT,
|
incidentType: incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION,
|
||||||
reservation,
|
unlockTimestamp: unlockEntry.timestamp,
|
||||||
|
memberId: reservation.memberId,
|
||||||
|
resourceId: unlockEntry.resourceId,
|
||||||
|
reservation: reservation && reservation.dataValues ? reservation.dataValues : emptyReservation,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// No lock entry, no unlock entry and no reservation after this one
|
// No lock entry, no unlock entry and no reservation after this one
|
||||||
@@ -428,8 +460,11 @@ const getIncidentData = (reservation) => {
|
|||||||
.then((lastEntry) => {
|
.then((lastEntry) => {
|
||||||
if (lastEntry && lastEntry.event === doorLockEvents.USER_UNLOCKED){
|
if (lastEntry && lastEntry.event === doorLockEvents.USER_UNLOCKED){
|
||||||
incidents.push({
|
incidents.push({
|
||||||
incidentType: incidentType.UNLOCKED_INCIDENT,
|
incidentType: incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION,
|
||||||
reservation,
|
unlockTimestamp: lastEntry.timestamp,
|
||||||
|
memberId: lastEntry.memberId,
|
||||||
|
resourceId: lastEntry.resourceId,
|
||||||
|
reservation: reservation && reservation.dataValues ? reservation.dataValues : emptyReservation,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -469,18 +504,14 @@ const calculateDoorLockCharges = () => {
|
|||||||
console.log('Error checking incident : ', incident.error);
|
console.log('Error checking incident : ', incident.error);
|
||||||
} else if (incident.incidentType) {
|
} else if (incident.incidentType) {
|
||||||
switch (incident.incidentType) {
|
switch (incident.incidentType) {
|
||||||
case incidentType.UNLOCKED_INCIDENT:
|
case incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
|
||||||
unlockedIncidents.push(incident.reservation);
|
case incidentType.UNLOCKED_INCIDENT_STANDALONE:
|
||||||
|
unlockedIncidents.push(incident);
|
||||||
break;
|
break;
|
||||||
case incidentType.UNSCHEDULED_INCIDENT:
|
case incidentType.UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
|
||||||
const {reservation, doorLockEntry, chargePrice, timeIntervalsToCharge, totalChargeFee} = incident;
|
case incidentType.UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
|
||||||
unscheduledIncidents.push({
|
case incidentType.UNSCHEDULED_INCIDENT_STANDALONE:
|
||||||
reservation,
|
unscheduledIncidents.push(incident);
|
||||||
lockEntry: doorLockEntry,
|
|
||||||
chargePrice,
|
|
||||||
timeIntervalsToCharge,
|
|
||||||
totalChargeFee,
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,17 +11,34 @@ const { fetchAllMembers } = require('../officeRnD/members');
|
|||||||
const { fetchOffices, fetchResources } = require('../officeRnD/resources');
|
const { fetchOffices, fetchResources } = require('../officeRnD/resources');
|
||||||
|
|
||||||
const getUnlockedIncidents = (startDate, endDate, memberId) => {
|
const getUnlockedIncidents = (startDate, endDate, memberId) => {
|
||||||
const attributes = ['id', 'memberId', 'resourceId', 'bookingStart', 'bookingEnd', 'incidentLevel', 'incidentLevelPrice'];
|
const attributes = ['id', 'reservationId', 'memberId', 'resourceId', 'bookingStart', 'bookingEnd', 'unlockTimestamp', 'incidentLevel', 'incidentLevelPrice'];
|
||||||
|
|
||||||
const filters = {};
|
const filters = {};
|
||||||
|
|
||||||
if (startDate && endDate) {
|
if (startDate && endDate) {
|
||||||
filters.bookingStart = {
|
const bookingStartCondition = {
|
||||||
[Op.and]: {
|
bookingStart: {
|
||||||
[Op.gte]: startDate.utc().toISOString(),
|
[Op.and]: {
|
||||||
[Op.lte]: endDate.utc().toISOString(),
|
[Op.gte]: startDate.toISOString(),
|
||||||
|
[Op.lte]: endDate.toISOString(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const unlockTimestampCondition = {
|
||||||
|
unlockTimestamp: {
|
||||||
|
[Op.and]: {
|
||||||
|
[Op.gte]: startDate.toISOString(),
|
||||||
|
[Op.lte]: endDate.toISOString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const bookingStartOrUnlockTimestamp = {
|
||||||
|
[Op.or]: [bookingStartCondition, unlockTimestampCondition]
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.assign(filters, bookingStartOrUnlockTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memberId){
|
if (memberId){
|
||||||
@@ -40,12 +57,13 @@ const getUnlockedIncidents = (startDate, endDate, memberId) => {
|
|||||||
const getUnscheduledIncidents = (startDate, endDate, memberId) => {
|
const getUnscheduledIncidents = (startDate, endDate, memberId) => {
|
||||||
const attributes = [
|
const attributes = [
|
||||||
'id',
|
'id',
|
||||||
|
'reservationId',
|
||||||
'memberId',
|
'memberId',
|
||||||
'resourceId',
|
'resourceId',
|
||||||
'bookingStart',
|
'bookingStart',
|
||||||
'bookingEnd',
|
'bookingEnd',
|
||||||
'doorLockEventTimestamp',
|
'unlockTimestamp',
|
||||||
'doorLockEventType',
|
'lockTimestamp',
|
||||||
'timeIntervalsToCharge',
|
'timeIntervalsToCharge',
|
||||||
'chargePrice',
|
'chargePrice',
|
||||||
'totalChargeFee'
|
'totalChargeFee'
|
||||||
@@ -54,14 +72,32 @@ const getUnscheduledIncidents = (startDate, endDate, memberId) => {
|
|||||||
const filters = {};
|
const filters = {};
|
||||||
|
|
||||||
if (startDate && endDate) {
|
if (startDate && endDate) {
|
||||||
filters.bookingStart = {
|
const bookingStartCondition = {
|
||||||
[Op.and]: {
|
bookingStart: {
|
||||||
[Op.gte]: startDate.utc().toISOString(),
|
[Op.and]: {
|
||||||
[Op.lte]: endDate.utc().toISOString(),
|
[Op.gte]: startDate.toISOString(),
|
||||||
|
[Op.lte]: endDate.toISOString(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const unlockTimestampCondition = {
|
||||||
|
unlockTimestamp: {
|
||||||
|
[Op.and]: {
|
||||||
|
[Op.gte]: startDate.toISOString(),
|
||||||
|
[Op.lte]: endDate.toISOString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const bookingStartOrUnlockTimestamp = {
|
||||||
|
[Op.or]: [bookingStartCondition, unlockTimestampCondition]
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.assign(filters, bookingStartOrUnlockTimestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (memberId){
|
if (memberId){
|
||||||
filters.memberId = memberId;
|
filters.memberId = memberId;
|
||||||
}
|
}
|
||||||
@@ -76,7 +112,12 @@ const getUnscheduledIncidents = (startDate, endDate, memberId) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const formatTime = (timestamp) => {
|
const formatTime = (timestamp) => {
|
||||||
return moment.tz(timestamp, UI_TIMEZONE).format('MM/DD/YYYY hh:mm a');
|
const momentObject = moment.tz(timestamp, UI_TIMEZONE);
|
||||||
|
if (momentObject.isValid()){
|
||||||
|
return momentObject.format('MM/DD/YYYY hh:mm a');
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAllDoorLockIncidents = (dateRange, memberId) => {
|
const getAllDoorLockIncidents = (dateRange, memberId) => {
|
||||||
@@ -114,6 +155,8 @@ const getAllDoorLockIncidents = (dateRange, memberId) => {
|
|||||||
const allIncidents = [];
|
const allIncidents = [];
|
||||||
|
|
||||||
unlockedIncidents.forEach((unlockedIncident) => {
|
unlockedIncidents.forEach((unlockedIncident) => {
|
||||||
|
const incidentTypeNumber = unlockedIncident.reservationId ?
|
||||||
|
incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION : incidentType.UNLOCKED_INCIDENT_STANDALONE;
|
||||||
allIncidents.push({
|
allIncidents.push({
|
||||||
incidentId: unlockedIncident.id,
|
incidentId: unlockedIncident.id,
|
||||||
memberId: unlockedIncident.memberId,
|
memberId: unlockedIncident.memberId,
|
||||||
@@ -122,13 +165,24 @@ const getAllDoorLockIncidents = (dateRange, memberId) => {
|
|||||||
officeName: officesMap[resourcesMap[unlockedIncident.resourceId].officeId].officeName,
|
officeName: officesMap[resourcesMap[unlockedIncident.resourceId].officeId].officeName,
|
||||||
bookingStart: formatTime(unlockedIncident.bookingStart),
|
bookingStart: formatTime(unlockedIncident.bookingStart),
|
||||||
bookingEnd: formatTime(unlockedIncident.bookingEnd),
|
bookingEnd: formatTime(unlockedIncident.bookingEnd),
|
||||||
incidentType: incidentType.UNLOCKED_INCIDENT,
|
unlockTimestamp: formatTime(unlockedIncident.unlockTimestamp),
|
||||||
|
incidentType: incidentTypeNumber,
|
||||||
incidentLevel: unlockedIncident.incidentLevel,
|
incidentLevel: unlockedIncident.incidentLevel,
|
||||||
incidentPrice: unlockedIncident.incidentLevelPrice,
|
incidentPrice: unlockedIncident.incidentLevelPrice,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
unscheduledIncidents.forEach((unscheduledIncident) => {
|
unscheduledIncidents.forEach((unscheduledIncident) => {
|
||||||
|
let incidentTypeNumber;
|
||||||
|
if (unscheduledIncident.reservationId){
|
||||||
|
if (unscheduledIncident.unlockTimestamp && !unscheduledIncident.lockTimestamp){
|
||||||
|
incidentTypeNumber = incidentType.UNSCHEDULED_INCIDENT_BEFORE_RESERVATION;
|
||||||
|
}else{
|
||||||
|
incidentTypeNumber = incidentType.UNSCHEDULED_INCIDENT_AFTER_RESERVATION;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
incidentTypeNumber = incidentType.UNSCHEDULED_INCIDENT_STANDALONE;
|
||||||
|
}
|
||||||
allIncidents.push({
|
allIncidents.push({
|
||||||
incidentId: unscheduledIncident.id,
|
incidentId: unscheduledIncident.id,
|
||||||
memberId: unscheduledIncident.memberId,
|
memberId: unscheduledIncident.memberId,
|
||||||
@@ -137,7 +191,9 @@ const getAllDoorLockIncidents = (dateRange, memberId) => {
|
|||||||
officeName: officesMap[resourcesMap[unscheduledIncident.resourceId].officeId].officeName,
|
officeName: officesMap[resourcesMap[unscheduledIncident.resourceId].officeId].officeName,
|
||||||
bookingStart: formatTime(unscheduledIncident.bookingStart),
|
bookingStart: formatTime(unscheduledIncident.bookingStart),
|
||||||
bookingEnd: formatTime(unscheduledIncident.bookingEnd),
|
bookingEnd: formatTime(unscheduledIncident.bookingEnd),
|
||||||
incidentType: incidentType.UNSCHEDULED_INCIDENT,
|
unlockTimestamp: formatTime(unscheduledIncident.unlockTimestamp),
|
||||||
|
lockTimestamp: formatTime(unscheduledIncident.lockTimestamp),
|
||||||
|
incidentType: incidentTypeNumber,
|
||||||
timeIntervalsToCharge: unscheduledIncident.timeIntervalsToCharge,
|
timeIntervalsToCharge: unscheduledIncident.timeIntervalsToCharge,
|
||||||
chargePrice: unscheduledIncident.chargePrice,
|
chargePrice: unscheduledIncident.chargePrice,
|
||||||
totalChargeFee: unscheduledIncident.totalChargeFee,
|
totalChargeFee: unscheduledIncident.totalChargeFee,
|
||||||
|
|||||||
Reference in New Issue
Block a user