diff --git a/.gitignore b/.gitignore deleted file mode 100644 index b105cb4..0000000 --- a/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -node_modules/ -.DS_Store -*.log -.idea/ -.vscode/ -dist/ -build/ -*.pyc -__pycache__/ diff --git a/README.md b/README.md deleted file mode 100644 index e1c47ba..0000000 --- a/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# EON_EMOBILITY_PROVIDER Deployment Unit - -This is the EON EMOBILITY PROVIDER deployment unit exported from SAP HANA XS repository. - -## Structure - -- `uniorg/eon/emobility/provider/backend/` - Backend XSJS services -- `uniorg/eon/emobility/provider/xsodata/` - OData service definitions -- `uniorg/eon/emobility/provider/ui/pricematrix/` - UI5 application for price matrix management - -## Components - -### Backend Services -- Provider management (add, update, get) -- Provider lines data management -- SubOperator management -- Period data management - -### OData Services -- Provider OData API - -### UI Application -- Price Matrix management interface built with SAP UI5 diff --git a/uniorg/eon/emobility/provider/Editor.hdbrole b/uniorg/eon/emobility/provider/Editor.hdbrole index 1b8f983..c41895d 100644 --- a/uniorg/eon/emobility/provider/Editor.hdbrole +++ b/uniorg/eon/emobility/provider/Editor.hdbrole @@ -4,6 +4,23 @@ catalog sql object "A19753_EON_P01"."V_EON_PROVIDER": //Objecttype: VIEW SELECT; catalog sql object "A19753_EON_P01"."V_EON_PROVIDER_LINES": //Objecttype: VIEW SELECT; +catalog sql object "A19753_EON_P01"."V_EON_PROVIDER_NEXT_PERIOD": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."V_EON_PROVIDER_PERIODS": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."@EON_SUBOPERATOR": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."@EON_SUBOPERATOR_L": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."CUFD": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."UFD1": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."OCRN": //Objecttype: VIEW + SELECT; +catalog sql object "INTEGRATION_DATA"."UO_USER_PAR": //Objecttype: TABLE + SELECT; + package uniorg.eon.emobility.provider: REPO.READ; diff --git a/uniorg/eon/emobility/provider/Viewer.hdbrole b/uniorg/eon/emobility/provider/Viewer.hdbrole index 0434671..6675571 100644 --- a/uniorg/eon/emobility/provider/Viewer.hdbrole +++ b/uniorg/eon/emobility/provider/Viewer.hdbrole @@ -2,6 +2,25 @@ role uniorg.eon.emobility.provider::Viewer { catalog sql object "A19753_EON_P01"."V_EON_PROVIDER": //Objecttype: VIEW SELECT; +catalog sql object "A19753_EON_P01"."V_EON_PROVIDER_LINES": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."V_EON_PROVIDER_NEXT_PERIOD": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."V_EON_PROVIDER_PERIODS": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."@EON_SUBOPERATOR": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."@EON_SUBOPERATOR_L": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."CUFD": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."UFD1": //Objecttype: VIEW + SELECT; +catalog sql object "A19753_EON_P01"."OCRN": //Objecttype: VIEW + SELECT; +catalog sql object "INTEGRATION_DATA"."UO_USER_PAR": //Objecttype: TABLE + SELECT; + package uniorg.eon.emobility.provider: REPO.READ; diff --git a/uniorg/eon/emobility/provider/backend/.xsaccess b/uniorg/eon/emobility/provider/backend/.xsaccess index 87c7b18..735846e 100644 --- a/uniorg/eon/emobility/provider/backend/.xsaccess +++ b/uniorg/eon/emobility/provider/backend/.xsaccess @@ -1,8 +1,29 @@ { "exposed": true, - "authentication": [ - { + "authentication": [{ "method": "Basic" - } - ] + }], + + "mime_mapping": [{ + "extension": "jpg", + "mimetype": "image/jpeg" + }], + "force_ssl": false, + "enable_etags": true, + "prevent_xsrf": false, + "cache_control": "no-cache, no-store", + "default_file": "index.html", + "cors" : + { + "enabled" : true, + "allowMethods": [ + "GET", + "POST", + "HEAD", + "PUT", + "OPTIONS"], + "allowOrigin" : ["*"], + "allowHeaders" : ["crossdomain","X-Requested-With","Access-Control-Request-Method","Referer","Access-Control-Request-Headers","Accept-Encoding","Sec-Fetch-Mode","Sec-Fetch-Site","authorization","Accept","Origin","Content-Type","Content-Length","content-encoding","Depth","User-Agent","Cache-Control","x-csrf-token","x-sap-cid","Accept-Language","sap-cancel-on-close","sap-contextid-accept","DataServiceVersion","MaxDataServiceVersion","sec-ch-ua","sec-ch-ua-mobile","Prefer"], + "exposeHeaders" : ["x-csrf-token","access-control-allow-headers","Access-Control-Allow-Origin","access-control-expose-headers","authorization"] + } } \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/backend/addNewProvider.xsjs b/uniorg/eon/emobility/provider/backend/addNewProvider.xsjs new file mode 100644 index 0000000..e61831c --- /dev/null +++ b/uniorg/eon/emobility/provider/backend/addNewProvider.xsjs @@ -0,0 +1,264 @@ +var datetimeLib = $.import("uniorg.libs", "datetime"); +//var logginglib = $.import("uniorg.libs", "uologging"); +//var billingEngine = $.import("uniorg.eon.emobility.billing.engine.v1", "BillingEngine"); +var destLib = $.import("uniorg.destinations", "uodestlib"); +var slLib = $.import("uniorg.ServiceLayer", "B1SLLogic"); + +var serviceName = "eon.emobility.provider.backend.addNewProvider.xsjs"; +var serviceVersion = '1.0'; + +var output = {}; +var outMessages = []; +var outMsg = {}; +var outStatus = "success"; +var myDebug = {}; + +var companyid = 0; +var UserName = ''; +var UserPass = ''; +var UserComp = ''; + +var SESSIONID = ""; +var NODEID = ""; +var slLoggedIn = false; +var schemaName = "A19753_EON_P01"; + +var debugLevel = 0; +switch ($.request.parameters.get("debug")) { + case "true": + case "yes": + case "1": + debugLevel = 1; + break; + case "full": + case "2": + debugLevel = 2; + break; +} + +if (debugLevel > 0) { + output.requestParams = $.request.parameters; +} + +function setOutputMessage() { + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + $.response.contentType = "application/json"; + $.response.setBody(JSON.stringify(output)); + //$.response.status = $.net.http.OK; +} + +function exceptionHandler(ex) { + if (outMsg.method && outMessages.indexOf(outMsg) === -1) { + outMsg.status = "canceled"; + outMessages.push(outMsg); + } + outMsg = {}; + outMsg.method = "exceptionHandler"; + outMsg.status = "error"; + outMsg.message = ex.toString(); + if (debugLevel > 0) { + outMsg.exceptionInfo = {}; + outMsg.exceptionInfo.name = ex.name; + outMsg.exceptionInfo.message = ex.message; + outMsg.exceptionInfo.fileName = ex.fileName; + outMsg.exceptionInfo.lineNumber = ex.lineNumber; + outMsg.exceptionInfo.columnNumber = ex.columnNumber; + outMsg.exceptionInfo.stack = ex.stack; + //outMsg.exceptionInfo.source = ex.toSource(); + } + outMessages.push(outMsg); + outStatus = "error"; + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + + var errbody = JSON.stringify(output); + $.response.contentType = 'application/json'; + $.response.setBody(errbody); + $.response.status = $.net.http.INTERNAL_SERVER_ERROR; + try { + if (slLoggedIn) { + slLib.SLLogout(SESSIONID, NODEID); + } + } catch (e) { + + } +} + +function checkAuthorization() { + var isAuthorized = true; + try { + $.session.assertAppPrivilege("uniorg.eon.emobility.provider::MaintainProviderData"); + } catch (ex) { + isAuthorized = false; + outMsg = {}; + outMsg.method = "checkAuthorization"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "Privilege '" + ex.privilege + "' is missing"; + outMessages.push(outMsg); + $.response.status = $.net.http.FORBIDDEN; + } + return isAuthorized; +} + +function checkPayload(inObj) { + var isValid = true; + try { + var provider = JSON.parse(inObj); + if (!provider.hasOwnProperty('Code') || !provider.hasOwnProperty('Name') || !provider.hasOwnProperty('U_ACTIVE') || + !provider.hasOwnProperty('U_ACTIVE_FROM') || !provider.hasOwnProperty('U_ACTIVE_TO')) { + isValid = false; + } + } catch (e) { + exceptionHandler(e); + isValid = false; + } + if (!isValid) { + outMsg = {}; + outMsg.method = "checkPayload"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "invalid payload content"; + outMessages.push(outMsg); + $.response.status = $.net.http.BAD_REQUEST; + } + return isValid; +} + +function setConnectionParams() { + var idValue = schemaName; + var idFieldname = 'SYS_NAME'; + var CompanyConfig = destLib.getCompanyCfg(idValue, idFieldname); + UserComp = CompanyConfig.COMPANYNAME; + UserName = CompanyConfig.USERNAME; + UserPass = destLib.readSecureStore(CompanyConfig.ID); + if (debugLevel > 1) { + myDebug.connectionParams = CompanyConfig; + } + myDebug.idValue = idValue; + myDebug.idFieldname = idFieldname; + if (CompanyConfig.COMPANYNAME === undefined) { + outMsg = {}; + outMsg.method = "getCompany"; + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "System " + idValue + " is invalid for this endpoint"; + outMessages.push(outMsg); + } + + myDebug.CompanyName = UserComp; +} + +function slLogin() { + var loginResult = false; + var loginInfo = {}; + loginInfo.UserName = UserName; + loginInfo.Password = UserPass; + loginInfo.CompanyDB = UserComp; + + // SL LOGIN + var response = slLib.SLLogin(JSON.stringify(loginInfo), null, null); + + // B1SESSION and ROUTEID cookies returned by Login + for (var j in response.cookies) { + if (response.cookies[j].name == "B1SESSION") { + SESSIONID = response.cookies[j].value; + //output.SessionID = SESSIONID; + } else if (response.cookies[j].name == "ROUTEID") { + NODEID = response.cookies[j].value; + //output.NodeID = NODEID; + } + } + + var loginResponse; + try { + loginResponse = JSON.parse(response.body.asString()); + } catch (e) { + loginResponse = response.body.asString(); + } + + if (debugLevel > 1) { + myDebug.loginInfo = loginInfo; + } + myDebug.loginResponse = loginResponse; + if (response.status === 200) { + loginResult = true; + } else { + outMsg = {}; + outMsg.method = "login"; + outMsg.status = "error"; + var slError = myDebug.loginResponse.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(myDebug.loginResponse); + } + outMsg.response = myDebug.loginResponse; + //outMsg.message = loginResponse; + outMessages.push(outMsg); + outStatus = "error"; + } + return loginResult; +} + +function createUDO(provider) { + outMsg = {}; + outMsg.method = "createUDO"; + outMsg.status = "error"; + try { + var slProviderObj = { + Code: provider.Code, + Name: provider.Name, + U_ACTIVE: provider.U_ACTIVE, + U_ACTIVE_FROM: datetimeLib.convertToISODate(provider.U_ACTIVE_FROM), + U_ACTIVE_TO: datetimeLib.convertToISODate(provider.U_ACTIVE_TO) + }; + myDebug.slProviderObj = slProviderObj; + var responseProvider = slLib.postDynamicEntity('EON_PROVIDER', JSON.stringify(slProviderObj), SESSIONID, NODEID); + if (responseProvider.status >= 200 && responseProvider.status < 300) { + outMsg.status = "success"; + } else { + if (responseProvider.body) { + var responseBodyParsed = JSON.parse(responseProvider.body.asString()); + var slError = responseBodyParsed.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = responseProvider.body.asString(); + } + outMsg.response = responseBodyParsed; + } else { + outMsg.message = JSON.stringify(responseProvider); + } + outStatus = "error"; + } + outMessages.push(outMsg); + } catch (ex) { + exceptionHandler(ex); + } +} + +// main +var content = ""; +if ($.request.body) { + content = $.request.body.asString(); +} +if (checkPayload(content) && checkAuthorization()) { + setConnectionParams(); + slLoggedIn = slLogin(); + if (slLoggedIn) { + var inObj = JSON.parse(content); + createUDO(inObj); + slLib.SLLogout(SESSIONID, NODEID); + } +} + +$.trace.debug("DEBUG: " + JSON.stringify(myDebug)); +setOutputMessage(); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/backend/addNextPeriodData.xsjs b/uniorg/eon/emobility/provider/backend/addNextPeriodData.xsjs new file mode 100644 index 0000000..f508541 --- /dev/null +++ b/uniorg/eon/emobility/provider/backend/addNextPeriodData.xsjs @@ -0,0 +1,308 @@ +var datetimeLib = $.import("uniorg.libs", "datetime"); +//var logginglib = $.import("uniorg.libs", "uologging"); +//var billingEngine = $.import("uniorg.eon.emobility.billing.engine.v1", "BillingEngine"); +var destLib = $.import("uniorg.destinations", "uodestlib"); +var slLib = $.import("uniorg.ServiceLayer", "B1SLLogic"); + +var serviceName = "eon.emobility.provider.backend.addNextPeriodData.xsjs"; +var serviceVersion = '1.3'; + +var output = {}; +var outMessages = []; +var outMsg = {}; +var outStatus = "success"; +var myDebug = {}; + +var companyid = 0; +var UserName = ''; +var UserPass = ''; +var UserComp = ''; + +var SESSIONID = ""; +var NODEID = ""; +var slLoggedIn = false; +var schemaName = "A19753_EON_P01"; + +var debugLevel = 0; +switch ($.request.parameters.get("debug")) { + case "true": + case "yes": + case "1": + debugLevel = 1; + break; + case "full": + case "2": + debugLevel = 2; + break; +} + +if (debugLevel > 0) { + output.requestParams = $.request.parameters; +} + +function setOutputMessage() { + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + $.response.contentType = "application/json"; + $.response.setBody(JSON.stringify(output)); + //$.response.status = $.net.http.OK; +} + +function exceptionHandler(ex) { + if (outMsg.method && outMessages.indexOf(outMsg) === -1) { + outMsg.status = "canceled"; + outMessages.push(outMsg); + } + outMsg = {}; + outMsg.method = "exceptionHandler"; + outMsg.status = "error"; + outMsg.message = ex.toString(); + if (debugLevel > 0) { + outMsg.exceptionInfo = {}; + outMsg.exceptionInfo.name = ex.name; + outMsg.exceptionInfo.message = ex.message; + outMsg.exceptionInfo.fileName = ex.fileName; + outMsg.exceptionInfo.lineNumber = ex.lineNumber; + outMsg.exceptionInfo.columnNumber = ex.columnNumber; + outMsg.exceptionInfo.stack = ex.stack; + //outMsg.exceptionInfo.source = ex.toSource(); + } + outMessages.push(outMsg); + outStatus = "error"; + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + + var errbody = JSON.stringify(output); + $.response.contentType = 'application/json'; + $.response.setBody(errbody); + $.response.status = $.net.http.INTERNAL_SERVER_ERROR; + try { + if (slLoggedIn) { + slLib.SLLogout(SESSIONID, NODEID); + } + } catch (e) { + + } +} + +function checkAuthorization() { + var isAuthorized = true; + try { + $.session.assertAppPrivilege("uniorg.eon.emobility.provider::MaintainProviderData"); + } catch (ex) { + isAuthorized = false; + outMsg = {}; + outMsg.method = "checkAuthorization"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "Privilege '" + ex.privilege + "' is missing"; + outMessages.push(outMsg); + $.response.status = $.net.http.FORBIDDEN; + } + return isAuthorized; +} + +function checkPayload(inObj) { + var isValid = true; + var errorList = []; + try { + var provider = JSON.parse(inObj); + if (!provider.hasOwnProperty('Code')) { + isValid = false; + } + if (Array.isArray(provider.NextPeriod)) { + provider.NextPeriod.forEach(function(npl) { + if (!npl.hasOwnProperty('U_CODE') || !npl.hasOwnProperty('U_FROM') || !npl.hasOwnProperty('U_TO') || !npl.hasOwnProperty('U_TYP') || !npl.hasOwnProperty('U_OPERATOR') || !npl.hasOwnProperty('U_SUBOPERATOR')) { + isValid = false; + } else { + var errorDetails = { + U_CODE: npl.U_CODE, + U_FROM: npl.U_FROM, + U_TO: npl.U_TO, + U_TYP: npl.U_TYP, + U_OPERATOR: npl.U_OPERATOR, + U_SUBOPERATOR: npl.U_SUBOPERATOR, + Status: 'error' + }; + if (errorDetails.StatusText) { + errorList.push(errorDetails); + isValid = false; + } else if (debugLevel > 0) { + errorDetails.Status = "success"; + errorList.push(errorDetails); + } + } + }); + } else { + isValid = false; + } + } catch (e) { + exceptionHandler(e); + isValid = false; + } + if (!isValid) { + outMsg = {}; + outMsg.method = "checkPayload"; + outMsg.status = "error"; + outStatus = "error"; + if (errorList.length > 0) { + outMsg.message = "invalid payload content"; + output.results = errorList; + } else { + outMsg.message = "invalid payload structure"; + } + outMessages.push(outMsg); + $.response.status = $.net.http.BAD_REQUEST; + } + return isValid; +} + +function setConnectionParams() { + var idValue = schemaName; + var idFieldname = 'SYS_NAME'; + var CompanyConfig = destLib.getCompanyCfg(idValue, idFieldname); + UserComp = CompanyConfig.COMPANYNAME; + UserName = CompanyConfig.USERNAME; + UserPass = destLib.readSecureStore(CompanyConfig.ID); + if (debugLevel > 1) { + myDebug.connectionParams = CompanyConfig; + } + myDebug.idValue = idValue; + myDebug.idFieldname = idFieldname; + if (CompanyConfig.COMPANYNAME === undefined) { + outMsg = {}; + outMsg.method = "getCompany"; + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "System " + idValue + " is invalid for this endpoint"; + outMessages.push(outMsg); + } + + myDebug.CompanyName = UserComp; +} + +function slLogin() { + var loginResult = false; + var loginInfo = {}; + loginInfo.UserName = UserName; + loginInfo.Password = UserPass; + loginInfo.CompanyDB = UserComp; + + // SL LOGIN + var response = slLib.SLLogin(JSON.stringify(loginInfo), null, null); + + // B1SESSION and ROUTEID cookies returned by Login + for (var j in response.cookies) { + if (response.cookies[j].name == "B1SESSION") { + SESSIONID = response.cookies[j].value; + //output.SessionID = SESSIONID; + } else if (response.cookies[j].name == "ROUTEID") { + NODEID = response.cookies[j].value; + //output.NodeID = NODEID; + } + } + + var loginResponse; + try { + loginResponse = JSON.parse(response.body.asString()); + } catch (e) { + loginResponse = response.body.asString(); + } + + if (debugLevel > 1) { + myDebug.loginInfo = loginInfo; + } + myDebug.loginResponse = loginResponse; + if (response.status === 200) { + loginResult = true; + } else { + outMsg = {}; + outMsg.method = "login"; + outMsg.status = "error"; + var slError = myDebug.loginResponse.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(myDebug.loginResponse); + } + outMsg.response = myDebug.loginResponse; + //outMsg.message = loginResponse; + outMessages.push(outMsg); + outStatus = "error"; + } + return loginResult; +} + +function updateUDO(provider) { + outMsg = {}; + outMsg.method = "updateUDO"; + outMsg.status = "failure"; + try { + var slProviderObj = { + EON_PROVIDER_LINESCollection: provider.NextPeriod.map(function(npl) {return { + Code: npl.Code, + U_CODE: npl.U_CODE, + U_FROM: datetimeLib.convertToISODate(npl.U_FROM), + U_TO: datetimeLib.convertToISODate(npl.U_TO), + U_OPERATOR: npl.U_OPERATOR, + U_SUBOPERATOR: npl.U_SUBOPERATOR, + U_TYP: npl.U_TYP, + U_CURRENCY: npl.U_CURRENCY, + U_VALUE: npl.NewValue, + U_BLOCK_FROM: npl.U_BLOCK_FROM, + U_BLOCK_TO: npl.U_BLOCK_TO, + U_BLOCKMAX: npl.U_BLOCKMAX, + U_RELEASED: 'Y', + U_RELEASE_DATE: datetimeLib.convertToISODate(new Date()), + U_RELEASE_USER: $.session.getUsername(), + U_CHANGE_DATE: datetimeLib.convertToISODate(new Date()), + U_CHANGE_USER: $.session.getUsername() + };}) + }; + myDebug.slProviderObj = slProviderObj; + var responseProvider = slLib.patchDynamicEntity('EON_PROVIDER', provider.Code, JSON.stringify(slProviderObj), SESSIONID, NODEID, false); + if (responseProvider.status >= 200 && responseProvider.status < 300) { + outMsg.status = "success"; + } else { + if (responseProvider.body) { + var responseBodyParsed = JSON.parse(responseProvider.body.asString()); + var slError = responseBodyParsed.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = responseProvider.body.asString(); + } + outMsg.response = responseBodyParsed; + } else { + outMsg.message = JSON.stringify(responseProvider); + } + outStatus = "error"; + } + outMessages.push(outMsg); + } catch (ex) { + exceptionHandler(ex); + } +} + +// main +var content = ""; +if ($.request.body) { + content = $.request.body.asString(); +} +if (checkPayload(content) && checkAuthorization()) { + setConnectionParams(); + slLoggedIn = slLogin(); + if (slLoggedIn) { + updateUDO(JSON.parse(content)); + slLib.SLLogout(SESSIONID, NODEID); + } +} + +$.trace.debug("DEBUG: " + JSON.stringify(myDebug)); +setOutputMessage(); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/backend/deleteSubOperator.xsjs b/uniorg/eon/emobility/provider/backend/deleteSubOperator.xsjs new file mode 100644 index 0000000..bc1d544 --- /dev/null +++ b/uniorg/eon/emobility/provider/backend/deleteSubOperator.xsjs @@ -0,0 +1,269 @@ +var datetimeLib = $.import("uniorg.libs", "datetime"); +//var logginglib = $.import("uniorg.libs", "uologging"); +//var billingEngine = $.import("uniorg.eon.emobility.billing.engine.v1", "BillingEngine"); +var destLib = $.import("uniorg.destinations", "uodestlib"); +var slLib = $.import("uniorg.ServiceLayer", "B1SLLogic"); + +var serviceName = "eon.emobility.provider.backend.deleteSubOperator.xsjs"; +var serviceVersion = '1.0'; + +var output = {}; +var outMessages = []; +var outMsg = {}; +var outStatus = "success"; +var myDebug = {}; + +var companyid = 0; +var UserName = ''; +var UserPass = ''; +var UserComp = ''; + +var SESSIONID = ""; +var NODEID = ""; +var slLoggedIn = false; +var schemaName = "A19753_EON_P01"; + +var debugLevel = 0; +switch ($.request.parameters.get("debug")) { + case "true": + case "yes": + case "1": + debugLevel = 1; + break; + case "full": + case "2": + debugLevel = 2; + break; +} + +if (debugLevel > 0) { + output.requestParams = $.request.parameters; +} + +function setOutputMessage() { + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + $.response.contentType = "application/json"; + $.response.setBody(JSON.stringify(output)); + //$.response.status = $.net.http.OK; +} + +function exceptionHandler(ex) { + if (outMsg.method && outMessages.indexOf(outMsg) === -1) { + outMsg.status = "canceled"; + outMessages.push(outMsg); + } + outMsg = {}; + outMsg.method = "exceptionHandler"; + outMsg.status = "error"; + outMsg.message = ex.toString(); + if (debugLevel > 0) { + outMsg.exceptionInfo = {}; + outMsg.exceptionInfo.name = ex.name; + outMsg.exceptionInfo.message = ex.message; + outMsg.exceptionInfo.fileName = ex.fileName; + outMsg.exceptionInfo.lineNumber = ex.lineNumber; + outMsg.exceptionInfo.columnNumber = ex.columnNumber; + outMsg.exceptionInfo.stack = ex.stack; + //outMsg.exceptionInfo.source = ex.toSource(); + } + outMessages.push(outMsg); + outStatus = "error"; + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + + var errbody = JSON.stringify(output); + $.response.contentType = 'application/json'; + $.response.setBody(errbody); + $.response.status = $.net.http.INTERNAL_SERVER_ERROR; + try { + if (slLoggedIn) { + slLib.SLLogout(SESSIONID, NODEID); + } + } catch (e) { + + } +} + +function checkAuthorization() { + var isAuthorized = true; + try { + $.session.assertAppPrivilege("uniorg.eon.emobility.provider::MaintainProviderData"); + } catch (ex) { + isAuthorized = false; + outMsg = {}; + outMsg.method = "checkAuthorization"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "Privilege '" + ex.privilege + "' is missing"; + outMessages.push(outMsg); + $.response.status = $.net.http.FORBIDDEN; + } + return isAuthorized; +} + +function checkPayload(inObj) { + var isValid = true; + var errorList = []; + try { + var subOperator = JSON.parse(inObj); + if (!subOperator.hasOwnProperty('Code')) { + isValid = false; + } + } catch (e) { + exceptionHandler(e); + isValid = false; + } + if (!isValid) { + outMsg = {}; + outMsg.method = "checkPayload"; + outMsg.status = "error"; + outStatus = "error"; + if (errorList.length > 0) { + outMsg.message = "invalid payload content"; + output.results = errorList; + } else { + outMsg.message = "invalid payload structure"; + } + outMessages.push(outMsg); + $.response.status = $.net.http.BAD_REQUEST; + } + return isValid; +} + +function setConnectionParams() { + var idValue = schemaName; + var idFieldname = 'SYS_NAME'; + var CompanyConfig = destLib.getCompanyCfg(idValue, idFieldname); + UserComp = CompanyConfig.COMPANYNAME; + UserName = CompanyConfig.USERNAME; + UserPass = destLib.readSecureStore(CompanyConfig.ID); + if (debugLevel > 1) { + myDebug.connectionParams = CompanyConfig; + } + myDebug.idValue = idValue; + myDebug.idFieldname = idFieldname; + if (CompanyConfig.COMPANYNAME === undefined) { + outMsg = {}; + outMsg.method = "getCompany"; + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "System " + idValue + " is invalid for this endpoint"; + outMessages.push(outMsg); + } + + myDebug.CompanyName = UserComp; +} + +function slLogin() { + var loginResult = false; + var loginInfo = {}; + loginInfo.UserName = UserName; + loginInfo.Password = UserPass; + loginInfo.CompanyDB = UserComp; + + // SL LOGIN + var response = slLib.SLLogin(JSON.stringify(loginInfo), null, null); + + // B1SESSION and ROUTEID cookies returned by Login + for (var j in response.cookies) { + if (response.cookies[j].name == "B1SESSION") { + SESSIONID = response.cookies[j].value; + //output.SessionID = SESSIONID; + } else if (response.cookies[j].name == "ROUTEID") { + NODEID = response.cookies[j].value; + //output.NodeID = NODEID; + } + } + + var loginResponse; + try { + loginResponse = JSON.parse(response.body.asString()); + } catch (e) { + loginResponse = response.body.asString(); + } + + if (debugLevel > 1) { + myDebug.loginInfo = loginInfo; + } + myDebug.loginResponse = loginResponse; + if (response.status === 200) { + loginResult = true; + } else { + outMsg = {}; + outMsg.method = "login"; + outMsg.status = "error"; + var slError = myDebug.loginResponse.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(myDebug.loginResponse); + } + outMsg.response = myDebug.loginResponse; + //outMsg.message = loginResponse; + outMessages.push(outMsg); + outStatus = "error"; + } + return loginResult; +} + +function deleteUDO(Code) { + outMsg = {}; + outMsg.method = "deleteUDO"; + outMsg.code = Code; + outMsg.status = "error"; + var result = {}; + try { + var responseDelete = slLib.deleteDynamicEntity('EON_SUBOPERATOR', Code, SESSIONID, NODEID); + outMsg.statuscode = responseDelete.status; + if (responseDelete.status >= 200 && responseDelete.status < 300) { + outMsg.status = "success"; + } else { + if (responseDelete.body) { + var responseBodyParsed = JSON.parse(responseDelete.body.asString()); + var slError = responseBodyParsed.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = responseDelete.body.asString(); + } + outMsg.response = responseBodyParsed; + } else { + outMsg.message = JSON.stringify(responseDelete); + } + outStatus = "error"; + } + if (debugLevel > 0 || outMsg.status !== "success") { + outMessages.push(outMsg); + } + } catch (ex) { + exceptionHandler(ex); + } + return result; +} + +// main +var content = ""; +if ($.request.body) { + content = $.request.body.asString(); +} +if (checkPayload(content) && checkAuthorization()) { + setConnectionParams(); + slLoggedIn = slLogin(); + if (slLoggedIn) { + var inObj = JSON.parse(content); + if (outStatus !== "error") { + deleteUDO(inObj.Code); + } + slLib.SLLogout(SESSIONID, NODEID); + } +} + +$.trace.debug("DEBUG: " + JSON.stringify(myDebug)); +setOutputMessage(); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/backend/getProviderData.xsjs b/uniorg/eon/emobility/provider/backend/getProviderData.xsjs new file mode 100644 index 0000000..909780b --- /dev/null +++ b/uniorg/eon/emobility/provider/backend/getProviderData.xsjs @@ -0,0 +1,971 @@ +//var datetimelib = $.import("uniorg.libs", "datetime"); +//var logginglib = $.import("uniorg.libs", "uologging"); +//var billingEngine = $.import("uniorg.eon.emobility.billing.engine.v1", "BillingEngine"); + +var serviceName = "eon.emobility.provider.backend.getProviderData.xsjs"; +var serviceVersion = '1.3'; + +var output = {}; +var outMessages = []; +var outMsg = {}; +var outStatus = "success"; +var myDebug = {}; + +var debugLevel = 0; +switch ($.request.parameters.get("debug")) { + case "true": + case "yes": + case "1": + debugLevel = 1; + break; + case "full": + case "2": + debugLevel = 2; + break; +} + +if (debugLevel > 0) { + output.requestParams = $.request.parameters; +} + +function setOutputMessage() { + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + $.response.contentType = "application/json"; + $.response.setBody(JSON.stringify(output)); + //$.response.status = $.net.http.OK; +} + +function exceptionHandler(ex) { + outMsg = {}; + outMsg.method = "exceptionHandler"; + outMsg.status = "error"; + outMsg.message = ex.toString(); + if (debugLevel > 0) { + outMsg.exceptionInfo = {}; + outMsg.exceptionInfo.name = ex.name; + outMsg.exceptionInfo.message = ex.message; + outMsg.exceptionInfo.fileName = ex.fileName; + outMsg.exceptionInfo.lineNumber = ex.lineNumber; + outMsg.exceptionInfo.columnNumber = ex.columnNumber; + outMsg.exceptionInfo.stack = ex.stack; + //outMsg.exceptionInfo.source = ex.toSource(); + } + outMessages.push(outMsg); + outStatus = "error"; + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + + var errbody = JSON.stringify(output); + $.response.contentType = 'application/json'; + $.response.setBody(errbody); + $.response.status = $.net.http.INTERNAL_SERVER_ERROR; +} + +function checkAuthorization() { + var isAuthorized = true; + try { + $.session.assertAppPrivilege("uniorg.eon.emobility.provider::ViewProviderData"); + } catch (ex) { + isAuthorized = false; + outMsg = {}; + outMsg.method = "checkAuthorization"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "Privilege '" + ex.privilege + "' is missing"; + outMessages.push(outMsg); + $.response.status = $.net.http.FORBIDDEN; + } + // temporary test + /*var random_boolean = Math.random() < 0.5; + if (random_boolean) { + isAuthorized = false; + outMsg = {}; + outMsg.method = "checkAuthorization"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "Random test exception"; + outMessages.push(outMsg); + $.response.status = $.net.http.UNAUTHORIZED; + }*/ + // + return isAuthorized; +} + +function checkParams() { + var isValid = true; + var missingParams = []; + try { + /*if (!$.request.parameters.get("billingrunid")) { + missingParams.push("billingrunid"); + isValid = false; + } + if (!$.request.parameters.get("phase")) { + missingParams.push("phase"); + isValid = false; + }*/ + } catch (e) { + exceptionHandler(e); + isValid = false; + } + if (!isValid) { + outMsg = {}; + outMsg.method = "checkParams"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "missing mandatory parameters: " + missingParams.join(); + outMessages.push(outMsg); + $.response.status = $.net.http.BAD_REQUEST; + } + return isValid; +} + +function setScheduled(billingRunId) { + outMsg = {}; + outMsg.method = "schedule"; + outMsg.status = "failure"; + try { + var conn = $.hdb.getConnection(); + var query = + 'update BRL set BRL."STATUS"=\'scheduled\' from \ +"A19753_EON_P01"."UO_BILLINGRUN_LINE" BRL INNER JOIN "A19753_EON_P01"."UO_BILLINGRUN_HEAD" BRH ON BRH."ID"=BRL."BILLING_RUN_ID" \ +where BRL."STATUS" = \'phase1\' and BRH."RUN_ID" = ?'; + myDebug.updateStatement = query; + var rc = conn.executeUpdate(query, billingRunId); + outMsg.rowsAffected = rc; + if (rc > 0) { + outMsg.status = "success"; + } else { + outStatus = "error"; + outMsg.message = "No Billing Lines for Billing Run ID " + billingRunId + " were found"; + $.response.status = $.net.http.NOT_FOUND; + } + conn.commit(); + conn.close(); + + outMessages.push(outMsg); + } catch (ex) { + exceptionHandler(ex); + } +} + +function setPhase(billingRunId, phase) { + outMsg = {}; + outMsg.method = "update"; + outMsg.status = "failure"; + try { + var conn = $.hdb.getConnection(); + var query = + 'UPDATE "A19753_EON_P01"."UO_BILLINGRUN_HEAD" SET "PHASE" = ?, "UPDATE_TS" = CURRENT_TIMESTAMP, "USER_EXECUTE" = ? WHERE "RUN_ID" = ?'; + myDebug.updateStatement = query; + var rc = conn.executeUpdate(query, phase, $.session.getUsername(), billingRunId); + outMsg.rowsAffected = rc; + if (rc > 0) { + outMsg.status = "success"; + } else { + outStatus = "error"; + outMsg.message = "Billing Run ID " + billingRunId + " was not found"; + $.response.status = $.net.http.NOT_FOUND; + } + conn.commit(); + conn.close(); + + outMessages.push(outMsg); + if (outMsg.status = "success" && phase === 'INVOICED') { + setScheduled(billingRunId); + } + } catch (ex) { + exceptionHandler(ex); + } +} + +function getData() { + outMsg = {}; + outMsg.method = "get"; + outMsg.status = "success"; + var rsMsg = {}; + rsMsg.ReadOnly = !$.session.hasAppPrivilege("uniorg.eon.emobility.provider::MaintainProviderData"); + try { + + var conn = $.db.getConnection(); + var pstmt; + var query = 'SELECT * FROM "A19753_EON_P01"."V_EON_PROVIDER" ORDER BY "Code"'; + pstmt = conn.prepareStatement(query); + var rs = pstmt.executeQuery(); + var rsmd = rs.getMetaData(); + var colCount = rsmd.getColumnCount(); + var rc = 0; + var providerRows = []; + while (rs.next()) { + var row = {}; + rc++; + for (var c = 1; c <= colCount; c++) { + var colName = rsmd.getColumnLabel(c); + var colType = rsmd.getColumnTypeName(c); + switch (colType) { + case 'TINYINT': + case 'SMALLINT': + case 'INT': + case 'INTEGER': + case 'BIGINT': + row[colName] = rs.getInteger(c); + break; + case 'DECIMAL': + row[colName] = rs.getDecimal(c); + break; + case 'REAL': + case 'DOUBLE': + case 'FLOAT': + row[colName] = rs.getDouble(c); + break; + case 'NVARCHAR': + case 'NCHAR': + case 'SHORTTEXT': + row[colName] = rs.getNString(c); + break; + case 'VARCHAR': + case 'CHAR': + row[colName] = rs.getString(c); + break; + case 'BINARY': + case 'VARBINARY': + row[colName] = rs.getBString(c); + break; + case 'DATE': + row[colName] = rs.getDate(c); + break; + case 'TIME': + row[colName] = rs.getTime(c); + break; + case 'TIMESTAMP': + row[colName] = rs.getTimestamp(c); + break; + case 'CLOB': + row[colName] = rs.getClob(c); + break; + case 'NCLOB': + case 'TEXT': + row[colName] = rs.getNClob(c); + break; + case 'BLOB': + row[colName] = rs.getBlob(c); + break; + case 'SECONDDATE': + row[colName] = rs.getSeconddate(c); + break; + } + //row[colName] = colType; + } + providerRows.push(row); + } + + query = 'SELECT * FROM "A19753_EON_P01"."V_EON_PROVIDER_LINES" ORDER BY "Code", U_CODE DESC, U_FROM DESC, U_TYP, U_OPERATOR'; + pstmt = conn.prepareStatement(query); + rs = pstmt.executeQuery(); + rsmd = rs.getMetaData(); + colCount = rsmd.getColumnCount(); + rc = 0; + var lineRows = []; + while (rs.next()) { + row = {}; + rc++; + for (c = 1; c <= colCount; c++) { + colName = rsmd.getColumnLabel(c); + colType = rsmd.getColumnTypeName(c); + switch (colType) { + case 'TINYINT': + case 'SMALLINT': + case 'INT': + case 'INTEGER': + case 'BIGINT': + row[colName] = rs.getInteger(c); + break; + case 'DECIMAL': + row[colName] = rs.getDecimal(c); + break; + case 'REAL': + case 'DOUBLE': + case 'FLOAT': + row[colName] = rs.getDouble(c); + break; + case 'NVARCHAR': + case 'NCHAR': + case 'SHORTTEXT': + row[colName] = rs.getNString(c); + break; + case 'VARCHAR': + case 'CHAR': + row[colName] = rs.getString(c); + break; + case 'BINARY': + case 'VARBINARY': + row[colName] = rs.getBString(c); + break; + case 'DATE': + row[colName] = rs.getDate(c); + break; + case 'TIME': + row[colName] = rs.getTime(c); + break; + case 'TIMESTAMP': + row[colName] = rs.getTimestamp(c); + break; + case 'CLOB': + row[colName] = rs.getClob(c); + break; + case 'NCLOB': + case 'TEXT': + row[colName] = rs.getNClob(c); + break; + case 'BLOB': + row[colName] = rs.getBlob(c); + break; + case 'SECONDDATE': + row[colName] = rs.getSeconddate(c); + break; + } + //row[colName] = colType; + } + row.editable = false; + row.new = false; + row.pendingChanges = false; + row.highlight = 'None'; + row.highlightText = ''; + row.guid = $.util.createUuid(); + lineRows.push(row); + } + + query = 'SELECT * FROM "A19753_EON_P01"."V_EON_PROVIDER_PERIODS" ORDER BY "Code", U_FROM DESC'; + pstmt = conn.prepareStatement(query); + rs = pstmt.executeQuery(); + rsmd = rs.getMetaData(); + colCount = rsmd.getColumnCount(); + rc = 0; + var periodRows = []; + while (rs.next()) { + row = {}; + rc++; + for (c = 1; c <= colCount; c++) { + colName = rsmd.getColumnLabel(c); + colType = rsmd.getColumnTypeName(c); + switch (colType) { + case 'TINYINT': + case 'SMALLINT': + case 'INT': + case 'INTEGER': + case 'BIGINT': + row[colName] = rs.getInteger(c); + break; + case 'DECIMAL': + row[colName] = rs.getDecimal(c); + break; + case 'REAL': + case 'DOUBLE': + case 'FLOAT': + row[colName] = rs.getDouble(c); + break; + case 'NVARCHAR': + case 'NCHAR': + case 'SHORTTEXT': + row[colName] = rs.getNString(c); + break; + case 'VARCHAR': + case 'CHAR': + row[colName] = rs.getString(c); + break; + case 'BINARY': + case 'VARBINARY': + row[colName] = rs.getBString(c); + break; + case 'DATE': + row[colName] = rs.getDate(c); + break; + case 'TIME': + row[colName] = rs.getTime(c); + break; + case 'TIMESTAMP': + row[colName] = rs.getTimestamp(c); + break; + case 'CLOB': + row[colName] = rs.getClob(c); + break; + case 'NCLOB': + case 'TEXT': + row[colName] = rs.getNClob(c); + break; + case 'BLOB': + row[colName] = rs.getBlob(c); + break; + case 'SECONDDATE': + row[colName] = rs.getSeconddate(c); + break; + } + //row[colName] = colType; + } + periodRows.push(row); + } + query = 'SELECT * FROM "A19753_EON_P01"."V_EON_PROVIDER_NEXT_PERIOD" ORDER BY "Code", U_CODE DESC, U_FROM DESC, U_TYP, U_OPERATOR, U_SUBOPERATOR'; + pstmt = conn.prepareStatement(query); + rs = pstmt.executeQuery(); + rsmd = rs.getMetaData(); + colCount = rsmd.getColumnCount(); + rc = 0; + var nextPeriodRows = []; + while (rs.next()) { + row = {}; + rc++; + for (c = 1; c <= colCount; c++) { + colName = rsmd.getColumnLabel(c); + colType = rsmd.getColumnTypeName(c); + switch (colType) { + case 'TINYINT': + case 'SMALLINT': + case 'INT': + case 'INTEGER': + case 'BIGINT': + row[colName] = rs.getInteger(c); + break; + case 'DECIMAL': + row[colName] = rs.getDecimal(c); + break; + case 'REAL': + case 'DOUBLE': + case 'FLOAT': + row[colName] = rs.getDouble(c); + break; + case 'NVARCHAR': + case 'NCHAR': + case 'SHORTTEXT': + row[colName] = rs.getNString(c); + break; + case 'VARCHAR': + case 'CHAR': + row[colName] = rs.getString(c); + break; + case 'BINARY': + case 'VARBINARY': + row[colName] = rs.getBString(c); + break; + case 'DATE': + row[colName] = rs.getDate(c); + break; + case 'TIME': + row[colName] = rs.getTime(c); + break; + case 'TIMESTAMP': + row[colName] = rs.getTimestamp(c); + break; + case 'CLOB': + row[colName] = rs.getClob(c); + break; + case 'NCLOB': + case 'TEXT': + row[colName] = rs.getNClob(c); + break; + case 'BLOB': + row[colName] = rs.getBlob(c); + break; + case 'SECONDDATE': + row[colName] = rs.getSeconddate(c); + break; + } + //row[colName] = colType; + } + row.editable = false; + row.guid = $.util.createUuid(); + row.highlight = 'None'; + row.highlightText = ''; + nextPeriodRows.push(row); + } + + var provider = providerRows.map(function(p) { + var prov = {}; + // copy all properties of provider head object + Object.keys(p).forEach(function(k) { + prov[k] = p[k]; + }); + prov.editable = false; + prov.new = false; + prov.pendingChanges = false; + prov.allowNewPeriod = $.session.hasAppPrivilege("uniorg.eon.emobility.provider::MaintainProviderData"); + prov.Lines = lineRows.filter(function(lr) { + return lr.Code === p.Code; + }); + prov.Periods = periodRows.filter(function(pr) { + return pr.Code === p.Code; + }); + prov.NextPeriod = nextPeriodRows.filter(function(npr) { + return npr.Code === p.Code; + }); + return prov; + }); + rsMsg.Provider = provider; + + + query = 'SELECT T1."FldValue" AS "U_CODE" FROM "A19753_EON_P01"."CUFD" D1 INNER JOIN "A19753_EON_P01"."UFD1" T1 ON D1."TableID"=T1."TableID" AND D1."FieldID"=T1."FieldID" AND D1."AliasID"=\'CODE\' WHERE D1."TableID" = \'@EON_PROVIDER_LINES\''; + pstmt = conn.prepareStatement(query); + rs = pstmt.executeQuery(); + rsmd = rs.getMetaData(); + colCount = rsmd.getColumnCount(); + rc = 0; + var valuesCode = []; + while (rs.next()) { + row = {}; + rc++; + for (c = 1; c <= colCount; c++) { + colName = rsmd.getColumnLabel(c); + colType = rsmd.getColumnTypeName(c); + switch (colType) { + case 'TINYINT': + case 'SMALLINT': + case 'INT': + case 'INTEGER': + case 'BIGINT': + row[colName] = rs.getInteger(c); + break; + case 'DECIMAL': + row[colName] = rs.getDecimal(c); + break; + case 'REAL': + case 'DOUBLE': + case 'FLOAT': + row[colName] = rs.getDouble(c); + break; + case 'NVARCHAR': + case 'NCHAR': + case 'SHORTTEXT': + row[colName] = rs.getNString(c); + break; + case 'VARCHAR': + case 'CHAR': + row[colName] = rs.getString(c); + break; + case 'BINARY': + case 'VARBINARY': + row[colName] = rs.getBString(c); + break; + case 'DATE': + row[colName] = rs.getDate(c); + break; + case 'TIME': + row[colName] = rs.getTime(c); + break; + case 'TIMESTAMP': + row[colName] = rs.getTimestamp(c); + break; + case 'CLOB': + row[colName] = rs.getClob(c); + break; + case 'NCLOB': + case 'TEXT': + row[colName] = rs.getNClob(c); + break; + case 'BLOB': + row[colName] = rs.getBlob(c); + break; + case 'SECONDDATE': + row[colName] = rs.getSeconddate(c); + break; + } + //row[colName] = colType; + } + valuesCode.push(row); + } + + query = 'SELECT T1."FldValue" AS "U_TYP" FROM "A19753_EON_P01"."CUFD" D1 INNER JOIN "A19753_EON_P01"."UFD1" T1 ON D1."TableID"=T1."TableID" AND D1."FieldID"=T1."FieldID" AND D1."AliasID"=\'TYP\' WHERE D1."TableID" = \'@EON_PROVIDER_LINES\''; + pstmt = conn.prepareStatement(query); + rs = pstmt.executeQuery(); + rsmd = rs.getMetaData(); + colCount = rsmd.getColumnCount(); + rc = 0; + var valuesType = []; + while (rs.next()) { + row = {}; + rc++; + for (c = 1; c <= colCount; c++) { + colName = rsmd.getColumnLabel(c); + colType = rsmd.getColumnTypeName(c); + switch (colType) { + case 'TINYINT': + case 'SMALLINT': + case 'INT': + case 'INTEGER': + case 'BIGINT': + row[colName] = rs.getInteger(c); + break; + case 'DECIMAL': + row[colName] = rs.getDecimal(c); + break; + case 'REAL': + case 'DOUBLE': + case 'FLOAT': + row[colName] = rs.getDouble(c); + break; + case 'NVARCHAR': + case 'NCHAR': + case 'SHORTTEXT': + row[colName] = rs.getNString(c); + break; + case 'VARCHAR': + case 'CHAR': + row[colName] = rs.getString(c); + break; + case 'BINARY': + case 'VARBINARY': + row[colName] = rs.getBString(c); + break; + case 'DATE': + row[colName] = rs.getDate(c); + break; + case 'TIME': + row[colName] = rs.getTime(c); + break; + case 'TIMESTAMP': + row[colName] = rs.getTimestamp(c); + break; + case 'CLOB': + row[colName] = rs.getClob(c); + break; + case 'NCLOB': + case 'TEXT': + row[colName] = rs.getNClob(c); + break; + case 'BLOB': + row[colName] = rs.getBlob(c); + break; + case 'SECONDDATE': + row[colName] = rs.getSeconddate(c); + break; + } + //row[colName] = colType; + } + valuesType.push(row); + } + + query = 'SELECT T1."FldValue" AS "U_OPERATOR" FROM "A19753_EON_P01"."CUFD" D1 INNER JOIN "A19753_EON_P01"."UFD1" T1 ON D1."TableID"=T1."TableID" AND D1."FieldID"=T1."FieldID" AND D1."AliasID"=\'OPERATOR\' WHERE D1."TableID" = \'@EON_PROVIDER_LINES\''; + pstmt = conn.prepareStatement(query); + rs = pstmt.executeQuery(); + rsmd = rs.getMetaData(); + colCount = rsmd.getColumnCount(); + rc = 0; + var valuesOperator = []; + while (rs.next()) { + row = {}; + rc++; + for (c = 1; c <= colCount; c++) { + colName = rsmd.getColumnLabel(c); + colType = rsmd.getColumnTypeName(c); + switch (colType) { + case 'TINYINT': + case 'SMALLINT': + case 'INT': + case 'INTEGER': + case 'BIGINT': + row[colName] = rs.getInteger(c); + break; + case 'DECIMAL': + row[colName] = rs.getDecimal(c); + break; + case 'REAL': + case 'DOUBLE': + case 'FLOAT': + row[colName] = rs.getDouble(c); + break; + case 'NVARCHAR': + case 'NCHAR': + case 'SHORTTEXT': + row[colName] = rs.getNString(c); + break; + case 'VARCHAR': + case 'CHAR': + row[colName] = rs.getString(c); + break; + case 'BINARY': + case 'VARBINARY': + row[colName] = rs.getBString(c); + break; + case 'DATE': + row[colName] = rs.getDate(c); + break; + case 'TIME': + row[colName] = rs.getTime(c); + break; + case 'TIMESTAMP': + row[colName] = rs.getTimestamp(c); + break; + case 'CLOB': + row[colName] = rs.getClob(c); + break; + case 'NCLOB': + case 'TEXT': + row[colName] = rs.getNClob(c); + break; + case 'BLOB': + row[colName] = rs.getBlob(c); + break; + case 'SECONDDATE': + row[colName] = rs.getSeconddate(c); + break; + } + //row[colName] = colType; + } + valuesOperator.push(row); + } + + query = 'select "CurrCode", "CurrName", "ChkName" from "A19753_EON_P01".OCRN ORDER BY "CurrCode"'; + pstmt = conn.prepareStatement(query); + rs = pstmt.executeQuery(); + rsmd = rs.getMetaData(); + colCount = rsmd.getColumnCount(); + rc = 0; + var currencies = []; + while (rs.next()) { + row = {}; + rc++; + for (c = 1; c <= colCount; c++) { + colName = rsmd.getColumnLabel(c); + colType = rsmd.getColumnTypeName(c); + switch (colType) { + case 'TINYINT': + case 'SMALLINT': + case 'INT': + case 'INTEGER': + case 'BIGINT': + row[colName] = rs.getInteger(c); + break; + case 'DECIMAL': + row[colName] = rs.getDecimal(c); + break; + case 'REAL': + case 'DOUBLE': + case 'FLOAT': + row[colName] = rs.getDouble(c); + break; + case 'NVARCHAR': + case 'NCHAR': + case 'SHORTTEXT': + row[colName] = rs.getNString(c); + break; + case 'VARCHAR': + case 'CHAR': + row[colName] = rs.getString(c); + break; + case 'BINARY': + case 'VARBINARY': + row[colName] = rs.getBString(c); + break; + case 'DATE': + row[colName] = rs.getDate(c); + break; + case 'TIME': + row[colName] = rs.getTime(c); + break; + case 'TIMESTAMP': + row[colName] = rs.getTimestamp(c); + break; + case 'CLOB': + row[colName] = rs.getClob(c); + break; + case 'NCLOB': + case 'TEXT': + row[colName] = rs.getNClob(c); + break; + case 'BLOB': + row[colName] = rs.getBlob(c); + break; + case 'SECONDDATE': + row[colName] = rs.getSeconddate(c); + break; + } + //row[colName] = colType; + } + currencies.push(row); + } + + rsMsg.ValueHelp = { + Code: valuesCode, + Type: valuesType, + Operator: valuesOperator, + Currencies: currencies + }; + + query = 'SELECT "Code", "Name" FROM "A19753_EON_P01"."@EON_SUBOPERATOR" ORDER BY "Code"'; + pstmt = conn.prepareStatement(query); + rs = pstmt.executeQuery(); + rsmd = rs.getMetaData(); + colCount = rsmd.getColumnCount(); + rc = 0; + var subOperators = []; + while (rs.next()) { + row = {}; + rc++; + for (c = 1; c <= colCount; c++) { + colName = rsmd.getColumnLabel(c); + colType = rsmd.getColumnTypeName(c); + switch (colType) { + case 'TINYINT': + case 'SMALLINT': + case 'INT': + case 'INTEGER': + case 'BIGINT': + row[colName] = rs.getInteger(c); + break; + case 'DECIMAL': + row[colName] = rs.getDecimal(c); + break; + case 'REAL': + case 'DOUBLE': + case 'FLOAT': + row[colName] = rs.getDouble(c); + break; + case 'NVARCHAR': + case 'NCHAR': + case 'SHORTTEXT': + row[colName] = rs.getNString(c); + break; + case 'VARCHAR': + case 'CHAR': + row[colName] = rs.getString(c); + break; + case 'BINARY': + case 'VARBINARY': + row[colName] = rs.getBString(c); + break; + case 'DATE': + row[colName] = rs.getDate(c); + break; + case 'TIME': + row[colName] = rs.getTime(c); + break; + case 'TIMESTAMP': + row[colName] = rs.getTimestamp(c); + break; + case 'CLOB': + row[colName] = rs.getClob(c); + break; + case 'NCLOB': + case 'TEXT': + row[colName] = rs.getNClob(c); + break; + case 'BLOB': + row[colName] = rs.getBlob(c); + break; + case 'SECONDDATE': + row[colName] = rs.getSeconddate(c); + break; + } + //row[colName] = colType; + } + row.pendingChanges = false; + row.newEntry = false; + subOperators.push(row); + } + + query = 'SELECT "Code", "LineId", "U_ORG_ID" FROM "A19753_EON_P01"."@EON_SUBOPERATOR_L" ORDER BY "Code", "U_ORG_ID"'; + pstmt = conn.prepareStatement(query); + rs = pstmt.executeQuery(); + rsmd = rs.getMetaData(); + colCount = rsmd.getColumnCount(); + rc = 0; + var organizations = []; + while (rs.next()) { + row = {}; + rc++; + for (c = 1; c <= colCount; c++) { + colName = rsmd.getColumnLabel(c); + colType = rsmd.getColumnTypeName(c); + switch (colType) { + case 'TINYINT': + case 'SMALLINT': + case 'INT': + case 'INTEGER': + case 'BIGINT': + row[colName] = rs.getInteger(c); + break; + case 'DECIMAL': + row[colName] = rs.getDecimal(c); + break; + case 'REAL': + case 'DOUBLE': + case 'FLOAT': + row[colName] = rs.getDouble(c); + break; + case 'NVARCHAR': + case 'NCHAR': + case 'SHORTTEXT': + row[colName] = rs.getNString(c); + break; + case 'VARCHAR': + case 'CHAR': + row[colName] = rs.getString(c); + break; + case 'BINARY': + case 'VARBINARY': + row[colName] = rs.getBString(c); + break; + case 'DATE': + row[colName] = rs.getDate(c); + break; + case 'TIME': + row[colName] = rs.getTime(c); + break; + case 'TIMESTAMP': + row[colName] = rs.getTimestamp(c); + break; + case 'CLOB': + row[colName] = rs.getClob(c); + break; + case 'NCLOB': + case 'TEXT': + row[colName] = rs.getNClob(c); + break; + case 'BLOB': + row[colName] = rs.getBlob(c); + break; + case 'SECONDDATE': + row[colName] = rs.getSeconddate(c); + break; + } + //row[colName] = colType; + } + row.guid = $.util.createUuid(); + row.highlight = 'None'; + row.highlightText = ''; + organizations.push(row); + } + + subOperators.forEach(function(subOp) { + subOp.Organizations = organizations.filter(function(org) {return org.Code === subOp.Code;}); + }); + + rsMsg.SubOperators = subOperators; + + rs.close(); + pstmt.close(); + conn.close(); + outMessages.push(outMsg); + } catch (ex) { + exceptionHandler(ex); + } + + output.resultSet = rsMsg; +} + +// main +var content = ""; +if ($.request.body) { + content = $.request.body.asString(); +} +if (checkParams() && checkAuthorization()) { + getData(); + //setPhase($.request.parameters.get("billingrunid"), $.request.parameters.get("phase")); +} + +$.trace.debug("DEBUG: " + JSON.stringify(myDebug)); +setOutputMessage(); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/backend/keepAlive.xsjs b/uniorg/eon/emobility/provider/backend/keepAlive.xsjs new file mode 100644 index 0000000..13aac38 --- /dev/null +++ b/uniorg/eon/emobility/provider/backend/keepAlive.xsjs @@ -0,0 +1,116 @@ +//var datetimelib = $.import("uniorg.libs", "datetime"); +//var logginglib = $.import("uniorg.libs", "uologging"); +//var billingEngine = $.import("uniorg.eon.emobility.billing.engine.v1", "BillingEngine"); + +var serviceName = "eon.emobility.provider.backend.keepAlive.xsjs"; +var serviceVersion = '1.0'; + +var output = {}; +var outMessages = []; +var outMsg = {}; +var outStatus = "success"; +var myDebug = {}; + +var debugLevel = 0; +switch ($.request.parameters.get("debug")) { + case "true": + case "yes": + case "1": + debugLevel = 1; + break; + case "full": + case "2": + debugLevel = 2; + break; +} + +if (debugLevel > 0) { + output.requestParams = $.request.parameters; +} + +function setOutputMessage() { + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + $.response.contentType = "application/json"; + $.response.setBody(JSON.stringify(output)); + //$.response.status = $.net.http.OK; +} + +function exceptionHandler(ex) { + outMsg = {}; + outMsg.method = "exceptionHandler"; + outMsg.status = "error"; + outMsg.message = ex.toString(); + if (debugLevel > 0) { + outMsg.exceptionInfo = {}; + outMsg.exceptionInfo.name = ex.name; + outMsg.exceptionInfo.message = ex.message; + outMsg.exceptionInfo.fileName = ex.fileName; + outMsg.exceptionInfo.lineNumber = ex.lineNumber; + outMsg.exceptionInfo.columnNumber = ex.columnNumber; + outMsg.exceptionInfo.stack = ex.stack; + //outMsg.exceptionInfo.source = ex.toSource(); + } + outMessages.push(outMsg); + outStatus = "error"; + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + + var errbody = JSON.stringify(output); + $.response.contentType = 'application/json'; + $.response.setBody(errbody); + $.response.status = $.net.http.INTERNAL_SERVER_ERROR; +} + +function checkAuthorization() { + var isAuthorized = true; + try { + $.session.assertAppPrivilege("uniorg.eon.emobility.provider::ViewProviderData"); + } catch (ex) { + isAuthorized = false; + outMsg = {}; + outMsg.method = "checkAuthorization"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "Privilege '" + ex.privilege + "' is missing"; + outMessages.push(outMsg); + $.response.status = $.net.http.FORBIDDEN; + } + return isAuthorized; +} + +function dbRequest() { + outMsg = {}; + outMsg.method = "databaseKeepAliveRequest"; + outMsg.status = "success"; + try { + + var conn = $.db.getConnection(); + var pstmt; + var query = "SELECT 'ok' as \"Alive\" FROM DUMMY"; + pstmt = conn.prepareStatement(query); + var rs = pstmt.executeQuery(); + if (rs.next()) { + outMsg.status = 'success'; + outStatus = 'success'; + } + rs.close(); + pstmt.close(); + conn.close(); + outMessages.push(outMsg); + } catch (ex) { + exceptionHandler(ex); + } +} + +// main +if (checkAuthorization()) { + dbRequest(); +} +setOutputMessage(); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/backend/setProviderData.xsjs b/uniorg/eon/emobility/provider/backend/setProviderData.xsjs new file mode 100644 index 0000000..424cd25 --- /dev/null +++ b/uniorg/eon/emobility/provider/backend/setProviderData.xsjs @@ -0,0 +1,263 @@ +var datetimeLib = $.import("uniorg.libs", "datetime"); +//var logginglib = $.import("uniorg.libs", "uologging"); +//var billingEngine = $.import("uniorg.eon.emobility.billing.engine.v1", "BillingEngine"); +var destLib = $.import("uniorg.destinations", "uodestlib"); +var slLib = $.import("uniorg.ServiceLayer", "B1SLLogic"); + +var serviceName = "eon.emobility.provider.backend.setProviderData.xsjs"; +var serviceVersion = '1.0'; + +var output = {}; +var outMessages = []; +var outMsg = {}; +var outStatus = "success"; +var myDebug = {}; + +var companyid = 0; +var UserName = ''; +var UserPass = ''; +var UserComp = ''; + +var SESSIONID = ""; +var NODEID = ""; +var slLoggedIn = false; +var schemaName = "A19753_EON_P01"; + +var debugLevel = 0; +switch ($.request.parameters.get("debug")) { + case "true": + case "yes": + case "1": + debugLevel = 1; + break; + case "full": + case "2": + debugLevel = 2; + break; +} + +if (debugLevel > 0) { + output.requestParams = $.request.parameters; +} + +function setOutputMessage() { + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + $.response.contentType = "application/json"; + $.response.setBody(JSON.stringify(output)); + //$.response.status = $.net.http.OK; +} + +function exceptionHandler(ex) { + if (outMsg.method && outMessages.indexOf(outMsg) === -1) { + outMsg.status = "canceled"; + outMessages.push(outMsg); + } + outMsg = {}; + outMsg.method = "exceptionHandler"; + outMsg.status = "error"; + outMsg.message = ex.toString(); + if (debugLevel > 0) { + outMsg.exceptionInfo = {}; + outMsg.exceptionInfo.name = ex.name; + outMsg.exceptionInfo.message = ex.message; + outMsg.exceptionInfo.fileName = ex.fileName; + outMsg.exceptionInfo.lineNumber = ex.lineNumber; + outMsg.exceptionInfo.columnNumber = ex.columnNumber; + outMsg.exceptionInfo.stack = ex.stack; + //outMsg.exceptionInfo.source = ex.toSource(); + } + outMessages.push(outMsg); + outStatus = "error"; + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + + var errbody = JSON.stringify(output); + $.response.contentType = 'application/json'; + $.response.setBody(errbody); + $.response.status = $.net.http.INTERNAL_SERVER_ERROR; + try { + if (slLoggedIn) { + slLib.SLLogout(SESSIONID, NODEID); + } + } catch (e) { + + } +} + +function checkAuthorization() { + var isAuthorized = true; + try { + $.session.assertAppPrivilege("uniorg.eon.emobility.provider::MaintainProviderData"); + } catch (ex) { + isAuthorized = false; + outMsg = {}; + outMsg.method = "checkAuthorization"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "Privilege '" + ex.privilege + "' is missing"; + outMessages.push(outMsg); + $.response.status = $.net.http.FORBIDDEN; + } + return isAuthorized; +} + +function checkPayload(inObj) { + var isValid = true; + try { + var provider = JSON.parse(inObj); + if (!provider.hasOwnProperty('Code') || !provider.hasOwnProperty('Name') || !provider.hasOwnProperty('U_ACTIVE') || + !provider.hasOwnProperty('U_ACTIVE_FROM') || !provider.hasOwnProperty('U_ACTIVE_TO')) { + isValid = false; + } + } catch (e) { + exceptionHandler(e); + isValid = false; + } + if (!isValid) { + outMsg = {}; + outMsg.method = "checkPayload"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "invalid payload content"; + outMessages.push(outMsg); + $.response.status = $.net.http.BAD_REQUEST; + } + return isValid; +} + +function setConnectionParams() { + var idValue = schemaName; + var idFieldname = 'SYS_NAME'; + var CompanyConfig = destLib.getCompanyCfg(idValue, idFieldname); + UserComp = CompanyConfig.COMPANYNAME; + UserName = CompanyConfig.USERNAME; + UserPass = destLib.readSecureStore(CompanyConfig.ID); + if (debugLevel > 1) { + myDebug.connectionParams = CompanyConfig; + } + myDebug.idValue = idValue; + myDebug.idFieldname = idFieldname; + if (CompanyConfig.COMPANYNAME === undefined) { + outMsg = {}; + outMsg.method = "getCompany"; + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "System " + idValue + " is invalid for this endpoint"; + outMessages.push(outMsg); + } + + myDebug.CompanyName = UserComp; +} + +function slLogin() { + var loginResult = false; + var loginInfo = {}; + loginInfo.UserName = UserName; + loginInfo.Password = UserPass; + loginInfo.CompanyDB = UserComp; + + // SL LOGIN + var response = slLib.SLLogin(JSON.stringify(loginInfo), null, null); + + // B1SESSION and ROUTEID cookies returned by Login + for (var j in response.cookies) { + if (response.cookies[j].name == "B1SESSION") { + SESSIONID = response.cookies[j].value; + //output.SessionID = SESSIONID; + } else if (response.cookies[j].name == "ROUTEID") { + NODEID = response.cookies[j].value; + //output.NodeID = NODEID; + } + } + + var loginResponse; + try { + loginResponse = JSON.parse(response.body.asString()); + } catch (e) { + loginResponse = response.body.asString(); + } + + if (debugLevel > 1) { + myDebug.loginInfo = loginInfo; + } + myDebug.loginResponse = loginResponse; + if (response.status === 200) { + loginResult = true; + } else { + outMsg = {}; + outMsg.method = "login"; + outMsg.status = "error"; + var slError = myDebug.loginResponse.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(myDebug.loginResponse); + } + outMsg.response = myDebug.loginResponse; + //outMsg.message = loginResponse; + outMessages.push(outMsg); + outStatus = "error"; + } + return loginResult; +} + +function updateUDO(provider) { + outMsg = {}; + outMsg.method = "updateUDO"; + outMsg.status = "error"; + try { + var slProviderObj = { + Name: provider.Name, + U_ACTIVE: provider.U_ACTIVE, + U_ACTIVE_FROM: datetimeLib.convertToISODate(provider.U_ACTIVE_FROM), + U_ACTIVE_TO: datetimeLib.convertToISODate(provider.U_ACTIVE_TO) + }; + myDebug.slProviderObj = slProviderObj; + var responseProvider = slLib.patchDynamicEntity('EON_PROVIDER', provider.Code, JSON.stringify(slProviderObj), SESSIONID, NODEID, false); + if (responseProvider.status >= 200 && responseProvider.status < 300) { + outMsg.status = "success"; + } else { + if (responseProvider.body) { + var responseBodyParsed = JSON.parse(responseProvider.body.asString()); + var slError = responseBodyParsed.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = responseProvider.body.asString(); + } + outMsg.response = responseBodyParsed; + } else { + outMsg.message = JSON.stringify(responseProvider); + } + outStatus = "error"; + } + outMessages.push(outMsg); + } catch (ex) { + exceptionHandler(ex); + } +} + +// main +var content = ""; +if ($.request.body) { + content = $.request.body.asString(); +} +if (checkPayload(content) && checkAuthorization()) { + setConnectionParams(); + slLoggedIn = slLogin(); + if (slLoggedIn) { + var inObj = JSON.parse(content); + updateUDO(inObj); + slLib.SLLogout(SESSIONID, NODEID); + } +} + +$.trace.debug("DEBUG: " + JSON.stringify(myDebug)); +setOutputMessage(); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/backend/setProviderLinesData.xsjs b/uniorg/eon/emobility/provider/backend/setProviderLinesData.xsjs new file mode 100644 index 0000000..2dfa6e4 --- /dev/null +++ b/uniorg/eon/emobility/provider/backend/setProviderLinesData.xsjs @@ -0,0 +1,493 @@ +var datetimeLib = $.import("uniorg.libs", "datetime"); +//var logginglib = $.import("uniorg.libs", "uologging"); +//var billingEngine = $.import("uniorg.eon.emobility.billing.engine.v1", "BillingEngine"); +var destLib = $.import("uniorg.destinations", "uodestlib"); +var slLib = $.import("uniorg.ServiceLayer", "B1SLLogic"); + +var serviceName = "eon.emobility.provider.backend.setProviderLinesData.xsjs"; +var serviceVersion = '1.2'; + +var output = {}; +var outMessages = []; +var outMsg = {}; +var outStatus = "success"; +var myDebug = {}; + +var companyid = 0; +var UserName = ''; +var UserPass = ''; +var UserComp = ''; + +var SESSIONID = ""; +var NODEID = ""; +var slLoggedIn = false; +var schemaName = "A19753_EON_P01"; + +var debugLevel = 0; +switch ($.request.parameters.get("debug")) { + case "true": + case "yes": + case "1": + debugLevel = 1; + break; + case "full": + case "2": + debugLevel = 2; + break; +} + +if (debugLevel > 0) { + output.requestParams = $.request.parameters; +} + +function setOutputMessage() { + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + $.response.contentType = "application/json"; + $.response.setBody(JSON.stringify(output)); + //$.response.status = $.net.http.OK; +} + +function exceptionHandler(ex) { + if (outMsg.method && outMessages.indexOf(outMsg) === -1) { + outMsg.status = "canceled"; + outMessages.push(outMsg); + } + outMsg = {}; + outMsg.method = "exceptionHandler"; + outMsg.status = "error"; + outMsg.message = ex.toString(); + if (debugLevel > 0) { + outMsg.exceptionInfo = {}; + outMsg.exceptionInfo.name = ex.name; + outMsg.exceptionInfo.message = ex.message; + outMsg.exceptionInfo.fileName = ex.fileName; + outMsg.exceptionInfo.lineNumber = ex.lineNumber; + outMsg.exceptionInfo.columnNumber = ex.columnNumber; + outMsg.exceptionInfo.stack = ex.stack; + //outMsg.exceptionInfo.source = ex.toSource(); + } + outMessages.push(outMsg); + outStatus = "error"; + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + + var errbody = JSON.stringify(output); + $.response.contentType = 'application/json'; + $.response.setBody(errbody); + $.response.status = $.net.http.INTERNAL_SERVER_ERROR; + try { + if (slLoggedIn) { + slLib.SLLogout(SESSIONID, NODEID); + } + } catch (e) { + + } +} + +function checkAuthorization() { + var isAuthorized = true; + try { + $.session.assertAppPrivilege("uniorg.eon.emobility.provider::MaintainProviderData"); + } catch (ex) { + isAuthorized = false; + outMsg = {}; + outMsg.method = "checkAuthorization"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "Privilege '" + ex.privilege + "' is missing"; + outMessages.push(outMsg); + $.response.status = $.net.http.FORBIDDEN; + } + return isAuthorized; +} + +function checkPayload(inObj) { + var isValid = true; + var errorList = []; + try { + var provider = JSON.parse(inObj); + if (!provider.hasOwnProperty('Code')) { + isValid = false; + } + if (Array.isArray(provider.Lines)) { + provider.Lines.forEach(function(l) { + if (!l.hasOwnProperty('U_CODE') || !l.hasOwnProperty('U_FROM') || !l.hasOwnProperty('U_TO') || + !l.hasOwnProperty('U_TYP') || !l.hasOwnProperty('U_OPERATOR') || !l.hasOwnProperty('U_SUBOPERATOR') || !l.hasOwnProperty('U_RELEASED')) { + isValid = false; + } else { + var errorDetails = { + U_CODE: l.U_CODE, + U_FROM: l.U_FROM, + U_TO: l.U_TO, + U_TYP: l.U_TYP, + U_OPERATOR: l.U_OPERATOR, + U_SUBOPERATOR: l.U_SUBOPERATOR, + U_RELEASED: l.U_RELEASED, + Status: 'error' + }; + /*if (debugLevel > 0) { + errorDetails.Price = npl.Price; + errorDetails.Currency = npl.Currency; + } + if (typeof npl.MaterialNo !== 'string' || !npl.MaterialNo) { + errorDetails.StatusText = "MaterialNo is not valid"; + } else { + if (!npl.MaterialNo.length > 0) { + errorDetails.StatusText = "MaterialNo is empty"; + } + if (npl.MaterialNo.length > 18) { + errorDetails.StatusText = "MaterialNo too long"; + } + } + if (typeof npl.PriceList !== 'string' || !npl.PriceList) { + errorDetails.StatusText = "PriceList is not valid"; + } else { + if (!npl.PriceList.length > 0) { + errorDetails.StatusText = "PriceList is empty"; + } + if (npl.PriceList.length > 32) { + errorDetails.StatusText = "PriceList too long"; + } + } + try { + var parsedDate = npl.DateFrom.startsWith('/Date(') ? new Date(parseInt(npl.DateFrom.substr(6))) : new Date(npl.DateFrom); + if (debugLevel > 0) { + errorDetails.ParsedDate = parsedDate; + } + if (!parsedDate instanceof Date || isNaN(parsedDate.valueOf())) { + errorDetails.StatusText = "DateFrom is not a valid date"; + } else if (!(parsedDate.getTime() >= new Date('2000-01-01').getTime() && parsedDate.getTime() <= new Date('9999-12-31').getTime())) { + errorDetails.StatusText = "DateFrom is outside of valid range"; + } + } catch (e) { + errorDetails.StatusText = "DateFrom is not a valid date"; + } + if (typeof npl.Price !== 'number' || isNaN(npl.Price)) { + errorDetails.StatusText = "Price is not valid"; + } else { + var priceParts = npl.Price.toString().split('.'); + var priceExp = npl.Price.toString().split('e'); + if (debugLevel > 0) { + errorDetails.PriceDecimalParts = priceParts; + } + if (npl.Price < 0) { + errorDetails.StatusText = "Price must be a positive value"; + } else if (priceExp.length > 1 && !isNaN(priceExp[1]) && parseInt(priceExp[1]) + priceParts[0].length > 17) { + errorDetails.StatusText = "Price decimal precision too high"; + } else if ((priceParts.length > 1 && priceParts[0].length + priceParts[1].length > 17) || priceParts[0].length > 17) { + errorDetails.StatusText = "Price decimal precision too high"; + } else if (priceParts.length > 1 && priceParts[1].length > 6) { + errorDetails.StatusText = "Price decimal scale too high"; + } + } + if (typeof npl.Currency !== 'string' || !npl.Currency) { + errorDetails.StatusText = "Currency is not valid"; + } else { + if (!npl.Currency.length > 0) { + errorDetails.StatusText = "Currency is empty"; + } + if (npl.Currency.length > 3) { + errorDetails.StatusText = "Currency too long"; + } + }*/ + if (errorDetails.StatusText) { + errorList.push(errorDetails); + isValid = false; + } else if (debugLevel > 0) { + errorDetails.Status = "success"; + errorList.push(errorDetails); + } + } + }); + } else { + isValid = false; + } + } catch (e) { + exceptionHandler(e); + isValid = false; + } + if (!isValid) { + outMsg = {}; + outMsg.method = "checkPayload"; + outMsg.status = "error"; + outStatus = "error"; + if (errorList.length > 0) { + outMsg.message = "invalid payload content"; + output.results = errorList; + } else { + outMsg.message = "invalid payload structure"; + } + outMessages.push(outMsg); + $.response.status = $.net.http.BAD_REQUEST; + } + return isValid; +} + +function setConnectionParams() { + var idValue = schemaName; + var idFieldname = 'SYS_NAME'; + var CompanyConfig = destLib.getCompanyCfg(idValue, idFieldname); + UserComp = CompanyConfig.COMPANYNAME; + UserName = CompanyConfig.USERNAME; + UserPass = destLib.readSecureStore(CompanyConfig.ID); + if (debugLevel > 1) { + myDebug.connectionParams = CompanyConfig; + } + myDebug.idValue = idValue; + myDebug.idFieldname = idFieldname; + if (CompanyConfig.COMPANYNAME === undefined) { + outMsg = {}; + outMsg.method = "getCompany"; + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "System " + idValue + " is invalid for this endpoint"; + outMessages.push(outMsg); + } + + myDebug.CompanyName = UserComp; +} + +function slLogin() { + var loginResult = false; + var loginInfo = {}; + loginInfo.UserName = UserName; + loginInfo.Password = UserPass; + loginInfo.CompanyDB = UserComp; + + // SL LOGIN + var response = slLib.SLLogin(JSON.stringify(loginInfo), null, null); + + // B1SESSION and ROUTEID cookies returned by Login + for (var j in response.cookies) { + if (response.cookies[j].name == "B1SESSION") { + SESSIONID = response.cookies[j].value; + //output.SessionID = SESSIONID; + } else if (response.cookies[j].name == "ROUTEID") { + NODEID = response.cookies[j].value; + //output.NodeID = NODEID; + } + } + + var loginResponse; + try { + loginResponse = JSON.parse(response.body.asString()); + } catch (e) { + loginResponse = response.body.asString(); + } + + if (debugLevel > 1) { + myDebug.loginInfo = loginInfo; + } + myDebug.loginResponse = loginResponse; + if (response.status === 200) { + loginResult = true; + } else { + outMsg = {}; + outMsg.method = "login"; + outMsg.status = "error"; + var slError = myDebug.loginResponse.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(myDebug.loginResponse); + } + outMsg.response = myDebug.loginResponse; + //outMsg.message = loginResponse; + outMessages.push(outMsg); + outStatus = "error"; + } + return loginResult; +} + +function updateUDO(provider, oldUDO) { + outMsg = {}; + outMsg.method = "updateUDO"; + outMsg.status = "error"; + try { + var slProviderObj = { + U_ACTIVE: provider.U_ACTIVE, + U_ACTIVE_FROM: datetimeLib.convertToISODate(provider.U_ACTIVE_FROM), + U_ACTIVE_TO: datetimeLib.convertToISODate(provider.U_ACTIVE_TO), + EON_PROVIDER_LINESCollection: oldUDO.EON_PROVIDER_LINESCollection.map(function(ol) { + var line = { + Code: ol.Code, + LineId: ol.LineId, + Object: ol.Object + }; + var changedLine = false; + var nl = provider.Lines.find(function(l) { + return l.Code === ol.Code && l.LineId === ol.LineId; + }); + if (typeof nl !== "undefined") { + if (nl.U_RELEASED !== ol.U_RELEASED) { + //changedLine = true; + line.U_RELEASED = nl.U_RELEASED; + if (nl.U_RELEASED === 'Y') { + line.U_RELEASE_DATE = datetimeLib.convertToISODate(new Date()); + line.U_RELEASE_USER = $.session.getUsername(); + } + } + if (datetimeLib.convertToISODate(nl.U_TO) !== ol.U_TO) { + changedLine = true; + line.U_TO = datetimeLib.convertToISODate(nl.U_TO); + } + if (nl.U_SUBOPERATOR !== ol.U_SUBOPERATOR) { + changedLine = true; + line.U_SUBOPERATOR = nl.U_SUBOPERATOR; + } + if (nl.U_VALUE !== ol.U_VALUE) { + changedLine = true; + line.U_VALUE = nl.U_VALUE; + } + if (nl.U_CURRENCY !== ol.U_CURRENCY) { + changedLine = true; + line.U_CURRENCY = nl.U_CURRENCY; + } + if (ol.U_CODE === 'MINUTES_BLOCK') { + if (nl.U_BLOCK_FROM !== ol.U_BLOCK_FROM.substring(0,5)) { + changedLine = true; + line.U_BLOCK_FROM = nl.U_BLOCK_FROM; + } + if (nl.U_BLOCK_TO !== ol.U_BLOCK_TO.substring(0,5)) { + changedLine = true; + line.U_BLOCK_TO = nl.U_BLOCK_TO; + } + if (nl.U_BLOCKMAX !== ol.U_BLOCKMAX) { + changedLine = true; + line.U_BLOCKMAX = nl.U_BLOCKMAX; + } + } + if (changedLine) { + line.U_CHANGE_DATE = datetimeLib.convertToISODate(new Date()); + line.U_CHANGE_USER = $.session.getUsername(); + } + } + return line; + /*{ + Code: l.Code, + LineId: l.LineId, + U_CODE: l.U_CODE, + U_FROM: datetimeLib.convertToISODate(l.U_FROM), + U_TO: datetimeLib.convertToISODate(l.U_TO), + U_OPERATOR: l.U_OPERATOR, + U_TYP: l.U_TYP, + U_VALUE: l.U_VALUE, + U_BLOCK_FROM: l.U_BLOCK_FROM, + U_BLOCK_TO: l.U_BLOCK_TO, + U_BLOCKMAX: l.U_BLOCKMAX, + U_RELEASED: l.U_RELEASED, + U_RELEASE_DATE: l.U_RELEASED === 'Y' ? datetimeLib.convertToISODate(new Date()) : l.U_RELEASE_DATE, + U_RELEASE_USER: l.U_RELEASED === 'Y' ? $.session.getUsername() : l.U_RELEASED, + U_CHANGE_DATE: datetimeLib.convertToISODate(new Date()) + };*/ + }).concat(provider.Lines.filter(function(l) { + return l.new === true; + }).map(function(nl) {return { + U_CODE: nl.U_CODE, + U_FROM: datetimeLib.convertToISODate(nl.U_FROM), + U_TO: datetimeLib.convertToISODate(nl.U_TO), + U_OPERATOR: nl.U_OPERATOR, + U_SUBOPERATOR: nl.U_SUBOPERATOR, + U_TYP: nl.U_TYP, + U_CURRENCY: nl.U_CURRENCY, + U_VALUE: nl.U_VALUE, + U_BLOCK_FROM: nl.U_BLOCK_FROM, + U_BLOCK_TO: nl.U_BLOCK_TO, + U_BLOCKMAX: nl.U_BLOCKMAX, + U_RELEASED: nl.U_RELEASED, + U_RELEASE_DATE: nl.U_RELEASED === 'Y' ? datetimeLib.convertToISODate(new Date()) : nl.U_RELEASE_DATE, + U_RELEASE_USER: nl.U_RELEASED === 'Y' ? $.session.getUsername() : nl.U_RELEASE_USER, + U_CHANGE_DATE: datetimeLib.convertToISODate(new Date()), + U_CHANGE_USER: $.session.getUsername() + };})) + }; + myDebug.slProviderObj = slProviderObj; + var responseProvider = slLib.patchDynamicEntity('EON_PROVIDER', provider.Code, JSON.stringify(slProviderObj), SESSIONID, NODEID, true); + if (responseProvider.status >= 200 && responseProvider.status < 300) { + outMsg.status = "success"; + } else { + if (responseProvider.body) { + var responseBodyParsed = JSON.parse(responseProvider.body.asString()); + var slError = responseBodyParsed.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = responseProvider.body.asString(); + } + outMsg.response = responseBodyParsed; + } else { + outMsg.message = JSON.stringify(responseProvider); + } + outStatus = "error"; + } + outMessages.push(outMsg); + } catch (ex) { + exceptionHandler(ex); + } +} + +function getUDO(Code) { + outMsg = {}; + outMsg.method = "getUDO"; + outMsg.code = Code; + outMsg.status = "error"; + var result = {}; + try { + var responseGet = slLib.getDynamicEntity('EON_PROVIDER', Code, SESSIONID, NODEID); + outMsg.statuscode = responseGet.status; + if (responseGet.status >= 200 && responseGet.status < 300) { + var bodyGet = JSON.parse(responseGet.body.asString()); + outMsg.status = "success"; + result = bodyGet; + outMsg.response = bodyGet; + } else { + if (responseGet.body) { + var responseBodyParsed = JSON.parse(responseGet.body.asString()); + var slError = responseBodyParsed.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = responseGet.body.asString(); + } + outMsg.response = responseBodyParsed; + } else { + outMsg.message = JSON.stringify(responseGet); + } + outStatus = "error"; + } + if (debugLevel > 0 || outMsg.status !== "success") { + outMessages.push(outMsg); + } + } catch (ex) { + exceptionHandler(ex); + } + return result; +} + +// main +var content = ""; +if ($.request.body) { + content = $.request.body.asString(); +} +if (checkPayload(content) && checkAuthorization()) { + setConnectionParams(); + slLoggedIn = slLogin(); + if (slLoggedIn) { + var inObj = JSON.parse(content); + var oldUDO = getUDO(inObj.Code); + if (outStatus !== "error" && oldUDO.Code) { + updateUDO(inObj, oldUDO); + } + slLib.SLLogout(SESSIONID, NODEID); + } +} + +$.trace.debug("DEBUG: " + JSON.stringify(myDebug)); +setOutputMessage(); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/backend/setSubOperatorData.xsjs b/uniorg/eon/emobility/provider/backend/setSubOperatorData.xsjs new file mode 100644 index 0000000..ec8cbce --- /dev/null +++ b/uniorg/eon/emobility/provider/backend/setSubOperatorData.xsjs @@ -0,0 +1,333 @@ +var datetimeLib = $.import("uniorg.libs", "datetime"); +//var logginglib = $.import("uniorg.libs", "uologging"); +//var billingEngine = $.import("uniorg.eon.emobility.billing.engine.v1", "BillingEngine"); +var destLib = $.import("uniorg.destinations", "uodestlib"); +var slLib = $.import("uniorg.ServiceLayer", "B1SLLogic"); + +var serviceName = "eon.emobility.provider.backend.setSubOperatorData.xsjs"; +var serviceVersion = '1.0'; + +var output = {}; +var outMessages = []; +var outMsg = {}; +var outStatus = "success"; +var myDebug = {}; + +var companyid = 0; +var UserName = ''; +var UserPass = ''; +var UserComp = ''; + +var SESSIONID = ""; +var NODEID = ""; +var slLoggedIn = false; +var schemaName = "A19753_EON_P01"; + +var debugLevel = 0; +switch ($.request.parameters.get("debug")) { + case "true": + case "yes": + case "1": + debugLevel = 1; + break; + case "full": + case "2": + debugLevel = 2; + break; +} + +if (debugLevel > 0) { + output.requestParams = $.request.parameters; +} + +function setOutputMessage() { + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + $.response.contentType = "application/json"; + $.response.setBody(JSON.stringify(output)); + //$.response.status = $.net.http.OK; +} + +function exceptionHandler(ex) { + if (outMsg.method && outMessages.indexOf(outMsg) === -1) { + outMsg.status = "canceled"; + outMessages.push(outMsg); + } + outMsg = {}; + outMsg.method = "exceptionHandler"; + outMsg.status = "error"; + outMsg.message = ex.toString(); + if (debugLevel > 0) { + outMsg.exceptionInfo = {}; + outMsg.exceptionInfo.name = ex.name; + outMsg.exceptionInfo.message = ex.message; + outMsg.exceptionInfo.fileName = ex.fileName; + outMsg.exceptionInfo.lineNumber = ex.lineNumber; + outMsg.exceptionInfo.columnNumber = ex.columnNumber; + outMsg.exceptionInfo.stack = ex.stack; + //outMsg.exceptionInfo.source = ex.toSource(); + } + outMessages.push(outMsg); + outStatus = "error"; + output.status = outStatus; + if (debugLevel > 0) { + output.debugInfos = myDebug; + } + output.messages = outMessages; + + var errbody = JSON.stringify(output); + $.response.contentType = 'application/json'; + $.response.setBody(errbody); + $.response.status = $.net.http.INTERNAL_SERVER_ERROR; + try { + if (slLoggedIn) { + slLib.SLLogout(SESSIONID, NODEID); + } + } catch (e) { + + } +} + +function checkAuthorization() { + var isAuthorized = true; + try { + $.session.assertAppPrivilege("uniorg.eon.emobility.provider::MaintainProviderData"); + } catch (ex) { + isAuthorized = false; + outMsg = {}; + outMsg.method = "checkAuthorization"; + outMsg.status = "error"; + outStatus = "error"; + outMsg.message = "Privilege '" + ex.privilege + "' is missing"; + outMessages.push(outMsg); + $.response.status = $.net.http.FORBIDDEN; + } + return isAuthorized; +} + +function checkPayload(inObj) { + var isValid = true; + var errorList = []; + try { + var subOperator = JSON.parse(inObj); + if (!subOperator.hasOwnProperty('Code')) { + isValid = false; + } + if (Array.isArray(subOperator.Organizations)) { + subOperator.Organizations.forEach(function(org) { + if (!org.hasOwnProperty('U_ORG_ID')) { + isValid = false; + } else { + var errorDetails = { + U_ORG_ID: org.U_ORG_ID, + Status: 'error' + }; + if (errorDetails.StatusText) { + errorList.push(errorDetails); + isValid = false; + } else if (debugLevel > 0) { + errorDetails.Status = "success"; + errorList.push(errorDetails); + } + } + }); + } else { + isValid = false; + } + } catch (e) { + exceptionHandler(e); + isValid = false; + } + if (!isValid) { + outMsg = {}; + outMsg.method = "checkPayload"; + outMsg.status = "error"; + outStatus = "error"; + if (errorList.length > 0) { + outMsg.message = "invalid payload content"; + output.results = errorList; + } else { + outMsg.message = "invalid payload structure"; + } + outMessages.push(outMsg); + $.response.status = $.net.http.BAD_REQUEST; + } + return isValid; +} + +function setConnectionParams() { + var idValue = schemaName; + var idFieldname = 'SYS_NAME'; + var CompanyConfig = destLib.getCompanyCfg(idValue, idFieldname); + UserComp = CompanyConfig.COMPANYNAME; + UserName = CompanyConfig.USERNAME; + UserPass = destLib.readSecureStore(CompanyConfig.ID); + if (debugLevel > 1) { + myDebug.connectionParams = CompanyConfig; + } + myDebug.idValue = idValue; + myDebug.idFieldname = idFieldname; + if (CompanyConfig.COMPANYNAME === undefined) { + outMsg = {}; + outMsg.method = "getCompany"; + outStatus = "error"; + outMsg.status = "error"; + outMsg.message = "System " + idValue + " is invalid for this endpoint"; + outMessages.push(outMsg); + } + + myDebug.CompanyName = UserComp; +} + +function slLogin() { + var loginResult = false; + var loginInfo = {}; + loginInfo.UserName = UserName; + loginInfo.Password = UserPass; + loginInfo.CompanyDB = UserComp; + + // SL LOGIN + var response = slLib.SLLogin(JSON.stringify(loginInfo), null, null); + + // B1SESSION and ROUTEID cookies returned by Login + for (var j in response.cookies) { + if (response.cookies[j].name == "B1SESSION") { + SESSIONID = response.cookies[j].value; + //output.SessionID = SESSIONID; + } else if (response.cookies[j].name == "ROUTEID") { + NODEID = response.cookies[j].value; + //output.NodeID = NODEID; + } + } + + var loginResponse; + try { + loginResponse = JSON.parse(response.body.asString()); + } catch (e) { + loginResponse = response.body.asString(); + } + + if (debugLevel > 1) { + myDebug.loginInfo = loginInfo; + } + myDebug.loginResponse = loginResponse; + if (response.status === 200) { + loginResult = true; + } else { + outMsg = {}; + outMsg.method = "login"; + outMsg.status = "error"; + var slError = myDebug.loginResponse.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = JSON.stringify(myDebug.loginResponse); + } + outMsg.response = myDebug.loginResponse; + //outMsg.message = loginResponse; + outMessages.push(outMsg); + outStatus = "error"; + } + return loginResult; +} + +function updateUDO(subOperator) { + outMsg = {}; + outMsg.method = "updateUDO"; + outMsg.status = "error"; + try { + var slSubOperatorObj = { + Code: subOperator.Code, + Name: subOperator.Name, + EON_SUBOPERATOR_LCollection: subOperator.Organizations.map(function(org) {return { + Code: subOperator.Code, + LineId: org.LineId, + Object: 'EON_SUBOPERATOR', + U_ORG_ID: org.U_ORG_ID + };}) + }; + myDebug.slSubOperatorObj = slSubOperatorObj; + var responseSubOperator = subOperator.newEntry ? slLib.postDynamicEntity('EON_SUBOPERATOR', JSON.stringify(slSubOperatorObj), SESSIONID, NODEID) : slLib.patchDynamicEntity('EON_SUBOPERATOR', subOperator.Code, JSON.stringify(slSubOperatorObj), SESSIONID, NODEID, true); + if (responseSubOperator.status >= 200 && responseSubOperator.status < 300) { + outMsg.status = "success"; + } else { + if (responseSubOperator.body) { + var responseBodyParsed = JSON.parse(responseSubOperator.body.asString()); + var slError = responseBodyParsed.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = responseSubOperator.body.asString(); + } + outMsg.response = responseBodyParsed; + } else { + outMsg.message = JSON.stringify(responseSubOperator); + } + outStatus = "error"; + } + outMessages.push(outMsg); + } catch (ex) { + exceptionHandler(ex); + } +} + +function getUDO(Code) { + outMsg = {}; + outMsg.method = "getUDO"; + outMsg.code = Code; + outMsg.status = "error"; + var result = {}; + try { + var responseGet = slLib.getDynamicEntity('EON_SUBOPERATOR', Code, SESSIONID, NODEID); + outMsg.statuscode = responseGet.status; + if (responseGet.status >= 200 && responseGet.status < 300) { + var bodyGet = JSON.parse(responseGet.body.asString()); + outMsg.status = "success"; + result = bodyGet; + outMsg.response = bodyGet; + } else { + if (responseGet.body) { + var responseBodyParsed = JSON.parse(responseGet.body.asString()); + var slError = responseBodyParsed.error; + if (slError && slError.hasOwnProperty("code") && slError.message && slError.message.value) { + outMsg.message = slError.message.value + " (Code: " + slError.code.toString() + ")"; + } else { + outMsg.message = responseGet.body.asString(); + } + outMsg.response = responseBodyParsed; + } else { + outMsg.message = JSON.stringify(responseGet); + } + outStatus = "error"; + } + if (debugLevel > 0 || outMsg.status !== "success") { + outMessages.push(outMsg); + } + } catch (ex) { + exceptionHandler(ex); + } + return result; +} + +// main +var content = ""; +if ($.request.body) { + content = $.request.body.asString(); +} +if (checkPayload(content) && checkAuthorization()) { + setConnectionParams(); + slLoggedIn = slLogin(); + if (slLoggedIn) { + var inObj = JSON.parse(content); + if (outStatus !== "error") { + updateUDO(inObj); + } + slLib.SLLogout(SESSIONID, NODEID); + } +} + +$.trace.debug("DEBUG: " + JSON.stringify(myDebug)); +setOutputMessage(); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/.xsaccess b/uniorg/eon/emobility/provider/ui/pricematrix/.xsaccess index e939545..4128656 100644 --- a/uniorg/eon/emobility/provider/ui/pricematrix/.xsaccess +++ b/uniorg/eon/emobility/provider/ui/pricematrix/.xsaccess @@ -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" } \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/Component.js b/uniorg/eon/emobility/provider/ui/pricematrix/Component.js new file mode 100644 index 0000000..1fd6a01 --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/Component.js @@ -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); + } + } + }); + } + }); + +}); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/controller/App.controller.js b/uniorg/eon/emobility/provider/ui/pricematrix/controller/App.controller.js new file mode 100644 index 0000000..32dc75e --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/controller/App.controller.js @@ -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", { + }); + +}); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/controller/BaseController.js b/uniorg/eon/emobility/provider/ui/pricematrix/controller/BaseController.js new file mode 100644 index 0000000..20b6386 --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/controller/BaseController.js @@ -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*/ ); + } + } + }); +}); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/controller/NotFound.controller.js b/uniorg/eon/emobility/provider/ui/pricematrix/controller/NotFound.controller.js new file mode 100644 index 0000000..3d78977 --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/controller/NotFound.controller.js @@ -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); + } + + }); + +}); diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/controller/Overview.controller.js b/uniorg/eon/emobility/provider/ui/pricematrix/controller/Overview.controller.js new file mode 100644 index 0000000..f90906c --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/controller/Overview.controller.js @@ -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); + } + } + }); + +}); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/controller/Provider.controller.js b/uniorg/eon/emobility/provider/ui/pricematrix/controller/Provider.controller.js new file mode 100644 index 0000000..2888e51 --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/controller/Provider.controller.js @@ -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); + } + } + + }); + +}); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/controller/ProviderNextPeriod.controller.js b/uniorg/eon/emobility/provider/ui/pricematrix/controller/ProviderNextPeriod.controller.js new file mode 100644 index 0000000..a22b19b --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/controller/ProviderNextPeriod.controller.js @@ -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); + } + }); + +}); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/controller/SubOperator.controller.js b/uniorg/eon/emobility/provider/ui/pricematrix/controller/SubOperator.controller.js new file mode 100644 index 0000000..1a9a0b2 --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/controller/SubOperator.controller.js @@ -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 + }); + }); + } + } + + }); + + }); \ No newline at end of file diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/css/style.css b/uniorg/eon/emobility/provider/ui/pricematrix/css/style.css new file mode 100644 index 0000000..9cc474b --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/css/style.css @@ -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; +} diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/i18n/i18n.properties b/uniorg/eon/emobility/provider/ui/pricematrix/i18n/i18n.properties new file mode 100644 index 0000000..9c88a0b --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/i18n/i18n.properties @@ -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. diff --git a/uniorg/eon/emobility/provider/ui/pricematrix/index.html b/uniorg/eon/emobility/provider/ui/pricematrix/index.html new file mode 100644 index 0000000..ec1b190 --- /dev/null +++ b/uniorg/eon/emobility/provider/ui/pricematrix/index.html @@ -0,0 +1,25 @@ + + +
+ + +