Correct export of Delivery Unit EON_EMOBILITY_PROVIDER (37 files, replaces incomplete initial export)

This commit is contained in:
Thorsten Schmitz
2026-07-09 01:59:09 +02:00
parent 1baef99314
commit dce458f6c1
38 changed files with 6669 additions and 75 deletions
@@ -1,10 +1,20 @@
{
"exposed": true,
"authentication": [
{
"authentication": [{
"method": "Form"
}
],
}],
"mime_mapping": [{
"extension": "jpg",
"mimetype": "image/jpeg"
}],
"force_ssl": false,
"cache_control": "no-cache, no-store"
"enable_etags": true,
"prevent_xsrf": true,
"anonymous_connection": null,
"cors": [{
"enabled": false
}],
"cache_control": "no-cache, no-store",
"default_file": "index.html"
}
@@ -0,0 +1,134 @@
sap.ui.define([
"sap/ui/core/UIComponent",
"sap/ui/model/json/JSONModel",
"sap/ui/core/IconPool",
"sap/m/MessageBox"
], function(UIComponent, JSONModel, IconPool, MessageBox) {
"use strict";
return UIComponent.extend("uniorg.eon.emobility.provider.ui.pricematrix.Component", {
metadata: {
manifest: "json"
},
init: function() {
// call the init function of the parent
UIComponent.prototype.init.apply(this, arguments);
// Reference the view (root control)
var oRootView = this.getAggregation("rootControl");
var oBusyDialog = new sap.m.BusyDialog({
title: "Please wait",
text: "Loading data...",
showCancelButton: false
});
oBusyDialog.open();
var b = [];
var c = {};
//Fiori Theme font family and URI
var t = {
fontFamily: "SAP-icons-TNT",
fontURI: sap.ui.require.toUrl("sap/tnt/themes/base/fonts/")
};
//Registering to the icon pool
IconPool.registerFont(t);
b.push(IconPool.fontLoaded("SAP-icons-TNT"));
c["SAP-icons-TNT"] = t;
//SAP Business Suite Theme font family and URI
var B = {
fontFamily: "BusinessSuiteInAppSymbols",
fontURI: sap.ui.require.toUrl("sap/ushell/themes/base/fonts/")
};
//Registering to the icon pool
IconPool.registerFont(B);
b.push(IconPool.fontLoaded("BusinessSuiteInAppSymbols"));
c["BusinessSuiteInAppSymbols"] = B;
// set data model
/*var oData = {
recipient : {
name : "World"
}
};
var oModel = new JSONModel(oData);
this.setModel(oModel);*/
//this.getModel().attachEventOnce("metadataFailed", function(oEvent) {
/*eslint-disable no-alert */
// alert("Request to the OData remote service failed.");
/*eslint-enable no-alert */
//});
fetch("/uniorg/eon/emobility/provider/backend/getProviderData.xsjs")
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw new Error('Failed to retrieve data. HTTP STATUS ' + response.status.toString() + ' ' + response.statusText);
}
}
return response.json();
})
.then(data => {
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw new Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw new Error("Unexpected response from backend service");
} else if (!data.resultSet) {
throw new Error("Unexpected response from backend service");
}
const provider = data.resultSet;
const oModel = new JSONModel(provider);
this.setModel(oModel);
// Manually trigger binding to ensure UI re-renders
oRootView.setModel(oModel);
// Wait until the UI is fully rendered
sap.ui.getCore().applyChanges(); // Apply model changes to the UI
oBusyDialog.close();
this.getRouter().initialize();
})
.catch(error => {
console.error(error);
MessageBox.error("Communication with backend service failed", {
details: error.message
});
oBusyDialog.close();
});
// Set up the interval to keep the session alive (e.g., every 1 minutes)
setInterval(function() {
this.keepSessionAlive();
}.bind(this), 1 * 60 * 1000); // 1 minutes
},
// Function to keep the backend session alive
keepSessionAlive: function() {
// Send a request to the backend to keep the session active
jQuery.ajax({
url: "/uniorg/eon/emobility/provider/backend/keepAlive.xsjs",
type: "GET",
success: function() {
// Request succeeded, session is kept alive
console.log("Backend session is alive.");
},
error: function(jqXHR, textStatus, errorThrown) {
// Handle error cases, such as authentication issues (401 status code)
if (jqXHR.status === 401) {
console.log("Authentication error. Prompt user to re-authenticate.");
// Perform necessary actions, such as displaying an authentication dialog
} else {
console.log("Error occurred during session keep-alive request:", errorThrown);
}
}
});
}
});
});
@@ -0,0 +1,9 @@
sap.ui.define([
"sap/ui/core/mvc/Controller"
], function (Controller) {
"use strict";
return Controller.extend("uniorg.eon.emobility.provider.ui.pricematrix.controller.App", {
});
});
@@ -0,0 +1,79 @@
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/ui/core/routing/History",
"sap/ui/core/UIComponent",
"sap/ui/core/format/NumberFormat",
"sap/ui/model/json/JSONModel",
"../model/formatter"
], function(Controller, History, UIComponent, NumberFormat, JSONModel, formatter) {
"use strict";
return Controller.extend("uniorg.eon.emobility.provider.ui.pricematrix.controller.BaseController", {
formatter: formatter,
getRouter: function() {
return UIComponent.getRouterFor(this);
},
// just this.getModel() ...
getModel: function(sName) {
// ... instead of
return this.getView().getModel(sName);
},
// just this.setModel() ...
setModel: function(oModel, sName) {
// ... instead of
return this.getView().setModel(oModel, sName);
},
reloadModelData: function() {
var oBusyDialog = new sap.m.BusyDialog({
title: "Please wait",
text: "Loading data...",
showCancelButton: false
});
oBusyDialog.open();
var that = this;
fetch("/uniorg/eon/emobility/provider/backend/getProviderData.xsjs")
.then(response => response.json())
.then(data => {
const provider = data.resultSet;
//const oModel = new JSONModel(provider);
this.getView().getModel().setProperty("/", provider);
//this.getView().getModel().refresh(true);
oBusyDialog.close();
})
.catch(error => {
console.error(error);
oBusyDialog.close();
});
},
formatPercentage: function(number) {
return NumberFormat.getPercentInstance().format(number);
},
generateUUID: function() {
var uuid = '';
var characters = '0123456789ABCDEF';
for (var i = 0; i < 32; i++) {
uuid += characters[Math.floor(Math.random() * 16)];
}
return uuid;
},
onNavBack: function() {
var oHistory, sPreviousHash;
oHistory = History.getInstance();
sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
this.getRouter().navTo("Overview", {}, true /*no history*/ );
}
}
});
});
@@ -0,0 +1,33 @@
sap.ui.define([
"./BaseController"
], function (BaseController) {
"use strict";
return BaseController.extend("uniorg.eon.emobility.provider.ui.pricematrix.controller.NotFound", {
onInit: function () {
var oRouter, oTarget;
oRouter = this.getRouter();
oTarget = oRouter.getTarget("notFound");
oTarget.attachDisplay(function (oEvent) {
this._oData = oEvent.getParameter("data"); // store the data
}, this);
},
// override the parent's onNavBack (inherited from BaseController)
onNavBack : function () {
// in some cases we could display a certain target when the back button is pressed
if (this._oData && this._oData.fromTarget) {
this.getRouter().getTargets().display(this._oData.fromTarget);
delete this._oData.fromTarget;
return;
}
// call the parent's onNavBack
BaseController.prototype.onNavBack.apply(this, arguments);
}
});
});
@@ -0,0 +1,243 @@
sap.ui.define([
"./BaseController"
], function(BaseController) {
"use strict";
return BaseController.extend("uniorg.eon.emobility.provider.ui.pricematrix.controller.Overview", {
onInit: function() {},
onRowPress: function(evt) {
const modelContext = evt.getSource().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
this.getOwnerComponent().getRouter().navTo("Provider", {
Code: modelData.Code
});
},
onSubOperatorRowPress: function(evt) {
const modelContext = evt.getSource().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
this.getOwnerComponent().getRouter().navTo("SubOperator", {
Code: modelData.Code
});
},
onAddNext: function(evt) {
const modelContext = this.byId("tableProviderList").getSelectedItem().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
this.getOwnerComponent().getRouter().navTo("ProviderNextPeriod", {
Code: modelData.Code
});
},
onAddNew: function(evt) {
if (this.byId("otbCancel").getEnabled()) {
this.onCancel();
}
const oModel = this.getView().getModel(),
modelData = JSON.parse(JSON.stringify(oModel.getProperty('/Provider')));
modelData.push({
Code: "",
Name: "",
U_ACTIVE: 'N',
U_ACTIVE_FROM: '',
U_ACTIVE_TO: '',
editable: true,
new: true
});
oModel.setProperty('/Provider', modelData);
this.byId("tableProviderList").getItems()[0].setSelected(true);
this.byId("otbEdit").setVisible(false);
this.byId("otbEdit").setEnabled(false);
this.byId("otbSave").setVisible(true);
this.byId("otbSave").setEnabled(true);
this.byId("otbCancel").setVisible(true);
this.byId("otbCancel").setEnabled(true);
this.byId("otbAddNext").setEnabled(false);
},
onEdit: function(evt) {
const modelContext = this.byId("tableProviderList").getSelectedItem().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
this.getView().getModel().setProperty("editable", true, modelContext);
this.byId("otbEdit").setVisible(false);
this.byId("otbEdit").setEnabled(false);
this.byId("otbSave").setVisible(true);
this.byId("otbSave").setEnabled(true);
this.byId("otbCancel").setVisible(true);
this.byId("otbCancel").setEnabled(true);
},
/*onSaveNew: function(evt) {
const modelContext = evt.getSource().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
//this.getView().getModel().setProperty("editable", false, modelContext);
var payload = JSON.parse(JSON.stringify(modelData));
delete payload.New;
delete payload.Periods;
delete payload.Lines;
delete payload.NextPeriod;
//this.onOpenDialog();
var oBusyDialog = new sap.m.BusyDialog({
title: "Please wait",
text: "Processing data...",
showCancelButton: false
});
oBusyDialog.open();
fetch('/uniorg/eon/emobility/provider/backend/addNewProvider.xsjs', {
method: 'POST',
async: false,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
})
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw Error(response.statusText);
}
}
return response.json();
})
.then(data => {
console.log(data);
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw Error("unexpected response from backend service");
}
return fetch('/uniorg/eon/emobility/provider/backend/getProviderData.xsjs');
})
.then(response => response.json())
.then(data => {
const provider = data.resultSet;
//const oModel = new JSONModel(provider);
this.getView().getModel().setProperty("/", provider);
this.getView().getModel().refresh(true);
oBusyDialog.close();
})
.then(() => {
// this.byId("otbEdit").setVisible(true);
// this.byId("otbEdit").setEnabled(true);
// this.byId("otbSave").setVisible(false);
// this.byId("otbSave").setEnabled(false);
this.byId("otbCancel").setVisible(false);
this.byId("otbCancel").setEnabled(false);
})
.catch(error => {
console.error(error);
oBusyDialog.close();
});
},*/
onSave: function(evt) {
const modelContext = this.byId("tableProviderList").getSelectedItem().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
//this.getView().getModel().setProperty("editable", false, modelContext);
var payload = JSON.parse(JSON.stringify(modelData));
delete payload.Periods;
delete payload.Lines;
delete payload.NextPeriod;
//this.onOpenDialog();
var oBusyDialog = new sap.m.BusyDialog({
title: "Please wait",
text: "Processing data...",
showCancelButton: false
});
oBusyDialog.open();
var url = payload.new === true ? '/uniorg/eon/emobility/provider/backend/addNewProvider.xsjs' :
'/uniorg/eon/emobility/provider/backend/setProviderData.xsjs'
fetch(url, {
method: 'POST',
async: false,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
})
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw Error(response.statusText);
}
}
return response.json();
})
.then(data => {
console.log(data);
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw Error("unexpected response from backend service");
}
return fetch('/uniorg/eon/emobility/provider/backend/getProviderData.xsjs');
})
.then(response => response.json())
.then(data => {
const provider = data.resultSet;
//const oModel = new JSONModel(provider);
this.getView().getModel().setProperty("/", provider);
this.getView().getModel().refresh(true);
oBusyDialog.close();
/*this.getOwnerComponent().getRouter().navTo("Provider", {
Code: payload.Code
});*/
})
.then(() => {
this.byId("otbEdit").setVisible(true);
this.byId("otbEdit").setEnabled(true);
this.byId("otbSave").setVisible(false);
this.byId("otbSave").setEnabled(false);
this.byId("otbCancel").setVisible(false);
this.byId("otbCancel").setEnabled(false);
if (payload.new === true) {
this.byId("otbAddNext").setEnabled(true);
}
})
.catch(error => {
console.error(error);
oBusyDialog.close();
});
},
onCancel: function(evt) {
/*const modelContext = this.byId("tableProviderList").getSelectedItem().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);*/
this.reloadModelData();
this.byId("otbEdit").setVisible(true);
if (this.byId("tableProviderList").getSelectedItem().getBindingContext().getProperty('new') === false) {
this.byId("otbEdit").setEnabled(true);
}
this.byId("otbSave").setVisible(false);
this.byId("otbSave").setEnabled(false);
this.byId("otbCancel").setVisible(false);
this.byId("otbCancel").setEnabled(false);
},
onSelectionChange: function(evt) {
if (this.byId("otbCancel").getEnabled()) {
this.onCancel();
}
/*const modelContext = evt.getParameters().listItem.getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);*/
const readOnly = this.getView().getModel().getProperty('/ReadOnly');
if (!readOnly) {
this.byId("otbEdit").setEnabled(true);
this.byId("otbAddNext").setEnabled(true);
}
}
});
});
@@ -0,0 +1,461 @@
sap.ui.define([
"./BaseController",
"sap/ui/core/routing/History",
"sap/ui/model/Filter",
"sap/ui/model/json/JSONModel",
"sap/m/MessageBox",
'sap/ui/core/Fragment'
], function(BaseController, History, Filter, JSONModel, MessageBox, Fragment) {
"use strict";
return BaseController.extend("uniorg.eon.emobility.provider.ui.pricematrix.controller.Provider", {
onInit: function() {
this.getOwnerComponent().getRouter().getRoute("Provider").attachPatternMatched(this.onRouteMatched, this);
const oModelAppData = new JSONModel({
editable: false,
showDetails: false
});
this.getView().setModel(oModelAppData, "appData");
this.byId("tableProviderPrices").setKeyboardMode(sap.m.ListKeyboardMode.Edit);
},
onRouteMatched: function(evt) {
var providerCode = evt.getParameter("arguments").Code;
this.getView().getModel().refresh(true);
var oData = this.getView().getModel().getData();
if (oData.Provider) {
var pIdx = oData.Provider.findIndex(p => p.Code === providerCode);
if (pIdx === -1) {
pIdx = 0;
}
this.getView().bindElement({
path: "/Provider/" + pIdx
});
if (oData.Provider[pIdx].Periods.length > 0) {
this.byId("cbPeriod").setSelectedKey(oData.Provider[pIdx].Periods[0].U_FROM);
//console.log("Set first period in ComboBox: " + this.byId("cbPeriod").getSelectedKey());
this.applyFilters();
}
}
},
onBackPress: function() {
// this.getOwnerComponent().getRouter().navTo("BillingRunList");
var oHistory = History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
this.getOwnerComponent().getRouter().navTo("Overview", true);
}
},
onToggleDetails: function() {
var oModelAppData = this.getView().getModel("appData");
oModelAppData.setProperty("/showDetails", !oModelAppData.getProperty("/showDetails"));
},
onSubOperatorPress: function(evt) {
const modelContext = evt.getSource().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
this.getOwnerComponent().getRouter().navTo("SubOperator", {
Code: modelData.U_SUBOPERATOR
});
},
applyFilters: function() {
var sKey = this.byId("cbPeriod").getProperty("selectedKey");
//console.log("Filter: " + this.byId("cbPeriod").getSelectedKey());
var aFilters = [];
if (sKey && sKey.length > 0) {
aFilters.push(new Filter("U_FROM", sap.ui.model.FilterOperator.EQ, sKey));
}
var oFilter = new Filter({
filters: aFilters,
and: true
});
var oBinding = this.byId("tableProviderPrices").getBinding("items");
oBinding.filter(oFilter, "Application");
this.refreshModelAppData();
},
onSelectPeriod: function(evt) {
this.applyFilters();
},
// Function to normalize values (treat null as empty string)
normalizeValue: function(value) {
return (value === null) ? '' : value;
},
// Function to check for duplicate property values based on specified properties
findDuplicatesByProperties: function(arr, props) {
const occurrences = new Map();
const duplicates = [];
arr.forEach(item => {
const key = props.map(prop => this.normalizeValue(item[prop])).join('|');
if (occurrences.has(key)) {
duplicates.push(item);
} else {
occurrences.set(key, true);
}
});
return duplicates;
},
checkDuplicates: function() {
// List of properties to check for duplicates
const properties = ['Code', 'U_CODE', 'U_FROM', 'U_OPERATOR', 'U_TYP', 'U_SUBOPERATOR'];
const oModel = this.getView().getModel(),
oContext = this.getView().getBindingContext(),
oData = JSON.parse(JSON.stringify(oModel.getProperty("Lines", oContext)));
// reset highlight status
oData.forEach((row) => {
row.highlight = 'None';
row.highlightText = '';
});
// Check for duplicates by the specified properties
const duplicates = this.findDuplicatesByProperties(oData, properties);
oData.forEach((row) => {
if (duplicates.some((d) => {
return row.Code === d.Code && row.U_CODE === d.U_CODE && row.U_FROM === d.U_FROM && row.U_OPERATOR === d.U_OPERATOR && row.U_TYP ===
d.U_TYP && this.normalizeValue(row.U_SUBOPERATOR) === this.normalizeValue(d.U_SUBOPERATOR);
})) {
row.highlight = 'Error';
row.highlightText = 'Duplicate';
}
});
oModel.setProperty("Lines", oData, oContext);
return duplicates.length > 0;
},
refreshModelAppData: function() {
var oBusyDialog = new sap.m.BusyDialog({
title: "Please wait",
text: "Loading data...",
showCancelButton: false
});
oBusyDialog.open();
const readOnly = this.getView().getModel().getProperty('/ReadOnly');
var filterPeriodFrom = this.byId("cbPeriod").getProperty("selectedKey");
var oModelAppData = this.getView().getModel("appData");
var oData = this.getView().getBindingContext().getObject();
var oPeriod = oData.Periods.find(p => p.U_FROM === filterPeriodFrom);
var released = typeof oPeriod !== 'undefined' && oPeriod.U_RELEASED === 'Y';
oModelAppData.setProperty("/editable", !released && !readOnly);
oModelAppData.setProperty("/released", released);
this.byId("otbEdit").setEnabled(false);
this.byId("otbEdit").setPressed(false);
this.byId("otbRemove").setEnabled(false);
this.byId("tableProviderPrices").removeSelections();
var oLinesData = JSON.parse(JSON.stringify(this.getView().getBindingContext().getProperty('Lines')));
for (let i = 0; i < oLinesData.length; i++) {
oLinesData[i].editable = false;
}
this.getView().getBindingContext().setProperty('Lines', oLinesData);
this.checkDuplicates();
oBusyDialog.close();
},
updateData: function(method, filterPeriodFrom) {
var that = this;
var oModel = this.getView().getModel();
var oData = this.getView().getBindingContext().getObject();
var payload = JSON.parse(JSON.stringify(oData));
delete payload.Periods;
delete payload.NextPeriod;
if (method === 'approve' || method === 'reject') {
payload.Lines.forEach(function(l) {
if (l.U_FROM === filterPeriodFrom) {
l.U_RELEASED = method === 'approve' ? 'Y' : 'N';
}
});
} else if (method !== 'save') {
throw new Error("method not implemented: " + method);
}
var isInvalid = false;
payload.Lines.forEach(l => {
isInvalid = parseFloat(l.U_VALUE) < 0 || isInvalid;
});
var hasDuplicate = this.checkDuplicates();
if (isInvalid && method !== 'reject') {
MessageBox.alert("Cannot save with invalid values");
} else if (hasDuplicate && method !== 'reject') {
MessageBox.alert("Cannot save with duplicate entries");
} else {
var oBusyDialog = new sap.m.BusyDialog({
title: "Please wait",
text: "Processing data...",
showCancelButton: false
});
oBusyDialog.open();
fetch('/uniorg/eon/emobility/provider/backend/setProviderLinesData.xsjs', {
method: 'POST',
async: false,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
})
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw Error(response.statusText);
}
}
return response.json();
})
.then(data => {
console.log(data);
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw Error("unexpected response from backend service");
}
fetch('/uniorg/eon/emobility/provider/backend/getProviderData.xsjs')
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw new Error('Failed to retrieve data. HTTP STATUS ' + response.status.toString() + ' ' + response.statusText);
}
}
return response.json();
})
.then(data => {
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw new Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw new Error("Unexpected response from backend service");
} else if (!data.resultSet) {
throw new Error("Unexpected response from backend service");
}
const provider = data.resultSet;
//const oModel = new JSONModel(provider);
this.getView().getModel().setProperty("/", provider);
this.getView().getModel().refresh(true);
this.refreshModelAppData();
oBusyDialog.close();
})
.catch(error => {
console.error(error);
oBusyDialog.close();
MessageBox.error("Communication with backend service failed", {
details: error.message
});
});
})
.catch(error => {
console.error(error);
oBusyDialog.close();
MessageBox.error("Communication with backend service failed", {
details: error.message
});
});
}
},
onDateToChange: function(evt) {
var filterPeriodFrom = this.byId("cbPeriod").getProperty("selectedKey");
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
var oEvtContext = evt.getSource().getBindingContext();
var newValue = oEvtContext.getProperty("U_TO");
var oData = oModel.getProperty("Lines", oContext);
var newData = JSON.parse(JSON.stringify(oData));
newData.forEach(row => {
if (row.U_FROM === filterPeriodFrom) {
row.U_TO = newValue;
}
});
oModel.setProperty("Lines", newData, oContext);
oModel.setProperty("pendingChanges", true, oContext);
oModel.refresh(true);
},
updatePendingChanges: function(evt) {
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
oModel.setProperty("pendingChanges", true, oContext);
//oModel.refresh(true);
},
onCodeChange: function(evt) {
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
var oEvtContext = evt.getSource().getBindingContext();
var code = oEvtContext.getProperty("U_CODE");
if (code === 'MINUTES_BLOCK') {
oEvtContext.setProperty("Decimals", 0);
oEvtContext.setProperty("Unit", "min")
} else if (code === 'PRICE_BLOCK') {
oEvtContext.setProperty("Decimals", 4);
oEvtContext.setProperty("Unit", "EUR / min")
} else {
oEvtContext.setProperty("Decimals", 4);
oEvtContext.setProperty("Unit", "EUR / kWh")
}
oModel.setProperty("pendingChanges", true, oContext);
this.checkDuplicates();
oModel.refresh(true);
},
onAddLine: function(evt) {
const filterPeriodFrom = this.byId("cbPeriod").getProperty("selectedKey");
const oModel = this.getView().getModel(),
oContext = this.getView().getBindingContext(),
modelData = JSON.parse(JSON.stringify(oContext.getProperty('Lines'))),
providerCode = oContext.getProperty('Code'),
guid = this.generateUUID();
modelData.push({
BlockMaxCurrency: "EUR",
Code: providerCode,
Decimals: 4,
LineId: null,
U_BLOCKMAX: 0,
U_BLOCK_FROM: "00:00",
U_BLOCK_TO: "00:00",
U_CHANGE_DATE: null,
U_CHANGE_USER: null,
U_CODE: "PRICE_KWH",
U_FROM: filterPeriodFrom,
U_OPERATOR: "--",
U_SUBOPERATOR: '',
U_RELEASED: "N",
U_RELEASE_DATE: null,
U_RELEASE_USER: null,
U_TO: modelData.find((l) => l.U_FROM === filterPeriodFrom).U_TO,
U_TYP: "--",
U_VALUE: 0.0,
U_CURRENCY: 'EUR',
Unit: "EUR / kWh",
ValueCurrency: "EUR",
editable: true,
new: true,
guid: guid,
highlight: "None",
highlightText: ""
});
oModel.setProperty('Lines', modelData, oContext);
this.updatePendingChanges();
this.byId("tableProviderPrices").getSelectedContexts().forEach((context) => {
context.setProperty('editable', false);
});
this.byId("tableProviderPrices").getItems().find((item) => {
return item.getBindingContext().getProperty('guid') === guid;
})?.setSelected(true);
this.byId("otbEdit").setEnabled(true);
this.byId("otbEdit").setPressed(true);
this.byId("otbRemove").setEnabled(true);
},
updatePendingChanges: function(evt) {
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
oModel.setProperty("pendingChanges", true, oContext);
//oModel.refresh(true);
},
onChangeRefresh: function(evt) {
this.updatePendingChanges(evt);
this.checkDuplicates();
var oModel = this.getView().getModel();
oModel.refresh(true);
},
onSave: function(evt) {
this.updateData('save');
},
onCancel: function(evt) {
this.reloadModelData();
this.refreshModelAppData();
},
onReject: function(evt) {
var filterPeriodFrom = this.byId("cbPeriod").getProperty("selectedKey");
if (filterPeriodFrom) {
this.updateData('reject', filterPeriodFrom);
}
},
onApprove: function(evt) {
var filterPeriodFrom = this.byId("cbPeriod").getProperty("selectedKey");
if (filterPeriodFrom) {
this.updateData('approve', filterPeriodFrom);
}
},
/*onRowPress: function(evt) {
const modelContext = evt.getSource().getBindingContext(),
modelPath = evt.getSource().getBindingContext().getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
this.getOwnerComponent().getRouter().navTo("Lines", {
Code: modelData.Code,
LineId: modelData.LineId
});
},*/
onEditLine: function(evt) {
const modelContext = this.byId("tableProviderPrices").getSelectedItem().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
var editPressed = this.byId("otbEdit").getPressed();
this.getView().getModel().setProperty("editable", editPressed, modelContext);
},
onRemoveLine: function(evt) {
const modelContext = this.byId("tableProviderPrices").getSelectedItem().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath),
guid = modelData.guid,
oLinesData = JSON.parse(JSON.stringify(this.getView().getBindingContext().getProperty('Lines'))),
lineIdx = oLinesData.findIndex((l) => l.guid === guid);
oLinesData.splice(lineIdx, 1);
this.getView().getBindingContext().setProperty('Lines', oLinesData);
this.updatePendingChanges();
this.refreshModelAppData();
},
onSelectionChange: function(evt) {
const selectedContext = this.byId("tableProviderPrices").getSelectedItem().getBindingContext();
var oLinesData = JSON.parse(JSON.stringify(this.getView().getBindingContext().getProperty('Lines')));
for (let i = 0; i < oLinesData.length; i++) {
oLinesData[i].editable = false;
}
this.getView().getBindingContext().setProperty('Lines', oLinesData);
this.byId("otbEdit").setPressed(false);
/*const modelContext = evt.getParameters().listItem.getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);*/
var oModelAppData = this.getView().getModel("appData");
var released = oModelAppData.getProperty("/released");
const readOnly = this.getView().getModel().getProperty('/ReadOnly');
if (!readOnly && !released) {
this.byId("otbEdit").setEnabled(true);
// only allow remove for new (unsafed) lines
this.byId("otbRemove").setEnabled(selectedContext.getProperty('new'));
} else {
this.byId("otbEdit").setEnabled(false);
this.byId("otbRemove").setEnabled(false);
}
}
});
});
@@ -0,0 +1,367 @@
sap.ui.define([
"./BaseController",
"sap/ui/core/routing/History",
"sap/m/MessageBox"
], function(BaseController, History, MessageBox) {
"use strict";
return BaseController.extend("uniorg.eon.emobility.provider.ui.pricematrix.controller.ProviderNextPeriod", {
onInit: function() {
this.getOwnerComponent().getRouter().getRoute("ProviderNextPeriod").attachPatternMatched(this.onRouteMatched, this);
this.byId("tableProviderNextPeriod").setKeyboardMode(sap.m.ListKeyboardMode.Edit);
},
onRouteMatched: function(evt) {
var providerCode = evt.getParameter("arguments").Code;
var oData = this.getView().getModel().getData();
var pIdx = oData.Provider.findIndex(p => p.Code === providerCode);
if (pIdx === -1) {
pIdx = 0;
}
this.getView().bindElement({
path: "/Provider/" + pIdx
});
/*this.getView().bindElement({
path: "/Provider/'" + evt.getParameter("arguments").Code + "')"
});*/
},
onSubmit: function(evt) {
var that = this;
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
var oData = this.getView().getBindingContext().getObject();
var payload = JSON.parse(JSON.stringify(oData));
delete payload.Periods;
delete payload.Lines;
var isInvalid = false;
payload.NextPeriod.forEach(np => {
isInvalid = parseFloat(np.NewValue) < 0 || isInvalid;
});
var hasDuplicate = this.checkDuplicates();
if (isInvalid) {
MessageBox.alert("Cannot save with invalid values");
} else if (hasDuplicate) {
MessageBox.alert("Cannot save with duplicate entries");
} else {
var oBusyDialog = new sap.m.BusyDialog({
title: "Please wait",
text: "Processing data...",
showCancelButton: false
});
oBusyDialog.open();
fetch('/uniorg/eon/emobility/provider/backend/addNextPeriodData.xsjs', {
method: 'POST',
async: false,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
})
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw new Error('Failed to save data. HTTP STATUS ' + response.status.toString() + ' ' + response.statusText);
}
}
return response.json();
})
.then(data => {
console.log(data);
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw new Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw new Error("Unexpected response from backend service");
}
oModel.setProperty("allowNewPeriod", false, oContext);
fetch('/uniorg/eon/emobility/provider/backend/getProviderData.xsjs')
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw new Error('Failed to retrieve data. HTTP STATUS ' + response.status.toString() + ' ' + response.statusText);
}
}
return response.json();
})
.then(data => {
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw new Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw new Error("Unexpected response from backend service");
} else if (!data.resultSet) {
throw new Error("Unexpected response from backend service");
}
const provider = data.resultSet;
//const oModel = new JSONModel(provider);
this.getView().getModel().setProperty("/", provider);
this.getView().getModel().refresh(true);
oBusyDialog.close();
this.getOwnerComponent().getRouter().navTo("Provider", {
Code: payload.Code
}, true /*no history*/ );
})
.catch(error => {
console.error(error);
oBusyDialog.close();
MessageBox.error("Communication with backend service failed", {
details: error.message
});
});
})
.catch(error => {
console.error(error);
oBusyDialog.close();
MessageBox.error("Communication with backend service failed", {
details: error.message
});
});
}
},
onBackPress: function() {
// this.getOwnerComponent().getRouter().navTo("BillingRunList");
var oHistory = History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
this.getOwnerComponent().getRouter().navTo("Overview", true);
}
},
onChangeRefresh: function(evt) {
this.checkDuplicates();
var oModel = this.getView().getModel();
oModel.refresh(true);
},
// Function to normalize values (treat null as empty string)
normalizeValue: function(value) {
return (value === null) ? '' : value;
},
// Function to check for duplicate property values based on specified properties
findDuplicatesByProperties: function(arr, props) {
const occurrences = new Map();
const duplicates = [];
arr.forEach(item => {
const key = props.map(prop => this.normalizeValue(item[prop])).join('|');
if (occurrences.has(key)) {
duplicates.push(item);
} else {
occurrences.set(key, true);
}
});
return duplicates;
},
checkDuplicates: function() {
// List of properties to check for duplicates
const properties = ['Code', 'U_CODE', 'U_FROM', 'U_OPERATOR', 'U_TYP', 'U_SUBOPERATOR'];
const oModel = this.getView().getModel(),
oContext = this.getView().getBindingContext(),
oData = JSON.parse(JSON.stringify(oModel.getProperty("NextPeriod", oContext)));
// reset highlight status
oData.forEach((row) => {
row.highlight = 'None';
row.highlightText = '';
});
// Check for duplicates by the specified properties
const duplicates = this.findDuplicatesByProperties(oData, properties);
oData.forEach((row) => {
if (duplicates.some((d) => {
return row.Code===d.Code && row.U_CODE===d.U_CODE && row.U_FROM===d.U_FROM && row.U_OPERATOR===d.U_OPERATOR && row.U_TYP===d.U_TYP && this.normalizeValue(row.U_SUBOPERATOR) === this.normalizeValue(d.U_SUBOPERATOR);
})) {
row.highlight = 'Error';
row.highlightText = 'Duplicate';
}
});
oModel.setProperty("NextPeriod", oData, oContext);
return duplicates.length > 0;
},
onDateToChange: function(evt) {
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
var oEvtContext = evt.getSource().getBindingContext();
var newValue = oEvtContext.getProperty("U_TO");
var oData = oModel.getProperty("NextPeriod", oContext);
var newData = JSON.parse(JSON.stringify(oData));
newData.forEach(row => row.U_TO = newValue);
oModel.setProperty("NextPeriod", newData, oContext);
oModel.refresh(true);
},
/*onOrgIdChange: function(evt) {
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
var oEvtContext = evt.getSource().getBindingContext();
var orgId = oEvtContext.getProperty("U_ORG_ID");
if (orgId === '') {
oEvtContext.setProperty("U_ORG_NAME", '');
} else {
var oData = oModel.getProperty("NextPeriod", oContext);
var newData = JSON.parse(JSON.stringify(oData));
var orgName = newData.find((l) => l.U_ORG_ID === orgId && l.U_ORG_NAME)?.U_ORG_NAME;
newData.forEach(row => {
if (row.U_ORG_ID === orgId) {
row.U_ORG_NAME = orgName;
}
});
oModel.setProperty("NextPeriod", newData, oContext);
}
this.checkDuplicates();
oModel.refresh(true);
},
onOrgNameChange: function(evt) {
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
var oEvtContext = evt.getSource().getBindingContext();
var orgId = oEvtContext.getProperty("U_ORG_ID");
var orgName = oEvtContext.getProperty("U_ORG_NAME");
var oData = oModel.getProperty("NextPeriod", oContext);
var newData = JSON.parse(JSON.stringify(oData));
newData.forEach(row => {
if (row.U_ORG_ID === orgId) {
row.U_ORG_NAME = orgName;
}
});
oModel.setProperty("NextPeriod", newData, oContext);
oModel.refresh(true);
},*/
onCodeChange: function(evt) {
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
var oEvtContext = evt.getSource().getBindingContext();
var code = oEvtContext.getProperty("U_CODE");
if (code === 'MINUTES_BLOCK') {
oEvtContext.setProperty("Decimals", 0);
oEvtContext.setProperty("Unit", "min")
} else if (code === 'PRICE_BLOCK'){
oEvtContext.setProperty("Decimals", 4);
oEvtContext.setProperty("Unit", "EUR / min")
} else {
oEvtContext.setProperty("Decimals", 4);
oEvtContext.setProperty("Unit", "EUR / kWh")
}
this.checkDuplicates();
oModel.refresh(true);
},
onAddLine: function(evt) {
const oModel = this.getView().getModel(),
oContext = this.getView().getBindingContext(),
modelData = JSON.parse(JSON.stringify(oContext.getProperty('NextPeriod'))),
providerCode = oContext.getProperty('Code'),
guid = this.generateUUID();
modelData.push({
BlockMaxCurrency: "EUR",
Code: providerCode,
Decimals: 4,
LineId: null,
U_BLOCKMAX: 0,
U_BLOCK_FROM: "00:00",
U_BLOCK_TO: "00:00",
U_CHANGE_DATE: null,
U_CHANGE_USER: null,
U_CODE: "PRICE_KWH",
U_FROM: modelData[0]?.U_FROM,
U_OPERATOR: "--",
U_SUBOPERATOR: "",
U_RELEASED: "N",
U_RELEASE_DATE: null,
U_RELEASE_USER: null,
U_TO: modelData[0]?.U_TO,
U_TYP: "--",
U_VALUE: 0.0,
U_CURRENCY: 'EUR',
NewValue: 0.0,
Unit: "EUR / kWh",
ValueCurrency: "EUR",
editable: true,
guid: guid,
highlight: "None",
highlightText: ""
});
oModel.setProperty('NextPeriod', modelData, oContext);
this.byId("tableProviderNextPeriod").getSelectedContexts().forEach((context) => {context.setProperty('editable', false);});
this.byId("tableProviderNextPeriod").getItems().find((item) => {return item.getBindingContext().getProperty('guid') === guid;})?.setSelected(true);
this.byId("otbEdit").setEnabled(true);
this.byId("otbEdit").setPressed(true);
this.byId("otbRemove").setEnabled(true);
},
onEditLine: function(evt) {
const modelContext = this.byId("tableProviderNextPeriod").getSelectedItem().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
var editPressed = this.byId("otbEdit").getPressed();
this.getView().getModel().setProperty("editable", editPressed, modelContext);
if (!editPressed) {
this.byId("otbEdit").setEnabled(false);
this.byId("otbRemove").setEnabled(false);
this.byId("tableProviderNextPeriod").removeSelections();
}
},
onRemoveLine: function(evt) {
const modelContext = this.byId("tableProviderNextPeriod").getSelectedItem().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath),
guid = modelData.guid,
oLinesData = JSON.parse(JSON.stringify(this.getView().getBindingContext().getProperty('NextPeriod'))),
lineIdx = oLinesData.findIndex((l) => l.guid === guid);
oLinesData.splice(lineIdx, 1);
this.getView().getBindingContext().setProperty('NextPeriod', oLinesData);
this.byId("otbEdit").setPressed(false);
this.byId("otbEdit").setEnabled(false);
this.byId("otbRemove").setEnabled(false);
this.byId("tableProviderNextPeriod").removeSelections();
this.checkDuplicates();
},
onSelectionChange: function(evt) {
const selectedContext = this.byId("tableProviderNextPeriod").getSelectedItem().getBindingContext();
var oLinesData = JSON.parse(JSON.stringify(this.getView().getBindingContext().getProperty('NextPeriod')));
for (let i = 0; i < oLinesData.length; i++) {
oLinesData[i].editable = false;
}
this.getView().getBindingContext().setProperty('NextPeriod', oLinesData);
this.byId("otbEdit").setPressed(false);
this.byId("otbEdit").setEnabled(true);
this.byId("otbRemove").setEnabled(true);
},
onClearPress: function(evt) {
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
var oData = oModel.getProperty("NextPeriod", oContext);
var newData = JSON.parse(JSON.stringify(oData));
newData.forEach(row => row.NewValue = 0.0);
oModel.setProperty("NextPeriod", newData, oContext);
oModel.refresh(true);
},
onCopyPress: function(evt) {
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
var oData = oModel.getProperty("NextPeriod", oContext);
var newData = JSON.parse(JSON.stringify(oData));
newData.forEach(row => row.NewValue = row.U_VALUE);
oModel.setProperty("NextPeriod", newData, oContext);
oModel.refresh(true);
}
});
});
@@ -0,0 +1,489 @@
sap.ui.define([
"./BaseController",
"sap/ui/core/routing/History",
"sap/ui/model/Filter",
"sap/ui/model/json/JSONModel",
"sap/m/MessageBox",
'sap/ui/core/Fragment'
], function(BaseController, History, Filter, JSONModel, MessageBox, Fragment) {
"use strict";
return BaseController.extend("uniorg.eon.emobility.provider.ui.pricematrix.controller.SubOperator", {
onInit: function() {
this.getOwnerComponent().getRouter().getRoute("SubOperator").attachPatternMatched(this.onRouteMatched, this);
const oModelAppData = new JSONModel({
editable: false
});
this.getView().setModel(oModelAppData, "appData");
this.byId("tableOrganizations").setKeyboardMode(sap.m.ListKeyboardMode.Edit);
},
onRouteMatched: function(evt) {
var subOperatorCode = evt.getParameter("arguments").Code;
var subOperators = this.getView().getModel().getProperty("/SubOperators");
if (!subOperators) {
return;
}
var idx = subOperators.findIndex(s => s.Code === subOperatorCode);
if (idx === -1) {
idx = 0;
}
this.getView().bindElement({
path: "/SubOperators/" + idx
});
},
onBackPress: function() {
var oHistory = History.getInstance();
var sPreviousHash = oHistory.getPreviousHash();
if (sPreviousHash !== undefined) {
window.history.go(-1);
} else {
this.getOwnerComponent().getRouter().navTo("Overview", true);
}
},
onPreviousPress: function() {
const subOperators = this.getView().getModel().getProperty("/SubOperators"),
currentCode = this.getView().getBindingContext().getProperty("Code");
var idx = subOperators.findIndex(s => s.Code === currentCode);
var nextIdx = idx - 1;
if (idx === -1) {
nextIdx = 0;
}
if (nextIdx === -1) {
nextIdx = subOperators.length - 1;
}
var nextCode = subOperators[nextIdx].Code;
this.getOwnerComponent().getRouter().navTo("SubOperator", {
Code: nextCode
}, true);
},
onNextPress: function() {
const subOperators = this.getView().getModel().getProperty("/SubOperators"),
currentCode = this.getView().getBindingContext().getProperty("Code");
var idx = subOperators.findIndex(s => s.Code === currentCode);
var nextIdx = idx + 1;
if (idx === -1) {
nextIdx = 0;
}
if (nextIdx > subOperators.length - 1) {
nextIdx = 0;
}
var nextCode = subOperators[nextIdx].Code;
this.getOwnerComponent().getRouter().navTo("SubOperator", {
Code: nextCode
}, true);
},
onCancel: function(evt) {
const newEntry = this.getView().getBindingContext().getProperty('newEntry');
this.reloadModelData();
this.byId("otbRemove").setEnabled(false);
this.byId("tableOrganizations").removeSelections();
if (newEntry) {
this.onPreviousPress();
}
},
onAddLine: function(evt) {
const oModel = this.getView().getModel(),
oContext = this.getView().getBindingContext(),
modelData = JSON.parse(JSON.stringify(oContext.getProperty('Organizations'))),
subOperatorCode = oContext.getProperty('Code'),
guid = this.generateUUID();
modelData.push({
Code: subOperatorCode,
LineId: null,
U_ORG_ID: "",
guid: guid,
highlight: "None",
highlightText: ""
});
oModel.setProperty('Organizations', modelData, oContext);
this.byId("tableOrganizations").getSelectedContexts().forEach((context) => {
context.setProperty('editable', false);
});
this.byId("tableOrganizations").getItems().find((item) => {
return item.getBindingContext().getProperty('guid') === guid;
})?.setSelected(true);
this.byId("otbRemove").setEnabled(true);
},
onEditLine: function(evt) {
const modelContext = this.byId("tableOrganizations").getSelectedItem().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath);
var editPressed = this.byId("otbEdit").getPressed();
this.getView().getModel().setProperty("editable", editPressed, modelContext);
if (!editPressed) {
this.byId("otbRemove").setEnabled(false);
this.byId("tableOrganizations").removeSelections();
}
},
onRemoveLine: function(evt) {
const modelContext = this.byId("tableOrganizations").getSelectedItem().getBindingContext(),
modelPath = modelContext.getPath(),
modelData = this.getView().getModel().getProperty(modelPath),
guid = modelData.guid,
oLinesData = JSON.parse(JSON.stringify(this.getView().getBindingContext().getProperty('Organizations'))),
lineIdx = oLinesData.findIndex((l) => l.guid === guid);
oLinesData.splice(lineIdx, 1);
this.getView().getBindingContext().setProperty('Organizations', oLinesData);
this.byId("otbRemove").setEnabled(false);
this.byId("tableOrganizations").removeSelections();
this.checkDuplicates();
this.updatePendingChanges();
},
onOrgIdChange: function(evt) {
this.checkDuplicates();
this.getView().getModel().refresh(true);
},
updatePendingChanges: function(evt) {
var oModel = this.getView().getModel();
var oContext = this.getView().getBindingContext();
oModel.setProperty("pendingChanges", true, oContext);
//oModel.refresh(true);
},
// Function to normalize values (treat null as empty string)
normalizeValue: function(value) {
return (value === null) ? '' : value;
},
// Function to check for duplicate property values based on specified properties
findDuplicatesByProperties: function(arr, props) {
const occurrences = new Map();
const duplicates = [];
arr.forEach(item => {
const key = props.map(prop => this.normalizeValue(item[prop])).join('|');
if (occurrences.has(key)) {
duplicates.push(item);
} else {
occurrences.set(key, true);
}
});
return duplicates;
},
checkDuplicates: function() {
// List of properties to check for duplicates
const properties = ['U_ORG_ID'];
const oModel = this.getView().getModel(),
oContext = this.getView().getBindingContext(),
oData = JSON.parse(JSON.stringify(oModel.getProperty("Organizations", oContext)));
// reset highlight status
oData.forEach((row) => {
row.highlight = 'None';
row.highlightText = '';
});
// Check for duplicates by the specified properties
const duplicates = this.findDuplicatesByProperties(oData, properties);
oData.forEach((row) => {
if (duplicates.some((d) => {
return this.normalizeValue(row.U_ORG_ID) === this.normalizeValue(d.U_ORG_ID);
})) {
row.highlight = 'Error';
row.highlightText = 'Duplicate';
}
});
oModel.setProperty("Organizations", oData, oContext);
return duplicates.length > 0;
},
updateData: function(method) {
var that = this;
var oModel = this.getView().getModel();
var oData = this.getView().getBindingContext().getObject();
var payload = JSON.parse(JSON.stringify(oData));
if (method !== 'save') {
throw new Error("method not implemented: " + method);
}
var isInvalid = false;
payload.Organizations.forEach(l => {
isInvalid = !l.U_ORG_ID || isInvalid;
});
var hasDuplicate = this.checkDuplicates();
if (isInvalid) {
MessageBox.alert("Cannot save with invalid values");
} else if (hasDuplicate) {
MessageBox.alert("Cannot save with duplicate entries");
} else {
var oBusyDialog = new sap.m.BusyDialog({
title: "Please wait",
text: "Processing data...",
showCancelButton: false
});
oBusyDialog.open();
fetch('/uniorg/eon/emobility/provider/backend/setSubOperatorData.xsjs', {
method: 'POST',
async: false,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
})
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw Error(response.statusText);
}
}
return response.json();
})
.then(data => {
console.log(data);
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw Error("unexpected response from backend service");
}
fetch('/uniorg/eon/emobility/provider/backend/getProviderData.xsjs')
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw new Error('Failed to retrieve data. HTTP STATUS ' + response.status.toString() + ' ' + response.statusText);
}
}
return response.json();
})
.then(data => {
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw new Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw new Error("Unexpected response from backend service");
} else if (!data.resultSet) {
throw new Error("Unexpected response from backend service");
}
const provider = data.resultSet;
//const oModel = new JSONModel(provider);
this.getView().getModel().setProperty("/", provider);
this.getView().getModel().refresh(true);
oBusyDialog.close();
})
.catch(error => {
console.error(error);
oBusyDialog.close();
MessageBox.error("Communication with backend service failed", {
details: error.message
});
});
})
.catch(error => {
console.error(error);
oBusyDialog.close();
MessageBox.error("Communication with backend service failed", {
details: error.message
});
});
}
},
onSave: function(evt) {
this.updateData('save');
},
onSelectionChange: function(evt) {
const selectedContext = this.byId("tableOrganizations").getSelectedItem().getBindingContext();
var oLinesData = JSON.parse(JSON.stringify(this.getView().getBindingContext().getProperty('Organizations')));
for (let i = 0; i < oLinesData.length; i++) {
oLinesData[i].editable = false;
}
this.getView().getBindingContext().setProperty('Organizations', oLinesData);
const readOnly = this.getView().getModel().getProperty('/ReadOnly');
if (!readOnly) {
this.byId("otbRemove").setEnabled(true);
}
},
onCreateSubOperator: function() {
// Open the dialog to create a new SubOperator
if (!this._oDialog) {
this._oDialog = this.byId("createSubOperatorDialog");
}
this._oDialog.open();
},
onCancelCreateSubOperator: function() {
// Close the dialog when cancel button is pressed
this._oDialog.close();
},
onConfirmCreateSubOperator: function() {
// Get the values from the input fields
var oCodeInput = this.byId("subOperatorCode");
var oNameInput = this.byId("subOperatorName");
var sCode = oCodeInput.getValue();
var sName = oNameInput.getValue();
// Validate the inputs
if (!sCode || !sName) {
MessageBox.error("Please enter both Code and Name.");
return;
}
// Create a new SubOperator entry
var oModel = this.getView().getModel();
var aSubOperators = JSON.parse(JSON.stringify(oModel.getProperty("/SubOperators"))); // Adjust the path to your model
// Push the new SubOperator into the list
aSubOperators.push({
Code: sCode,
Name: sName,
pendingChanges: true,
newEntry: true,
Organizations: [
{
Code: sCode,
LineId: null,
U_ORG_ID: "",
guid: this.generateUUID(),
highlight: "None",
highlightText: ""
}
]
});
// Update the model with the new entry
oModel.setProperty("/SubOperators", aSubOperators);
// Close the dialog and reset input fields
this._oDialog.close(); oCodeInput.setValue(""); oNameInput.setValue("");
this.getOwnerComponent().getRouter().navTo("SubOperator", {
Code: sCode
}, true);
},
onDeleteSubOperator: function() {
// Open the delete confirmation dialog
var oDialog = this.byId("deleteSubOperatorDialog");
oDialog.open();
},
onCancelDeleteSubOperator: function() {
// Close the delete confirmation dialog
this.byId("deleteSubOperatorDialog").close();
},
onConfirmDeleteSubOperator: function() {
this.byId("deleteSubOperatorDialog").close();
var that = this;
const oModel = this.getView().getModel(),
subOperators = oModel.getProperty("/SubOperators"),
subOperatorCode = this.getView().getBindingContext().getProperty("Code"),
newEntry = this.getView().getBindingContext().getProperty("newEntry"),
providerData = JSON.parse(JSON.stringify(oModel.getProperty('/Provider')));
// find previous SubOperator Code to navigate to after successful deletion
var idx = subOperators.findIndex(s => s.Code === subOperatorCode);
var nextIdx = idx - 1;
if (idx === -1) {
nextIdx = 0;
}
if (nextIdx === -1) {
nextIdx = subOperators.length - 1;
}
var nextCode = subOperators[nextIdx].Code;
// check if the SubOperator Code is still in use
if (providerData.some((prov) => prov.Lines.some((l) => l.U_SUBOPERATOR === subOperatorCode))) {
MessageBox.alert("SubOperator is still in use and cannot be deleted.")
} else if (newEntry) {
MessageBox.alert("This new SubOperator was not saved yet, no need to delete it.")
}else {
var oBusyDialog = new sap.m.BusyDialog({
title: "Please wait",
text: "Processing data...",
showCancelButton: false
});
oBusyDialog.open();
fetch('/uniorg/eon/emobility/provider/backend/deleteSubOperator.xsjs?debug=true', {
method: 'POST',
async: false,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
Code: subOperatorCode
})
})
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw Error(response.statusText);
}
}
return response.json();
})
.then(data => {
console.log(data);
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw Error("unexpected response from backend service");
}
fetch('/uniorg/eon/emobility/provider/backend/getProviderData.xsjs')
.then(response => {
if (!response.ok) {
const contentType = response.headers.get("content-type");
if (!contentType || contentType.indexOf("application/json") === -1) {
throw new Error('Failed to retrieve data. HTTP STATUS ' + response.status.toString() + ' ' + response.statusText);
}
}
return response.json();
})
.then(data => {
if (data.status === "error" && data.messages.some(outMsg => outMsg.status === "error")) {
throw new Error(data.messages.find(outMsg => outMsg.status === "error").message);
} else if (data.status !== "success") {
throw new Error("Unexpected response from backend service");
} else if (!data.resultSet) {
throw new Error("Unexpected response from backend service");
}
const provider = data.resultSet;
//const oModel = new JSONModel(provider);
this.getView().getModel().setProperty("/", provider);
this.getView().getModel().refresh(true);
oBusyDialog.close();
this.getOwnerComponent().getRouter().navTo("SubOperator", {
Code: nextCode
}, true);
})
.catch(error => {
console.error(error);
oBusyDialog.close();
MessageBox.error("Communication with backend service failed", {
details: error.message
});
});
})
.catch(error => {
console.error(error);
oBusyDialog.close();
MessageBox.error("Communication with backend service failed", {
details: error.message
});
});
}
}
});
});
@@ -0,0 +1,12 @@
html[dir="ltr"] .myAppDemoWT .myCustomButton.sapMBtn {
margin-right: 0.125rem
}
html[dir="rtl"] .myAppDemoWT .myCustomButton.sapMBtn {
margin-left: 0.125rem
}
.myAppDemoWT .myCustomText {
display: inline-block;
font-weight: bold;
}
@@ -0,0 +1,11 @@
# App Descriptor
appTitle=e.on Provider Price Matrix
appDescription=Maintain provider charges
# General
homePageTitle=e.on Provider Price Matrix
#NotFound
NotFound=Page not found
NotFound.text=Page not found
NotFound.description=The requested page could not be found.
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>e.on Provider Price Matrix</title>
<!-- Use last stable ui5 Version: src="https://sapui5.hana.ondemand.com/1.108.12/resources/sap-ui-core.js" -->
<script
id="sap-ui-bootstrap"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_horizon"
data-sap-ui-libs="sap.m, sap.ui.core"
data-sap-ui-resourceroots='{
"uniorg.eon.emobility.provider.ui.pricematrix": "./"
}'
data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
data-sap-ui-compatVersion="edge"
data-sap-ui-async="true">
</script>
<link rel="stylesheet" type="text/css" href="https://sapui5.hana.ondemand.com/resources/sap/ui/core/themes/sap_horizon/library.css" />
</head>
<body class="sapUiBody" id="content">
<div data-sap-ui-component data-name="uniorg.eon.emobility.provider.ui.pricematrix" data-id="container" data-settings='{"id" : "pricematrix"}'></div>
</body>
</html>
@@ -1,19 +1,147 @@
{
"_version": "1.0.0",
"sap.app": {
"id": "uniorg.eon.emobility.provider.ui.pricematrix",
"type": "application",
"i18n": "i18n/i18n.properties",
"title": "{{appTitle}}",
"description": "{{appDescription}}",
"applicationVersion": {
"version": "1.0.0"
}
},
"sap.ui5": {
"rootView": {
"viewName": "uniorg.eon.emobility.provider.ui.pricematrix.view.App",
"type": "XML"
}
}
"_version": "1.0.0",
"sap.app": {
"id": "uniorg.eon.emobility.provider.ui.pricematrix",
"type": "application",
"i18n": "i18n/i18n.properties",
"title": "{{appTitle}}",
"description": "{{appDescription}}",
"applicationVersion": {
"version": "1.0.0"
},
"dataSources": {
"provider": {
"uri": "../../xsodata/eonProvider.xsodata",
"type": "OData",
"settings": {
"odataVersion": "2.0",
"disableHeadRequestForToken": true
}
}
}
},
"sap.ui": {
"technology": "UI5",
"deviceTypes": {
"desktop": true,
"tablet": true,
"phone": true
}
},
"sap.ui5": {
"rootView": {
"viewName": "uniorg.eon.emobility.provider.ui.pricematrix.view.App",
"type": "XML",
"async": true,
"id": "app"
},
"dependencies": {
"minUI5Version": "1.60",
"libs": {
"sap.ui.core": {},
"sap.m": {},
"sap.f": {}
}
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "uniorg.eon.emobility.provider.ui.pricematrix.i18n.i18n"
}
},
"odata": {
"dataSource": "provider",
"settings": {
"disableHeadRequestForToken": true,
"defaultBindingMode": "TwoWay"
}
},
"": {
"type": "sap.ui.model.json.JSONModel"
},
"appData": {
"type": "sap.ui.model.json.JSONModel"
}
},
"resources": {
"css": [
{
"uri": "css/style.css"
}
]
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewPath": "uniorg.eon.emobility.provider.ui.pricematrix.view",
"controlId": "rootControl",
"controlAggregation": "pages",
"bypassed": {
"target": "notFound"
},
"async": true,
"viewType": "XML"
},
"routes": [
{
"name": "Overview",
"pattern": "",
"target": "overview"
},
{
"name": "ProviderNextPeriod",
"pattern": "ProviderNextPeriod({Code})",
"target": "providerNextPeriod"
},
{
"name": "Provider",
"pattern": "Provider({Code})",
"target": "provider"
},
{
"name": "SubOperator",
"pattern": "SubOperator({Code})",
"target": "suboperator"
},
{
"name": "Lines",
"pattern": "Provider({Code})/Lines({LineId})",
"target": "lines"
}
],
"targets": {
"notFound": {
"viewId": "notFound",
"viewName": "NotFound",
"transition": "show"
},
"overview": {
"viewId": "overview",
"viewName": "Overview",
"viewLevel": 0
},
"providerNextPeriod": {
"viewId": "providerNextPeriod",
"viewName": "ProviderNextPeriod",
"viewLevel": 1
},
"provider": {
"viewId": "provider",
"viewName": "Provider",
"viewLevel": 1
},
"suboperator": {
"viewId": "suboperator",
"viewName": "SubOperator",
"viewLevel": 2
},
"lines": {
"viewId": "lines",
"viewName": "Lines",
"viewLevel": 2
}
}
}
}
}
@@ -0,0 +1,78 @@
sap.ui.define([], function() {
"use strict";
return {
valueStateNewValue: function(oldValue, newValue) {
const warningPercentage = 20;
newValue = parseFloat(newValue);
if (newValue >= 0) {
oldValue = parseFloat(oldValue);
if (oldValue && newValue) {
var difference = Math.abs(oldValue - newValue);
var percentageDifference = (difference / ((oldValue + newValue) / 2)) * 100;
if (newValue < oldValue) {
return "Warning";
} else if (percentageDifference > warningPercentage) {
return "Warning";
}
}
return "None";
} else {
return "Error";
}
},
valueStateTextNewValue: function(oldValue, newValue) {
const warningPercentage = 20;
newValue = parseFloat(newValue);
if (newValue >= 0) {
oldValue = parseFloat(oldValue);
if (oldValue && newValue) {
var difference = Math.abs(oldValue - newValue);
var percentageDifference = (difference / ((oldValue + newValue) / 2)) * 100;
if (newValue < oldValue) {
return "Warning: new value lower than old value";
} else if (percentageDifference > warningPercentage) {
return "Warning: Difference to old value more than " + warningPercentage + "%";
}
}
return "";
} else {
return "Only positive numeric values allowed!";
}
},
getDateObject: function(sDate) {
if (sDate) {
return new Date(sDate);
}
return null;
},
activeState: function(activeFlag) {
return activeFlag === 'Y' ? 'Success' : 'Error';
},
activeStateText: function(activeFlag) {
return activeFlag === 'Y' ? 'Active' : 'Inactive';
},
releasedState: function(releasedFlag) {
if (typeof releasedFlag === 'boolean') {
return releasedFlag ? 'Success' : 'Error'
}
return releasedFlag === 'Y' ? 'Success' : 'Error';
},
releasedStateText: function(releasedFlag) {
if (typeof releasedFlag === 'boolean') {
return releasedFlag ? 'Released' : 'Not released'
}
return releasedFlag === 'Y' ? 'Released' : 'Not released';
},
decimalsByCode: function(uCode) {
return uCode === 'MINUTES_BLOCK' ? 0 : 4;
},
unitByCode: function(uCode) {
return uCode === 'MINUTES_BLOCK' ? 'min.' : 'EUR';
},
convertIntToTimeString: function(timeInt) {
let hours = Math.floor(timeInt / 100); // get the hours part
let minutes = timeInt % 100; // get the minutes part
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
}
};
});
@@ -0,0 +1,10 @@
// defining a new custom Type as a subclass of the sap.ui.model.type.Unit type
sap.ui.require(["sap/ui/model/type/Unit"], function(UnitType) {
UnitType.extend("uniorg.eon.emobility.provider.ui.pricematrix.model.type.MeterType", {
constructor: function(oFormatOptions, oConstraints){
// define the dynamic format options as the third argument
// aDynamicFormatOptionNames
UnitType.call(this, oFormatOptions, oConstraints, ["decimals"]);
}
});
});
@@ -0,0 +1,10 @@
sap.ui.define([
"sap/ui/model/SimpleType",
], Type => Type.extend("uniorg.eon.emobility.provider.ui.pricematrix.model.type.YnBoolean", {
constructor: function() { // JS doesn't allow arrow function for constructors
Type.apply(this, arguments);
},
formatValue: cValue => cValue === 'Y',
parseValue: bValue => bValue ? 'Y' : 'N',
validateValue: (/*...*/) => {/*...*/},
}));
@@ -0,0 +1,6 @@
<mvc:View
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
displayBlock="true">
<App id="rootControl" busy="false" busyIndicatorDelay="0" />
</mvc:View>
@@ -0,0 +1,11 @@
<mvc:View
controllerName="uniorg.eon.emobility.provider.ui.pricematrix.controller.NotFound"
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc">
<MessagePage
title="{i18n>NotFound}"
text="{i18n>NotFound.text}"
description="{i18n>NotFound.description}"
showNavButton="true"
navButtonPress=".onNavBack"/>
</mvc:View>
@@ -0,0 +1,222 @@
<mvc:View
controllerName="uniorg.eon.emobility.provider.ui.pricematrix.controller.Overview"
xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core"
core:require="{ YnBoolean: 'uniorg/eon/emobility/provider/ui/pricematrix/model/type/YnBoolean' }"
xmlns="sap.m">
<Page title="e.on Provider Overview">
<Table
id="tableProviderList"
headerText="Provider List"
mode="SingleSelectLeft"
selectionChange="onSelectionChange"
sticky="HeaderToolbar,InfoToolbar,ColumnHeaders"
items="{
path: '/Provider',
parameters: {select: 'Code, Name, U_ACTIVE, U_ACTIVE_FROM, U_ACTIVE_TO, LastPeriodFrom, LastPeriodTo, Lines, NextPeriod'},
sorter: {
path: 'Code',
descending: false
}
}" >
<headerToolbar>
<OverflowToolbar>
<ToolbarSpacer/>
<!--<OverflowToolbarButton
id="otbApprove"
tooltip="Approve correctness of provider data"
type="Accept"
text="Approve"
icon="sap-icon://accept"
enabled="false"
press="onApprove">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<OverflowToolbarButton
id="otbReject"
tooltip="Reject approval"
type="Reject"
text="Reject"
icon="sap-icon://decline"
enabled="false"
press="onReject">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>-->
<OverflowToolbarButton
id="otbAddNew"
tooltip="Create new provider"
type="Ghost"
text="Create new provider"
icon="sap-icon://create-form"
enabled="{= !${/ReadOnly}}"
press="onAddNew">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<OverflowToolbarButton
id="otbEdit"
tooltip="Edit provider data"
type="Ghost"
text="Edit"
icon="sap-icon://edit"
enabled="false"
press="onEdit">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<OverflowToolbarButton
id="otbSave"
tooltip="Save provider data"
type="Emphasized"
text="Save"
icon="sap-icon://save"
enabled="{/ReadOnly}"
visible="false"
press="onSave">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<OverflowToolbarButton
id="otbCancel"
tooltip="Cancel editing"
type="Transparent"
text="Cancel"
icon="sap-icon://cancel"
enabled="false"
visible="false"
press="onCancel">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<OverflowToolbarButton
id="otbAddNext"
tooltip="Create next period for provider"
type="Ghost"
text="Create next period"
icon="sap-icon://add"
enabled="false"
press="onAddNext">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column
width="8em">
<header>
<Text text="Provider" />
</header>
</Column>
<Column
width="6em"
minScreenWidth="Tablet"
demandPopin="true">
<header>
<Text text="Active" />
</header>
</Column>
<Column
width="6em"
minScreenWidth="Tablet"
demandPopin="true">
<header>
<Text text="Active from" />
</header>
</Column>
<Column
width="6em"
minScreenWidth="Tablet"
demandPopin="true">
<header>
<Text text="Active to" />
</header>
</Column>
<Column
width="6em"
minScreenWidth="Tablet"
demandPopin="true">
<header>
<Text text="Last Period From" />
</header>
</Column>
<Column
width="6em"
minScreenWidth="Tablet"
demandPopin="true">
<header>
<Text text="Last Period To" />
</header>
</Column>
<Column
width="6em"
minScreenWidth="Tablet"
demandPopin="true">
<header>
<Text text="Last Period Released" />
</header>
</Column>
</columns>
<ColumnListItem type="Navigation" press="onRowPress">
<VBox>
<ObjectIdentifier title="{Code}" text="{Name}" visible="{= !${editable}}" />
<ObjectIdentifier title="{Code}" visible="{= ${editable} &amp;&amp; !${new}}" />
<Input value="{Code}" placeholder="Enter provider code" editable="{new}" visible="{new}"/>
<Input value="{Name}" placeholder="Enter provider name" visible="{editable}"/>
</VBox>
<CheckBox selected="{path: 'U_ACTIVE', type: 'YnBoolean'}" displayOnly="{= !${editable}}"/>
<HBox>
<Text text="{path: 'U_ACTIVE_FROM', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"
visible="{= !${editable}}"/>
<DatePicker value="{path: 'U_ACTIVE_FROM', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"
maxDate="{path: 'U_ACTIVE_TO', formatter: '.formatter.getDateObject'}"
visible="{editable}"/>
</HBox>
<HBox>
<Text text="{path: 'U_ACTIVE_TO', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"
visible="{= !${editable}}"/>
<DatePicker value="{path: 'U_ACTIVE_TO', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"
minDate="{path: 'U_ACTIVE_FROM', formatter: '.formatter.getDateObject'}"
visible="{editable}"/>
</HBox>
<Text text="{path: 'LastPeriodFrom', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}" />
<Text text="{path: 'LastPeriodTo', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}" />
<CheckBox selected="{path: 'LastPeriodReleased', type: 'YnBoolean'}" displayOnly="true"/>
</ColumnListItem>
</Table>
<Table
id="tableSubOperatorList"
class="sapUiResponsiveContentPadding"
headerText="SubOperators"
sticky="HeaderToolbar,InfoToolbar,ColumnHeaders"
items="{
path: '/SubOperators',
parameters: {select: 'Code, Name'},
sorter: {
path: 'Code',
descending: false
}
}" >
<columns>
<Column
width="20em">
<header>
<Text text="SubOperator" />
</header>
</Column>
</columns>
<ColumnListItem type="Navigation" press="onSubOperatorRowPress">
<ObjectIdentifier title="{Code}" text="{Name}" />
</ColumnListItem>
</Table>
</Page>
</mvc:View>
@@ -0,0 +1,565 @@
<mvc:View
controllerName="uniorg.eon.emobility.provider.ui.pricematrix.controller.Provider"
xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core"
core:require="{
YnBoolean: 'uniorg/eon/emobility/provider/ui/pricematrix/model/type/YnBoolean',
MeterType: 'uniorg/eon/emobility/provider/ui/pricematrix/model/type/MeterType'
}"
xmlns="sap.m">
<Page title="e.on Provider Prices" showHeader="true" showNavButton="true" navButtonPress="onBackPress">
<ObjectHeader
intro="{Name}"
title="{Code}"
icon="sap-icon://BusinessSuiteInAppSymbols/icon-manage-charging-stations"
backgroundDesign="Translucent"
responsive="true"
fullScreenOptimized="true"
class="sapUiResponsivePadding--header" >
<ObjectAttribute
title="Active from"
text="{path: 'U_ACTIVE_FROM', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"/>
<ObjectAttribute
title="Active to"
text="{path: 'U_ACTIVE_TO', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"/>
<statuses>
<ObjectStatus
text="{
path: 'U_ACTIVE',
formatter: '.formatter.activeStateText'
}"
state="{
path: 'U_ACTIVE',
formatter: '.formatter.activeState'
}"/>
</statuses>
</ObjectHeader>
<Table
id="tableProviderPrices"
mode="SingleSelectLeft"
selectionChange="onSelectionChange"
headerText="Provider Prices"
sticky="HeaderToolbar,InfoToolbar,ColumnHeaders"
popinLayout="GridSmall"
items="{
path: 'Lines',
parameters: {select: 'Code, LineId, U_CODE, U_FROM, U_TO, U_OPERATOR, U_SUBOPERATOR, OrganizationIDs, U_TYP, U_VALUE, Decimals, ValueCurrency, Unit, U_BLOCK_FROM, U_BLOCK_TO, U_BLOCKMAX, BlockMaxCurrency, U_CURRENCY, U_CHANGE_DATE, U_RELEASE_DATE, U_RELEASE_USER, U_RELEASED'},
sorter: [
{ path: 'U_CODE', descending: true, group: true },
{ path: 'U_FROM', descending: true, group: false },
{ path: 'U_OPERATOR', descending: false, group: false },
{ path: 'U_SUBOPERATOR', descending: false, group: false },
{ path: 'U_TYP', descending: false, group: false }
]
}" >
<headerToolbar>
<OverflowToolbar>
<Label text="Filter Period:" labelFor="cbPeriod">
<layoutData>
<OverflowToolbarLayoutData group="1" />
</layoutData>
</Label>
<ComboBox
id="cbPeriod"
selectionChange="onSelectPeriod"
showSecondaryValues="true"
items="{
path: 'Periods',
sorter: {
path: 'U_FROM',
descending: true
}
}">
<core:ListItem
key="{U_FROM}"
text="{path: 'U_FROM', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"
additionalText="{
path: 'U_RELEASED',
formatter: '.formatter.releasedStateText'
}"
/>
<layoutData>
<OverflowToolbarLayoutData group="1" />
</layoutData>
</ComboBox>
<ToolbarSpacer/>
<ObjectStatus
text="{
path: 'appData>/released',
formatter: '.formatter.releasedStateText'
}"
state="{
path: 'appData>/released',
formatter: '.formatter.releasedState'
}"/>
<ToolbarSpacer/>
<OverflowToolbarButton
id="otbAddNew"
tooltip="Add line"
type="Ghost"
text="Add line"
icon="sap-icon://add"
enabled="{= !${appData>/released} &amp;&amp; !${/ReadOnly}}"
press="onAddLine">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<OverflowToolbarToggleButton
id="otbEdit"
tooltip="Edit line"
type="Ghost"
text="Edit line"
icon="sap-icon://edit"
enabled="false"
press="onEditLine">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarToggleButton>
<OverflowToolbarButton
id="otbRemove"
tooltip="Remove line"
type="Transparent"
text="Remove line"
icon="sap-icon://delete"
enabled="false"
press="onRemoveLine">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<OverflowToolbarButton
id="otbShowDetails"
tooltip="{= ${appData>/showDetails} ? 'Show less details' : 'Show more details'}"
text="{= ${appData>/showDetails} ? 'Show less details' : 'Show more details'}"
icon="{= ${appData>/showDetails} ? 'sap-icon://detail-less' : 'sap-icon://detail-more'}"
press="onToggleDetails">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column
width="8em">
<header>
<Text text="Code" />
</header>
</Column>
<Column
width="7em"
minScreenWidth="16em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="From" />
</header>
</Column>
<Column
width="8em"
minScreenWidth="23em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="To" />
</header>
</Column>
<Column
width="6em"
minScreenWidth="36em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Operator" />
</header>
</Column>
<Column
width="8em"
minScreenWidth="36em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="SubOperator" />
</header>
</Column>
<Column
width="4em"
minScreenWidth="40em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Type" />
</header>
</Column>
<Column
width="7em"
visible="{appData>/editable}"
minScreenWidth="63em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Currency" />
</header>
</Column>
<Column
width="10em"
hAlign="End"
minScreenWidth="63em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Value" />
</header>
</Column>
<Column
width="7em"
hAlign="End"
minScreenWidth="84em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Block from" />
</header>
</Column>
<Column
width="7em"
hAlign="End"
minScreenWidth="84em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Block to" />
</header>
</Column>
<Column
width="7em"
hAlign="End"
minScreenWidth="84em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Block Max" />
</header>
</Column>
<Column
width="5em"
visible="{appData>/showDetails}"
minScreenWidth="102em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Released" />
</header>
</Column>
<Column
width="6em"
visible="{appData>/showDetails}"
minScreenWidth="102em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Release Date" />
</header>
</Column>
<Column
width="6em"
minScreenWidth="102em"
visible="{appData>/showDetails}"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Released by" />
</header>
</Column>
<Column
width="6em"
visible="{appData>/showDetails}"
minScreenWidth="114em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Change Date" />
</header>
</Column>
<Column
width="6em"
visible="{appData>/showDetails}"
minScreenWidth="114em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Changed by" />
</header>
</Column>
</columns>
<ColumnListItem
highlight="{highlight}"
highlightText="{highlightText}">
<!--<ObjectIdentifier title="{LineId}" />-->
<HBox>
<Text text="{U_CODE}" visible="{= !${appData>/editable} || !${editable}}"/>
<Select
visible="{= ${appData>/editable} &amp;&amp; ${editable}}"
liveChange="updatePendingChanges"
change="onCodeChange"
forceSelection="false"
autoAdjustWidth="true"
selectedKey="{U_CODE}"
items="{
path: '/ValueHelp/Code',
sorter: { path: 'U_CODE', descending: true }
}">
<core:Item key="{U_CODE}" text="{U_CODE}" />
</Select>
</HBox>
<Text text="{path: 'U_FROM', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}" />
<HBox>
<Text text="{path: 'U_TO', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"
visible="{= !${appData>/editable} || !${editable}}" />
<DatePicker
value="{path: 'U_TO', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"
minDate="{path: 'U_FROM', formatter: '.formatter.getDateObject'}"
visible="{= ${appData>/editable} &amp;&amp; ${editable}}"
change="onDateToChange" />
</HBox>
<HBox>
<Text text="{U_OPERATOR}" visible="{= !${appData>/editable} || !${editable}}">
<layoutData>
<FlexItemData growFactor="1" baseSize="auto"/>
</layoutData>
</Text>
<Select
visible="{= ${appData>/editable} &amp;&amp; ${editable}}"
liveChange="updatePendingChanges"
change="onChangeRefresh"
forceSelection="false"
autoAdjustWidth="false"
selectedKey="{U_OPERATOR}"
items="{
path: '/ValueHelp/Operator',
sorter: { path: 'U_OPERATOR' }
}">
<core:Item key="{U_OPERATOR}" text="{U_OPERATOR}" />
<layoutData>
<FlexItemData growFactor="1" baseSize="auto"/>
</layoutData>
</Select>
</HBox>
<HBox>
<ObjectIdentifier
title="{U_SUBOPERATOR}"
text="{OrganizationIDs}"
titleActive="true"
titlePress="onSubOperatorPress"
visible="{= !${appData>/editable} || !${editable}}">
<layoutData>
<FlexItemData growFactor="1" baseSize="auto"/>
</layoutData>
</ObjectIdentifier>
<!--<VBox>
<Text text="{U_SUBOPERATOR}" visible="{= !${appData>/editable} || !${editable}}"/>
<Text text="{OrganizationIDs}" visible="{= !${appData>/editable} || !${editable}}" wrapping="false"/>
</VBox>-->
<Select
visible="{= ${appData>/editable} &amp;&amp; ${editable}}"
liveChange="updatePendingChanges"
change="onChangeRefresh"
forceSelection="false"
autoAdjustWidth="false"
showSecondaryValues="false"
wrapItemsText="true"
columnRatio="2:3"
selectedKey="{U_SUBOPERATOR}"
items="{
path: '/SubOperators',
sorter: { path: 'Code' }
}">
<core:ListItem key="{Code}" text="{Code}" additionalText="{Name}"/>
<layoutData>
<FlexItemData growFactor="1" baseSize="auto"/>
</layoutData>
</Select>
</HBox>
<HBox>
<Text text="{U_TYP}" visible="{= !${appData>/editable} || !${editable}}"/>
<Select
visible="{= ${appData>/editable} &amp;&amp; ${editable}}"
liveChange="updatePendingChanges"
change="onChangeRefresh"
forceSelection="false"
autoAdjustWidth="true"
selectedKey="{U_TYP}"
items="{
path: '/ValueHelp/Type',
sorter: { path: 'U_TYP' }
}">
<core:Item key="{U_TYP}" text="{U_TYP}" />
</Select>
</HBox>
<!--<HBox>
<ObjectIdentifier title="{U_ORG_ID}" text="{U_ORG_NAME}" visible="{= !${appData>/editable} || !${editable}}">
</ObjectIdentifier>
<Input value="{U_ORG_ID}" placeholder="ID" liveChange="updatePendingChanges" change="onOrgIdChange" visible="{= ${appData>/editable} &amp;&amp; ${editable}}">
<layoutData>
<FlexItemData minWidth="5em" maxWidth="5em"/>
</layoutData>
</Input>
<Input value="{U_ORG_NAME}" placeholder="Name" liveChange="updatePendingChanges" change="onOrgNameChange" visible="{= ${appData>/editable} &amp;&amp; ${editable}}">
<layoutData>
<FlexItemData growFactor="2" baseSize="0"/>
</layoutData>
</Input>
</HBox>-->
<Select
visible="{appData>/editable}"
liveChange="updatePendingChanges"
change="updatePendingChanges"
forceSelection="false"
autoAdjustWidth="true"
showSecondaryValues="false"
wrapItemsText="false"
columnRatio="2:3"
selectedKey="{U_CURRENCY}"
items="{
path: '/ValueHelp/Currencies',
sorter: { path: 'CurrCode' }
}">
<core:ListItem key="{CurrCode}" text="{CurrCode}" additionalText="{CurrName}"/>
</Select>
<HBox alignItems="Center" justifyContent="End">
<ObjectNumber
number="{parts:['U_VALUE', '{}', 'Decimals'], type: 'MeterType'}"
unit="{Unit}"
textAlign="End"
visible="{= !${appData>/editable}}">
<layoutData>
<FlexItemData growFactor="1" baseSize="0"/>
</layoutData>
</ObjectNumber>
<Input
value="{U_VALUE}"
type="Number"
textAlign="End"
liveChange="updatePendingChanges"
valueState="{parts: [{path: 'U_VALUE'}, {path: 'U_VALUE'}], formatter: '.formatter.valueStateNewValue'}"
valueStateText="{parts: [{path: 'U_VALUE'}, {path: 'U_VALUE'}], formatter: '.formatter.valueStateTextNewValue'}"
visible="{appData>/editable}">
<layoutData>
<FlexItemData growFactor="1" baseSize="0"/>
</layoutData>
</Input>
<Text
text="{Unit}"
textAlign="End"
visible="{appData>/editable}">
<layoutData>
<FlexItemData growFactor="0" baseSize="auto"/>
</layoutData>
</Text>
</HBox>
<HBox alignItems="Center" justifyContent="End">
<Text text="{U_BLOCK_FROM}" visible="{= ${U_CODE} === 'MINUTES_BLOCK' &amp;&amp; !${appData>/editable} }" />
<TimePicker value="{path: 'U_BLOCK_FROM'}" visible="{= ${U_CODE} === 'MINUTES_BLOCK' &amp;&amp; ${appData>/editable} }" liveChange="updatePendingChanges" />
</HBox>
<HBox alignItems="Center" justifyContent="End">
<Text text="{U_BLOCK_TO}" visible="{= ${U_CODE} === 'MINUTES_BLOCK' &amp;&amp; !${appData>/editable} }" />
<TimePicker value="{path: 'U_BLOCK_TO'}" visible="{= ${U_CODE} === 'MINUTES_BLOCK' &amp;&amp; ${appData>/editable} }" liveChange="updatePendingChanges" />
</HBox>
<HBox alignItems="Center" justifyContent="End">
<ObjectNumber
number="{
parts:[
{path:'U_BLOCKMAX'},
{path:'U_CURRENCY'}
],
type: 'sap.ui.model.type.Currency'
}"
textAlign="End"
visible="{= ${U_CODE} === 'MINUTES_BLOCK' &amp;&amp; !${appData>/editable} }" />
<Input
value="{
parts:[
{path:'U_BLOCKMAX'},
{path:'U_CURRENCY'}
],
type: 'sap.ui.model.type.Currency',
formatOptions: {
showMeasure: false
}
}"
textAlign="End"
liveChange="updatePendingChanges"
visible="{= ${U_CODE} === 'MINUTES_BLOCK' &amp;&amp; ${appData>/editable} }">
<layoutData>
<FlexItemData
growFactor="1"
baseSize="0"/>
</layoutData>
</Input>
<Text
text="{BlockMaxCurrency}"
textAlign="End"
visible="{= ${U_CODE} === 'MINUTES_BLOCK' &amp;&amp; ${appData>/editable} }">
<layoutData>
<FlexItemData
growFactor="0"
baseSize="auto"/>
</layoutData>
</Text>
</HBox>
<CheckBox selected="{path: 'U_RELEASED', type: 'YnBoolean'}" displayOnly="true"/>
<Text text="{path: 'U_RELEASE_DATE', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}" />
<Text text="{U_RELEASE_USER}" />
<Text text="{path: 'U_CHANGE_DATE', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}" />
<Text text="{U_CHANGE_USER}" />
</ColumnListItem>
</Table>
<footer>
<OverflowToolbar id="otbFooter">
<ToolbarSpacer/>
<Button
type="Accept"
icon="sap-icon://accept"
text="Approve"
enabled="{= !${appData>/released} &amp;&amp; !${/ReadOnly}}"
press="onApprove">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
<Button
type="Reject"
icon="sap-icon://decline"
text="Reject"
enabled="{= ${appData>/released} &amp;&amp; !${/ReadOnly}}"
press="onReject">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
<Button
type="Emphasized"
icon="sap-icon://save"
text="Save"
enabled="{pendingChanges}"
press="onSave">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
<Button
type="Transparent"
icon="sap-icon://cancel"
text="Cancel"
enabled="{pendingChanges}"
press="onCancel">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
</OverflowToolbar>
</footer>
</Page>
</mvc:View>
@@ -0,0 +1,393 @@
<mvc:View
controllerName="uniorg.eon.emobility.provider.ui.pricematrix.controller.ProviderNextPeriod"
xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core"
core:require="{ MeterType: 'uniorg/eon/emobility/provider/ui/pricematrix/model/type/MeterType' }"
xmlns="sap.m">
<Page title="e.on Provider next period" showHeader="true" showNavButton="true" navButtonPress="onBackPress">
<ObjectHeader
intro="{Name}"
title="{Code}"
icon="sap-icon://BusinessSuiteInAppSymbols/icon-manage-charging-stations"
backgroundDesign="Translucent"
responsive="true"
fullScreenOptimized="true"
class="sapUiResponsivePadding--header" >
<ObjectAttribute
title="Active from"
text="{path: 'U_ACTIVE_FROM', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"/>
<ObjectAttribute
title="Active to"
text="{path: 'U_ACTIVE_TO', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"/>
<statuses>
<ObjectStatus
text="{
path: 'U_ACTIVE',
formatter: '.formatter.activeStateText'
}"
state="{
path: 'U_ACTIVE',
formatter: '.formatter.activeState'
}"/>
</statuses>
</ObjectHeader>
<Table
id="tableProviderNextPeriod"
mode="SingleSelectLeft"
selectionChange="onSelectionChange"
headerText="Provider next period"
sticky="HeaderToolbar,InfoToolbar,ColumnHeaders"
popinLayout="GridSmall"
items="{
path: 'NextPeriod',
parameters: {select: 'Code, U_CODE, U_FROM, U_TO, U_OPERATOR, U_SUBOPERATOR, OrganizationIDs, U_TYP, U_VALUE, NewValue, Decimals, ValueCurrency, Unit, U_BLOCK_FROM, U_BLOCK_TO, U_BLOCKMAX, BlockMaxCurrency'},
sorter: [
{ path: 'U_CODE', descending: true, group: true },
{ path: 'U_FROM', descending: true, group: false },
{ path: 'U_OPERATOR', descending: false, group: false },
{ path: 'U_SUBOPERATOR', descending: false, group: false },
{ path: 'U_TYP', descending: false, group: false }
]
}" >
<headerToolbar>
<OverflowToolbar>
<ToolbarSpacer/>
<OverflowToolbarButton
id="otbAddNew"
tooltip="Add line"
type="Ghost"
text="Add line"
icon="sap-icon://add"
press="onAddLine">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<OverflowToolbarToggleButton
id="otbEdit"
tooltip="Edit line"
type="Ghost"
text="Edit line"
icon="sap-icon://edit"
enabled="false"
press="onEditLine">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarToggleButton>
<OverflowToolbarButton
id="otbRemove"
tooltip="Remove line"
type="Transparent"
text="Remove line"
icon="sap-icon://delete"
enabled="false"
press="onRemoveLine">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column
width="8em">
<header>
<Text text="Code" />
</header>
</Column>
<Column
width="7em"
minScreenWidth="20em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="From" />
</header>
</Column>
<Column
width="7em"
minScreenWidth="26em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="To" />
</header>
</Column>
<Column
width="6em"
minScreenWidth="41em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Operator" />
</header>
</Column>
<Column
width="8em"
minScreenWidth="41em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="SubOperator" />
</header>
</Column>
<Column
width="4em"
minScreenWidth="45em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Type" />
</header>
</Column>
<Column
width="10em"
hAlign="End"
minScreenWidth="56em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Old Value" />
</header>
</Column>
<Column
width="7em"
minScreenWidth="73em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Currency" />
</header>
</Column>
<Column
hAlign="End"
width="6em"
minScreenWidth="73em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="New Value" />
</header>
</Column>
<Column
width="6em"
hAlign="End"
minScreenWidth="88em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Block from" />
</header>
</Column>
<Column
width="6em"
hAlign="End"
minScreenWidth="88em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Block to" />
</header>
</Column>
<Column
width="6em"
hAlign="End"
minScreenWidth="88em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Block Max" />
</header>
</Column>
</columns>
<ColumnListItem
highlight="{highlight}"
highlightText="{highlightText}">
<HBox>
<Text text="{U_CODE}" visible="{= !${editable}}"/>
<Select
visible="{editable}"
change="onCodeChange"
forceSelection="false"
autoAdjustWidth="true"
selectedKey="{U_CODE}"
items="{
path: '/ValueHelp/Code',
sorter: { path: 'U_CODE', descending: true }
}">
<core:Item key="{U_CODE}" text="{U_CODE}" />
</Select>
</HBox>
<Text text="{path: 'U_FROM', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}" />
<HBox>
<Text text="{path: 'U_TO', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"
visible="{= !${editable}}" />
<DatePicker
value="{path: 'U_TO', type: 'sap.ui.model.type.Date', formatOptions: { style: 'medium', source: { pattern: 'yyyy-MM-ddTHH:mm:ss.SSSZ' }, UTC: false }}"
minDate="{path: 'U_FROM', formatter: '.formatter.getDateObject'}"
visible="{editable}"
change="onDateToChange" />
</HBox>
<HBox>
<Text text="{U_OPERATOR}" visible="{= !${editable}}"/>
<Select
visible="{editable}"
change="onChangeRefresh"
forceSelection="false"
autoAdjustWidth="true"
selectedKey="{U_OPERATOR}"
items="{
path: '/ValueHelp/Operator',
sorter: { path: 'U_OPERATOR' }
}">
<core:Item key="{U_OPERATOR}" text="{U_OPERATOR}" />
</Select>
</HBox>
<HBox>
<ObjectIdentifier title="{U_SUBOPERATOR}" text="{OrganizationIDs}" visible="{= !${editable}}">
</ObjectIdentifier>
<Select
visible="{editable}"
change="onChangeRefresh"
forceSelection="false"
autoAdjustWidth="true"
showSecondaryValues="true"
selectedKey="{U_SUBOPERATOR}"
items="{
path: '/SubOperators',
sorter: { path: 'Code' }
}">
<core:Item key="{Code}" text="{Code}" additionalText="{Name}"/>
</Select>
</HBox>
<HBox>
<Text text="{U_TYP}" visible="{= !${editable}}"/>
<Select
visible="{editable}"
change="onChangeRefresh"
forceSelection="false"
autoAdjustWidth="true"
selectedKey="{U_TYP}"
items="{
path: '/ValueHelp/Type',
sorter: { path: 'U_TYP' }
}">
<core:Item key="{U_TYP}" text="{U_TYP}" />
</Select>
</HBox>
<!--<HBox>
<ObjectIdentifier title="{U_ORG_ID}" text="{U_ORG_NAME}" visible="{= !${editable}}">
</ObjectIdentifier>
<Input value="{U_ORG_ID}" placeholder="ID" change="onOrgIdChange" visible="{editable}">
<layoutData>
<FlexItemData minWidth="5em" maxWidth="5em"/>
</layoutData>
</Input>
<Input value="{U_ORG_NAME}" placeholder="Name" change="onOrgNameChange" visible="{editable}">
<layoutData>
<FlexItemData growFactor="2" baseSize="0"/>
</layoutData>
</Input>
</HBox>-->
<ObjectNumber
number="{parts:['U_VALUE', '{}', 'Decimals'], type: 'MeterType'}"
unit="{Unit}" />
<Select
forceSelection="true"
autoAdjustWidth="false"
showSecondaryValues="false"
wrapItemsText="true"
columnRatio="2:3"
selectedKey="{U_CURRENCY}"
items="{
path: '/ValueHelp/Currencies',
sorter: { path: 'CurrCode' }
}">
<core:ListItem key="{CurrCode}" text="{CurrCode}" additionalText="{CurrName}"/>
</Select>
<Input
value="{NewValue}"
type="Number"
showClearIcon="true"
valueState="{parts: [{path: 'U_VALUE'}, {path: 'NewValue'}], formatter: '.formatter.valueStateNewValue'}"
valueStateText="{parts: [{path: 'U_VALUE'}, {path: 'NewValue'}], formatter: '.formatter.valueStateTextNewValue'}"
editable="true"/>
<TimePicker value="{path: 'U_BLOCK_FROM'}" visible="{= ${U_CODE} === 'MINUTES_BLOCK' }" />
<TimePicker value="{path: 'U_BLOCK_TO'}" visible="{= ${U_CODE} === 'MINUTES_BLOCK' }" />
<!--<ObjectNumber
number="{
parts:[
{path:'U_BLOCKMAX'},
{path:'U_CURRENCY'}
],
type: 'sap.ui.model.type.Currency'
}" />-->
<HBox alignItems="Center">
<Input
value="{
parts:[
{path:'U_BLOCKMAX'},
{path:'U_CURRENCY'}
],
type: 'sap.ui.model.type.Currency',
formatOptions: {
showMeasure: false
}
}"
visible="{= ${U_CODE} === 'MINUTES_BLOCK' }">
<layoutData>
<FlexItemData
growFactor="1"
baseSize="0"/>
</layoutData>
</Input>
<Text
text="{BlockMaxCurrency}"
visible="{= ${U_CODE} === 'MINUTES_BLOCK' }">
<layoutData>
<FlexItemData
growFactor="0"
baseSize="auto"/>
</layoutData>
</Text>
</HBox>
</ColumnListItem>
</Table>
<footer>
<OverflowToolbar id="otbFooter">
<ToolbarSpacer/>
<Button
type="Ghost"
icon="sap-icon://clear-all"
text="Clear"
enabled="true"
press="onClearPress">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
<Button
type="Ghost"
icon="sap-icon://action"
text="Take over values"
enabled="true"
press="onCopyPress">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
<Button
type="Emphasized"
icon="sap-icon://save"
text="Save &amp; Approve"
enabled="{allowNewPeriod}"
press="onSubmit">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
</OverflowToolbar>
</footer>
</Page>
</mvc:View>
@@ -0,0 +1,20 @@
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
<QuickView>
<QuickViewPage
header="Sub Operator Details"
title="{Code}"
description="{Name}">
<QuickViewGroup heading="Organizations">
<QuickViewGroupElement
label="Organization IDs">
<VBox>
<items>
<Text text="{U_ORG_ID}"
visible="{= ${Organizations}.length > 0}" />
</items>
</VBox>
</QuickViewGroupElement>
</QuickViewGroup>
</QuickViewPage>
</QuickView>
</core:FragmentDefinition>
@@ -0,0 +1,215 @@
<mvc:View
controllerName="uniorg.eon.emobility.provider.ui.pricematrix.controller.SubOperator"
xmlns:mvc="sap.ui.core.mvc"
xmlns:core="sap.ui.core"
core:require="{
YnBoolean: 'uniorg/eon/emobility/provider/ui/pricematrix/model/type/YnBoolean',
MeterType: 'uniorg/eon/emobility/provider/ui/pricematrix/model/type/MeterType'
}"
xmlns="sap.m">
<Dialog id="createSubOperatorDialog" title="New SubOperator" stretchOnPhone="true">
<VBox>
<Label text="Code" />
<Input id="subOperatorCode" placeholder="Enter Code" />
<Label text="Name" />
<Input id="subOperatorName" placeholder="Enter Name" />
</VBox>
<endButton>
<Button text="Cancel" press="onCancelCreateSubOperator" />
</endButton>
<beginButton>
<Button text="Create" type="Emphasized" press="onConfirmCreateSubOperator" />
</beginButton>
</Dialog>
<Dialog id="deleteSubOperatorDialog" title="Confirm Delete" type="Message">
<Text text="Are you sure you want to delete this SubOperator?" />
<beginButton>
<Button text="Yes" type="Emphasized" press="onConfirmDeleteSubOperator" />
</beginButton>
<endButton>
<Button text="No" press="onCancelDeleteSubOperator" />
</endButton>
</Dialog>
<Page title="e.on Provider SubOperator" showHeader="true" showNavButton="true" navButtonPress="onBackPress">
<ObjectHeader
intro="{Name}"
title="{Code}"
icon="sap-icon://BusinessSuiteInAppSymbols/icon-manage-charging-stations"
backgroundDesign="Translucent"
responsive="true"
fullScreenOptimized="true"
class="sapUiResponsivePadding--header" >
</ObjectHeader>
<Table
id="tableOrganizations"
mode="{= ${ReadOnly} ? 'None' : 'SingleSelectLeft'}"
selectionChange="onSelectionChange"
headerText="Provider Prices"
sticky="HeaderToolbar,InfoToolbar,ColumnHeaders"
popinLayout="GridSmall"
items="{
path: 'Organizations',
parameters: {select: 'Code, LineId, U_ORG_ID'},
sorter: [
{ path: 'LineId', descending: false, group: false }
]
}" >
<headerToolbar>
<OverflowToolbar>
<ToolbarSpacer/>
<OverflowToolbarButton
id="otbPrevious"
tooltip="Navigate to previous entry"
type="Transparent"
text="Previous"
icon="sap-icon://navigation-left-arrow"
press="onPreviousPress">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<OverflowToolbarButton
id="otbNext"
tooltip="Navigate to next entry"
type="Transparent"
text="Next"
icon="sap-icon://navigation-right-arrow"
press="onNextPress">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<ToolbarSpacer/>
<OverflowToolbarButton
id="otbAddNew"
tooltip="Add line"
type="Ghost"
text="Add line"
icon="sap-icon://add"
enabled="{= !${/ReadOnly}}"
press="onAddLine">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
<!--<OverflowToolbarToggleButton
id="otbEdit"
tooltip="Edit line"
type="Ghost"
text="Edit line"
icon="sap-icon://edit"
enabled="false"
press="onEditLine">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarToggleButton>-->
<OverflowToolbarButton
id="otbRemove"
tooltip="Remove line"
type="Transparent"
text="Remove line"
icon="sap-icon://delete"
enabled="false"
press="onRemoveLine">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow"/>
</layoutData>
</OverflowToolbarButton>
</OverflowToolbar>
</headerToolbar>
<columns>
<Column
width="8em">
<header>
<Text text="Line ID" />
</header>
</Column>
<Column
width="10em"
popinDisplay="Inline"
demandPopin="true">
<header>
<Text text="Organization ID" />
</header>
</Column>
</columns>
<ColumnListItem
highlight="{highlight}"
highlightText="{highlightText}">
<ObjectIdentifier title="{LineId}" />
<HBox>
<Text text="{U_ORG_ID}" visible="{/ReadOnly}">
</Text>
<Input value="{U_ORG_ID}" liveChange="updatePendingChanges" change="onOrgIdChange" visible="{= !${/ReadOnly}}">
</Input>
</HBox>
</ColumnListItem>
</Table>
<footer>
<OverflowToolbar id="otbFooter">
<!--<Button
type="Accept"
icon="sap-icon://accept"
text="Approve"
enabled="{= !${appData>/released} &amp;&amp; !${/ReadOnly}}"
press="onApprove">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
<Button
type="Reject"
icon="sap-icon://decline"
text="Reject"
enabled="{= ${appData>/released} &amp;&amp; !${/ReadOnly}}"
press="onReject">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>-->
<Button
type="Default"
icon="sap-icon://create-form"
text="New SubOperator"
enabled="{= !${/ReadOnly}}"
press="onCreateSubOperator">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
<Button
type="Transparent"
icon="sap-icon://delete"
text="Delete SubOperator"
enabled="{= !${/ReadOnly}}"
press="onDeleteSubOperator">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
<ToolbarSpacer/>
<Button
type="Emphasized"
icon="sap-icon://save"
text="Save"
enabled="{= ${pendingChanges} &amp;&amp; !${/ReadOnly}}"
press="onSave">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
<Button
type="Transparent"
icon="sap-icon://cancel"
text="Cancel"
enabled="{= ${pendingChanges} &amp;&amp; !${/ReadOnly}}"
press="onCancel">
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
</OverflowToolbar>
</footer>
</Page>
</mvc:View>