/* ** Views/Partial/LCA/BOM.cshtml is using this controller */ angular.module('CarbonFootprint') .controller('LifecycleAssmtController', ['$scope', '$http', '$routeParams', 'JoinSurveyItemAndParameter', 'LCADetailCacheService', 'MultiLanguageService', '$q', '$filter', 'Notification', 'ExportCsvService', function ($scope, $http, $routeParams, JoinService, LCADetailCacheService, MultiLanguageService, $q, $filter, Notification, ExportCsvService) { // Multi-language resource object var resource, inited = false; // This property controlls modal form, will be passed to table-edit-modal directive $scope.modalFormOption = {}; $scope.modalUpdateOption = {}; $scope.model = []; // set $scope.baseUrl var baseUrl = $scope.baseUrl; if (typeof (baseUrl) === 'undefined' || baseUrl == null) { var arr = window.location.href.split("/"); if (arr[3].indexOf('app') == 0) baseUrl = ''; else baseUrl = '/' + arr[3]; $scope.baseUrl = baseUrl; } $scope.lifeCycleStage = { value: '', category: '', categorySubItem: '', GHGinventoryItemNo: '' }; $scope.categoryOptions = {}; $scope.categorySub1Options = {}; //$scope.categorySelected = []; //$scope.categorySub1Selected = []; $scope.inUnit = false; $scope.preAlertTime = new Date(); $scope.checkUnit = function (selectRow, curUnit) { //console.log('checkUnit', curUnit, selectRow); if (typeof (selectRow.ActivityIntensityUnit) === 'undefined' || typeof (selectRow.Unit) === 'undefined') { $scope.inUnit = false; //console.log('checkUnit end1'); return; } selectRow.ActivityIntensityUnit = selectRow.ActivityIntensityUnit.trim(); selectRow.Unit = selectRow.Unit.trim(); if (selectRow.ActivityIntensityUnit.length <= 0 || selectRow.Unit.length <= 0 || selectRow.ActivityIntensityUnit === selectRow.Unit) { $scope.inUnit = false; //console.log('checkUnit end2'); return; } var timeDiff = new Date() - $scope.preAlertTime; //console.log('timeDiff', timeDiff); //var msg = selectRow.ActivityIntensityUnit + '!=' + selectRow.Unit; //console.log(selectRow.ActivityIntensityUnit, selectRow.Unit); if (timeDiff > 99) alert(resource['ActivityStrengthUnitCheck'] + ''); $scope.inUnit = false; //console.log('checkUnit end3'); $scope.preAlertTime = new Date(); } $scope.unitFocus = function (curUnit) { //console.log('unitFocus', curUnit); $scope.inUnit = true; } $scope.selectSimaproProcess = function (selectedMaterial) { //console.log('selectSimaproProcess', selectedMaterial); $scope.simaproOption = {}; $scope.simaproOption.show = true; $scope.simaproOption.onOk = function (selectedParameter) { //console.log(selectedParameter); selectedMaterial.Unit = selectedParameter.Unit; selectedMaterial.KgCO2e = selectedParameter.Value; selectedMaterial.Instruction = selectedParameter.DisplayNameTW + ': ' + selectedParameter.Remark; $scope.changeEmission(selectedMaterial); $scope.checkUnit(selectedMaterial); //var model = selectedMaterial; //var annualPurchaseAmount = model.AnnualPurchaseAmount || 0; //var materialSpec = model.MaterialSpec || 0; //var kgCO2e = model.KgCO2e || 0; //model.ActivityIntensity = annualPurchaseAmount * materialSpec; //model.Emission = model.ActivityIntensity * kgCO2e; //LCADetailCacheService.updateMaterialsAsync([selectedMaterial]); } }; $scope.isObjectEmpty = function (card) { return Object.keys(card).length === 0; } $scope.updateOption = { Material: false, MaterialDelete: false, UpstreamDelivery: false, UpstreamDeliveryDelete: false, Service: false, ServiceDelete: false, DownstreamDelivery: false, DownstreamDeliveryDelete: false, Product: false, ProductDelete: false, Waste: false, WasteDelete: false, }; $scope.getStageLabel = function (stage) { return $scope.stageOptions[stage]; }; $scope.getStageOption = function (stage) { var index = stage.indexOf("C"); return stage.substring(0, index); }; //$scope.getItemLabel = function (itemID) { // return Enumerable.From($scope.items) // .Where(function (x) { // return x.ID == itemID; // }) // .First().DisplayName; //}; $scope.catItemChange = function (toBeEdit, newVal) { $('#GHGEvaluateItem').val(newVal); //toBeEdit.GHGEvaluateItem = newVal; }; $scope.changeEmission = function (model) { var activityIntensity = model.ActivityIntensity || 0, kgCO2e = model.KgCO2e || 0, sumEmissionT = Enumerable.From($scope.model) .Where(function (x) { return x.ID != model.ID; }) .Sum(function (x) { return x.EmissionT; }); model.EmissionKg = activityIntensity * kgCO2e; model.EmissionT = model.EmissionKg / 1000; sumEmissionT += model.EmissionT; model.Percentage = ((model.EmissionT / sumEmissionT) * 100).toFixed(4); angular.forEach($scope.model, function (item) { if (item.ID != model.ID) { item.Percentage = ((item.EmissionT / sumEmissionT) * 100).toFixed(4); } }); }; $scope.sumPercentage = function () { var result = 0; angular.forEach($scope.model, function (item) { result += parseFloat(item.Percentage || 0); }); alert(result.toFixed(4)); }; $scope.changeUncertaintyAnalysis = function (model) { var dataAttribute = parseInt(model.DataAttribute || '0'), dataSource = parseInt(model.DataSource || '0'); switch (dataAttribute * dataSource) { case 1: model.UncertaintyAnalysis = 'C'; break; case 2: model.UncertaintyAnalysis = 'B'; break; case 4: model.UncertaintyAnalysis = 'A'; break; default: model.UncertaintyAnalysis = ''; } }; //產生風險評估報表 $scope.toGenerateRiskAssessmentReport = function () { LCADetailCacheService.GenerateRiskAssessmentReport($routeParams.LCAID).then(res => { if (res != null) { let arr = res.slice(1, res.length - 1).split(','); for (let i = 0; i < arr.length; i++) { var url = arr[i]; //console.log(url); //console.log(url.length); //console.log(url.substring(3)); if (url.length >= 3 && url.substring(0, 3) == 'err') { alert(decodeURI(url)); return false; } var elemIF = document.createElement("iframe"); elemIF.src = url; elemIF.style.display = "none"; document.body.appendChild(elemIF); } } }); }; //function getKeyValuesAsync(LCScat) { // var deferred = $q.defer(); // $http.get($scope.baseUrl+'/api/LifecycleAssmt/LCScat2keyValues/' // + LCScat) // .success(function (data) { // deferred.resolve(data); // }) // .error(function () { // deferred.resolve(null); // }) // return deferred.promise; //} $scope.onLifeCycleStageChange = function (LifecycleStage) { //console.log('onLifeCycleStageChange', LifecycleStage); $scope.lifeCycleStage.category = ''; $scope.lifeCycleStage.categorySubItem = ''; $scope.lifeCycleStage.GHGinventoryItemNo = ''; $scope.categorySub1Options = {}; if (LifecycleStage == '') { $scope.categoryOptions = {}; return; } $http.get($scope.baseUrl+'/api/LifecycleAssmt/LCScat2keyValues/' + LifecycleStage).success(function (data) { $scope.categoryOptions = data.keyValues; //console.log('categoryOptions', $scope.categoryOptions); }); //$scope.categoryOptions = getKeyValuesAsync( // LifecycleStage); } $scope.onCategoryChange = function (category) { $scope.category = $('#category option:selected').text().trim(); $scope.lifeCycleStage.categorySubItem = ''; $scope.lifeCycleStage.GHGinventoryItemNo = ''; if (category == '') { $scope.categorySub1Options = {}; return; } $http.get($scope.baseUrl+'/api/LifecycleAssmt/LCScat2keyValues/' + category).success(function (data) { $scope.categorySub1Options = data.keyValues; //console.log('categorySub1Options', $scope.categorySub1Options); }); } $scope.onCategorySub1Change = function (categorySub1) { //console.log('onCategorySub1Change', categorySub1); //console.log($('#categorySub1').val()); $scope.categorySubItem = $('#categorySub1 option:selected').text().trim(); $scope.GHGinventoryItemNo = categorySub1; //console.log(); } $scope.createProcess = function () { // Create an object & select it var toBeCreated = {}; toBeCreated.ID = 0; toBeCreated.LCAID = $routeParams.LCAID; toBeCreated.LifeCycleStage = $scope.lifeCycleStage.value; var formData = new FormData(); var hasFile = false; var fileIndex = -1; //console.log('create LifeCycleStage', toBeCreated.LifeCycleStage); //$scope.categoryDisabled = false; //$scope.categorySub1Disabled = true; //$scope.categorySub2Disabled = true; // For modal form //console.log('lifeCycleStage', $scope.lifeCycleStage); toBeCreated.category = ''; if ($scope.lifeCycleStage.category.length == 2) toBeCreated.category = $scope.lifeCycleStage.category.substring(1, 2); toBeCreated.categorySubItem = $('#categorySub1 option:selected').text().trim(); toBeCreated.GHGinventoryItemNo = $scope.lifeCycleStage.categorySubItem; if (toBeCreated.GHGinventoryItemNo == '4.1b2') toBeCreated.GHGinventoryItemNo = '4.1b'; $scope.selectRow.toBeEdit = toBeCreated; //console.log('toBeCreated', toBeCreated); $scope.modalFormOption.show = true; //$scope.selectRow.toBeEdit.LifeCycleStage = lifeCycleStage.value; // just for testing //toBeCreated.LifeCycleStage = ""; //toBeCreated.GHGEvaluateItem = ""; //toBeCreated.ActivityIntensity = 3661.7864; //toBeCreated.KgCO2e = 9.42; //toBeCreated.Unit = "kg"; //toBeCreated.EmissionKg = toBeCreated.ActivityIntensity * toBeCreated.KgCO2e; //toBeCreated.EmissionT = toBeCreated.EmissionKg / 1000; //toBeCreated.Percentage = 0.003390; //toBeCreated.Instruction = "產品碳足跡計算服務平台聚碳酸酯(非光氣法,一般級)Polycarbonate, PC-2014"; //toBeCreated.Scenario = "單一重量:0.01631Kg 來源: GPM系統(520 - 98765 - R2)"; //toBeCreated.UncertaintyAnalysis = "A"; $scope.selectFile = function (file) { fileIndex = fileIndex + 1; formData.append('la' + "_lca" + $routeParams.LCAID + "_" + fileIndex, file); hasFile = true; }; $scope.save = function () { //console.log('save toBeCreated', toBeCreated); //var GHGEvaluateItem = $('#GHGEvaluateItem').val(); //var category = $('#category').val(); //var categorySubItem = $('#categorySubItem').val(); //var GHGinventoryItemNo = $('#GHGinventoryItemNo').val(); //if (typeof (GHGEvaluateItem) === 'undefined' || GHGEvaluateItem.length == 0) { // //console.log(error); // Notification.error({ message: error.ExceptionMessage, positionX: 'center', delay: 3000 }); // return; //} //toBeCreated.GHGEvaluateItem = GHGEvaluateItem; //toBeCreated.category = category; //toBeCreated.categorySubItem = categorySubItem; //toBeCreated.GHGinventoryItemNo = GHGinventoryItemNo; //if (toBeCreated.ActivityIntensityUnit != toBeCreated.Unit) { // alert(resource['ActivityStrengthUnitCheck'] + '') // return; //} $http.post($scope.baseUrl+'/api/Upload', formData, { transformRequest: angular.identity, headers: { 'Content-Type': undefined } }).success(function (urlList) { if (hasFile) toBeCreated.ReferenceFileUrl = $scope.baseUrl +urlList[fileIndex]; $http.post($scope.baseUrl+'/api/LifecycleAssmt/Save/' + $routeParams.LCAID + "/" + toBeCreated.ID , toBeCreated) .success(function (data) { //console.log('save done data', data); $scope.model.unshift(data); $scope.modalFormOption.show = false; calcTotalKgCO2e(); }) .error(function (error) { //console.log('LifecycleAssmt/Save 1', error); Notification.error({ message: error.ExceptionMessage, positionX: 'center', delay: 3000 }); }); }); }; }; $scope.updateProcess = function () { //console.log('updateProcess', $scope.updateOption); $http.post($scope.baseUrl+'/api/LifecycleAssmt/Sync/' + $routeParams.LCAID, $scope.updateOption) .success(function (response) { $scope.model = response.Analysis; $scope.lifeCycleStage.value = ''; calcTotalKgCO2e(); }); }; $scope.editProcess = function (selected) { var toBeEdit = $scope.selectRow.toBeEdit = angular.copy(selected); var formData = new FormData(); var hasFile = false; var fileIndex = -1; toBeEdit.ActivityIntensityUnit = toBeEdit.Unit; //console.log('edit LifeCycleStage', toBeEdit.LifeCycleStage); //$scope.categoryDisabled = true; //$scope.categorySub1Disabled = true; //$scope.categorySub2Disabled = true; $scope.modalFormOption.show = true; $scope.selectFile = function (file) { fileIndex = fileIndex + 1; formData.append('la' + "_lca" + $routeParams.LCAID + "_" + fileIndex, file); hasFile = true; }; $scope.save = function () { //if (toBeEdit.ActivityIntensityUnit != toBeEdit.Unit) { // alert(resource['ActivityStrengthUnitCheck'] + '') // return; //} $http.post($scope.baseUrl+'/api/Upload', formData, { transformRequest: angular.identity, headers: { 'Content-Type': undefined } }).success(function (urlList) { if (hasFile) toBeEdit.ReferenceFileUrl = $scope.baseUrl + urlList[fileIndex]; $http.post($scope.baseUrl+'/api/LifecycleAssmt/Save/' + toBeEdit.LCAID + "/" + toBeEdit.ID, toBeEdit) .success(function (data) { angular.copy(data, selected); $scope.modalFormOption.show = false; calcTotalKgCO2e(); }) .error(function (error) { //console.log('LifecycleAssmt/Save 2',error); Notification.error({ message: error.ExceptionMessage, positionX: 'center', delay: 3000 }); }); }); }; }; $scope.deleteProcess = function (selected) { var isConfirm = confirm(resource.DeleteItemMsg); if (isConfirm) { $http.delete($scope.baseUrl+"/api/LifecycleAssmt/Delete/" + selected.ID) .success(function () { var index = $scope.model.indexOf(selected); $scope.model.splice(index, 1); // 重新计算百分比 if ($scope.model.length > 0) { var sumEmissionT = Enumerable.From($scope.model) .Sum(function (x) { return x.EmissionT; }); angular.forEach($scope.model, function (item) { item.Percentage = ((item.EmissionT / sumEmissionT) * 100).toFixed(4); }); } // This operate is base on selectRow directive in TableEdit.js file $scope.selectRow.unSelect(); calcTotalKgCO2e(); }); } }; $scope.loadData = function () { getAllDataAsync($routeParams.LCAID) .then(function (response) { $scope.model = response.Analysis; $scope.stageOptions = response.StageOptions; calcTotalKgCO2e(); }, function (error) { //console.log(error); }); // Get multilanguage resource MultiLanguageService.getResourceAsync() .then(function (response) { resource = response; }, function (error) { //console.log(error); }); }; $scope.loadData(); $scope.$on('changeSelectedTab', function (event, args) { if (/*!inited &&*/ args.selectedTab == 'LifecycleAssmt') { inited = true; // Get data and prepare $scope.model $scope.loadData(); //// Get multilanguage resource //MultiLanguageService.getResourceAsync() // .then(function (response) { // resource = response; // }, function (error) { // }); } }); /** * Get all list data from server * @param {[Int]} : LCAID * @return {[promise]} */ function getAllDataAsync(LCAID) { var deferred = $q.defer(); $http.get($scope.baseUrl+'/api/LifecycleAssmt/GetByLcaId/' + LCAID) .success(function (data) { deferred.resolve(data); }) .error(function () { deferred.resolve(null); }) return deferred.promise; } /* modelBuilder for create & export */ /** Caution!: The 'ParameterID' property depends on '$scope.sources'. This modelBuilder is binded with this controller. Refactoring modelBuilder.create() with more arugments will be better **/ $scope.modelBuilder = { create: function (data, LCAID) { try { var getValue = getCategoryKeyByValue(data[1]) var model = { LifeCycleStage: getKeyByValue($scope.stageOptions, data[0]), categorySubItem: data[1], category: getValue[0], GHGinventoryItemNo: getValue[1], GHGEvaluateItem: data[2], MaterialNo: data[3], ActivityIntensity: data[4], ActivityIntensityUnit: data[5], KgCO2e: data[6], Unit: data[7], //EmissionT: data[7], //Percentage: data[8], Instruction: data[8], UncertaintyAnalysis: data[9], LCAID: LCAID }; // check imported data length and model length (-1 for LCAID) if (data.length !== getObjectSize(model) - 3) { throw resource['EXCELFileFormatWrong']; } if (model.Unit != model.ActivityIntensityUnit) { throw resource['ActivityStrengthUnitCheck']; } return model; } catch (err) { return { error: err }; } }, export: function (list) { var data = []; // header data.push([ resource['LifecycleStage'], resource['CategorySubItem'], resource['EvaluationItem'], resource['MaterialNo'], resource['ActivityStrength'], resource['ActivityStrength'] + resource['StaticLabelGlobal_Unit'], resource['Parameter'] + " (kgCO2e)", resource['DeclareUnit'], //resource['CarbonEmitQuan'] + " (" + resource['Ton'] + ")", //resource['Percentage'], resource['ParaDesc'], resource['UncertaintyAnalysis'] ]); // body angular.forEach(list, function (entry) { var csv = []; //column 1 csv.push($scope.getStageLabel(entry.LifeCycleStage)); //column 2 csv.push(entry.categorySubItem); //column 3 csv.push(entry.GHGEvaluateItem); //column 4 csv.push(entry.MaterialNo); //column 5 csv.push(entry.ActivityIntensity); //column 6 csv.push(entry.Unit); //column 7 csv.push(entry.KgCO2e); //column 8 csv.push(entry.Unit); //csv.push(entry.EmissionT); //csv.push(entry.Percentage); //column 9 csv.push(entry.Instruction); //column 10 csv.push(entry.UncertaintyAnalysis); data.push(csv); }); ExportCsvService.startExport(data, "Export_LifecycleAssmt.csv"); } } function getCategoryKeyByValue(value) { switch (value) { case "組織採購的貨物": return ["4","4.1a"] break; case "其他": return ["6", "6"] break; case "貨物上游運輸與配送": return ["3", "3.1"] break; case "員工通勤": return ["3", "3.3"] break; case "運輸客戶和訪客": return ["3", "3.4"] break; case "業務旅運 (商務旅行)": return ["3", "3.5"] break; case "輸入電力": return ["2", "2.1"] break; case "輸入能源": return ["2", "2.2"] break; case "輸入電力上游": return ["4", "4.1b"] break; case "輸入能源上游": return ["4", "4.1b2"] break; case "資本財 (產生之排放)": return ["4", "4.2"] break; case "組織使用之服務": return ["4", "4.5"] break; case "租賃設備資產使用": return ["4", "4.4"] break; case "貨物下游運輸與配送": return ["3", "3.2"] break; case "產品使用階段": return ["5", "5.1"] break; case "下游承租資產": return ["5", "5.2"] break; case "產品生命終止階段": return ["5", "5.3"] break; case "投資": return ["5", "5.4"] break; case "處置固態和液態廢棄物": return ["4", "4.3"] break; } return ["", ""]; } /* file import options & modal control */ $scope.fileImportOptions = { modelBuilder: $scope.modelBuilder, saveAsync: batchCreateAndUpdateCache }; $scope.fileImportModal = { show: false }; /* quote options & modal control */ $scope.quoteOptions = { queryDataAsyncFn: function (LCAID) { var deferred = $q.defer(); getAllDataAsync(LCAID).then(function (data) { deferred.resolve(data.Analysis); }) return deferred.promise; }, saveAsyncFn: batchCreateAndUpdateCache }; $scope.quoteModal = { show: false }; /** * Private function: save all async * @param {[Array]} : array of parsed objects * @return {[promise]} */ function batchCreateAndUpdateCache(parsedList) { var deferred = $q.defer(); // Calculate KgCO2e and sava all JoinService.joinAsync(parsedList) .then(function () { //console.log(parsedList); parsedList.forEach(function (item, index) { var ActivityIntensity = Number(item.ActivityIntensity); var KgCO2e = Number(item.KgCO2e); if (ActivityIntensity != NaN && KgCO2e != NaN) item.EmissionKg = ActivityIntensity * KgCO2e; else item.EmissionKg = 0; item.EmissionT = item.EmissionKg/1000; }); sumEmissionT = Enumerable.From($scope.model) .Where(function (x) { return x.ID != $scope.model.ID; }) .Sum(function (x) { return x.EmissionT; }) + Enumerable.From(parsedList) .Sum(function (x) { return x.EmissionT; }) ; parsedList.forEach(function (item, index) { item.Percentage = ((item.EmissionT / sumEmissionT) * 100).toFixed(4) }); angular.forEach($scope.model, function (item) { item.Percentage = ((item.EmissionT / sumEmissionT) * 100).toFixed(4); }); $http.post($scope.baseUrl+'/api/LifecycleAssmt/SaveAll/', parsedList) .success(function (data) { // Close modals $scope.fileImportModal.show = false; $scope.quoteModal.show = false; // Concat created data and $scope.model $scope.model = data.result.concat($scope.model); deferred.resolve(data); if (data.errMsg!="") Notification.error({ message: data.errMsg, positionX: 'center', delay: 3000 }); calcTotalKgCO2e(); }) .error(function (e) { console.log(e); if (e.ExceptionMessage) { deferred.reject(e.ExceptionMessage); } else { deferred.reject(e.Message); } }); }); return deferred.promise; } function calcTotalKgCO2e() { $scope.summary = Enumerable.From($scope.model).GroupBy("$.LifeCycleStage", "$.EmissionT", function (key, group) { return { LifeCycleStage: key, totalKgCO2e: Enumerable.From(group).Sum()}; }).ToArray(); var sumKgCO2e = 0; angular.forEach($scope.summary, function (item) { sumKgCO2e += item.totalKgCO2e; }); $scope.sumKgCO2e = sumKgCO2e; } }]);