393 lines
11 KiB
JavaScript
393 lines
11 KiB
JavaScript
sap.ui.define([
|
|
"sap/ui/core/mvc/Controller",
|
|
"sap/m/MessageBox",
|
|
"sap/ui/model/Filter",
|
|
"sap/ui/model/FilterOperator"
|
|
], function (Controller, MessageBox, Filter, FilterOperator) {
|
|
"use strict";
|
|
|
|
return Controller.extend("restaurant.z00124ss25restaurant.controller.managerReservation", {
|
|
onInit: function () {
|
|
var oDataForChart = {
|
|
totalReservations: 0,
|
|
totalRevenue: "35,918.29",
|
|
monthlyData: [
|
|
{ Month: "Jan", Count: 20, Revenue: 5000 },
|
|
{ Month: "Feb", Count: 30, Revenue: 7000 },
|
|
{ Month: "Mar", Count: 25, Revenue: 6000 },
|
|
{ Month: "Apr", Count: 15, Revenue: 3500 },
|
|
{ Month: "May", Count: 10, Revenue: 2000 },
|
|
{ Month: "Jun", Count: 20, Revenue: 7500 }
|
|
]
|
|
};
|
|
|
|
var oDashboardModel = new sap.ui.model.json.JSONModel(oDataForChart);
|
|
this.getView().setModel(oDashboardModel, "dashboard");
|
|
this._loadReservationCount();
|
|
},
|
|
_padAndEncodeId: function (id) {
|
|
id = id.toString(); // Ensure it's a string
|
|
|
|
if (id.length === 9) {
|
|
return id;
|
|
}
|
|
|
|
var padding = 9 - id.length;
|
|
return "%20".repeat(padding) + id;
|
|
},
|
|
onModelRefresh: function () {
|
|
var oTable = this.byId("reservationTable");
|
|
oTable.getBinding().refresh(true);
|
|
},
|
|
formatDimensions: function (sWidth, sHeight, sDepth, sUnit) {
|
|
if (sWidth && sHeight && sDepth && sUnit) {
|
|
return sWidth + "x" + sHeight + "x" + sDepth + " " + (sUnit.toLowerCase());
|
|
}
|
|
return null;
|
|
},
|
|
initBindingEventHandler: function () {
|
|
const oBusyIndicator = this.oBusyIndicator;
|
|
const oTable = this.getTable();
|
|
const oBinding = oTable.getBinding();
|
|
|
|
oBinding.attachDataRequested(function () {
|
|
oTable.setNoData(oBusyIndicator);
|
|
});
|
|
oBinding.attachDataReceived(function () {
|
|
oTable.setNoData(null); //Use default again ("No Data" in case no data is available)
|
|
});
|
|
},
|
|
_resetForm: function () {
|
|
this.byId("decoration").setSelectedKey("");
|
|
this.byId("location").setSelectedKey("");
|
|
this.byId("numofseats").setValue(1);
|
|
},
|
|
onCreateTable: function () {
|
|
var iNumberOfSeats = this.byId("numofseats").getValue();
|
|
var sDecoration = this.byId("decoration").getSelectedKey();
|
|
var sLocation = this.byId("location").getSelectedKey();
|
|
|
|
if (!iNumberOfSeats) {
|
|
MessageBox.error("Please enter number of seats");
|
|
return;
|
|
}
|
|
|
|
if (!sDecoration) {
|
|
MessageBox.error("Please select a decoration for the table");
|
|
return;
|
|
}
|
|
|
|
if (!sLocation) {
|
|
MessageBox.error("Please select a location for the table");
|
|
return;
|
|
}
|
|
|
|
var oPayload = {
|
|
NumberOfSeats: iNumberOfSeats,
|
|
Location: sLocation,
|
|
Decoration: sDecoration
|
|
};
|
|
var oModel = this.getOwnerComponent().getModel();
|
|
|
|
// Show busy indicator
|
|
this.getView().setBusy(true);
|
|
|
|
var endPoint = "/tablePos";
|
|
|
|
oModel.create(endPoint, oPayload, {
|
|
success: function (oData, oResponse) {
|
|
this.getView().setBusy(false);
|
|
MessageBox.success("Table created successfully", {
|
|
onClose: this._resetForm.bind(this)
|
|
});
|
|
}.bind(this),
|
|
error: function (oError) {
|
|
this.getView().setBusy(false);
|
|
|
|
// Extract error message from backend response
|
|
var sErrorMessage = "Error creating Table";
|
|
|
|
try {
|
|
if (oError.responseText) {
|
|
var oErrorResponse = JSON.parse(oError.responseText);
|
|
sErrorMessage = oErrorResponse.error.message.value ||
|
|
(oErrorResponse.error.innererror &&
|
|
oErrorResponse.error.innererror.errordetails &&
|
|
oErrorResponse.error.innererror.errordetails.length > 0 ?
|
|
oErrorResponse.error.innererror.errordetails[0].message :
|
|
sErrorMessage);
|
|
}
|
|
} catch (e) {
|
|
// Use default error message if parsing fails
|
|
console.error("Error parsing error response:", e);
|
|
}
|
|
|
|
// Log detailed error information for debugging
|
|
console.error("Error status:", oError.statusCode);
|
|
console.error("Error message:", sErrorMessage);
|
|
console.error("Request URL:", oError.request ? oError.request.requestUri : "unknown");
|
|
console.error("Full error object:", oError);
|
|
|
|
MessageBox.error(sErrorMessage);
|
|
|
|
// Test with a different endpoint if this fails
|
|
if (oError.statusCode === 404) {
|
|
console.log("Trying alternative endpoint format...");
|
|
this._tryAlternativeEndpoint(oPayload);
|
|
}
|
|
}.bind(this)
|
|
});
|
|
|
|
},
|
|
onEditTable: function (oEvent) {
|
|
const oContext = oEvent.getSource().getBindingContext();
|
|
if (!oContext) return;
|
|
|
|
const oData = oContext.getObject();
|
|
|
|
// Create dialog only once
|
|
if (!this._oEditDialog) {
|
|
this._oEditDialog = new sap.m.Dialog({
|
|
title: "Edit Table",
|
|
contentWidth: "400px",
|
|
content: new sap.ui.layout.form.SimpleForm({
|
|
editable: true,
|
|
content: [
|
|
new sap.m.Label({ text: "Table ID" }),
|
|
new sap.m.Input({ value: "{/TableId}", enabled: false }),
|
|
|
|
new sap.m.Label({ text: "Decoration" }),
|
|
new sap.m.Input({ value: "{/Decoration}" }),
|
|
|
|
new sap.m.Label({ text: "Location" }),
|
|
new sap.m.Input({ value: "{/Location}" }),
|
|
|
|
new sap.m.Label({ text: "Seats" }),
|
|
new sap.m.StepInput({ value: "{/NumberOfSeats}", min: 1, max: 12 })
|
|
]
|
|
}),
|
|
buttons: [
|
|
new sap.m.Button({
|
|
text: "Save",
|
|
type: "Emphasized",
|
|
press: function () {
|
|
var oDialogModel = this._oEditDialog.getModel();
|
|
var oUpdatedData = oDialogModel.getData();
|
|
|
|
var oModel = this.getView().getModel();
|
|
|
|
var endPoint = "/tablePos('" + this._padAndEncodeId(oUpdatedData.TableId.trim()) + "')";
|
|
|
|
var oPayload = {
|
|
Decoration: oUpdatedData.Decoration,
|
|
Location: oUpdatedData.Location,
|
|
NumberOfSeats: oUpdatedData.NumberOfSeats
|
|
};
|
|
|
|
this.getView().setBusy(true);
|
|
|
|
oModel.update(endPoint, oPayload, {
|
|
success: function () {
|
|
this.getView().setBusy(false);
|
|
sap.m.MessageToast.show("Table updated successfully!");
|
|
|
|
this._oEditDialog.close();
|
|
this._oEditDialog.destroy();
|
|
this._oEditDialog = null;
|
|
}.bind(this),
|
|
error: function (oError) {
|
|
this.getView().setBusy(false);
|
|
sap.m.MessageBox.error("Failed to update table.");
|
|
console.error(oError);
|
|
}.bind(this)
|
|
});
|
|
}.bind(this)
|
|
}),
|
|
new sap.m.Button({
|
|
text: "Delete",
|
|
type: "Reject",
|
|
press: function () {
|
|
sap.m.MessageBox.confirm("Are you sure you want to delete this table?", {
|
|
onClose: function (sAction) {
|
|
if (sAction === sap.m.MessageBox.Action.OK) {
|
|
this._deleteTable();
|
|
}
|
|
}.bind(this)
|
|
});
|
|
}.bind(this)
|
|
}),
|
|
new sap.m.Button({
|
|
text: "Cancel",
|
|
press: function () {
|
|
this._oEditDialog.close();
|
|
}.bind(this)
|
|
})
|
|
],
|
|
afterClose: function () {
|
|
if (this._oEditDialog) {
|
|
this._oEditDialog.destroy();
|
|
this._oEditDialog = null;
|
|
}
|
|
}.bind(this)
|
|
});
|
|
}
|
|
|
|
// Bind a JSON model copy to dialog to avoid direct changes before save
|
|
const oTableData = Object.assign({}, oData);
|
|
const oDialogModel = new sap.ui.model.json.JSONModel(oTableData);
|
|
|
|
this._oEditDialog.setModel(oDialogModel);
|
|
this._oEditDialog.bindElement("/");
|
|
|
|
this._oEditDialog.open();
|
|
},
|
|
|
|
_deleteTable: function () {
|
|
var oDialogModel = this._oEditDialog.getModel();
|
|
var oData = oDialogModel.getData();
|
|
var oModel = this.getView().getModel();
|
|
|
|
var sPath = "/tablePos('" + this._padAndEncodeId(oData.TableId.trim()) + "')";
|
|
|
|
this.getView().setBusy(true);
|
|
oModel.remove(sPath, {
|
|
success: function () {
|
|
this.getView().setBusy(false);
|
|
sap.m.MessageToast.show("Table deleted successfully!");
|
|
this._oEditDialog.close();
|
|
}.bind(this),
|
|
error: function (oError) {
|
|
this.getView().setBusy(false);
|
|
sap.m.MessageBox.error("Failed to delete table.");
|
|
console.error(oError);
|
|
}.bind(this)
|
|
});
|
|
},
|
|
|
|
onSearchLiveChange: function (oEvent) {
|
|
// Get the search query
|
|
var sQuery = oEvent.getParameter("newValue");
|
|
var oTable = this.byId("reservationTable");
|
|
var oBinding = oTable.getBinding("rows");
|
|
|
|
// Apply filters
|
|
if (sQuery && sQuery.length > 0) {
|
|
var aFilters = [
|
|
new Filter("ReservationName", FilterOperator.Contains, sQuery)
|
|
];
|
|
oBinding.filter(new Filter({
|
|
filters: aFilters,
|
|
and: false
|
|
}));
|
|
} else {
|
|
// Clear filters if search field is empty
|
|
oBinding.filter([]);
|
|
}
|
|
},
|
|
onModelRefresh: function () {
|
|
var oModel = this.getView().getModel();
|
|
oModel.refresh(true); // Hard refresh from the server
|
|
},
|
|
/**
|
|
* Formats a date to show only year, month, and day (YYYY-MM-DD)
|
|
* @param {object} oDate - Date object or date string
|
|
* @returns {string} Formatted date string
|
|
*/
|
|
formatDate: function (oDate) {
|
|
if (!oDate) {
|
|
return "";
|
|
}
|
|
|
|
// Convert string to date object if needed
|
|
var dateObj = (typeof oDate === "string") ? new Date(oDate) : oDate;
|
|
|
|
if (isNaN(dateObj.getTime())) {
|
|
return "";
|
|
}
|
|
|
|
// Format as YYYY-MM-DD
|
|
var year = dateObj.getFullYear();
|
|
var month = String(dateObj.getMonth() + 1).padStart(2, '0');
|
|
var day = String(dateObj.getDate()).padStart(2, '0');
|
|
|
|
return year + "-" + month + "-" + day;
|
|
},
|
|
|
|
/**
|
|
* Formats a time to show in HH:MM:SS format
|
|
* @param {object} oTime - Time object, date object, or time string
|
|
* @returns {string} Formatted time string
|
|
*/
|
|
formatTime: function (oTime) {
|
|
if (!oTime) {
|
|
return "";
|
|
}
|
|
|
|
// Handle OData Edm.Time object which contains ms property
|
|
if (oTime && typeof oTime === "object" && oTime.ms !== undefined && oTime.__edmType === "Edm.Time") {
|
|
// Calculate hours, minutes, seconds from milliseconds
|
|
var totalSeconds = Math.floor(oTime.ms / 1000);
|
|
var hours = Math.floor(totalSeconds / 3600);
|
|
var minutes = Math.floor((totalSeconds % 3600) / 60);
|
|
var seconds = totalSeconds % 60;
|
|
|
|
// Format as HH:MM:SS
|
|
return String(hours).padStart(2, '0') + ":" +
|
|
String(minutes).padStart(2, '0') + ":" +
|
|
String(seconds).padStart(2, '0');
|
|
}
|
|
|
|
var timeObj;
|
|
|
|
// Handle other input types
|
|
if (typeof oTime === "string") {
|
|
// Try parsing as time string (like "14:30:00")
|
|
if (oTime.indexOf(":") !== -1) {
|
|
var parts = oTime.split(":");
|
|
timeObj = new Date();
|
|
timeObj.setHours(parseInt(parts[0], 10));
|
|
timeObj.setMinutes(parts.length > 1 ? parseInt(parts[1], 10) : 0);
|
|
timeObj.setSeconds(parts.length > 2 ? parseInt(parts[2], 10) : 0);
|
|
} else {
|
|
// Try parsing as date string
|
|
timeObj = new Date(oTime);
|
|
}
|
|
} else if (oTime instanceof Date) {
|
|
timeObj = oTime;
|
|
} else {
|
|
return ""; // Unsupported format
|
|
}
|
|
|
|
if (isNaN(timeObj.getTime())) {
|
|
return "";
|
|
}
|
|
|
|
// Format as HH:MM:SS
|
|
var hours = String(timeObj.getHours()).padStart(2, '0');
|
|
var minutes = String(timeObj.getMinutes()).padStart(2, '0');
|
|
var seconds = String(timeObj.getSeconds()).padStart(2, '0');
|
|
|
|
return hours + ":" + minutes + ":" + seconds;
|
|
},
|
|
_loadReservationCount: function () {
|
|
var oODataModel = this.getOwnerComponent().getModel();
|
|
|
|
// Show busy indicator
|
|
var oDashboardModel = this.getView().getModel("dashboard");
|
|
|
|
// Read count directly from the $count endpoint
|
|
oODataModel.read("/reservationPos/$count", {
|
|
success: function (count) {
|
|
// count is a number (integer)
|
|
oDashboardModel.setProperty("/totalReservations", count);
|
|
},
|
|
error: function (oError) {
|
|
console.error("Failed to fetch reservation count", oError);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
|