/* ** Views/Partial/LCA/Kitchen.cshtml is using this controller */ angular.module('CarbonFootprint') .controller('LCAKitchenCtrl', ['$scope', '$http', '$routeParams', 'ParameterCacheService', 'JoinSurveyItemAndParameter', '$q', 'MultiLanguageService', 'ExportCsvService', function ($scope, $http, $routeParams, ParameterService, JoinService, $q, MultiLanguageService, ExportCsvService) { // Multi-language resource object var resource; var options; // This property controlls modal form, will be passed to table-edit-modal directive $scope.modalFormOption = {}; // Set default radio button $scope.kitchenType = 0; $scope.model = []; $scope.summary = []; $scope.WarmGasType = 0; $scope.sumKgCO2e = 0; $scope.selectedUnit = ""; // 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.$watch('selectRow.toBeEdit.FuelType', function (newValue) { if (newValue) { var fuelTypeArray = newValue.split("KgCO2e/"); if (fuelTypeArray.length >= 2) { $scope.selectedUnit = fuelTypeArray[1]; } else { $scope.selectedUnit = ""; } } else { $scope.selectedUnit = ""; } }, true); $scope.createProcess = function () { // Create an object & select it var toBeCreated = {}; var formData = new FormData(); var hasFile = false; var fileIndex = -1; var hasPhoto = false; var photoIndex = -1; toBeCreated.ID = 0; toBeCreated.LCAID = $routeParams.LCAID; toBeCreated.Type = $scope.kitchenType; toBeCreated.activityDataType = 0; toBeCreated.emitParaType = 0; // Reset fuel types and years dropdown list options $scope.fuelTypes = []; $scope.years = []; $scope.WarmGasTypeList = {}; // For modal form $scope.selectRow.toBeEdit = toBeCreated; $scope.selectFile = function (file) { fileIndex = fileIndex > photoIndex ? fileIndex + 1 : photoIndex + 1; formData.append('kf' + "_lca" + $routeParams.LCAID + "_" + fileIndex, file); hasFile = true; }; $scope.selectPhoto = function (photo) { photoIndex = fileIndex > photoIndex ? fileIndex + 1 : photoIndex + 1; formData.append('kp' + "_lca" + $routeParams.LCAID + "_" + photoIndex, photo); hasPhoto = true; }; $scope.dataQualityOption = {}; $scope.dataQualityOption.data = {}; $scope.isEdit = false; $scope.modalFormOption.show = true; $scope.save = function () { JoinService.joinAsync([toBeCreated]).then(function () { //setKgCO2e([toBeCreated]); $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]; if (hasPhoto) toBeCreated.ReferencePhotoUrl = $scope.baseUrl +urlList[photoIndex]; $http.post($scope.baseUrl+'/api/Kitchen/Save/' + toBeCreated.LCAID + '/' + toBeCreated.ID, toBeCreated) .success(function (data) { data.Area = getArea(options[data.ParameterID]); data.FuelType = getFuelType(options[data.ParameterID]); data.Year = getYear(options[data.ParameterID]); $scope.model.unshift(data); calcTotalKgCO2e(); $scope.modalFormOption.show = false; }) .error(function (error) { console.log(error); }); }); }); } }; $scope.editProcess = function (selected) { var toBeEdit = $scope.selectRow.toBeEdit = angular.copy(selected); var formData = new FormData(); var hasFile = false; var fileIndex = -1; var hasPhoto = false; var photoIndex = -1; // Reset fuel types and years dropdown list options $scope.fuelTypes = []; $scope.years = []; $scope.selectFile = function (file) { fileIndex = fileIndex > photoIndex ? fileIndex + 1 : photoIndex + 1; formData.append('kf' + "_lca" + $routeParams.LCAID + "_" + fileIndex, file); hasFile = true; }; $scope.selectPhoto = function (photo) { photoIndex = fileIndex > photoIndex ? fileIndex + 1 : photoIndex + 1; formData.append('kp' + "_lca" + $routeParams.LCAID + "_" + photoIndex, photo); hasPhoto = true; }; /* angular.forEach(options, function (value) { if (value.search(toBeEdit.Area) !== -1 && toBeEdit.Area) { var fuelType = getFuelType(value); $scope.fuelTypes.push(fuelType); } }); $scope.fuelTypes = filterDuplicatedData($scope.fuelTypes); angular.forEach(options, function (value) { if (toBeEdit.Area && toBeEdit.FuelType && value.search(toBeEdit.Area) !== -1 && value.search(toBeEdit.FuelType) !== -1) { var year = getYear(value); $scope.years.push(year); } }); $scope.years = filterDuplicatedData($scope.years); */ ParameterService.onAreaChanged(options, $scope, $scope.selectRow.toBeEdit); ParameterService.onFuelTypeChanged(options, $scope, $scope.selectRow.toBeEdit); setTimeout(function () { $('#edit_year').val(selected.Year); }, 500); $scope.modalFormOption.show = true; $scope.dataQualityOption = {}; $scope.dataQualityOption.data = {}; $scope.isEdit = true; $('#activityDataType').val(selected.activityDataType); $('#emitParaType').val(selected.emitParaType); $scope.save = function () { JoinService.joinAsync([toBeEdit]).then(function () { //setKgCO2e([toBeEdit]); $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]; if (hasPhoto) toBeEdit.ReferencePhotoUrl = $scope.baseUrl +urlList[photoIndex]; $http.post($scope.baseUrl+'/api/Kitchen/Save/' + toBeEdit.LCAID + '/' + toBeEdit.ID, toBeEdit) .success(function (data) { // Update kitchen data angular.copy(data, selected); selected.Area = getArea(options[toBeEdit.ParameterID]); selected.FuelType = getFuelType(options[toBeEdit.ParameterID]); selected.Year = getYear(options[toBeEdit.ParameterID]); selected.factor = data.factor; calcTotalKgCO2e(); $scope.modalFormOption.show = false; }) .error(function (error) { console.log(error); }); }); }); }; }; $scope.dataQualityShow = function (selected) { $http.get($scope.baseUrl+'/api/DataQualityLevel/GetByTableId/LCACommonSurveyForm_Kitchens/' + selected.ID ).success(function (data) { angular.copy(data, $scope.dataQualityOption.data); $scope.dataQualityOption.data.Name = selected.Name; $scope.dataQualityOption.data.LCAID = selected.LCAID; //todo !!... load pre saved data //$scope.dataQualityOption.Fi = 0.0123;//test only; //todo !!... 還需要總碳排量才能算出 碳排量佔比 $scope.dataQualityOption.showSaveBtn = $scope.lcaDetail.Status == 1; $scope.dataQualityOption.show = true; }).error(function (data, status) { alert(data.ExceptionMessage); }); }; $scope.deleteProcess = function (selected) { var isConfirm = confirm(resource.DeleteItemMsg); if (isConfirm) { $http.delete($scope.baseUrl+'/api/Kitchen/Delete/' + selected.ID) .success(function () { var index = $scope.model.indexOf(selected); $scope.model.splice(index, 1); calcTotalKgCO2e(); // This operate is base on selectRow directive in TableEdit.js file $scope.selectRow.unSelect(); }) .error(function (error) { console.log(error); }); } }; /* modelBuilder for create & export */ /** Caution!: The 'Type' property depends on '$scope.kitchenType'. The 'ParameterID' property depends on 'options'. This modelBuilder is binded with this controller. Refactoring modelBuilder.create() with more arugments will be better **/ $scope.modelBuilder = { create: function (data, LCAID) { try { var model = { ProcessName: data[0], ResponsibleUnit: data[1], Name: data[2], ParameterID: getKeyByValue(options, data[3] + ',' + data[4] + ',' + data[5] + ','), Scalar: parseFloat(data[6]) ? data[6] : 0, Type: $scope.kitchenType, LCAID: LCAID }; // check imported data length and model length (-1 for LCAID, +2 for ParameterID, -1 fot Type) if (data.length !== getObjectSize(model)) { throw resource['EXCELFileFormatWrong']; } // if find incorrect ParameterID if (model.ParameterID === undefined) { throw resource['Area'] + '/' + resource['FuelType'] + '/' + resource['StaticLabelGlobal_Years'] + ' Error: ' + data[3] + ',' + data[4] + ',' + data[5] + ' not found.'; } return model; } catch (err) { return { error: err }; } }, export: function (list) { var data = []; // header data.push([resource['FactoryAndProcessItems'], resource['ResponsibleUnit'], resource['DeviceName'], resource['Area'], resource['FuelType'], resource['StaticLabelGlobal_Years'], resource['FuelConsumptionDuringInterrogation']]); // body angular.forEach(list, function (entry) { var csv = []; //column 1 csv.push(entry.ProcessName); //column 2 csv.push(entry.ResponsibleUnit); //column 3 csv.push(entry.Name); //column 4 csv.push(entry.Area); //column 5 csv.push(entry.FuelType); //column 6 csv.push(entry.Year); //column 7 csv.push(entry.Scalar); data.push(csv); }); ExportCsvService.startExport(data, "Export_Kitchen.csv"); } } /* 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.Kitchens); }); return deferred.promise; }, saveAsyncFn: batchCreateAndUpdateCache }; $scope.quoteModal = { show: false }; // Update "fuelTypes" dropdown list $scope.$watch('selectRow.toBeEdit.Area', function (area) { ParameterService.onAreaChanged(options, $scope, $scope.selectRow.toBeEdit); /* $scope.fuelTypes = []; $scope.years = []; angular.forEach(options, function (value) { if (value.search(area) !== -1 && area) { var fuelType = getFuelType(value); $scope.fuelTypes.push(fuelType); } }); $scope.fuelTypes = filterDuplicatedData($scope.fuelTypes); */ }); // Update "years" dorpdown list $scope.$watch('selectRow.toBeEdit.FuelType', function () { ParameterService.onFuelTypeChanged(options, $scope, $scope.selectRow.toBeEdit); /* var area = $scope.selectRow.toBeEdit.Area; var fuelType = $scope.selectRow.toBeEdit.FuelType; $scope.years = []; angular.forEach(options, function (value) { if (area && fuelType && value.search(area) !== -1 && value.search(fuelType) !== -1) { var year = getYear(value); $scope.years.push(year); } }); $scope.years = filterDuplicatedData($scope.years); */ }); // Update "ParameterID" attribute. // There might be some different "ParameterID" match to multiple identical "Value" // Here, we always return the last match (the biggest "ParameterID") $scope.$watch('selectRow.toBeEdit.Year', function () { ParameterService.onYearChanged(options, $scope, $scope.selectRow.toBeEdit); /* var area = $scope.selectRow.toBeEdit.Area; var fuelType = $scope.selectRow.toBeEdit.FuelType; var year = $scope.selectRow.toBeEdit.Year; angular.forEach(options, function (value, key) { if (value.search(area) !== -1 && value.search(fuelType) !== -1 && value.search(year) !== -1) { $scope.selectRow.toBeEdit.ParameterID = key; } }); */ }); $scope.onWarmGasTypeChange = function (warmGasType) { console.log(warmGasType); if (warmGasType == 0) { getAllDataAsync($routeParams.LCAID) .then(function (response) { options = response.Options; var sheetHeader = response.SheetHeader ? response.SheetHeader : {}; if (response.Kitchens) { $scope.model = response.Kitchens; } if (response.WarmGasTypes) { $scope.WarmGasTypeList = response.WarmGasTypes; } // Get each model's area, fuel type, year by "ParameterID" angular.forEach($scope.model, function (model) { if (model.ParameterID in options) { model.Area = getArea(options[model.ParameterID]); model.FuelType = getFuelType(options[model.ParameterID]); model.Year = getYear(options[model.ParameterID]); model.OriHeatValue = getHeatValue(options[model.ParameterID]); model.WarmGasType = getWarmGasType(model.ParameterID); if (model.heatValue == null || model.heatValue == "") { model.heatValue = model.OriHeatValue; } } }); calcTotalKgCO2e(); $scope.areas = ParameterService.getAreasFromParameters(options); $scope.sheetHeader.SheetFillerName = sheetHeader.SheetFillerName; $scope.sheetHeader.Phone = sheetHeader.Phone; $scope.sheetHeader.Department = sheetHeader.Department; $scope.activityOptions = response.ActivityOptions; $scope.emitParaOptions = response.EmitParaOptions; }, function (error) { console.log(error); }); } else { getAllDataWithWarmGasTypeAsync($routeParams.LCAID, warmGasType) .then(function (response) { options = response.Options; var sheetHeader = response.SheetHeader ? response.SheetHeader : {}; if (response.Kitchens) { $scope.model = response.Kitchens; } if (response.WarmGasTypes) { $scope.WarmGasTypeList = response.WarmGasTypes; } // Get each model's area, fuel type, year by "ParameterID" angular.forEach($scope.model, function (model) { if (model.ParameterID in options) { model.Area = getArea(options[model.ParameterID]); model.FuelType = getFuelType(options[model.ParameterID]); model.Year = getYear(options[model.ParameterID]); model.OriHeatValue = getHeatValue(options[model.ParameterID]); model.WarmGasType = getWarmGasType(model.ParameterID); if (model.heatValue == null || model.heatValue == "") { model.heatValue = model.OriHeatValue; } } }); calcTotalKgCO2e(); $scope.areas = ParameterService.getAreasFromParameters(options); $scope.sheetHeader.SheetFillerName = sheetHeader.SheetFillerName; $scope.sheetHeader.Phone = sheetHeader.Phone; $scope.sheetHeader.Department = sheetHeader.Department; $scope.activityOptions = response.ActivityOptions; $scope.emitParaOptions = response.EmitParaOptions; }, function (error) { console.log(error); }); } } // Get data and prepare $scope.model getAllDataAsync($routeParams.LCAID) .then(function (response) { options = response.Options; var sheetHeader = response.SheetHeader ? response.SheetHeader : {}; if (response.Kitchens) { $scope.model = response.Kitchens; } if (response.WarmGasTypes) { $scope.WarmGasTypeList = response.WarmGasTypes; } // Get each model's area, fuel type, year by "ParameterID" angular.forEach($scope.model, function (model) { if (model.ParameterID in options) { model.Area = getArea(options[model.ParameterID]); model.FuelType = getFuelType(options[model.ParameterID]); model.Year = getYear(options[model.ParameterID]); model.OriHeatValue = getHeatValue(options[model.ParameterID]); model.WarmGasType = getWarmGasType(model.ParameterID); if (model.heatValue == null || model.heatValue == "") { model.heatValue = model.OriHeatValue; } } }); calcTotalKgCO2e(); /* // Sources of dropdown lists $scope.areas = []; // Extract area from options angular.forEach(options, function (value) { var area = getArea(value); $scope.areas.push(area); }); // Duplicated areas $scope.areas = filterDuplicatedData($scope.areas); */ $scope.areas = ParameterService.getAreasFromParameters(options); // $scope.sheetHeader is parent's object $scope.sheetHeader.SheetFillerName = sheetHeader.SheetFillerName; $scope.sheetHeader.Phone = sheetHeader.Phone; $scope.sheetHeader.Department = sheetHeader.Department; $scope.activityOptions = response.ActivityOptions; $scope.emitParaOptions = response.EmitParaOptions; }, function (error) { console.log(error); }); // Get multilanguage resource MultiLanguageService.getResourceAsync() .then(function (response) { resource = response; //console.log(resource); }, function (error) { console.log(error); }); $http.get($scope.baseUrl+'/api/Kitchen/GetWarmGasType') .success(function (data) { //$scope.WarmGasTypes = data.WarmGasType; var removedWarmGasTypes = data.WarmGasType.splice(-1, 1); $scope.WarmGasTypes = data.WarmGasType; }) .error(function (error) { console.log(error); }); /** * 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 () { // Update KgCO2e properties //setKgCO2e(parsedList); $http.post($scope.baseUrl+'/api/Kitchen/SaveAll/', parsedList) .success(function (data) { // Close modals $scope.fileImportModal.show = false; $scope.quoteModal.show = false; // Get each model's area, fuel type, year by "ParameterID" angular.forEach(data.result, function (model) { model.Area = getArea(options[model.ParameterID]); model.FuelType = getFuelType(options[model.ParameterID]); model.Year = getYear(options[model.ParameterID]); }); // Concat created data and $scope.model $scope.model = data.result.concat($scope.model); calcTotalKgCO2e(); deferred.resolve(data); }) .error(function (e) { console.log(e.Message); }); }); return deferred.promise; } /** * Update the KgCO2e property of the model objects * @param {[Array]} : array of model objects */ function setKgCO2e(models) { angular.forEach(models, function (entry) { var heatValueMultiplier = 1; if (entry.heatValue != null && entry.OriHeatValue != "") { heatValueMultiplier = entry.heatValue / entry.OriHeatValue; } if (entry.parameterResult && entry.Scalar) { entry.KgCO2e = entry.parameterResult * entry.Scalar * heatValueMultiplier; } }); } /** * Get all list data from server * @param {[int]} : LCAID * @return {[promise]} */ function getAllDataAsync(LCAID) { var deferred = $q.defer(); $http.get($scope.baseUrl+'/api/Kitchen/GetByLcaId/' + LCAID) .success(function (data) { deferred.resolve(data); }) .error(function () { deferred.resolve(null); }); return deferred.promise; } /** * Get all list data from server * @param {[int]} : LCAID * @return {[promise]} */ function getAllDataWithWarmGasTypeAsync(LCAID, WarmGasType) { var deferred = $q.defer(); $http.get($scope.baseUrl+'/api/Kitchen/GetByLcaIdAndWarmGasType/' + LCAID + '/' + WarmGasType) .success(function (data) { deferred.resolve(data); }) .error(function () { deferred.resolve(null); }); return deferred.promise; } /** * Get substring "area" from a string * @parem String * @returns String */ function getArea(value) { return value.slice(0, getPosition(value, ",", 1)); } /** * Get substring "fuelType" from a string * @parem String * @returns String */ function getFuelType(value) { return value.slice(getPosition(value, ",", 1) + 1, getPosition(value, ",", 2)); } /** * Get substring "year" from a string * @parem String * @returns String */ function getYear(value) { return value.slice(getPosition(value, ",", 2) + 1, getPosition(value, ",", 3)); } /** * Get substring "heatvalue" from a string * @parem String * @returns String */ function getHeatValue(value) { return value.slice(getPosition(value, ",", 3) + 1, value.length); } /** * Get substring "WarmGasType" from a string * @parem String * @returns String */ function getWarmGasType(parameterID) { return $scope.WarmGasTypeList[parameterID]; } function getPosition(string, subString, index) { return string.split(subString, index).join(subString).length; } /** * Remove identical element from the array * @parem Array * @returns Array function filterDuplicatedData(array) { var filteredArray = []; angular.forEach(array, function (value) { if ($.inArray(value, filteredArray) === -1) { filteredArray.push(value); } }); return filteredArray; } */ function uploadFileAndGetDeferred(file) { var deferred = $q.defer(); var formData = new FormData(); formData.append('file', file); $http.post($scope.baseUrl+'/api/Upload', formData, { transformRequest: angular.identity, headers: { 'Content-Type': undefined } }).success(function (url) { url = $scope.baseUrl + url; console.log('uploadFileAndGetDeferred', url); deferred.resolve(url); }); return deferred.promise; } function calcTotalKgCO2e() { $scope.summary = Enumerable.From($scope.model).GroupBy("$.FuelType", "$.KgCO2e", function (key, group) { return { fuelType: key, totalKgCO2e: Enumerable.From(group).Sum(), AllocationKgCO2e: Enumerable.From(group).Sum() * $scope.Ratio }; }).ToArray(); var sumKgCO2e = 0; angular.forEach($scope.summary, function (item) { sumKgCO2e += item.totalKgCO2e; }); $scope.sumKgCO2e = sumKgCO2e; } $scope.onAllocationChange = function (Allocation) { $scope.Allocation = Allocation if ($scope.Allocation == 0) //重量分配 //$scope.Ratio = $scope.calculate($scope.lcaDetail.ProductProductionPcs, $scope.product.Weight, $scope.lcaDetail.FabProductionWeight); $scope.Ratio = $scope.calculate($scope.lcaDetail.ProductProductionPcs * $scope.product.Weight / $scope.lcaDetail.FabProductionWeight, 1, $scope.lcaDetail.ProductProductionPcs); else if ($scope.Allocation == 1) //面積分配 //$scope.Ratio = $scope.calculate($scope.lcaDetail.ProductProductionPcs, $scope.product.AreaSize, $scope.lcaDetail.FabProductionArea); $scope.Ratio = $scope.calculate($scope.lcaDetail.ProductProductionPcs * $scope.product.AreaSize / $scope.lcaDetail.FabProductionArea, 1, $scope.lcaDetail.ProductProductionPcs); else if ($scope.Allocation == 2) //產量分配 //$scope.Ratio = $scope.calculate($scope.lcaDetail.ProductProductionPcs, 1, $scope.lcaDetail.FabProductionPcs); $scope.Ratio = $scope.calculate($scope.lcaDetail.ProductProductionPcs, 1, $scope.lcaDetail.FabProductionPcs); else if ($scope.Allocation == 3) //經濟分配 //$scope.Ratio = $scope.calculate($scope.lcaDetail.ProductProductionPcs, $scope.lcaDetail.ProductProductionEconomic, $scope.lcaDetail.FabProductionEconomic); $scope.Ratio = $scope.calculate($scope.lcaDetail.ProductProductionPcs * $scope.lcaDetail.ProductProductionEconomic / $scope.lcaDetail.FabProductionEconomic, 1, $scope.lcaDetail.ProductProductionPcs); else if ($scope.Allocation == 4) //工時分配 //$scope.Ratio = $scope.calculate($scope.lcaDetail.ProductProductionPcs, $scope.lcaDetail.ProductProductionHour, $scope.lcaDetail.FabProductionHour); $scope.Ratio = $scope.calculate($scope.lcaDetail.ProductProductionPcs * $scope.lcaDetail.ProductProductionHour / $scope.lcaDetail.FabProductionHour, 1, $scope.lcaDetail.ProductProductionPcs); else if ($scope.Allocation == 99) $scope.Ratio = 1; $http.post($scope.baseUrl+'/api/LCA/SaveAllocation/' + $routeParams.LCAID + '/' + $routeParams.DetailType + '/' + $scope.Allocation) .success(function (data) { calcTotalKgCO2e(); $scope.modifyCacheAllocation(); }) } }]);