Compare commits
1 Commits
master
...
fix-how-lo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57cb6e8eaf |
@@ -12,21 +12,16 @@ import {
|
|||||||
incidentDescriptions,
|
incidentDescriptions,
|
||||||
incidentLevelDescriptions,
|
incidentLevelDescriptions,
|
||||||
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, UNLOCKED_INCIDENT_STANDALONE, UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
|
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, UNLOCKED_INCIDENT_STANDALONE, UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
|
||||||
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE, BOOKING_CANCELED_LATE, BOOKING_MOVED_TO_ANOTHER_DAY,
|
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE
|
||||||
BOOKING_SHORTENED
|
|
||||||
} from '../../../constants/enums';
|
} from '../../../constants/enums';
|
||||||
import { doorLockRelatedWithReservationIncidentHeaders, standaloneDoorLockIncidentHeaders, bookingChangeIncidentHeaders } from '../../../constants/constants';
|
import { doorLockRelatedWithReservationIncidentHeaders, standaloneDoorLockIncidentHeaders, bookingChangeIncidentHeaders } from '../../../constants/constants';
|
||||||
import { deleteIncidents, updateIncidentFees } from "../../../store/actions";
|
import { deleteIncidents } from "../../../store/actions";
|
||||||
|
|
||||||
class SingleIncidentsTable extends Component {
|
class SingleIncidentsTable extends Component {
|
||||||
state = {
|
state = {
|
||||||
selectedUnlockedIncidentIds: [],
|
selectedUnlockedIncidentIds: [],
|
||||||
selectedUnscheduledIncidentIds: [],
|
selectedUnscheduledIncidentIds: [],
|
||||||
selectedBookingChangeIncidentIds: [],
|
selectedBookingChangeIncidentIds: []
|
||||||
changedUnlockedIncidentIds: {},
|
|
||||||
changedUnscheduledIncidentIds: {},
|
|
||||||
changedBookingChangeIncidentIds: {},
|
|
||||||
inputIdToFocus: null,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onSelectChange = (selectedIncidents) => {
|
onSelectChange = (selectedIncidents) => {
|
||||||
@@ -87,24 +82,6 @@ class SingleIncidentsTable extends Component {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
updateChangedFees = () => {
|
|
||||||
const { dateRange, updateIncidentsById, memberId } = this.props;
|
|
||||||
const { changedUnlockedIncidentIds, changedUnscheduledIncidentIds, changedBookingChangeIncidentIds } = this.state;
|
|
||||||
|
|
||||||
const incidentFeesToUpdate = {
|
|
||||||
unlockedIncidentFees: changedUnlockedIncidentIds,
|
|
||||||
unscheduledIncidentFees: changedUnscheduledIncidentIds,
|
|
||||||
bookingChangeIncidentFees: changedBookingChangeIncidentIds
|
|
||||||
};
|
|
||||||
|
|
||||||
updateIncidentsById(dateRange, incidentFeesToUpdate, memberId);
|
|
||||||
this.setState({
|
|
||||||
changedUnlockedIncidentIds: {},
|
|
||||||
changedUnscheduledIncidentIds: {},
|
|
||||||
changedBookingChangeIncidentIds: {}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
const {
|
const {
|
||||||
loading,
|
loading,
|
||||||
@@ -117,22 +94,12 @@ class SingleIncidentsTable extends Component {
|
|||||||
const {
|
const {
|
||||||
selectedUnlockedIncidentIds,
|
selectedUnlockedIncidentIds,
|
||||||
selectedUnscheduledIncidentIds,
|
selectedUnscheduledIncidentIds,
|
||||||
selectedBookingChangeIncidentIds,
|
selectedBookingChangeIncidentIds
|
||||||
changedUnlockedIncidentIds,
|
|
||||||
changedUnscheduledIncidentIds,
|
|
||||||
changedBookingChangeIncidentIds,
|
|
||||||
inputIdToFocus
|
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
const totalSelected = selectedUnlockedIncidentIds.length + selectedUnscheduledIncidentIds.length + selectedBookingChangeIncidentIds.length;
|
const totalSelected = selectedUnlockedIncidentIds.length + selectedUnscheduledIncidentIds.length + selectedBookingChangeIncidentIds.length;
|
||||||
const numberOfSelectedText = totalSelected > 0 ? ` (${totalSelected})` : '';
|
const numberOfSelectedText = totalSelected > 0 ? ` (${totalSelected})` : '';
|
||||||
|
|
||||||
const totalChanged =
|
|
||||||
Object.keys(changedUnlockedIncidentIds).length +
|
|
||||||
Object.keys(changedUnscheduledIncidentIds).length +
|
|
||||||
Object.keys(changedBookingChangeIncidentIds).length;
|
|
||||||
const numberOfChangedText = totalChanged > 0 ? ` (${totalChanged})` : '';
|
|
||||||
|
|
||||||
const incidents = this.props.incidents ? this.props.incidents : [];
|
const incidents = this.props.incidents ? this.props.incidents : [];
|
||||||
incidents.forEach(incident => {
|
incidents.forEach(incident => {
|
||||||
incident.id = `${incident.incidentType}-${incident.incidentId}`;
|
incident.id = `${incident.incidentType}-${incident.incidentId}`;
|
||||||
@@ -155,44 +122,6 @@ class SingleIncidentsTable extends Component {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const priceChangeHandler = (element) => {
|
|
||||||
if (element && element.target){
|
|
||||||
const {value: newValue, id: incidentDescriptionID} = element.target;
|
|
||||||
const newValueFloat = parseFloat(newValue);
|
|
||||||
const incidentData = incidentDescriptionID.split('-');
|
|
||||||
const incidentType = parseInt(incidentData[0]) || null;
|
|
||||||
const incidentID = parseInt(incidentData[1]) || null;
|
|
||||||
|
|
||||||
if ((newValueFloat || (newValueFloat === 0) || (isNaN(newValueFloat))) && incidentType && incidentID){
|
|
||||||
const changedUnlockedIncidentIdsCopy = Object.assign({}, changedUnlockedIncidentIds);
|
|
||||||
const changedUnscheduledIncidentIdsCopy = Object.assign({}, changedUnscheduledIncidentIds);
|
|
||||||
const changedBookingChangeIncidentIdsCopy = Object.assign({}, changedBookingChangeIncidentIds);
|
|
||||||
|
|
||||||
switch (incidentType) {
|
|
||||||
case UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
|
|
||||||
case UNLOCKED_INCIDENT_STANDALONE:
|
|
||||||
changedUnlockedIncidentIdsCopy[incidentID] = newValueFloat;
|
|
||||||
this.setState({changedUnlockedIncidentIds: changedUnlockedIncidentIdsCopy, inputIdToFocus: incidentDescriptionID});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
|
|
||||||
case UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
|
|
||||||
case UNSCHEDULED_INCIDENT_STANDALONE:
|
|
||||||
changedUnscheduledIncidentIdsCopy[incidentID] = newValueFloat;
|
|
||||||
this.setState({changedUnscheduledIncidentIds: changedUnscheduledIncidentIdsCopy, inputIdToFocus: incidentDescriptionID});
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BOOKING_MOVED_TO_ANOTHER_DAY:
|
|
||||||
case BOOKING_SHORTENED:
|
|
||||||
case BOOKING_CANCELED_LATE:
|
|
||||||
changedBookingChangeIncidentIdsCopy[incidentID] = newValueFloat;
|
|
||||||
this.setState({changedBookingChangeIncidentIds: changedBookingChangeIncidentIdsCopy, inputIdToFocus: incidentDescriptionID});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
tableHeaders.forEach((header) => {
|
tableHeaders.forEach((header) => {
|
||||||
const columnTitle = incidentsReportHeaderTitles[header];
|
const columnTitle = incidentsReportHeaderTitles[header];
|
||||||
|
|
||||||
@@ -214,10 +143,6 @@ class SingleIncidentsTable extends Component {
|
|||||||
Cell: props => {
|
Cell: props => {
|
||||||
let cellValue = '';
|
let cellValue = '';
|
||||||
let urlValue = undefined;
|
let urlValue = undefined;
|
||||||
let clickablePrice = undefined;
|
|
||||||
let priceAsNumber = undefined;
|
|
||||||
let priceInputID = undefined;
|
|
||||||
let priceFontColor = 'black';
|
|
||||||
|
|
||||||
switch (props.column.id) {
|
switch (props.column.id) {
|
||||||
case 'memberName':
|
case 'memberName':
|
||||||
@@ -273,44 +198,9 @@ class SingleIncidentsTable extends Component {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'totalChargeFee':
|
case 'totalChargeFee':
|
||||||
clickablePrice = true;
|
const totalFee = (props.row['_original'].incidentPrice || props.value) || 0;
|
||||||
let totalFee = 0;
|
const totalFeeFormatted = parseFloat(totalFee).toFixed(2);
|
||||||
|
cellValue = `$ ${totalFeeFormatted}`;
|
||||||
let changedIncidentsProxy;
|
|
||||||
switch (props.row['_original'].incidentType) {
|
|
||||||
case UNLOCKED_INCIDENT_STANDALONE:
|
|
||||||
case UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION:
|
|
||||||
changedIncidentsProxy = changedUnlockedIncidentIds;
|
|
||||||
break;
|
|
||||||
case UNSCHEDULED_INCIDENT_STANDALONE:
|
|
||||||
case UNSCHEDULED_INCIDENT_BEFORE_RESERVATION:
|
|
||||||
case UNSCHEDULED_INCIDENT_AFTER_RESERVATION:
|
|
||||||
changedIncidentsProxy = changedUnscheduledIncidentIds;
|
|
||||||
break;
|
|
||||||
case BOOKING_CANCELED_LATE:
|
|
||||||
case BOOKING_MOVED_TO_ANOTHER_DAY:
|
|
||||||
case BOOKING_SHORTENED:
|
|
||||||
changedIncidentsProxy = changedBookingChangeIncidentIds;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const changedFee = changedIncidentsProxy[props.row['_original'].incidentId];
|
|
||||||
|
|
||||||
if (typeof changedFee === 'number'){
|
|
||||||
// Not undefined, maybe 0 or NaN
|
|
||||||
if (isNaN(changedFee)){
|
|
||||||
totalFee = '';
|
|
||||||
}else{
|
|
||||||
totalFee = changedFee;
|
|
||||||
priceFontColor = 'red';
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
//Not defined, in this context means it is not changed
|
|
||||||
totalFee = parseFloat((props.row['_original'].incidentPrice || props.value) || 0).toFixed(2);
|
|
||||||
}
|
|
||||||
// const totalFeeFormatted = parseFloat(totalFee).toFixed(2);
|
|
||||||
priceAsNumber = totalFee;
|
|
||||||
priceInputID = `${props.row['_original'].incidentType || ''}-${props.row['_original'].incidentId || ''}`;
|
|
||||||
// cellValue = `$ ${totalFeeFormatted}`;
|
|
||||||
columnContentsAlignment = columnAlignments.right;
|
columnContentsAlignment = columnAlignments.right;
|
||||||
break;
|
break;
|
||||||
case 'oldReservation':
|
case 'oldReservation':
|
||||||
@@ -327,22 +217,10 @@ class SingleIncidentsTable extends Component {
|
|||||||
cellValue = props.value;
|
cellValue = props.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clickablePrice){
|
if (openMemberSummaryOnMemberClick && urlValue){
|
||||||
return <p>$ <input
|
return <NavLink to={urlValue}>{cellValue}</NavLink>
|
||||||
id={priceInputID}
|
|
||||||
style={{ color: priceFontColor }}
|
|
||||||
type={'number'}
|
|
||||||
onChange={priceChangeHandler}
|
|
||||||
value={priceAsNumber}
|
|
||||||
autoFocus={priceInputID === inputIdToFocus}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
}else{
|
}else{
|
||||||
if (openMemberSummaryOnMemberClick && urlValue){
|
return <div style={{ textAlign: columnContentsAlignment, whiteSpace: 'pre' }}>{cellValue}</div>
|
||||||
return <NavLink to={urlValue}>{cellValue}</NavLink>
|
|
||||||
}else{
|
|
||||||
return <div style={{ textAlign: columnContentsAlignment, whiteSpace: 'pre' }}>{cellValue}</div>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -357,9 +235,6 @@ class SingleIncidentsTable extends Component {
|
|||||||
{
|
{
|
||||||
<Button disabled={loading || totalSelected === 0} onClick={this.deleteSelectedFees}>{`Delete selected ${numberOfSelectedText}`}</Button>
|
<Button disabled={loading || totalSelected === 0} onClick={this.deleteSelectedFees}>{`Delete selected ${numberOfSelectedText}`}</Button>
|
||||||
}
|
}
|
||||||
{
|
|
||||||
<Button disabled={loading || totalChanged === 0} onClick={this.updateChangedFees}>{`Save changed ${numberOfChangedText}`}</Button>
|
|
||||||
}
|
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
{
|
{
|
||||||
!loading && incidents &&
|
!loading && incidents &&
|
||||||
@@ -377,8 +252,7 @@ class SingleIncidentsTable extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
deleteIncidentsById: (dateRange, incidentsToDelete, memberId) => deleteIncidents(dispatch, {dateRange, incidentsToDelete, memberId}),
|
deleteIncidentsById: (dateRange, incidentsToDelete, memberId) => deleteIncidents(dispatch, {dateRange, incidentsToDelete, memberId})
|
||||||
updateIncidentsById: (dateRange, updatedIncidentsData, memberId) => updateIncidentFees(dispatch, {dateRange, updatedIncidentsData, memberId})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(null, mapDispatchToProps)(SingleIncidentsTable);
|
export default connect(null, mapDispatchToProps)(SingleIncidentsTable);
|
||||||
|
|||||||
@@ -103,21 +103,6 @@ export const deleteIncidents = (dispatch, deleteData) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateIncidentFees = (dispatch, updateData) => {
|
|
||||||
const pendingAction = updateData.memberId ? FETCH_MEMBER_INCIDENTS_PENDING : FETCH_INCIDENTS_PENDING;
|
|
||||||
const successAction = updateData.memberId ? FETCH_MEMBER_INCIDENTS_SUCCESS : FETCH_INCIDENTS_SUCCESS;
|
|
||||||
const failedAction = updateData.memberId ? FETCH_MEMBER_INCIDENTS_FAILED : FETCH_INCIDENTS_FAILED;
|
|
||||||
|
|
||||||
dispatch({type: pendingAction});
|
|
||||||
API.patch(`/integration/fees`, updateData)
|
|
||||||
.then(response => {
|
|
||||||
dispatch({type: successAction, payload: response.data});
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
dispatch({type: failedAction, payload: error.response});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const fetchMembersList = (dispatch) => {
|
export const fetchMembersList = (dispatch) => {
|
||||||
dispatch({type: FETCH_MEMBERS_PENDING});
|
dispatch({type: FETCH_MEMBERS_PENDING});
|
||||||
API.get('officeRnD/membersList')
|
API.get('officeRnD/membersList')
|
||||||
|
|||||||
@@ -2,25 +2,15 @@
|
|||||||
|
|
||||||
const moment = require('moment-timezone');
|
const moment = require('moment-timezone');
|
||||||
|
|
||||||
const {
|
const { getMappingsFromDatabase, fetchOffices, fetchResources, saveNewMappingToDatabase, deleteMappingById, updateMappingById } = require('../services/officeRnD/resources');
|
||||||
getMappingsFromDatabase,
|
|
||||||
fetchOffices,
|
|
||||||
fetchResources,
|
|
||||||
saveNewMappingToDatabase,
|
|
||||||
deleteMappingById,
|
|
||||||
updateMappingById } = require('../services/officeRnD/resources');
|
|
||||||
const { getAllIncidents, getMemberPracticeSummaryReport } = require('../services/integration/reports');
|
const { getAllIncidents, getMemberPracticeSummaryReport } = require('../services/integration/reports');
|
||||||
const { getMembersFeesForDateRange } = require('../services/integration/invoiceIntegration');
|
const { getMembersFeesForDateRange } = require('../services/integration/invoiceIntegration');
|
||||||
const { deleteFeesFromORD, addFeesToORD } = require('../services/officeRnD/fees');
|
const { deleteFeesFromORD, addFeesToORD } = require('../services/officeRnD/fees');
|
||||||
const { reformatMembershipsName } = require('../services/officeRnD/memberships');
|
const { reformatMembershipsName } = require('../services/officeRnD/memberships');
|
||||||
const { checkBookingChanges } = require('../services/integration/checkBookingChange');
|
const { checkBookingChanges } = require('../services/integration/checkBookingChange');
|
||||||
const { checkIfProcessing } = require('../services/integration/processingStatus');
|
const { checkIfProcessing } = require('../services/integration/processingStatus');
|
||||||
const {
|
const { deleteUnlockedIncidentsById, deleteUnscheduledIncidentsById } = require('../services/integration/doorLockCharges');
|
||||||
deleteUnlockedIncidentsById,
|
const { deleteBookingChangeIncidentsById } = require('../services/integration/bookingChangeCharges');
|
||||||
deleteUnscheduledIncidentsById,
|
|
||||||
updateUnscheduledIncidentsById,
|
|
||||||
updateUnlockedIncidentsById } = require('../services/integration/doorLockCharges');
|
|
||||||
const { deleteBookingChangeIncidentsById, updateBookingChangeIncidentsById } = require('../services/integration/bookingChangeCharges');
|
|
||||||
|
|
||||||
const { UI_TIMEZONE, DEFAULT_DATE_FORMAT, ALLOW_SENDING_FEES, integrationServiceErrors } = require('../constants/constants');
|
const { UI_TIMEZONE, DEFAULT_DATE_FORMAT, ALLOW_SENDING_FEES, integrationServiceErrors } = require('../constants/constants');
|
||||||
|
|
||||||
@@ -187,7 +177,7 @@ const addFees = (req, res) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteFees = (req, res) => {
|
const deleteFees= (req, res) => {
|
||||||
const deleteData = req.body;
|
const deleteData = req.body;
|
||||||
const dateRange = deleteData.dateRange ? deleteData.dateRange : null;
|
const dateRange = deleteData.dateRange ? deleteData.dateRange : null;
|
||||||
const incidents = deleteData.incidentsToDelete ? deleteData.incidentsToDelete : null;
|
const incidents = deleteData.incidentsToDelete ? deleteData.incidentsToDelete : null;
|
||||||
@@ -230,49 +220,6 @@ const deleteFees = (req, res) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateFees = (req, res) => {
|
|
||||||
const updateData = req.body;
|
|
||||||
const dateRange = updateData.dateRange ? updateData.dateRange : null;
|
|
||||||
const incidents = updateData.updatedIncidentsData ? updateData.updatedIncidentsData : null;
|
|
||||||
const memberId = updateData.memberId ? updateData.memberId : null;
|
|
||||||
|
|
||||||
const unlockedIncidentFees = incidents.unlockedIncidentFees ? incidents.unlockedIncidentFees : {};
|
|
||||||
const unscheduledIncidentFees = incidents.unscheduledIncidentFees ? incidents.unscheduledIncidentFees : {};
|
|
||||||
const bookingChangeIncidentFees = incidents.bookingChangeIncidentFees ? incidents.bookingChangeIncidentFees : {};
|
|
||||||
|
|
||||||
req.params.startDate = dateRange.startDate ? dateRange.startDate : null;
|
|
||||||
req.params.endDate = dateRange.endDate ? dateRange.endDate : null;
|
|
||||||
|
|
||||||
if (unlockedIncidentFees && unscheduledIncidentFees && bookingChangeIncidentFees){
|
|
||||||
const asyncUpdateActions = [
|
|
||||||
updateUnlockedIncidentsById(unlockedIncidentFees),
|
|
||||||
updateUnscheduledIncidentsById(unscheduledIncidentFees),
|
|
||||||
updateBookingChangeIncidentsById(bookingChangeIncidentFees)
|
|
||||||
];
|
|
||||||
|
|
||||||
Promise.all(asyncUpdateActions)
|
|
||||||
.then(() => {
|
|
||||||
if (memberId){
|
|
||||||
req.params.memberId = memberId;
|
|
||||||
getMemberIncidents(req, res);
|
|
||||||
}else{
|
|
||||||
getAllIncidentsController(req, res);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log('Error updating incidents : ', error);
|
|
||||||
res.status(500).send();
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
if (memberId){
|
|
||||||
req.params.memberId = memberId;
|
|
||||||
getMemberIncidents(req, res);
|
|
||||||
}else{
|
|
||||||
getAllIncidentsController(req, res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkProcessingStatus = (req, res) => {
|
const checkProcessingStatus = (req, res) => {
|
||||||
checkIfProcessing()
|
checkIfProcessing()
|
||||||
.then((processing) => {
|
.then((processing) => {
|
||||||
@@ -325,6 +272,5 @@ module.exports = {
|
|||||||
addFees,
|
addFees,
|
||||||
checkProcessingStatus,
|
checkProcessingStatus,
|
||||||
getPracticeSummaryReport,
|
getPracticeSummaryReport,
|
||||||
deleteFees,
|
deleteFees
|
||||||
updateFees
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ const {
|
|||||||
addFees,
|
addFees,
|
||||||
checkProcessingStatus,
|
checkProcessingStatus,
|
||||||
getPracticeSummaryReport,
|
getPracticeSummaryReport,
|
||||||
deleteFees,
|
deleteFees
|
||||||
updateFees
|
|
||||||
} = require('../controllers/integration');
|
} = require('../controllers/integration');
|
||||||
|
|
||||||
const { calculateDoorLockCharges } = require('../services/integration/doorLockCharges');
|
const { calculateDoorLockCharges } = require('../services/integration/doorLockCharges');
|
||||||
@@ -37,7 +36,6 @@ router.get('/officeRnD/membersList', fetchMembersList);
|
|||||||
|
|
||||||
router.post('/integration/addFees', addFees);
|
router.post('/integration/addFees', addFees);
|
||||||
router.delete('/integration/fees', deleteFees);
|
router.delete('/integration/fees', deleteFees);
|
||||||
router.patch('/integration/fees', updateFees);
|
|
||||||
|
|
||||||
router.get('/integration/processing', checkProcessingStatus);
|
router.get('/integration/processing', checkProcessingStatus);
|
||||||
|
|
||||||
@@ -46,14 +44,6 @@ router.get('/integration/report/practiceSummary/:year', getPracticeSummaryReport
|
|||||||
|
|
||||||
|
|
||||||
// temporary route, manually trigger door lock charge calculations
|
// temporary route, manually trigger door lock charge calculations
|
||||||
router.get('/calculate', (req, res) => {
|
router.get('/calculate', (req, res) => { calculateDoorLockCharges(); res.send();});
|
||||||
calculateDoorLockCharges()
|
|
||||||
.then(() => {
|
|
||||||
res.send('Done');
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
res.send(`Error \r\n ${err}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const {
|
|||||||
|
|
||||||
const { fetchAllMembers } = require('../officeRnD/members');
|
const { fetchAllMembers } = require('../officeRnD/members');
|
||||||
const { getMappingsFromDatabase } = require('../officeRnD/resources');
|
const { getMappingsFromDatabase } = require('../officeRnD/resources');
|
||||||
const { getFirstReservationInBlock, getFirstPreviousBooking } = require('../officeRnD/bookings');
|
const { getFirstReservationInBlock } = require('../officeRnD/bookings');
|
||||||
|
|
||||||
const extractMappingFromFileName = (fileName) => {
|
const extractMappingFromFileName = (fileName) => {
|
||||||
const contentBetweenBracketsRegex = /\[(.*?)\]/;
|
const contentBetweenBracketsRegex = /\[(.*?)\]/;
|
||||||
@@ -196,12 +196,12 @@ const getUnlockEntryForReservation = (reservation, previousReservation) => {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const { memberId, resourceId } = reservation;
|
const { memberId, resourceId } = reservation;
|
||||||
|
|
||||||
const previousReservationEndMoment = previousReservation && previousReservation.end ?
|
const previousReservationStartMoment = previousReservation && previousReservation.start ?
|
||||||
moment.utc(previousReservation.end) : null;
|
moment.utc(previousReservation.start) : null;
|
||||||
const reservationStartMoment = moment.utc(reservation.start);
|
const reservationStartMoment = moment.utc(reservation.start);
|
||||||
|
|
||||||
const fromTimestamp = previousReservationEndMoment && previousReservationEndMoment.tz(UI_TIMEZONE).isSame(reservationStartMoment.tz(UI_TIMEZONE), 'day') ?
|
const fromTimestamp = previousReservationStartMoment && previousReservationStartMoment.tz(UI_TIMEZONE).isSame(reservationStartMoment.tz(UI_TIMEZONE), 'day') ?
|
||||||
previousReservation.end : reservationStartMoment.tz(UI_TIMEZONE).startOf('day').toISOString();
|
previousReservation.start : reservationStartMoment.tz(UI_TIMEZONE).startOf('day').toISOString();
|
||||||
|
|
||||||
const toTimestamp = reservation.end;
|
const toTimestamp = reservation.end;
|
||||||
|
|
||||||
@@ -314,13 +314,13 @@ const getLockEntryForReservation = (reservation, nextReservation) => {
|
|||||||
|
|
||||||
const attributes = ['memberName', 'event', 'timestamp'];
|
const attributes = ['memberName', 'event', 'timestamp'];
|
||||||
|
|
||||||
const nextReservationStartMoment = nextReservation && nextReservation.start ?
|
const nextReservationEndMoment = nextReservation && nextReservation.end ?
|
||||||
moment.utc(nextReservation.start) : null;
|
moment.utc(nextReservation.end) : null;
|
||||||
const reservationStartMoment = moment.utc(reservation.start);
|
const reservationStartMoment = moment.utc(reservation.start);
|
||||||
|
|
||||||
const fromTimestamp = reservation.start;
|
const fromTimestamp = reservation.start;
|
||||||
const toTimestamp = nextReservationStartMoment && nextReservationStartMoment.tz(UI_TIMEZONE).isSame(reservationStartMoment.tz(UI_TIMEZONE), 'day') ?
|
const toTimestamp = nextReservationEndMoment && nextReservationEndMoment.tz(UI_TIMEZONE).isSame(reservationStartMoment.tz(UI_TIMEZONE), 'day') ?
|
||||||
nextReservation.start : reservationStartMoment.tz(UI_TIMEZONE).endOf('day').toISOString();
|
nextReservation.end : reservationStartMoment.tz(UI_TIMEZONE).endOf('day').toISOString();
|
||||||
|
|
||||||
const filters = {
|
const filters = {
|
||||||
memberId,
|
memberId,
|
||||||
@@ -425,25 +425,11 @@ const getLastEntryForReservation = (reservation) => {
|
|||||||
const order = [['timestamp', 'DESC']];
|
const order = [['timestamp', 'DESC']];
|
||||||
|
|
||||||
db.doorLockEvent.findAll({where: filters, order})
|
db.doorLockEvent.findAll({where: filters, order})
|
||||||
.then(async(entries) => {
|
.then((entries) => {
|
||||||
if (entries && entries.length > 0){
|
if (entries && entries.length > 0){
|
||||||
resolve(entries[0]);
|
resolve(entries[0]);
|
||||||
} else {
|
} else {
|
||||||
//No entry found in this block of reservations, now check if there is unlock entry for the first reservation in block, before reservation start time
|
resolve (undefined);
|
||||||
|
|
||||||
try {
|
|
||||||
const firstPreviousBookingBeforeFirstInBlock = await getFirstPreviousBooking(firstReservationInBlock);
|
|
||||||
const unlockEntryForFirstInBlock = await getUnlockEntryForReservation(firstReservationInBlock, firstPreviousBookingBeforeFirstInBlock);
|
|
||||||
|
|
||||||
if (unlockEntryForFirstInBlock){
|
|
||||||
resolve(unlockEntryForFirstInBlock);
|
|
||||||
}else{
|
|
||||||
resolve(undefined);
|
|
||||||
}
|
|
||||||
|
|
||||||
}catch (e) {
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => reject(error));
|
.catch((error) => reject(error));
|
||||||
|
|||||||
@@ -283,22 +283,6 @@ const deleteBookingChangeIncidentsById = (incidentIds) => {
|
|||||||
return db.bookingChangeIncident.update({deleted: true},{where: filters});
|
return db.bookingChangeIncident.update({deleted: true},{where: filters});
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateBookingChangeIncidentsById = (incidentFees) => {
|
|
||||||
const incidentIds = Object.keys(incidentFees);
|
|
||||||
|
|
||||||
const asyncUpdateActions = [];
|
|
||||||
|
|
||||||
incidentIds.forEach((incidentId) => {
|
|
||||||
const newFeeCharge = parseFloat(incidentFees[incidentId]);
|
|
||||||
|
|
||||||
if (newFeeCharge || (newFeeCharge === 0)){
|
|
||||||
asyncUpdateActions.push(db.bookingChangeIncident.update({chargeFee: newFeeCharge}, {where: {id: incidentId}}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return Promise.all(asyncUpdateActions);
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getChargedCanceledReservations,
|
getChargedCanceledReservations,
|
||||||
getIncidentsFromChanges,
|
getIncidentsFromChanges,
|
||||||
@@ -306,6 +290,5 @@ module.exports = {
|
|||||||
getShorteningIncidentsForReservationId,
|
getShorteningIncidentsForReservationId,
|
||||||
getReservationsIncidentsForRemoval,
|
getReservationsIncidentsForRemoval,
|
||||||
deleteBookingChangeIncidents,
|
deleteBookingChangeIncidents,
|
||||||
deleteBookingChangeIncidentsById,
|
deleteBookingChangeIncidentsById
|
||||||
updateBookingChangeIncidentsById
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const {
|
|||||||
UI_TIMEZONE
|
UI_TIMEZONE
|
||||||
} = require('../../constants/constants');
|
} = require('../../constants/constants');
|
||||||
const { getUnlockEntryForReservation, getLockEntryForReservation, getEntriesBetween, getLastEntryForReservation } = require('../doorLock/doorLock');
|
const { getUnlockEntryForReservation, getLockEntryForReservation, getEntriesBetween, getLastEntryForReservation } = require('../doorLock/doorLock');
|
||||||
const { getAllFinishedBookings, getFirstPreviousBooking, getFirstNextBooking, getLastReservationInBlock } = require('../officeRnD/bookings');
|
const { getAllFinishedBookings, getFirstPreviousBooking, getFirstNextBooking } = require('../officeRnD/bookings');
|
||||||
|
|
||||||
const getSortedIncidentsForMember = (memberId) => {
|
const getSortedIncidentsForMember = (memberId) => {
|
||||||
const attributes = ['bookingStart', 'incidentLevel', 'incidentLevelPrice', 'unlockTimestamp'];
|
const attributes = ['bookingStart', 'incidentLevel', 'incidentLevelPrice', 'unlockTimestamp'];
|
||||||
@@ -80,26 +80,6 @@ const deleteUnscheduledIncidentsById = (incidentIds) => {
|
|||||||
return db.unscheduledIncident.update({deleted: true},{where: filters});
|
return db.unscheduledIncident.update({deleted: true},{where: filters});
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateUnscheduledIncidentsById = (incidentFees) => {
|
|
||||||
const incidentIds = Object.keys(incidentFees);
|
|
||||||
|
|
||||||
const asyncUpdateActions = [];
|
|
||||||
|
|
||||||
incidentIds.forEach((incidentId) => {
|
|
||||||
const newFeeCharge = parseFloat(incidentFees[incidentId]);
|
|
||||||
|
|
||||||
if (newFeeCharge || (newFeeCharge === 0)){
|
|
||||||
asyncUpdateActions.push(db.unscheduledIncident.update({
|
|
||||||
totalChargeFee: newFeeCharge,
|
|
||||||
chargePrice: newFeeCharge,
|
|
||||||
timeIntervalsToCharge: 1
|
|
||||||
}, {where: {id: incidentId}}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return Promise.all(asyncUpdateActions);
|
|
||||||
};
|
|
||||||
|
|
||||||
const insertUnlockedIncidents = (incidents) => {
|
const insertUnlockedIncidents = (incidents) => {
|
||||||
const asyncJobs = [];
|
const asyncJobs = [];
|
||||||
incidents.forEach((incident) => {
|
incidents.forEach((incident) => {
|
||||||
@@ -126,6 +106,7 @@ const insertUnlockedIncidents = (incidents) => {
|
|||||||
bookingStart: start,
|
bookingStart: start,
|
||||||
bookingEnd: end,
|
bookingEnd: end,
|
||||||
unlockTimestamp,
|
unlockTimestamp,
|
||||||
|
incidentLevel,
|
||||||
},
|
},
|
||||||
defaults: {...incidentForDB},
|
defaults: {...incidentForDB},
|
||||||
}));
|
}));
|
||||||
@@ -143,22 +124,6 @@ const deleteUnlockedIncidentsById = (incidentIds) => {
|
|||||||
return db.unlockedIncident.update({deleted: true},{where: filters});
|
return db.unlockedIncident.update({deleted: true},{where: filters});
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateUnlockedIncidentsById = (incidentFees) => {
|
|
||||||
const incidentIds = Object.keys(incidentFees);
|
|
||||||
|
|
||||||
const asyncUpdateActions = [];
|
|
||||||
|
|
||||||
incidentIds.forEach((incidentId) => {
|
|
||||||
const newFeeCharge = parseFloat(incidentFees[incidentId]);
|
|
||||||
|
|
||||||
if (newFeeCharge || (newFeeCharge === 0)){
|
|
||||||
asyncUpdateActions.push(db.unlockedIncident.update({incidentLevelPrice: newFeeCharge}, {where: {id: incidentId}}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return Promise.all(asyncUpdateActions);
|
|
||||||
};
|
|
||||||
|
|
||||||
const setUnlockedIncidentsLevel = (incidents) => {
|
const setUnlockedIncidentsLevel = (incidents) => {
|
||||||
return new Promise ((resolve, reject) => {
|
return new Promise ((resolve, reject) => {
|
||||||
const sortingFunction = (incidentA, incidentB) => {
|
const sortingFunction = (incidentA, incidentB) => {
|
||||||
@@ -197,7 +162,7 @@ const setUnlockedIncidentsLevel = (incidents) => {
|
|||||||
const incidentsWithLevel = [];
|
const incidentsWithLevel = [];
|
||||||
|
|
||||||
incidents.forEach((incident) => {
|
incidents.forEach((incident) => {
|
||||||
const memberLastIncident = Object.assign({}, membersLastIncident[incident.memberId]);
|
const memberLastIncident = membersLastIncident[incident.memberId];
|
||||||
|
|
||||||
const formattedIncident = {
|
const formattedIncident = {
|
||||||
reservation: incident.reservation,
|
reservation: incident.reservation,
|
||||||
@@ -403,7 +368,10 @@ const getIncidentData = (reservation) => {
|
|||||||
const { resourceId } = currentReservation;
|
const { resourceId } = currentReservation;
|
||||||
|
|
||||||
// const reservationMoment = moment.tz(currentReservation.start, currentReservation.timezone);
|
// const reservationMoment = moment.tz(currentReservation.start, currentReservation.timezone);
|
||||||
// if (currentReservation.memberId === '5d240cd34a3efa00882d9526') {
|
// if (currentReservation.memberId === '5ce785af422bdd00967fb781' &&
|
||||||
|
// reservationMoment.isAfter('2019-12-11 00:00:16+00') &&
|
||||||
|
// reservationMoment.isBefore('2019-12-12 23:59:59')
|
||||||
|
// ) {
|
||||||
// console.log('\r\n\r\n==== ANALYSE RESERVATION [GET INCIDENT DATA] ==== ');
|
// console.log('\r\n\r\n==== ANALYSE RESERVATION [GET INCIDENT DATA] ==== ');
|
||||||
// console.log('\tStart : ', reservationMoment.format('DD.MM, HH:mm'));
|
// console.log('\tStart : ', reservationMoment.format('DD.MM, HH:mm'));
|
||||||
// console.log('\tEnd : ', moment.tz(currentReservation.end, currentReservation.timezone).format('DD.MM, HH:mm'));
|
// console.log('\tEnd : ', moment.tz(currentReservation.end, currentReservation.timezone).format('DD.MM, HH:mm'));
|
||||||
@@ -509,89 +477,7 @@ const getIncidentData = (reservation) => {
|
|||||||
// console.log('\tThere is res after : ', nextReservationIsBackToBack);
|
// console.log('\tThere is res after : ', nextReservationIsBackToBack);
|
||||||
// }
|
// }
|
||||||
let forgotToLockAsyncCheck;
|
let forgotToLockAsyncCheck;
|
||||||
let asyncUnscheduledUseTest = [];
|
|
||||||
if (!lockEntry && !nextReservationIsBackToBack){
|
if (!lockEntry && !nextReservationIsBackToBack){
|
||||||
|
|
||||||
// Special check
|
|
||||||
|
|
||||||
const checkForUnscheduledUseInBrakeBetweenReservations = async () => {
|
|
||||||
try {
|
|
||||||
if (nextReservation) {
|
|
||||||
const lastReservationInBlockAfterBrake = await getLastReservationInBlock(nextReservation);
|
|
||||||
|
|
||||||
const fromTimestamp = nextReservation.start;
|
|
||||||
const toTimestamp = lastReservationInBlockAfterBrake.end;
|
|
||||||
|
|
||||||
const entriesInBlock = await getEntriesBetween(fromTimestamp, toTimestamp, reservation.resourceId);
|
|
||||||
|
|
||||||
// const reservationMoment = moment.tz(reservation.start, reservation.timezone);
|
|
||||||
// if (reservation.memberId === '5d240cd34a3efa00882d9526') {
|
|
||||||
// console.log('\r\n\r\n==== ANALYSE RESERVATION [GET INCIDENT DATA] ==== ');
|
|
||||||
// console.log('\tStart : ', reservationMoment.format('DD.MM, HH:mm'));
|
|
||||||
// console.log('\tEnd : ', moment.tz(reservation.end, reservation.timezone).format('DD.MM, HH:mm'));
|
|
||||||
// console.log('\t----------------------------------');
|
|
||||||
// console.log('\tLast reservation in block after brake :');
|
|
||||||
// console.log('\t\tStart : ', moment.tz(lastReservationInBlockAfterBrake.start, UI_TIMEZONE).format('DD.MM, HH:mm'));
|
|
||||||
// console.log('\t\tEnd : ', moment.tz(lastReservationInBlockAfterBrake.end, UI_TIMEZONE).format('DD.MM, HH:mm'));
|
|
||||||
// console.log('\tSearch entries : ');
|
|
||||||
// console.log('\t\tFrom :', moment.tz(fromTimestamp, UI_TIMEZONE).format('DD.MM, HH:mm'));
|
|
||||||
// console.log('\t\tTo :', moment.tz(toTimestamp, UI_TIMEZONE).format('DD.MM, HH:mm'));
|
|
||||||
// console.log('\tFirst entry : ');
|
|
||||||
// }
|
|
||||||
|
|
||||||
const addStandaloneUnscheduledIncident = () => {
|
|
||||||
|
|
||||||
const unlockMoment = reservation.end ? moment.utc(reservation.end) : null;
|
|
||||||
const lockMoment = nextReservation.start ? moment.utc(nextReservation.start) : null;
|
|
||||||
|
|
||||||
if (unlockMoment && lockMoment) {
|
|
||||||
const timeDifference = lockMoment.diff(unlockMoment, 'minutes');
|
|
||||||
const timeIntervalsToCharge = Math.floor(timeDifference / UNSCHEDULED_TIME_RESOLUTION);
|
|
||||||
const totalChargeFee = timeIntervalsToCharge * UNSCHEDULED_CHARGE_PRICE;
|
|
||||||
if (timeIntervalsToCharge > 0) {
|
|
||||||
incidents.push({
|
|
||||||
incidentType: incidentType.UNSCHEDULED_INCIDENT_STANDALONE,
|
|
||||||
reservation: emptyReservation,
|
|
||||||
unlockTimestamp: reservation.end,
|
|
||||||
lockTimestamp: nextReservation.start,
|
|
||||||
memberId: reservation.memberId,
|
|
||||||
resourceId: reservation.resourceId,
|
|
||||||
chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
|
||||||
timeIntervalsToCharge,
|
|
||||||
totalChargeFee,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (Array.isArray(entriesInBlock) && entriesInBlock.length > 0) {
|
|
||||||
const firstEntry = entriesInBlock[0];
|
|
||||||
// console.log('\t\tTimestamp : ', moment.tz(firstEntry.timestamp, UI_TIMEZONE).format('DD.MM, HH:mm'));
|
|
||||||
// console.log('\t\tEvent : ', firstEntry.event);
|
|
||||||
if (firstEntry && firstEntry.event &&
|
|
||||||
firstEntry.memberId === reservation.memberId &&
|
|
||||||
firstEntry.event === doorLockEvents.USER_LOCKED) {
|
|
||||||
|
|
||||||
addStandaloneUnscheduledIncident();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const reservationAfterLastReservationInBlock = await getFirstNextBooking(nextReservation);
|
|
||||||
|
|
||||||
if (reservationAfterLastReservationInBlock) {
|
|
||||||
const lastReservationLockEntry = await getLockEntryForReservation(lastReservationInBlockAfterBrake, reservationAfterLastReservationInBlock);
|
|
||||||
if (lastReservationLockEntry) {
|
|
||||||
addStandaloneUnscheduledIncident();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}catch (e) {
|
|
||||||
console.log('ERROR while checking for unscheduled use in brake between reservations ');
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
if (unlockEntry){
|
if (unlockEntry){
|
||||||
// if (currentReservation.memberId === '5ce785af422bdd00967fb781' && reservationMoment.isAfter('2019-12-01 00:00:16+00')) {
|
// if (currentReservation.memberId === '5ce785af422bdd00967fb781' && reservationMoment.isAfter('2019-12-01 00:00:16+00')) {
|
||||||
// console.log('\tIncident : YES [#1]');
|
// console.log('\tIncident : YES [#1]');
|
||||||
@@ -603,8 +489,6 @@ const getIncidentData = (reservation) => {
|
|||||||
resourceId: unlockEntry.resourceId,
|
resourceId: unlockEntry.resourceId,
|
||||||
reservation: reservation && reservation.dataValues ? reservation.dataValues : emptyReservation,
|
reservation: reservation && reservation.dataValues ? reservation.dataValues : emptyReservation,
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncUnscheduledUseTest.push(checkForUnscheduledUseInBrakeBetweenReservations());
|
|
||||||
} 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
|
||||||
// This is either :
|
// This is either :
|
||||||
@@ -620,18 +504,17 @@ const getIncidentData = (reservation) => {
|
|||||||
forgotToLockAsyncCheck = getLastEntryForReservation(reservation);
|
forgotToLockAsyncCheck = getLastEntryForReservation(reservation);
|
||||||
forgotToLockAsyncCheck
|
forgotToLockAsyncCheck
|
||||||
.then((lastEntry) => {
|
.then((lastEntry) => {
|
||||||
if (lastEntry) {
|
if (lastEntry && lastEntry.event === doorLockEvents.USER_UNLOCKED){
|
||||||
if (lastEntry && lastEntry.event === doorLockEvents.USER_UNLOCKED) {
|
// if (currentReservation.memberId === '5ce785af422bdd00967fb781' && reservationMoment.isAfter('2019-12-01 00:00:16+00')) {
|
||||||
incidents.push({
|
// console.log('\tIncident : YES [#2]');
|
||||||
incidentType: incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION,
|
// }
|
||||||
unlockTimestamp: lastEntry.timestamp,
|
incidents.push({
|
||||||
memberId: lastEntry.memberId,
|
incidentType: incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION,
|
||||||
resourceId: lastEntry.resourceId,
|
unlockTimestamp: lastEntry.timestamp,
|
||||||
reservation: reservation && reservation.dataValues ? reservation.dataValues : emptyReservation,
|
memberId: lastEntry.memberId,
|
||||||
});
|
resourceId: lastEntry.resourceId,
|
||||||
|
reservation: reservation && reservation.dataValues ? reservation.dataValues : emptyReservation,
|
||||||
asyncUnscheduledUseTest.push(checkForUnscheduledUseInBrakeBetweenReservations());
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => reject(error));
|
.catch((error) => reject(error));
|
||||||
@@ -659,36 +542,35 @@ const getIncidentData = (reservation) => {
|
|||||||
const previousReservationUnlockEntry = previousReservationResults.unlockEntry;
|
const previousReservationUnlockEntry = previousReservationResults.unlockEntry;
|
||||||
|
|
||||||
//Special check for bookings with break between
|
//Special check for bookings with break between
|
||||||
// Check this for duplication, previous special check in step 3. can catch this scenario
|
if (previousReservation &&
|
||||||
// if (previousReservation &&
|
!previousReservationIsBackToBack &&
|
||||||
// !previousReservationIsBackToBack &&
|
previousReservation.memberId === currentReservation.memberId &&
|
||||||
// previousReservation.memberId === currentReservation.memberId &&
|
previousReservationUnlockEntry && !previousReservationLockEntry &&
|
||||||
// previousReservationUnlockEntry && !previousReservationLockEntry &&
|
!unlockEntry && lockEntry //current reservation unlock / lock entries
|
||||||
// !unlockEntry && lockEntry //current reservation unlock / lock entries
|
) {
|
||||||
// ) {
|
|
||||||
//
|
const unlockMoment = previousReservation.end ? moment.utc(previousReservation.end) : null;
|
||||||
// const unlockMoment = previousReservation.end ? moment.utc(previousReservation.end) : null;
|
const lockMoment = currentReservation.start ? moment.utc(currentReservation.start) : null;
|
||||||
// const lockMoment = currentReservation.start ? moment.utc(currentReservation.start) : null;
|
|
||||||
//
|
if (unlockMoment && lockMoment){
|
||||||
// if (unlockMoment && lockMoment){
|
const timeDifference = lockMoment.diff(unlockMoment, 'minutes');
|
||||||
// const timeDifference = lockMoment.diff(unlockMoment, 'minutes');
|
const timeIntervalsToCharge = Math.floor(timeDifference / UNSCHEDULED_TIME_RESOLUTION);
|
||||||
// const timeIntervalsToCharge = Math.floor(timeDifference / UNSCHEDULED_TIME_RESOLUTION);
|
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_STANDALONE,
|
||||||
// incidentType: incidentType.UNSCHEDULED_INCIDENT_STANDALONE,
|
reservation: emptyReservation,
|
||||||
// reservation: emptyReservation,
|
unlockTimestamp: previousReservation.end,
|
||||||
// unlockTimestamp: previousReservation.end,
|
lockTimestamp: currentReservation.start,
|
||||||
// lockTimestamp: currentReservation.start,
|
memberId: currentReservation.memberId,
|
||||||
// memberId: currentReservation.memberId,
|
resourceId,
|
||||||
// resourceId,
|
chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
||||||
// chargePrice: UNSCHEDULED_CHARGE_PRICE,
|
timeIntervalsToCharge,
|
||||||
// timeIntervalsToCharge,
|
totalChargeFee,
|
||||||
// totalChargeFee,
|
});
|
||||||
// });
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
fromTimestamp = previousReservationLockEntry && previousReservationLockEntry.timestamp ?
|
fromTimestamp = previousReservationLockEntry && previousReservationLockEntry.timestamp ?
|
||||||
previousReservationLockEntry.timestamp : previousReservation.end;
|
previousReservationLockEntry.timestamp : previousReservation.end;
|
||||||
@@ -709,7 +591,7 @@ const getIncidentData = (reservation) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Now wait for "forgotToLockAsyncCheck", and possible "getEntriesBetween" to finish
|
//Now wait for "forgotToLockAsyncCheck", and possible "getEntriesBetween" to finish
|
||||||
Promise.all([forgotToLockAsyncCheck, getEntriesAsyncCheck, asyncUnscheduledUseTest])
|
Promise.all([forgotToLockAsyncCheck, getEntriesAsyncCheck])
|
||||||
.then((asyncActionResults) => {
|
.then((asyncActionResults) => {
|
||||||
const entriesBetween = asyncActionResults[1];
|
const entriesBetween = asyncActionResults[1];
|
||||||
if (Array.isArray(entriesBetween)){
|
if (Array.isArray(entriesBetween)){
|
||||||
@@ -885,7 +767,5 @@ const calculateDoorLockCharges = () => {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
calculateDoorLockCharges,
|
calculateDoorLockCharges,
|
||||||
deleteUnlockedIncidentsById,
|
deleteUnlockedIncidentsById,
|
||||||
deleteUnscheduledIncidentsById,
|
deleteUnscheduledIncidentsById
|
||||||
updateUnlockedIncidentsById,
|
|
||||||
updateUnscheduledIncidentsById
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const Op = require('sequelize').Op;
|
|||||||
|
|
||||||
const workbookCreator = require('excel4node');
|
const workbookCreator = require('excel4node');
|
||||||
|
|
||||||
|
const { checkBookingChanges } = require('./checkBookingChange');
|
||||||
const { incidentType, UI_TIMEZONE, DEFAULT_DATE_FORMAT, integrationServiceErrors } = require('../../constants/constants');
|
const { incidentType, UI_TIMEZONE, DEFAULT_DATE_FORMAT, integrationServiceErrors } = require('../../constants/constants');
|
||||||
|
|
||||||
const { getAllBookingsForMembersInDateRange } = require('./bookings');
|
const { getAllBookingsForMembersInDateRange } = require('./bookings');
|
||||||
@@ -221,29 +222,19 @@ const getAllIncidents = (dateRange, memberIds) => {
|
|||||||
unlockedIncidents.forEach((unlockedIncident) => {
|
unlockedIncidents.forEach((unlockedIncident) => {
|
||||||
const incidentTypeNumber = unlockedIncident.reservationId ?
|
const incidentTypeNumber = unlockedIncident.reservationId ?
|
||||||
incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION : incidentType.UNLOCKED_INCIDENT_STANDALONE;
|
incidentType.UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION : incidentType.UNLOCKED_INCIDENT_STANDALONE;
|
||||||
|
|
||||||
const resourceObject = resourcesMap[unlockedIncident.resourceId];
|
|
||||||
const officeObject = resourceObject ? officesMap[resourceObject.officeId] : null;
|
|
||||||
|
|
||||||
const memberName = membersMap[unlockedIncident.memberId] ? membersMap[unlockedIncident.memberId].name : 'Unknown member';
|
|
||||||
const resourceName = resourceObject ? resourceObject.resourceName : 'Unknown room';
|
|
||||||
const officeId = resourceObject ? resourceObject.officeId : '';
|
|
||||||
const officeName = officeObject ? officeObject.officeName : 'Unknown office';
|
|
||||||
const officeSlug = officeObject ? officeObject.officeSlug : '-';
|
|
||||||
|
|
||||||
allIncidents.push({
|
allIncidents.push({
|
||||||
incidentId: unlockedIncident.id,
|
incidentId: unlockedIncident.id,
|
||||||
memberId: unlockedIncident.memberId,
|
memberId: unlockedIncident.memberId,
|
||||||
memberName,
|
memberName: membersMap[unlockedIncident.memberId].name,
|
||||||
resourceName,
|
resourceName: resourcesMap[unlockedIncident.resourceId].resourceName,
|
||||||
officeId,
|
officeId: resourcesMap[unlockedIncident.resourceId].officeId,
|
||||||
officeName,
|
officeName: officesMap[resourcesMap[unlockedIncident.resourceId].officeId].officeName,
|
||||||
officeSlug,
|
officeSlug: officesMap[resourcesMap[unlockedIncident.resourceId].officeId].officeSlug,
|
||||||
bookingStart: formatTime(unlockedIncident.bookingStart) || '-',
|
bookingStart: formatTime(unlockedIncident.bookingStart),
|
||||||
bookingEnd: formatTime(unlockedIncident.bookingEnd) || '-',
|
bookingEnd: formatTime(unlockedIncident.bookingEnd),
|
||||||
bookingStartRaw: unlockedIncident.bookingStart,
|
bookingStartRaw: unlockedIncident.bookingStart,
|
||||||
bookingEndRaw: unlockedIncident.bookingEnd,
|
bookingEndRaw: unlockedIncident.bookingEnd,
|
||||||
unlockTimestamp: formatTime(unlockedIncident.unlockTimestamp) || '-',
|
unlockTimestamp: formatTime(unlockedIncident.unlockTimestamp),
|
||||||
unlockTimestampRaw: unlockedIncident.unlockTimestamp,
|
unlockTimestampRaw: unlockedIncident.unlockTimestamp,
|
||||||
incidentType: incidentTypeNumber,
|
incidentType: incidentTypeNumber,
|
||||||
incidentLevel: unlockedIncident.incidentLevel,
|
incidentLevel: unlockedIncident.incidentLevel,
|
||||||
@@ -262,30 +253,20 @@ const getAllIncidents = (dateRange, memberIds) => {
|
|||||||
}else{
|
}else{
|
||||||
incidentTypeNumber = incidentType.UNSCHEDULED_INCIDENT_STANDALONE;
|
incidentTypeNumber = incidentType.UNSCHEDULED_INCIDENT_STANDALONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const resourceObject = resourcesMap[unscheduledIncident.resourceId];
|
|
||||||
const officeObject = resourceObject ? officesMap[resourceObject.officeId] : null;
|
|
||||||
|
|
||||||
const memberName = membersMap[unscheduledIncident.memberId] ? membersMap[unscheduledIncident.memberId].name : 'Unknown member';
|
|
||||||
const resourceName = resourceObject ? resourceObject.resourceName : 'Unknown room';
|
|
||||||
const officeId = resourceObject ? resourceObject.officeId : '';
|
|
||||||
const officeName = officeObject ? officeObject.officeName : 'Unknown office';
|
|
||||||
const officeSlug = officeObject ? officeObject.officeSlug : '-';
|
|
||||||
|
|
||||||
allIncidents.push({
|
allIncidents.push({
|
||||||
incidentId: unscheduledIncident.id,
|
incidentId: unscheduledIncident.id,
|
||||||
memberId: unscheduledIncident.memberId,
|
memberId: unscheduledIncident.memberId,
|
||||||
memberName,
|
memberName: membersMap[unscheduledIncident.memberId].name,
|
||||||
resourceName,
|
resourceName: resourcesMap[unscheduledIncident.resourceId].resourceName,
|
||||||
officeId,
|
officeId: resourcesMap[unscheduledIncident.resourceId].officeId,
|
||||||
officeName,
|
officeName: officesMap[resourcesMap[unscheduledIncident.resourceId].officeId].officeName,
|
||||||
officeSlug,
|
officeSlug: officesMap[resourcesMap[unscheduledIncident.resourceId].officeId].officeSlug,
|
||||||
bookingStart: formatTime(unscheduledIncident.bookingStart) || '-',
|
bookingStart: formatTime(unscheduledIncident.bookingStart),
|
||||||
bookingEnd: formatTime(unscheduledIncident.bookingEnd) || '-',
|
bookingEnd: formatTime(unscheduledIncident.bookingEnd),
|
||||||
bookingStartRaw: unscheduledIncident.bookingStart,
|
bookingStartRaw: unscheduledIncident.bookingStart,
|
||||||
bookingEndRaw: unscheduledIncident.bookingEnd,
|
bookingEndRaw: unscheduledIncident.bookingEnd,
|
||||||
unlockTimestamp: formatTime(unscheduledIncident.unlockTimestamp) || '-',
|
unlockTimestamp: formatTime(unscheduledIncident.unlockTimestamp),
|
||||||
lockTimestamp: formatTime(unscheduledIncident.lockTimestamp) || '-',
|
lockTimestamp: formatTime(unscheduledIncident.lockTimestamp),
|
||||||
unlockTimestampRaw: unscheduledIncident.unlockTimestamp,
|
unlockTimestampRaw: unscheduledIncident.unlockTimestamp,
|
||||||
lockTimestampRaw: unscheduledIncident.lockTimestamp,
|
lockTimestampRaw: unscheduledIncident.lockTimestamp,
|
||||||
incidentType: incidentTypeNumber,
|
incidentType: incidentTypeNumber,
|
||||||
@@ -310,14 +291,14 @@ const getAllIncidents = (dateRange, memberIds) => {
|
|||||||
deleted,
|
deleted,
|
||||||
createdAt,
|
createdAt,
|
||||||
} = bookingChangeIncident;
|
} = bookingChangeIncident;
|
||||||
const memberName = membersMap[memberId] ? membersMap[memberId].name : 'Unknown member';
|
const memberName = membersMap[memberId].name;
|
||||||
const oldResource = resourcesMap[oldResourceId];
|
const oldResource = resourcesMap[oldResourceId];
|
||||||
const newResource = newResourceId ? resourcesMap[newResourceId] : null;
|
const newResource = newResourceId ? resourcesMap[newResourceId] : null;
|
||||||
const oldResourceName = oldResource ? oldResource.resourceName : 'Unknown room';
|
const oldResourceName = oldResource.resourceName;
|
||||||
const newResourceName = newResource ? newResource.resourceName : null;
|
const newResourceName = newResource ? newResource.resourceName : null;
|
||||||
const officeId = oldResource ? oldResource.officeId : '';
|
const officeId = oldResource.officeId;
|
||||||
const officeName = officesMap[officeId] ? officesMap[officeId].officeName : 'Unknown office';
|
const officeName = officesMap[officeId].officeName;
|
||||||
const officeSlug = officesMap[officeId] ? officesMap[officeId].officeSlug : '-';
|
const officeSlug = officesMap[officeId].officeSlug;
|
||||||
allIncidents.push({
|
allIncidents.push({
|
||||||
incidentId: id,
|
incidentId: id,
|
||||||
memberId,
|
memberId,
|
||||||
@@ -327,10 +308,10 @@ const getAllIncidents = (dateRange, memberIds) => {
|
|||||||
officeId,
|
officeId,
|
||||||
officeName,
|
officeName,
|
||||||
officeSlug,
|
officeSlug,
|
||||||
oldBookingStart: formatTime(oldBookingStart) || '-',
|
oldBookingStart: formatTime(oldBookingStart),
|
||||||
oldBookingEnd: formatTime(oldBookingEnd) || '-',
|
oldBookingEnd: formatTime(oldBookingEnd),
|
||||||
newBookingStart: formatTime(newBookingStart) || '-',
|
newBookingStart: formatTime(newBookingStart),
|
||||||
newBookingEnd: formatTime(newBookingEnd) || '-',
|
newBookingEnd: formatTime(newBookingEnd),
|
||||||
oldBookingStartRaw: oldBookingStart,
|
oldBookingStartRaw: oldBookingStart,
|
||||||
oldBookingEndRaw: oldBookingEnd,
|
oldBookingEndRaw: oldBookingEnd,
|
||||||
newBookingStartRaw: newBookingStart,
|
newBookingStartRaw: newBookingStart,
|
||||||
@@ -338,7 +319,7 @@ const getAllIncidents = (dateRange, memberIds) => {
|
|||||||
incidentType,
|
incidentType,
|
||||||
totalChargeFee: chargeFee,
|
totalChargeFee: chargeFee,
|
||||||
deleted,
|
deleted,
|
||||||
incidentTimestamp: formatTime(createdAt) || '-',
|
incidentTimestamp: formatTime(createdAt),
|
||||||
incidentTimestampRaw: createdAt,
|
incidentTimestampRaw: createdAt,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -359,12 +340,12 @@ const getMemberPracticeSummaryReport = (year) => {
|
|||||||
endDate,
|
endDate,
|
||||||
};
|
};
|
||||||
|
|
||||||
const asyncJobs = [getAllBookingsForMembersInDateRange(dateRange), fetchAllMembers()];
|
const asyncJobs = [checkBookingChanges(), getAllBookingsForMembersInDateRange(dateRange), fetchAllMembers()];
|
||||||
|
|
||||||
Promise.all(asyncJobs)
|
Promise.all(asyncJobs)
|
||||||
.then((results) => {
|
.then((results) => {
|
||||||
const allBookings = results[0];
|
const allBookings = results[1];
|
||||||
const allMembers = results[1];
|
const allMembers = results[2];
|
||||||
|
|
||||||
const membersMap = {};
|
const membersMap = {};
|
||||||
|
|
||||||
@@ -413,7 +394,6 @@ const getMemberPracticeSummaryReport = (year) => {
|
|||||||
|
|
||||||
getChargedCanceledReservations(reservationIdsForAdditionalData)
|
getChargedCanceledReservations(reservationIdsForAdditionalData)
|
||||||
.then((incidents) => {
|
.then((incidents) => {
|
||||||
console.log('Charged canceled reservations ...');
|
|
||||||
incidents.forEach((incident) => {
|
incidents.forEach((incident) => {
|
||||||
const {memberId, oldBookingStart, oldBookingEnd} = incident.get();
|
const {memberId, oldBookingStart, oldBookingEnd} = incident.get();
|
||||||
|
|
||||||
|
|||||||
@@ -22,21 +22,6 @@ const fetchAllBookings = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const fees = fullBookingEntry.fees ? fullBookingEntry.fees : [];
|
const fees = fullBookingEntry.fees ? fullBookingEntry.fees : [];
|
||||||
const canceled = fullBookingEntry.canceled ? fullBookingEntry.canceled : false;
|
|
||||||
const recurringReservation = fullBookingEntry.recurrence && fullBookingEntry.recurrence.rrule ?
|
|
||||||
fullBookingEntry.recurrence.rrule : null;
|
|
||||||
const tentative = fullBookingEntry.tentative ? fullBookingEntry.tentative : false;
|
|
||||||
const free = fullBookingEntry.free ? fullBookingEntry.free : false;
|
|
||||||
|
|
||||||
//Special case, canceled recurring reservation
|
|
||||||
//It has empty fees array (fees.length = 0) and no "canceled" field
|
|
||||||
//Normally, canceled reservation has canceled field
|
|
||||||
//Also, it has rrule !== null
|
|
||||||
//If it is tentative, it will have tentative = true, skip those (do not delete)
|
|
||||||
//If it is free, it will have free = true, skip those (do not delete)
|
|
||||||
if (fees.length === 0 && !canceled && recurringReservation && !tentative && !free){
|
|
||||||
bookingIdsToRemove.push(fullBookingEntry['_id']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fees.length > 1){
|
if (fees.length > 1){
|
||||||
// Recurring booking, let's create new booking
|
// Recurring booking, let's create new booking
|
||||||
@@ -116,8 +101,6 @@ const fetchAllBookings = () => {
|
|||||||
const fees = fullBookingEntry && fullBookingEntry.fees ? fullBookingEntry.fees : [];
|
const fees = fullBookingEntry && fullBookingEntry.fees ? fullBookingEntry.fees : [];
|
||||||
const firstFee = fees.length > 0 && fees[0].fee ? fees[0].fee : undefined;
|
const firstFee = fees.length > 0 && fees[0].fee ? fees[0].fee : undefined;
|
||||||
const hourlyRate = firstFee && firstFee.price ? firstFee.price : 0;
|
const hourlyRate = firstFee && firstFee.price ? firstFee.price : 0;
|
||||||
const free = fullBookingEntry.free ? fullBookingEntry.free : false;
|
|
||||||
const tentative = fullBookingEntry.tentative ? fullBookingEntry.tentative : false;
|
|
||||||
|
|
||||||
const startMoment = fullBookingEntry && fullBookingEntry.start && fullBookingEntry.start.dateTime ?
|
const startMoment = fullBookingEntry && fullBookingEntry.start && fullBookingEntry.start.dateTime ?
|
||||||
moment.utc(fullBookingEntry.start.dateTime) : null;
|
moment.utc(fullBookingEntry.start.dateTime) : null;
|
||||||
@@ -128,7 +111,7 @@ const fetchAllBookings = () => {
|
|||||||
// console.log('End : ', endMoment.clone().tz(fullBookingEntry.timezone).format('DD.MM. HH:mm'), '[', endMoment.toISOString(), ']');
|
// console.log('End : ', endMoment.clone().tz(fullBookingEntry.timezone).format('DD.MM. HH:mm'), '[', endMoment.toISOString(), ']');
|
||||||
// console.log('Fees : ');
|
// console.log('Fees : ');
|
||||||
|
|
||||||
if (startMoment && endMoment && !free && !tentative){
|
if (startMoment && endMoment){
|
||||||
cleanedBookingReservations.push({
|
cleanedBookingReservations.push({
|
||||||
reservationId: fullBookingEntry['_id'],
|
reservationId: fullBookingEntry['_id'],
|
||||||
memberId: fullBookingEntry.member,
|
memberId: fullBookingEntry.member,
|
||||||
@@ -261,32 +244,6 @@ const getFirstReservationInBlock = (reservation) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getLastReservationInBlock = async (reservation) => {
|
|
||||||
const { resourceId, memberId, end } = reservation;
|
|
||||||
|
|
||||||
const toTimestamp = moment.utc(end).add(MAX_BACK_TO_BACK_DIFFERENCE).toISOString();
|
|
||||||
const fromTimestamp = end;
|
|
||||||
|
|
||||||
const filters = {
|
|
||||||
resourceId,
|
|
||||||
memberId,
|
|
||||||
start: {
|
|
||||||
[Op.and]: [
|
|
||||||
{[Op.gte]: fromTimestamp},
|
|
||||||
{[Op.lte]: toTimestamp}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const nextReservation = await db.bookingReservation.findOne({where: filters});
|
|
||||||
if (!nextReservation) {
|
|
||||||
return reservation;
|
|
||||||
} else {
|
|
||||||
return getLastReservationInBlock(nextReservation);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const writeBookingReservation = (bookingReservation) => {
|
const writeBookingReservation = (bookingReservation) => {
|
||||||
const { reservationId, memberId, officeId, resourceId, start, end, timezone, canceled, hourlyRate } = bookingReservation;
|
const { reservationId, memberId, officeId, resourceId, start, end, timezone, canceled, hourlyRate } = bookingReservation;
|
||||||
const bookingReservationForDB = {
|
const bookingReservationForDB = {
|
||||||
@@ -412,6 +369,5 @@ module.exports = {
|
|||||||
getFirstNextBooking,
|
getFirstNextBooking,
|
||||||
getFirstPreviousBooking,
|
getFirstPreviousBooking,
|
||||||
getFirstReservationInBlock,
|
getFirstReservationInBlock,
|
||||||
getLastReservationInBlock,
|
|
||||||
bulkWriteReservationsWithChangesTracking,
|
bulkWriteReservationsWithChangesTracking,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user