Editing of the fees before sending / bugfixes

This commit is contained in:
Senad Uka
2020-01-13 07:56:00 +01:00
parent 404f27e208
commit 3d8e9c987f
6 changed files with 281 additions and 22 deletions

View File

@@ -12,16 +12,21 @@ import {
incidentDescriptions,
incidentLevelDescriptions,
UNLOCKED_INCIDENT_RELATED_WITH_RESERVATION, UNLOCKED_INCIDENT_STANDALONE, UNSCHEDULED_INCIDENT_AFTER_RESERVATION,
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE
UNSCHEDULED_INCIDENT_BEFORE_RESERVATION, UNSCHEDULED_INCIDENT_STANDALONE, BOOKING_CANCELED_LATE, BOOKING_MOVED_TO_ANOTHER_DAY,
BOOKING_SHORTENED
} from '../../../constants/enums';
import { doorLockRelatedWithReservationIncidentHeaders, standaloneDoorLockIncidentHeaders, bookingChangeIncidentHeaders } from '../../../constants/constants';
import { deleteIncidents } from "../../../store/actions";
import { deleteIncidents, updateIncidentFees } from "../../../store/actions";
class SingleIncidentsTable extends Component {
state = {
selectedUnlockedIncidentIds: [],
selectedUnscheduledIncidentIds: [],
selectedBookingChangeIncidentIds: []
selectedBookingChangeIncidentIds: [],
changedUnlockedIncidentIds: {},
changedUnscheduledIncidentIds: {},
changedBookingChangeIncidentIds: {},
inputIdToFocus: null,
};
onSelectChange = (selectedIncidents) => {
@@ -82,6 +87,24 @@ 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(){
const {
loading,
@@ -94,12 +117,22 @@ class SingleIncidentsTable extends Component {
const {
selectedUnlockedIncidentIds,
selectedUnscheduledIncidentIds,
selectedBookingChangeIncidentIds
selectedBookingChangeIncidentIds,
changedUnlockedIncidentIds,
changedUnscheduledIncidentIds,
changedBookingChangeIncidentIds,
inputIdToFocus
} = this.state;
const totalSelected = selectedUnlockedIncidentIds.length + selectedUnscheduledIncidentIds.length + selectedBookingChangeIncidentIds.length;
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 : [];
incidents.forEach(incident => {
incident.id = `${incident.incidentType}-${incident.incidentId}`;
@@ -122,6 +155,44 @@ class SingleIncidentsTable extends Component {
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) => {
const columnTitle = incidentsReportHeaderTitles[header];
@@ -143,6 +214,10 @@ class SingleIncidentsTable extends Component {
Cell: props => {
let cellValue = '';
let urlValue = undefined;
let clickablePrice = undefined;
let priceAsNumber = undefined;
let priceInputID = undefined;
let priceFontColor = 'black';
switch (props.column.id) {
case 'memberName':
@@ -198,9 +273,44 @@ class SingleIncidentsTable extends Component {
}
break;
case 'totalChargeFee':
const totalFee = (props.row['_original'].incidentPrice || props.value) || 0;
const totalFeeFormatted = parseFloat(totalFee).toFixed(2);
cellValue = `$ ${totalFeeFormatted}`;
clickablePrice = true;
let totalFee = 0;
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;
break;
case 'oldReservation':
@@ -217,10 +327,22 @@ class SingleIncidentsTable extends Component {
cellValue = props.value;
}
if (openMemberSummaryOnMemberClick && urlValue){
return <NavLink to={urlValue}>{cellValue}</NavLink>
if (clickablePrice){
return <p>$ <input
id={priceInputID}
style={{ color: priceFontColor }}
type={'number'}
onChange={priceChangeHandler}
value={priceAsNumber}
autoFocus={priceInputID === inputIdToFocus}
/>
</p>
}else{
return <div style={{ textAlign: columnContentsAlignment, whiteSpace: 'pre' }}>{cellValue}</div>
if (openMemberSummaryOnMemberClick && urlValue){
return <NavLink to={urlValue}>{cellValue}</NavLink>
}else{
return <div style={{ textAlign: columnContentsAlignment, whiteSpace: 'pre' }}>{cellValue}</div>
}
}
}
});
@@ -235,6 +357,9 @@ class SingleIncidentsTable extends Component {
{
<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/>
{
!loading && incidents &&
@@ -252,7 +377,8 @@ class SingleIncidentsTable extends Component {
}
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);

View File

@@ -103,6 +103,21 @@ 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) => {
dispatch({type: FETCH_MEMBERS_PENDING});
API.get('officeRnD/membersList')