/** * 项目工料机相关spread * * @author CaiAoLin * @date 2017/7/19 * @version */ /** * 构造函数 * * @return {void} */ function ProjectGLJSpread() { this.isChanging = false; this.sheetObj = null; this.firstMachineRow = -1; this.firstMixRatioRow = -1; this.successCallback = null; this.supplyType = ['自行采购', '部分甲供', '完全甲供', '甲定乙供']; this.supplyComboMap = supplyComboMap // 工料机类型是混凝土、砂浆、配合比、机械(不包括机械组成物)时,供货方式列只读。 this.supplyReadonlyType = notEditType; } /** * 初始化 * * @return {object} */ ProjectGLJSpread.prototype.init = function () { // 供货方式类型 let supplySelect = []; for(let comM of this.supplyComboMap) { supplySelect.push({ text: comM.text, value: comM.value }); } let selectBox = new GC.Spread.Sheets.CellTypes.ComboBox(); selectBox.items(supplySelect); selectBox.editorValueType(GC.Spread.Sheets.CellTypes.EditorValueType.value); let header = [ {name: '编码', field: 'code', visible: true,width:80}, {name: '名称', field: 'name', visible: true,width:160}, {name: '规格型号', field: 'specs', visible: true,width:120}, {name: '单位', field: 'unit', visible: true,width:45}, {name: '类型', field: 'short_name', visible: true,width:45}, {name: '类型', field: 'unit_price.type', visible: false}, {name: '总消耗量', field: 'quantity', visible: true,width:100,decimalField:'glj.quantity'}, {name: '定额价', field: "base_price", visible: true,width:70,decimalField:"glj.unitPrice",validator: 'number'},//这里feiedID设置是为了在计不计取价差的时候做显示用 {name: '调整价', field: 'adjust_price', visible: true,width:70,decimalField:"glj.unitPrice"}, {name: '市场价', field: "unit_price.market_price", visible: true, validator: 'number',width:70,decimalField:"glj.unitPrice"}, { name: '是否暂估', field: 'is_evaluate', visible: true, cellType: new GC.Spread.Sheets.CellTypes.CheckBox(), validator: 'boolean' ,width:60 }, {name: '供货方式', field: 'supply', visible: true, cellType: selectBox,width:80}, {name: '甲供数量', field: 'supply_quantity',validator:'number', visible: true,width:100}, {name: '交货方式', field: 'delivery', visible: true,width:90}, {name: '送达地点', field: 'delivery_address', visible: true,width:100}, { name: '不调价', field: 'is_adjust_price', visible: true, cellType: new GC.Spread.Sheets.CellTypes.CheckBox(), validator: 'boolean', width:55 }, {name: 'UID', field: 'unit_price.id', visible: false}, {name: '工料机ID', field: 'glj_id', visible: false}, {name: '组成物消耗量', field: 'consumption', visible: false}, {name: '父级关联编码', field: 'connect_code', visible: false}, {name: '组成物信息', field: 'ratio_data', visible: false}, {name: '分部分项总消耗量', field: 'subdivisionQuantity', visible: false,width:100,decimalField:'glj.quantity'}, {name: '技术措施项目总消耗量', field: 'techQuantity', visible: false,width:100,decimalField:'glj.quantity'}, {name: 'ID', field: 'id', visible: false} ]; let sourceData = jsonData; this.sheetObj = new CommonSpreadJs(header); this.sheetObj.init('project-glj'); // 获取列号 let isEvaluateColumn = this.sheetObj.getFieldColumn('is_evaluate'); let isAdjustPriceColumn = this.sheetObj.getFieldColumn('is_adjust_price'); let unitColumn = this.sheetObj.getFieldColumn('unit'); let quantityColumn = this.sheetObj.getFieldColumn('quantity'); let basePriceColumn = this.sheetObj.getFieldColumn('base_price'); let adjustPriceColumn = this.sheetObj.getFieldColumn('adjust_price'); let marketPriceColumn = this.sheetObj.getFieldColumn('unit_price.market_price'); let supplyColumn = this.sheetObj.getFieldColumn('supply'); let shortNameColumn = this.sheetObj.getFieldColumn('unit_price.short_name'); let supplyQuantity = this.sheetObj.getFieldColumn('supply_quantity'); let nameColumn = this.sheetObj.getFieldColumn('name'); let specsColumn = this.sheetObj.getFieldColumn('specs'); //左对齐样式 let leftStyleSetting = {hAlign: GC.Spread.Sheets.HorizontalAlign.left}; this.sheetObj.setStyle(-1, nameColumn, leftStyleSetting); this.sheetObj.setStyle(-1, specsColumn, leftStyleSetting); // 居中样式 let centerStyleSetting = {hAlign: 1}; this.sheetObj.setStyle(-1, isEvaluateColumn, centerStyleSetting); this.sheetObj.setStyle(-1, isAdjustPriceColumn, centerStyleSetting); this.sheetObj.setStyle(-1, unitColumn, centerStyleSetting); this.sheetObj.setStyle(-1, shortNameColumn, centerStyleSetting); // 向右对齐样式 let rightStyleSetting = {hAlign: GC.Spread.Sheets.HorizontalAlign.right}; this.sheetObj.setStyle(-1, quantityColumn, rightStyleSetting); this.sheetObj.setStyle(-1, basePriceColumn, rightStyleSetting); this.sheetObj.setStyle(-1, adjustPriceColumn, rightStyleSetting); this.sheetObj.setStyle(-1, marketPriceColumn, rightStyleSetting); this.sheetObj.setStyle(-1, supplyColumn, rightStyleSetting); this.sheetObj.setStyle(-1, supplyQuantity, rightStyleSetting); // 设置可编辑列 this.sheetObj.setColumnEditable(basePriceColumn); this.sheetObj.setColumnEditable(marketPriceColumn); this.sheetObj.setColumnEditable(isEvaluateColumn); this.sheetObj.setColumnEditable(isAdjustPriceColumn); this.sheetObj.setColumnEditable(supplyColumn); this.sheetObj.setData(sourceData); // 取消正在加载字符提示 $("#project-glj > p").hide(); this.specialColumn(sourceData); // 绑定修改事件 let self = this; this.sheetObj.bind(GC.Spread.Sheets.Events.ValueChanged, function(element, info) { self.updateProjectGLJField(info, self.successCallback); }); // 绑定双击事件 this.sheetObj.bind(GC.Spread.Sheets.Events.CellDoubleClick, function (element, info) { let column = info.col; let row = info.row; let field = self.sheetObj.getColumnField(column); let activeSheet = self.sheetObj.getSheet(); // 获取类型 let typeColumn = self.sheetObj.getFieldColumn('unit_price.type'); let type = activeSheet.getValue(row, typeColumn); let ratioColumn = self.sheetObj.getFieldColumn('ratio_data'); let ratioData = activeSheet.getValue(row, ratioColumn); // 如果类型为混凝土、砂浆、配合比、机械,则提示 if (field === 'unit_price.market_price' && canNotChangeTypeId.indexOf(type) >= 0) { if(ratioData&&ratioData.length>0){ alert('当前工料机的市场单价由组成物计算得出,不可直接修改'); } } }); return this.sheetObj; }; /** * 更新项目工料机中的数据字段 * * @param {object} info * @param {function} callback * @return {void|boolean} */ ProjectGLJSpread.prototype.updateProjectGLJField = function(info, callback) { // 获取修改的数据 let column = info.col; let row = info.row; let idString = 'id'; let field = projectGLJSheet.getColumnField(column); if (field === '') { return false; } let activeSheet = projectGLJSheet.getSheet(); // 切割字段 let fieldArray = field.split('.'); idString = fieldArray.length > 1 ? 'unit_price.id' : idString; // 防止快速同时提交 if (isChanging) { return false; } // 校验数据 let value = info.newValue; if (!projectGLJSheet.checkData(column, value)) { alert('输入的数据类型不对,请重新输入!'); activeSheet.setValue(row, column, info.oldValue); return false; } // 获取id let idColumn = projectGLJSheet.getFieldColumn(idString); if (idColumn < 0) { return false; } let id = activeSheet.getValue(row, idColumn); // 直接在前端计算后传值后台改 let extend = {}; /* let updateRecord = jsonData[row]; 这时修改成在后端计算后直接更新,因为还要重新计算受影响的清单节点 let parentMarketPrice = projectGLJSpread.compositionCalculate(updateRecord); if (parentMarketPrice !== null && Object.keys(parentMarketPrice).length > 0) { for (let activeCode in parentMarketPrice) { let tmpObject = { market_price: parentMarketPrice[activeCode], }; extend[activeCode] = tmpObject; } }*/ // 如果是供货方式则需要处理数据 if (field === 'supply') { // value = this.supplyType.indexOf(value); extend.supply_quantity = this.getSupplyQuantity(value, activeSheet, info); } if(field === 'supply_quantity'){//修改数量需做4舍5入 value= value.toDecimal(getDecimal('glj.quantity')); } if(field === 'unit_price.market_price'||field === 'base_price'){ value= scMathUtil.roundForObj(value,getDecimal('glj.unitPrice'));//修改市场价和修改定额价时需要重新记算很多受影响的树节点,现在改成与定字额工料机那里调相同的方法。 let editField = field === 'base_price'?field:"market_price"; projectObj.project.projectGLJ.updatePrice(jsonData[row],editField,value); return; } extend = Object.keys(extend).length > 0 ? JSON.stringify(extend) : ''; this.postUpdate(id,field,value,info,extend,callback); }; ProjectGLJSpread.prototype.postUpdate=function (id,field,value,info,extend,callback) { $.bootstrapLoading.start(); $.ajax({ url: '/glj/update', type: 'post', data: {id: id, field: field, value: value, extend: extend}, dataType: 'json', error: function() { alert('数据传输有误!'); isChanging = false; }, beforeSend: function() { isChanging = true; }, success: function(response) { isChanging = false; // 修改失败则恢复原值 if (response.err !== 0&&info.fromRG!=true) { projectGLJSheet.getSheet().setValue(info.row, info.col, info.oldValue); alert('更改数据失败!'); } else { // 成功则触发相应事件 /* if (parentMarketPrice !== null) { info.parentMarketPrice = parentMarketPrice; }*/ if(field !== 'supply'&&info.fromRG!=true){ //供货方式需做转换才能直接设置值, 这里设置值是为了早点更新数据,等getdata返回数据再刷新的话会有比较大的延时 projectGLJSheet.getSheet().setValue(info.row, info.col, value); } callback(field, info,id); } } }); } /** * 设置特殊单元格数据 * * @param {object} sourceData * @return {void} */ ProjectGLJSpread.prototype.specialColumn = function (sourceData) { let rowCounter = 0; // 获取列号 let isEvaluateColumn = this.sheetObj.getFieldColumn('is_evaluate'); let marketPriceColumn = this.sheetObj.getFieldColumn('unit_price.market_price'); let basePriceColumn = this.sheetObj.getFieldColumn('base_price'); let adjustPriceColumn = this.sheetObj.getFieldColumn("adjust_price"); let connectCodeColumn = this.sheetObj.getFieldColumn('connect_code'); let consumptionColumn = this.sheetObj.getFieldColumn('consumption'); let supplyColumn = this.sheetObj.getFieldColumn('supply'); let shortNameColumn = this.sheetObj.getFieldColumn('short_name'); let supplyQuantity = this.sheetObj.getFieldColumn('supply_quantity'); let activeSheet = this.sheetObj.getSheet(); for (let data of sourceData) { let rowStyle = null; //设置类型名称: activeSheet.setValue(rowCounter, shortNameColumn,projectObj.project.projectGLJ.getShortNameByID(data.unit_price.type)); // 只有材料才显示是否暂估 if (materialIdList.indexOf(data.unit_price.type) < 0) { let string = new GC.Spread.Sheets.CellTypes.Text(); activeSheet.setCellType(rowCounter, isEvaluateColumn, string, GC.Spread.Sheets.SheetArea.viewport); // 锁定该单元格 activeSheet.getCell(rowCounter, isEvaluateColumn, GC.Spread.Sheets.SheetArea.viewport).locked(true); activeSheet.setValue(rowCounter, isEvaluateColumn, ''); }else { let checkBox = new GC.Spread.Sheets.CellTypes.CheckBox(); activeSheet.setCellType(rowCounter, isEvaluateColumn, checkBox, GC.Spread.Sheets.SheetArea.viewport); activeSheet.getCell(rowCounter, isEvaluateColumn, GC.Spread.Sheets.SheetArea.viewport).locked(false); activeSheet.setValue(rowCounter, isEvaluateColumn, data.is_evaluate); } /* // 设置供货方式列是否可选 if (this.supplyReadonlyType.indexOf(data.unit_price.type) >= 0) { // 锁定该单元格 activeSheet.getCell(rowCounter, supplyColumn, GC.Spread.Sheets.SheetArea.viewport).locked(true); }*/ // 如果为部分甲供则甲供数量需要可编辑 if (data.supply == 1) { activeSheet.getCell(rowCounter, supplyQuantity, GC.Spread.Sheets.SheetArea.viewport).locked(false); } //供货方式为完全甲供时设置甲供数量为总消耗量 if (data.supply == 2) { activeSheet.setValue(rowCounter, supplyQuantity, data.quantity); } // 供货方式数据 let supplyIndex = parseInt(data.supply); supplyIndex = isNaN(supplyIndex) ? 0 : supplyIndex; let supplyText = this.supplyType[supplyIndex] !== undefined ? this.supplyType[supplyIndex] : '自行采购'; activeSheet.setValue(rowCounter, supplyColumn, supplyText); // activeSheet.setValue(rowCounter, supplyColumn, supplyIndex); // 如果类型为混凝土、砂浆、配合比、机械,则市场单价和供货方式不能修改 if (canNotChangeTypeId.indexOf(data.unit_price.type) >= 0) { this.firstMixRatioRow = this.firstMixRatioRow === -1 && data.unit_price.type !== GLJTypeConst.GENERAL_MACHINE ? rowCounter : this.firstMixRatioRow; this.firstMachineRow = this.firstMachineRow === -1 && data.unit_price.type === GLJTypeConst.GENERAL_MACHINE ? rowCounter : this.firstMachineRow; // 锁定该单元格 if (data.ratio_data && data.ratio_data.length > 0){//有组成物时,市场单价、定额价、供货方式不能修改 activeSheet.getCell(rowCounter, marketPriceColumn, GC.Spread.Sheets.SheetArea.viewport).locked(true); activeSheet.getCell(rowCounter, basePriceColumn, GC.Spread.Sheets.SheetArea.viewport).locked(true); activeSheet.getCell(rowCounter, supplyColumn, GC.Spread.Sheets.SheetArea.viewport).locked(true); //设置底色 rowStyle = this.getRowStyle("#E0E0E0"); } } if(data.unit_price.is_add!=1){//如果不是新增,定额价不可修改。 activeSheet.getCell(rowCounter, basePriceColumn, GC.Spread.Sheets.SheetArea.viewport).locked(true); } // 处理数据 if (data.ratio_data !== undefined && data.ratio_data.length > 0) { let connectCode = []; let consumption = []; for (let tmp of data.ratio_data) { connectCode.push(tmp.connect_key); consumption.push(tmp.consumption); } let connectCodeString = connectCode.join(','); let consumptionString = consumption.join(','); activeSheet.setValue(rowCounter, connectCodeColumn, connectCodeString); activeSheet.setValue(rowCounter, consumptionColumn, consumptionString); } data=this.sheetObj.setProjectGLJDiffPrice(data); activeSheet.setValue(rowCounter,basePriceColumn,data.base_price); activeSheet.setValue(rowCounter,adjustPriceColumn,data.adjust_price); if(rowStyle==null&&data.base_price == data.unit_price.market_price){//如果定额价等于市场价时,改底色。 优先度低于有组成物时的底色 rowStyle = this.getRowStyle("#C4CAFB"); } activeSheet.setStyle(rowCounter, -1, rowStyle); rowCounter++; } }; ProjectGLJSpread.prototype.getRowStyle = function (bgColour) { let style = new GC.Spread.Sheets.Style(); style.backColor = bgColour; style.borderLeft = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin); style.borderTop = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin); style.borderRight = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin); style.borderBottom = new GC.Spread.Sheets.LineBorder("#D4D4D4", GC.Spread.Sheets.LineStyle.thin); return style; }; /** * 计算当前行对应组成物的市场以及基价单价价格 * * @param {Number} row * @return {Object} */ ProjectGLJSpread.prototype.compositionCalculate = function(updateRecord) { let gljData = projectObj.project.projectGLJ.datas; let m_index = gljOprObj.getIndex(updateRecord,gljKeyArray); let parent_connect_keys = gljData.mixRatioConnectData[m_index]; if(!parent_connect_keys||parent_connect_keys.length<=0){// 不属于组成物则忽略 return null; } let q_decimal = getDecimal("glj.quantity"); let p_decimal = getDecimal("glj.unitPrice"); let parentMarketPrice = {}; for(let p of parent_connect_keys) { let mix_ratios = gljData.mixRatioMap[p]; let sum = 0; for (let m of mix_ratios) { let unitPrice = this.sheetObj.getUnitPrice(m); if (unitPrice) { let com = scMathUtil.roundForObj(m.consumption, q_decimal); let marketPrice = scMathUtil.roundForObj(unitPrice.market_price, p_decimal); sum = scMathUtil.roundForObj(marketPrice * com + sum, p_decimal); } } parentMarketPrice[p]=sum; } return parentMarketPrice; }; /** * 组成物父类数据更新 * * @param {Object} parentMarketPrice * @return {void} */ ProjectGLJSpread.prototype.compositionParentUpdate = function(parentMarketPrice) { let marketPriceColumn = this.sheetObj.getFieldColumn('unit_price.market_price'); let activeSheet = this.sheetObj.getSheet(); // 定位到父节点,然后更新 for (let code in parentMarketPrice) { let changeRow = this.sheetObj.searchKeyword(code); activeSheet.setValue(changeRow, marketPriceColumn, parentMarketPrice[code]); } }; /** * 价格计算 * * @param {Object} info * @return {void} */ ProjectGLJSpread.prototype.priceCalculate = function(info) { let row = info.row; let typeColumn = this.sheetObj.getFieldColumn('unit_price.type'); let basePriceColumn = this.sheetObj.getFieldColumn('base_price'); let adjustPriceColumn = projectGLJSheet.getFieldColumn('adjust_price'); let activeSheet = this.sheetObj.getSheet(); // 获取类型 let type = activeSheet.getValue(row, typeColumn); /* let data = jsonData[row]; if(gljOprObj.calcPriceDiff(data)==true){//是否记算价差 data.base_price = data.unit_price.base_price; data.adjust_price = projectObj.project.projectGLJ.getAdjustPrice(data); }else { data.base_price = data.unit_price.market_price; data.adjust_price = data.unit_price.market_price; } activeSheet.setValue(info.row,basePriceColumn,data.base_price); activeSheet.setValue(info.row,adjustPriceColumn,data.adjust_price);*/ /* // 基价单价计算 switch (type) { // 主材、设备自动赋值基价单价=市场单价 case GLJTypeConst.MAIN_MATERIAL: case GLJTypeConst.EQUIPMENT: activeSheet.setValue(info.row, basePriceColumn, info.newValue); break; }*/ /* // 调整基价计算 switch (type) { // 材料、主材、设备 调整基价=基价单价 case GLJTypeConst.MAIN_MATERIAL: case GLJTypeConst.EQUIPMENT: let basePrice = activeSheet.getValue(info.row, basePriceColumn); activeSheet.setValue(info.row, adjustPriceColumn, basePrice); break; }*/ // 市场单价计算 switch (type) { // 人工、材料(普通材料)触发 需计算混凝土、砂浆、配合比、机械的市场单价 case GLJTypeConst.LABOUR: case GLJTypeConst.GENERAL_MATERIAL: // 计算 this.compositionParentUpdate(info.parentMarketPrice); break; } }; /** * 更改供货方式 * * @param {Object} info * @return {void} */ ProjectGLJSpread.prototype.changeSupplyType = function(info) { // let supply = info.newValue; // let supplyNumber = this.supplyType.indexOf(supply) > -1 ? this.supplyType.indexOf(supply) : 0; let supplyNumber = info.newValue; let supplyQuantityColumn = this.sheetObj.getFieldColumn('supply_quantity'); let activeSheet = this.sheetObj.getSheet(); // 部分甲供时可更改甲供数量数据,其余则只读 let locked = supplyNumber == 1 ? false : true; activeSheet.getCell(info.row, supplyQuantityColumn, GC.Spread.Sheets.SheetArea.viewport).locked(locked); let supplyQuantity = this.getSupplyQuantity(supplyNumber, activeSheet, info); activeSheet.setValue(info.row, supplyQuantityColumn, supplyQuantity); }; /** * 根据供货方式获取甲供数量 * * @param {Number} supplyType * @param {Object} activeSheet * @param {Object} info * @return {Number} */ ProjectGLJSpread.prototype.getSupplyQuantity = function(supplyType, activeSheet, info) { let quantityColumn = this.sheetObj.getFieldColumn('quantity'); // 获取总消耗量 let quantity = activeSheet.getValue(info.row, quantityColumn); // 自行采购和甲定乙供则把甲供数量设置为0,其余情况则设置为当前总消耗量 let supplyQuantity = supplyType == 0 || supplyType == 3 ? 0 : quantity; supplyQuantity = parseFloat(supplyQuantity); return supplyQuantity; };