import { JsonPipe } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { ResourceFields } from '@syncfusion/ej2-angular-gantt'; import { LanguageService } from './language.service'; import { ErrorService } from './error.service'; import { Location } from '@angular/common'; interface Preset { id: string; name: string; presetType: string; definition: any; } interface presetGroup { disabled?: boolean; name: string; presets: Preset[]; } @Injectable({ providedIn: 'root' }) /** * The DataService manages the communication between Frontend and Backend, fetches Data from the Backend and maps it to the Frontend Data Structure. Additionally it updates data on the Backend. * */ export class DataService { private states: any []; //Array of statuses and possible statuses, which is queried once at the beginning by backend and stored in dataservice private supportGroups: any []; private contracts: any []; private paketTypes: any []; private totalSize: number = null; private user: string = null; public userSupportGroup: string; public authUrl = 'https://itsm-dev-neu-rsso.asfinag.at/rsso/start?bypass-auth=true&tenant=itsm-dev-neu&goto=https://itsm-dev-neu.asfinag.at/arsys/calendar'; //public selectedLanguage: string = 'DE'; /** * This constructor builds the dataService and fetches the states from the backend * @param languageService injection of the languageService * @param http representation of the HttpClient */ constructor(public languageService: LanguageService, private http: HttpClient, public errorService: ErrorService, private location: Location) { this.getUser().then((res: any )=>{ this.user = res.userId; }); this.fetchStates().then((res: any [])=>{ this.states = res; }); this.fetchSupportGroups().then((res: any [])=>{ this.supportGroups = res; }); this.fetchContracts().then((res: any [])=>{ this.contracts = res; }); this.fetchPaketTypes().then((res: any [])=>{ this.paketTypes = res; // console.log(res); }); this.fetchUserSupportGroup().then((res: any)=>{ this.userSupportGroup = res.name; console.log(this.userSupportGroup); }); } public redirectToAuthUrl() { window.location.href = this.authUrl; } /** * the function getStates * @returns an array of states and possible states per state */ public getStates():any[]{ return this.states; } /** * the function getSupportGroups * @returns an array of all supportGroups */ public getSupportGroups():any[]{ return this.supportGroups; } /** * the function getContracts * @returns an array of all contracts */ public getContracts():any[]{ return this.contracts; } /** * the function getPaketTypes * @returns an array of all paketTypes */ public getPaketTypes():any[]{ return this.paketTypes; } /** * the function getTotalSize * @returns the size of all changes, that are matched by the actual filters * required for totalSize attribute of the paginator */ public getTotalSize():number{ return this.totalSize; } /** * the function getUserSupportGroup * @returns the supportGroup of the actual user */ public getUserSupportGroup():string{ return this.userSupportGroup; } /** * the function getStateIdByName translates the name of a state into the id * @param stateName name of the state * @returns id of the state */ public getStateIdByName(stateName: string): number { for (let state of this.states) { if(stateName == state.stateNameEN){ return state.id; } } return -1; } /** * the function getContractByName searches a contract by its uid and returns the name * @param contractId uid to search the contract * @returns the name of the corresponding contract */ public getContractName(contractId: string): string{ return this.contracts.find((contract)=> {return contract.id == contractId;}).name; } /** * The function fetchStates fetches an array from the possible statuses per state * @returns promise for the fetched Status Array */ public async getUser(){ const promise = new Promise(resolve=>{ let res : any; this.http.get('http://localhost:8080/api/getUser') .subscribe((response: any)=>{ res = response; resolve(res); },(error=>{ console.log("\n#############################\n"); this.redirectToAuthUrl(); this.errorService.handleRssoError(error); })) }) return promise; } /** * The function initPresets fetches an array of all presets * @returns promise for the fetched presets array */ public async initPresets(){ const promise = new Promise(resolve=>{ let res = {presets: [], selectedPreset: '', userPreferences: {}, presetGroups: []}; this.http.get('http://localhost:8080/api/initPresets') .subscribe((response: any)=>{ console.log(response); if(response.status == 500){ resolve({status: response.status ,message: response.error.message}); }else{ res.selectedPreset = response.selectedPreset; let userPreferences = {language: 'DE', showDetails: true, view: 2}; if(response.userPreferences.language == "EN"){ userPreferences.language = "EN"; } if(response.userPreferences.showDetails == 0){ userPreferences.showDetails = false; } if(response.userPreferences.view == 1){ userPreferences.view = 0; } if(response.userPreferences.view == 2){ userPreferences.view = 1; } if(response.userPreferences.view == 3){ userPreferences.view = 2; } res.userPreferences = userPreferences; response.presets.forEach(preset => { // console.log(preset); res.presets.push({ id: preset.id, name: preset.name, presetType: preset.presetType, definition: JSON.parse(preset.definition) }); for (const preset of res.presets) { if(preset.id == response.selectedPreset){ res.selectedPreset = preset; } } }); let presetGroups : presetGroup[] = []; let system = []; let user = []; let admin = []; for (const preset of res.presets) { if(preset.presetType == "System"){ system.push(preset); }else{ user.push(preset); } } presetGroups = [ { name: 'System', presets: system, }, { name: 'Admin', presets: admin }, { name: 'User', presets: user, }, ]; res.presetGroups = presetGroups; // console.log(res.presetGroups); if(response.status!=500){ resolve(res); } } }, (error=>{ this.errorService.handleInitError(error); } )) }) return promise; } /** * The function updateDatePerChange sends the new date to the backend if the date was moved * @param change the Change (the Resource) from which the date should be changed */ public async selectPreset(preset: any){ const promise = new Promise(resolve=>{ let serializableResource = {guid: preset.id}; let strigifiedResource = JSON.stringify(serializableResource); let resJson = JSON.parse(strigifiedResource) as typeof strigifiedResource; console.log(resJson); this.http.post('http://localhost:8080/api/selectPreset', resJson).subscribe((response:any)=>{ resolve(response); console.log(response); },(error:any)=>{ resolve(error); }); }); return promise; } /** * The function updateDatePerChange sends the new date to the backend if the date was moved * @param change the Change (the Resource) from which the date should be changed */ public async savePreset(preset: any){ const promise = new Promise(resolve=>{ let serializableResource = {name: preset.name, definition: JSON.stringify(preset.definition)}; let strigifiedResource = JSON.stringify(serializableResource); let resJson = JSON.parse(strigifiedResource) as typeof strigifiedResource; console.log(resJson); this.http.post('http://localhost:8080/api/savePreset', resJson).subscribe((response:any)=>{ resolve(response); console.log(response); },(error:any)=>{ resolve(error); }); }); return promise; } /** * The function updateDatePerChange sends the new date to the backend if the date was moved * @param change the Change (the Resource) from which the date should be changed */ public async updatePreset(preset: any){ console.log(preset); const promise = new Promise(resolve=>{ let serializableResource = {id: preset.id, definition: JSON.stringify(preset.definition)}; let strigifiedResource = JSON.stringify(serializableResource); let resJson = JSON.parse(strigifiedResource) as typeof strigifiedResource; this.http.post('http://localhost:8080/api/updatePreset', resJson).subscribe((response:any)=>{ resolve(response); },(error:any)=>{ resolve(error); }); }); return promise; } /** * The function updateDatePerChange sends the new date to the backend if the date was moved * @param change the Change (the Resource) from which the date should be changed */ public async renamePreset(preset: any){ const promise = new Promise(resolve=>{ let serializableResource = {id: preset.id, newName: preset.name}; let strigifiedResource = JSON.stringify(serializableResource); let resJson = JSON.parse(strigifiedResource) as typeof strigifiedResource; this.http.post('http://localhost:8080/api/renamePreset', resJson).subscribe((response:any)=>{ resolve(response); },(error:any)=>{ resolve(error); }); }); return promise; } /** * The function updateDatePerChange sends the new date to the backend if the date was moved * @param change the Change (the Resource) from which the date should be changed */ public async deletePreset(preset: any){ const promise = new Promise(resolve=>{ let serializableResource = {id: preset.id}; let strigifiedResource = JSON.stringify(serializableResource); let resJson = JSON.parse(strigifiedResource) as typeof strigifiedResource; this.http.post('http://localhost:8080/api/deletePreset', resJson).subscribe((response:any)=>{ resolve(response); },(error:any)=>{ resolve(error); }); }); return promise; } /** * The function updateDatePerChange sends the new date to the backend if the date was moved * @param change the Change (the Resource) from which the date should be changed */ public async editUserPreferences(userPreferences: any){ const promise = new Promise(resolve=>{ let serializableResource = {details: userPreferences.showDetails, view: userPreferences.view, language: userPreferences.language }; let strigifiedResource = JSON.stringify(serializableResource); let resJson = JSON.parse(strigifiedResource) as typeof strigifiedResource; console.log(resJson); this.http.post('http://localhost:8080/api/editUserPreferences', resJson).subscribe((response:any)=>{ resolve(response); },(error:any)=>{ resolve(error); }); }); return promise; } /** * The function fetchStates fetches an array from the possible statuses per state * @returns promise for the fetched Status Array */ public async fetchStates(){ const promise = new Promise(resolve=>{ let res : any[] = []; this.http.get('http://localhost:8080/api/getStates') .subscribe((response: any)=>{ console.log("###\n"); console.log(response); response.forEach(state => { res.push(state) }); resolve(res); }, (error=>{ this.errorService.handleInitError(error); } )) }) return promise; } /** * The function fetchSupportGroups fetches an array of all supportGroups * @returns promise for the fetched supportGroups array */ public async fetchSupportGroups(){ const promise = new Promise(resolve=>{ let res : any[] = []; this.http.get('http://localhost:8080/api/getSupportGroups') .subscribe((response: any)=>{ response.forEach(supportGroup => { res.push(supportGroup) }); console.log("\n###################") console.log(response); resolve(res); }) }) return promise; } /** * The function fetchContracts fetches an array of all contracts * @returns promise for the fetched contracts array */ public async fetchContracts(){ const promise = new Promise(resolve=>{ let res : any[] = []; this.http.get('http://localhost:8080/api/getContracts') .subscribe((response: any)=>{ response.forEach(contract => { res.push(contract) }); resolve(res); }) }) return promise; } /** * The function fetchPaketTypes fetches an array of all paketTypes * @returns promise for the fetched paketTypes array */ public async fetchPaketTypes(){ const promise = new Promise(resolve=>{ let res : any[] = []; this.http.get('http://localhost:8080/api/getPackageTypes') .subscribe((response: any)=>{ response.forEach(paketType => { res.push(paketType) }); resolve(res); }) }) return promise; } /** * The function fetchPaketTypes fetches the supportGroup of the current user * @returns promise for the fetched current user supportGroup */ public async fetchUserSupportGroup(){ const promise = new Promise(resolve=>{ let res : any = {}; this.http.get('http://localhost:8080/api/getUserSupportGroup') .subscribe((response: any)=>{ this.userSupportGroup = res.name; res = response; resolve(res); },(error=>{ this.errorService.handleInitError(error); })) }) return promise; } /** * The function fetchPlanTimes fetches the plan times per week from the backend * @param filters current applied filters for the planTime calculation * @param renderStartDate startDate of the current gantt chart (first week rendered) * @param renderEndtDate startDate of the current gantt chart (last week rendered) * @returns a promise for the response */ public async fetchPlanTimes(filters: any, renderStartDate: Date, renderEndtDate: Date){ const promise = new Promise(resolve=>{ let obj = {filter : filters.filter, renderStartDate : renderStartDate, renderEndDate: renderEndtDate }; let stringyfiedData = JSON.stringify(obj); let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData; let res : any[] = []; this.http.post('http://localhost:8080/api/fetchPlanTimes', dataJson) .subscribe((response: any[])=>{ response.forEach(week => { res.push(week); }); resolve(res); }) }) return promise; } /** * The function fetchImplementers fetches an array of all implementers of the supportGoup from a specific change * @param change change, for which the possible implementers should be fetched * @returns promise for the fetched implementers array */ public async fetchImplementers(change: any){ const promise = new Promise(resolve=>{ let obj = {entryId : change.resourceId, supportGroup : change.supportGroupId}; let stringyfiedData = JSON.stringify(obj); let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData; // console.log(dataJson); let res : any[] = []; this.http.post('http://localhost:8080/api/getImplementer', dataJson) .subscribe((response: any)=>{ response.members.forEach(implementer => { res.push(implementer) }); resolve(res); }) }) return promise; } /** * The function updateDatePerChange sends the new date to the backend if the date was moved * @param change the Change (the Resource) from which the date should be changed */ public async updateDatePerChange(change: any){ const promise = new Promise(resolve=>{ let serializableResource = { resourceId: change.resourceId, d2: change.tasks[1].StartDate, changeNr: change.changeNr, state: change.state}; let strigifiedResource = JSON.stringify(serializableResource); let resJson = JSON.parse(strigifiedResource) as typeof strigifiedResource; this.http.post('http://localhost:8080/api/updateChange', resJson).subscribe((response:any)=>{ resolve(response); },(error:any)=>{ resolve(error); }); }); return promise; } /** * The function updateStatePerChange performs a status transition on the backend * @param change the change for which the status transition is to be performed * @returns a aromise for the response */ public async updateStatePerChange(change: any){ const promise = new Promise(resolve=>{ let obj = {changeNr : change.changeNr, currentState : change.currentState, nextState : change.nextState}; let stringyfiedData = JSON.stringify(obj); let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData; // console.log(dataJson); this.http.post('http://localhost:8080/api/updateState', dataJson).subscribe((response:any)=>{ resolve(response); },(error:any)=>{ resolve(error); }); }); return promise; } /** * The function updateImplementerPerChange updates the implementer for a specific change on the backend * @param data the change for which the implementer update is to be performed and the loginId of the implementer * @returns a promise for the response */ public async updateImplementerPerChange(data: any){ const promise = new Promise(resolve=>{ // console.log(change); let obj = {pkgId : data.resourceId, loginId : data.loginId}; let stringyfiedData = JSON.stringify(obj); let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData; // console.log(dataJson); this.http.post('http://localhost:8080/api/updateImplementer', dataJson).subscribe((response:any)=>{ resolve(response); },(error:any)=>{ console.log(error); resolve(error); }); }) return promise; } /** * The function updateApproval updates the approvalStatus for a specific change on the backend * @param change concerning change * @returns a promise for the response */ public async updateApproval(change: any, approvalAction){ const promise = new Promise(resolve=>{ let obj = {changeNr : change.changeNr, approvalAction: approvalAction}; let stringyfiedData = JSON.stringify(obj); let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData; console.log(dataJson); this.http.post('http://localhost:8080/api/updateApproval', dataJson).subscribe((response:any)=>{ resolve(response); },(error:any)=>{ resolve(error); }); }).catch((error)=>{ throw(error); }) return promise; } /** * The function fetchChanges fetches the changes from backend and maps them to a structure that the Gannt component can interpret * @returns promise for the fetched Changes Array */ public async fetchChanges(reqestParams: any = null){ let stringyfiedData = JSON.stringify(reqestParams); console.log(reqestParams); let dataJson = JSON.parse(stringyfiedData) as typeof stringyfiedData; const promise = new Promise(resolve=>{ let first : boolean = true; let res : any[] = []; console.log(dataJson); this.http.post('http://localhost:8080/api/getChanges', dataJson) .subscribe((response:any)=>{ console.log(response); this.totalSize = response.totalSize; response.changes.forEach(resp=>{ //console.log(resp.resourceId+" "+resp.approvalStatus) //console.log(resp); let tasks : any[] = []; if(resp.d1!=null){ tasks.push( { TaskID: resp.resourceId+"D1", TaskName: "Requested Start Date", StartDate: new Date(resp.d1), Duration: 0, isFixed: true, resources: [{resourceId: resp.resourceId},], Progress: 0, work: 0, isRes: false } ); } if(resp.d2!=null){ let isFixed = true; if(resp.state == 0 || resp.state == 3){ isFixed = false; } tasks.push( { TaskID: resp.resourceId+"D2", TaskName: "Sheduled Start Date", StartDate: new Date(resp.d2), Duration: 0, isFixed: isFixed, resources: [{resourceId: resp.resourceId},], Progress: 0, work: 0, isRes: false } ); } if(resp.d3!=null && resp.state>1){ tasks.push( { TaskID: resp.resourceId+"D3", TaskName: "Approved Start Date", StartDate: new Date(resp.d3), Duration: 0, isFixed: true, resources: [{resourceId: resp.resourceId},], Progress: 0, work: 0, isRes: false } ); } if(resp.d4!=null && resp.state == 10){ tasks.push( { TaskID: resp.resourceId+"D4", TaskName: "Actual End Date", StartDate: new Date(resp.d4), Duration: 0, isFixed: true, resources: [{resourceId: resp.resourceId},], Progress: 0, work: 0, isRes: false } ); } //let approval = this.validateApproval(resp.approvalStatus); res.push({ resourceId: resp.resourceId, approvalStatus: resp.approvalStatus, statusReason: resp.statusReason, changeNr: resp.changeNr, resourceName: resp.resourceName, vertrag: resp.contract, vertragName: this.getContractName(resp.contract), isExpand: false, isRes: true, state: resp.state, stateName: this.getStateNameById(resp.state), supportGroup: resp.supportGroup, tasks: tasks, supportGroupId: resp.supportGroupId, implementerEdit: this.validateImplementerEdit(resp.state), flagApproval: this.validateApproval(resp), flagReject: this.validateApproval(resp), flagCancel: this.validateCancel(resp.state), flagPermit: this.validatePermit(resp.state), changeImplementerLogin: resp.changeImplementerLogin, packageName: resp.packageName, coordinatorSg: resp.coordinatorSg, plantime: resp.planTime, }); }) console.log(res); this.errorService.error = false; resolve(res); },(error=>{ this.errorService.handleCostumError('Fehler beim Laden der Change Pakete','Möglicherweise sind dem User keine Changes zugewiesen', error.message, 'error'); })) }) return promise; } /** * The function validateImplementerEdit validates if a change is in a state where its implementer can be updated * @param state state of the concerning change * @returns true or false for a boolean flag */ private validateImplementerEdit(state):boolean{ if(state == 3 || state == 6){ return true; }else{ return false; } } /** * The function validateCancel validates if a change is in a state where it can be canceld * @param state state of the concerning change * @returns true or false for a boolean flag */ private validateCancel(state):boolean{ if(state == 1){ return true }else{ return false } } /** * The function validatePermit validates if a change is in a state where it can be permited * @param state state of the concerning change * @returns true or false for a boolean flag */ private validatePermit(state): boolean{ if(state == 0){ return true }else{ return false } } /** * The function validatePermit validates if a change has an active approval * @param state approvalString * @returns true or false for a boolean flag */ private validateApproval(resp):boolean{ // console.log(resp.changeNr); // console.log(resp.approvalStatus); // console.log('\n'); if(resp.approvalStatus!=undefined && resp.approvalStatus!="0"){ return true; }else{ return false; } } /** * The function getStateNameById searches the name of a status by its id, depending on the set language * @param stateNr state number (uid) * @returns string with the stateName */ public getStateNameById(stateNr): String { if(this.languageService.language == 'EN'){ for (let state of this.states) { if(stateNr == state.actualState){ return state.stateNameEN; } } } if(this.languageService.language == 'DE'){ for (let state of this.states) { if(stateNr == state.actualState){ return state.stateNameDE; } } } return ""; } public getContractNameByID(contractId){ for (let contract of this.contracts) { if(contractId == contract.id){ return contract.name; } } } public getPaketTypeNameByID(paketTypeId){ for (let paketType of this.paketTypes) { if(paketTypeId == paketType.id){ return paketType.name; } } } public getPaketTypeIdByName(paketTypeName){ for (let paketType of this.paketTypes) { if(paketTypeName == paketType.name){ return paketType.id; } } } }