Browse Source

Merge branch 'master' into olym

olym 7 năm trước cách đây
mục cha
commit
7a2421d071

+ 4 - 4
modules/ration_glj/facade/ration_glj_facade.js

@@ -92,10 +92,10 @@ function combineQuantity(results,rations) {
         }
         resultList.push(tmp);
       /*  if(resultMap.hasOwnProperty(data.projectGLJID)){
-            resultMap[data.projectGLJID] += data.quantity;
-        }else {
-            resultMap[data.projectGLJID] = data.quantity;
-        }*/
+         resultMap[data.projectGLJID] += data.quantity;
+         }else {
+         resultMap[data.projectGLJID] = data.quantity;
+         }*/
     });
 
  /*   var resultList =[];

+ 5 - 0
public/web/common_util.js

@@ -13,3 +13,8 @@ String.prototype.hasSubStr = function (str) {
     return this.toLowerCase().indexOf(str.toLowerCase()) > -1;
 };
 
+// 树结点计算时,取费会出现值为NaN的情况,导致往父节点汇总(递归相加)会出现错误。
+function parseFloatPlus(value){
+    let rst = parseFloat(value);
+    return  isNaN(rst) ? 0 : rst;
+};

+ 3 - 0
public/web/sheet/sheet_common.js

@@ -126,6 +126,9 @@ var sheetCommonObj = {
                 //var cell = sheet.getCell(row, col, GC.Spread.Sheets.SheetArea.viewport);
                 var val = data[row][setting.header[col].dataCode];
                 if(val&&setting.header[col].dataType === "Number"){
+                    if(setting.header[col].hasOwnProperty('tofix')){
+                        val =scMathUtil.roundToString(val,setting.header[col].tofix);
+                    }
                     if(setting.header[col].hasOwnProperty('decimalField')){
                         var decimal = getDecimal(setting.header[col].decimalField);
                         val =scMathUtil.roundToString(val,decimal);

+ 35 - 1
web/building_saas/main/html/main.html

@@ -5,7 +5,7 @@
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
-    <title>造价书-Smartcost</title>
+    <title>造价书-纵横云造价</title>
     <!-- inject:css -->
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/web/building_saas/css/main.css">
@@ -572,6 +572,40 @@
             </div>
         </div>
     </div>
+    <!--弹出 清单 计算基数-->
+    <div class="modal fade" id="qd-jsjs" data-backdrop="static">
+        <div class="modal-dialog" role="document">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">计算基础选择</h5>
+                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                        <span aria-hidden="true">&times;</span>
+                    </button>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group">
+                        <input class="form-control" value="分部分项工程费+100">
+                        <p class="form-text">
+                            <button class="btn btn-secondary btn-sm">+</button>
+                            <button class="btn btn-secondary btn-sm">-</button>
+                            <button class="btn btn-secondary btn-sm">*</button>
+                            <button class="btn btn-secondary btn-sm">/</button>
+                            <button class="btn btn-secondary btn-sm">(</button>
+                            <button class="btn btn-secondary btn-sm">)</button>
+                        </p>
+                    </div>
+                    <div class=" modal-auto-height" style="overflow: hidden" id="billsBaseSpread">
+                        <p></p>
+                        <p></p>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                    <a href="" class="btn btn-primary">确定</a>
+                </div>
+            </div>
+        </div>
+    </div>
         <!-- JS. -->
         <script type="text/javascript" src="/lib/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
 

+ 1 - 1
web/building_saas/main/js/controllers/project_controller.js

@@ -63,7 +63,7 @@ ProjectController = {
                     newSource = project.Ration.insertStdRation(selected.source.getID(), null, std);
                     project.ration_glj.addRationGLJ(newSource,std);
                 } else {
-                    newSource = project.Ration.insertRation(selected.source.getID());
+                    newSource = project.Ration.insertRation(selected.source.getID(),null, rationType);
                 }
 
                 newNode = project.mainTree.insert(selected.getID(), selected.tree.rootID());

+ 1 - 15
web/building_saas/main/js/models/bills.js

@@ -244,21 +244,7 @@ var Bills = {
             calcFees.setFee(node.data, field, newValue);
             let updateData = [];
             let data = {'ID': node.getID(), 'projectID': this.project.ID()};
-            if (field === 'quantity') {
-                data[field] = newValue;
-                data.isFromDetail=0;
-                // to do Calculate
-                if (node.data.fees) {
-                    data.fees = node.data.fees;
-                }
-            } else if (field === 'feesIndex.common.unitFee') {
-                // to do Calculate
-                if (node.data.fees) {
-                    data.fees = node.data.fees;
-                }
-            } else {
-                data[field] = newValue;
-            }
+            data[field] = newValue;
             updateData.push({'updateType': 'ut_update', 'updateData': tools.formatBillsUpdateData(data)});
             this.project.pushNow('updateBills', this.getSourceType(), updateData);
         };

+ 62 - 15
web/building_saas/main/js/models/calc_program.js

@@ -6,7 +6,7 @@
  *  用到费率的规则必须有feeRateID属性,当有该属性时,会自动显示费率值。
  */
 
-let defaultBillTemplate = {
+/*let defaultBillTemplate = {
     ID: 15,
     name: "清单公式",
     calcItems: [
@@ -98,7 +98,7 @@ let defaultBillTemplate = {
             memo: ''
         }
     ]
-};
+};*/
 
 const baseCalcType = {baseCalc: 0, adjustCalc: 1, budgetCalc: 2, diffCalc: 3,  offerCalc: 4};
 
@@ -434,7 +434,7 @@ class CalcProgram {
         me.calcBases = rationCalcBase;
         me.templates = this.project.calcProgram.datas.templates;
 
-        me.templates.push(defaultBillTemplate);
+        // me.templates.push(defaultBillTemplate);
         // 先编译公用的基础数据
         me.compilePublics();
         for (let t of me.templates){
@@ -595,7 +595,30 @@ class CalcProgram {
                treeNode.source.children.length === 0;
     };
 
-    // 仅内部调用。注意:外部不能直接使用,因为这里传入的树节点必须有一定的初始化。
+    isNullBill(treeNode){
+        let me = this;
+        return me.isLeafBill(treeNode) && (treeNode.children.length ===0) && (!treeNode.data.calcBase);
+    };
+
+    initFeeField(treeNode, fieldName){
+        if (!treeNode.data.fees) {
+            treeNode.data.fees = [];
+            treeNode.data.feesIndex = {};
+        };
+        if (!treeNode.data.feesIndex[fieldName]) {
+            let fee = {
+                'fieldName': fieldName,
+                'unitFee': 0,
+                'totalFee': 0,
+                'tenderUnitFee': 0,
+                'tenderTotalFee': 0
+            };
+            treeNode.data.fees.push(fee);
+            treeNode.data.feesIndex[fieldName] = fee;
+        };
+    };
+
+  // 仅内部调用。注意:外部不能直接使用,因为这里传入的树节点必须有一定的初始化。
     InnerCalc(treeNode){
         let me = this;
         let project = me.project;
@@ -657,10 +680,10 @@ class CalcProgram {
                     for (let item of objsArr) {
                         let data = item.data;
                         if (data.feesIndex && data.feesIndex[ft.type]) {
-                            buf = (buf + parseFloat(data.feesIndex[ft.type].unitFee)).toDecimal(decimalObj.process);
-                            btf = (btf + parseFloat(data.feesIndex[ft.type].totalFee)).toDecimal(decimalObj.process);
-                            btuf = (btuf + parseFloat(data.feesIndex[ft.type].tenderUnitFee)).toDecimal(decimalObj.process);
-                            bttf = (bttf + parseFloat(data.feesIndex[ft.type].tenderTotalFee)).toDecimal(decimalObj.process);
+                            buf = (buf + parseFloatPlus(data.feesIndex[ft.type].unitFee)).toDecimal(decimalObj.process);
+                            btf = (btf + parseFloatPlus(data.feesIndex[ft.type].totalFee)).toDecimal(decimalObj.process);
+                            btuf = (btuf + parseFloatPlus(data.feesIndex[ft.type].tenderUnitFee)).toDecimal(decimalObj.process);
+                            bttf = (bttf + parseFloatPlus(data.feesIndex[ft.type].tenderTotalFee)).toDecimal(decimalObj.process);
                         };
                     };
                 }
@@ -712,14 +735,35 @@ class CalcProgram {
             };
             treeNode.data.calcTemplate = {"calcItems": rst};
         }
+        else if (treeNode.calcType == treeNodeCalcType.ctCommonUnitFee){
+            delete treeNode.data.gljList;
+            if (treeNode.data.calcBase) treeNode.data.calcBase = null;  // 不能直接删除该属性,否则无法冲掉库中已存储的值
+            if (treeNode.data.programID) treeNode.data.programID = null;
+
+            let uf = (treeNode.data.feesIndex && treeNode.data.feesIndex.common && treeNode.data.feesIndex.common.unitFee) ? treeNode.data.feesIndex.common.unitFee : 0;
+            let tuf = (treeNode.data.feesIndex && treeNode.data.feesIndex.common && treeNode.data.feesIndex.common.tenderUnitFee) ? treeNode.data.feesIndex.common.tenderUnitFee : 0;
+            let q = treeNode.data.quantity ? treeNode.data.quantity : 0;
+            let tf = (uf * q).toDecimal(decimalObj.decimal('totalPrice', treeNode));
+            let ttf = (tuf * q).toDecimal(decimalObj.decimal('totalPrice', treeNode));
+
+            delete treeNode.data.fees;    // 直接删掉再新增,不用一个个费判断更新,效率更高。
+            delete treeNode.data.feesIndex;
+            me.initFeeField(treeNode, 'common');
+            treeNode.data.feesIndex.common.unitFee = uf;
+            treeNode.data.feesIndex.common.totalFee = tf;
+            treeNode.data.feesIndex.common.tenderUnitFee = tuf;
+            treeNode.data.feesIndex.common.tenderTotalFee = ttf;
+
+            treeNode.data.calcTemplate = {"calcItems": []};
+        }
         else{
             // 叶子清单的公式计算:使用缺省清单计算程序。需要提供总金额作为计算基数(不需要工料机),然后每条按比例(费率)计算,不需要工料机明细。
             if (treeNode.calcType == treeNodeCalcType.ctCalcBaseValue){
                 delete treeNode.data.gljList;
 
-                if (treeNode.data.programID == undefined){
+/*                if (treeNode.data.programID == undefined){
                     treeNode.data.programID = defaultBillTemplate.ID;
-                };
+                };*/
             }
             else if (treeNode.calcType == treeNodeCalcType.ctRationCalcProgram) {
                 if (treeNode.data.type == rationType.volumePrice){
@@ -743,7 +787,8 @@ class CalcProgram {
                 let rations = project.Ration.getBillsSortRation(treeNode.source.getID());
                 treeNode.data.gljList = project.ration_glj.getGatherGljArrByRations(rations);
 
-                if (treeNode.data.programID == undefined || treeNode.data.programID == defaultBillTemplate.ID){
+                // if (treeNode.data.programID == undefined || treeNode.data.programID == defaultBillTemplate.ID){
+                if (treeNode.data.programID == undefined){
                     treeNode.data.programID = projectInfoObj.projectInfo.property.engineering;
                 }
             };
@@ -781,17 +826,19 @@ class CalcProgram {
         let me = this;
         let isRation = treeNode.sourceType === me.project.Ration.getSourceType();
         let isBill = treeNode.sourceType === me.project.Bills.getSourceType();
-        let isBillPriceCalc = me.project.projSetting.billsCalcMode === leafBillGetFeeType.billsPrice;
-        let isLeafBill = me.isLeafBill(treeNode);
 
         if (isRation){
             treeNode.calcType = treeNodeCalcType.ctRationCalcProgram;
         }
-        else if (isLeafBill) {
+        else  if (me.isNullBill(treeNode)){
+            treeNode.calcType = treeNodeCalcType.ctCommonUnitFee;
+        }
+        else if (me.isLeafBill(treeNode)) {
             if (treeNode.children && treeNode.children.length > 0){
                 // me.calcLeafBillChildren(treeNode);
 
-                if (isBillPriceCalc)                        // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
+                // 清单单价计算模式下的叶子清单:取自己的计算程序ID,找到自己的计算程序计算。(汇总清单所有定额的工料机)
+                if (me.project.projSetting.billsCalcMode === leafBillGetFeeType.billsPrice)
                     treeNode.calcType = treeNodeCalcType.ctBillCalcProgram;
                 else                                        // 前三种计算模式下的叶子清单:汇总定额的计算程序的费用类别
                     treeNode.calcType = treeNodeCalcType.ctGatherRationsFees;

+ 7 - 6
web/building_saas/main/js/models/fee_rate.js

@@ -123,12 +123,13 @@ var FeeRate = {
                 rateIndex:params.sourceIndex,
                 rate:params.dataItem
             }
-            doc.rate.rate =doc.rate.rate.toDecimal(feeRate_consts.decimal);
+            doc.rate.rate =doc.rate.rate.toDecimal(getDecimal("feeRate"));
             this.updateFeeRate(query,doc);
             if(this.ifRateChange(params)){
                 //this.synchronizeFeeRate();
                 this.onFeeRateChange(params.dataItem.ID,params.dataItem.rate);
             }
+            $.bootstrapLoading.end();
         };
 
         FeeRate.prototype.batchUpdateFeeRate = function (items,feerate) {
@@ -211,7 +212,7 @@ var FeeRate = {
                     if(n.data.hasOwnProperty("feeRateID")&&n.data.feeRateID){
                         var rate = me.getFeeRateByID(n.data.feeRateID);
                         if(rate){
-                            n.data.feeRate=number_util.roundToString(rate.rate,feeRate_consts.decimal);
+                            n.data.feeRate=number_util.roundToString(rate.rate,getDecimal("feeRate"));
                             return true;
                         }else {
                             n.data.feeRate=null;
@@ -256,7 +257,7 @@ var FeeRate = {
         FeeRate.prototype.refreshBillsByRateID=function(rateID,value){
             var nodes = _.filter(projectObj.project.mainTree.items,function (n) {
                 if(n.sourceType==ModuleNames.bills&&n.data.feeRateID==rateID){
-                    n.data.feeRate=number_util.roundToString(value,feeRate_consts.decimal);
+                    n.data.feeRate=number_util.roundToString(value,getDecimal("feeRate"));
                     return true;
                 }else {
                     return false;
@@ -338,7 +339,7 @@ var FeeRate = {
         FeeRate.prototype.updateFeeRateFromBills=function(value,node){
             var me =this;
             if(node.sourceType === project.Bills.getSourceType()){
-                var value= number_util.checkNumberValue(value,feeRate_consts.decimal);
+                var value= number_util.checkNumberValue(value,getDecimal("feeRate"));
                 if(value){
                     var bill = node.data;
                     var rate =me.getFeeRateByID(bill.feeRateID);
@@ -359,7 +360,7 @@ var FeeRate = {
         };
 
         FeeRate.prototype.updateFeeRateFromCalc=function (value,editInfo) {
-            var value= number_util.checkNumberValue(value,feeRate_consts.decimal);
+            var value= number_util.checkNumberValue(value,getDecimal("feeRate"));
             if(value){
                 if(editInfo.calcItem.feeRateID){
                     var rate = projectObj.project.FeeRate.getFeeRateByID(editInfo.calcItem.feeRateID);
@@ -470,7 +471,7 @@ var FeeRate = {
             if(node.data.feeRateID){
                 var feeRate = this.getFeeRateByID(node.data.feeRateID);
                 if(feeRate){
-                    node.data.feeRate=number_util.roundToString(feeRate.rate,feeRate_consts.decimal);// parseFloat(feeRate.rate).toFixed(feeRate_consts.decimal);
+                    node.data.feeRate=number_util.roundToString(feeRate.rate,getDecimal("feeRate"));// parseFloat(feeRate.rate).toFixed(feeRate_consts.decimal);
                 }
             }
         };

+ 2 - 4
web/building_saas/main/js/models/main_consts.js

@@ -48,9 +48,6 @@ const gljType = {
     EQUIPMENT: 5
 };
 
-const feeRate_consts={
-    decimal:3
-};
 
 const CP_Col_Width = {          // 多处计算程序界面的列宽统一设置
     rowHeader: 30,
@@ -72,7 +69,8 @@ const treeNodeCalcType = {
     ctBillCalcProgram: 2,       // 汇总清单下所有定额的工料机
     ctGatherRationsFees: 3,     // 汇总定额的各个费
     ctGatherBillsFees: 4,       // 汇总清单的各个费
-    ctCalcBaseValue: 5
+    ctCalcBaseValue: 5,
+    ctCommonUnitFee: 6
 };
 
 const calcAllType = {

+ 1 - 1
web/building_saas/main/js/views/calc_program_manage.js

@@ -26,7 +26,7 @@ let rationPM = {
             {headerName:"费用代号",headerWidth:CP_Col_Width.code, dataCode:"code", dataType: "String"},
             {headerName:"费用名称",headerWidth:CP_Col_Width.name, dataCode:"name", dataType: "String"},
             {headerName:"计算基数",headerWidth:CP_Col_Width.dispExprUser, dataCode:"dispExprUser", dataType: "String"},
-            {headerName:"费率",headerWidth:CP_Col_Width.feeRate, dataCode:"feeRate", dataType: "Number",hAlign: "right",tofix: feeRate_consts.decimal},
+            {headerName:"费率",headerWidth:CP_Col_Width.feeRate, dataCode:"feeRate", dataType: "Number",hAlign: "right",decimalField:"feeRate"},
             {headerName:"费用类别",headerWidth:CP_Col_Width.displayFieldName, dataCode:"displayFieldName", dataType: "String", hAlign: "center"},
             {headerName:"基数说明",headerWidth:CP_Col_Width.statement, dataCode:"statement", dataType: "String"},
             {headerName:"备注",headerWidth:CP_Col_Width.memo, dataCode:"memo", dataType: "String"}

+ 9 - 7
web/building_saas/main/js/views/fee_rate_view.js

@@ -19,7 +19,7 @@ var feeRateObject={
     sheetSetting: {
         header: [
             {headerName: "专业名称", headerWidth: 200, dataCode: "name", dataType: "String"},
-            {headerName: "值%", headerWidth: 150, dataCode: "rate", dataType: "Number",hAlign: "right",tofix:feeRate_consts.decimal},
+            {headerName: "值%", headerWidth: 150, dataCode: "rate", dataType: "Number",hAlign: "right",decimalField:"feeRate"},
             {headerName: "备注", dataCode: "memo", dataType: "String"}
         ],
         view: {
@@ -39,7 +39,6 @@ var feeRateObject={
             id: 'rate',
             caption: '值%',
             dataField: 'rate',
-            format: '0.000',
             width: 120,
             minWidth: 50,
             allowEditing: true
@@ -113,7 +112,6 @@ var feeRateObject={
             if(!$('#cascadeSet').prop('checked')||params.hasOwnProperty('viewIndex')){
                 projectObj.project.FeeRate.updateFeeRateByEdit(params,feeRateObject.activateFeeRate);
             }
-
         }
     },
     createSheet:function(){
@@ -151,10 +149,12 @@ var feeRateObject={
             for (var row = 0; row < data.length; row++) {
                 var val = data[row][setting.header[col].dataCode];
                 if(val&&setting.header[col].dataType === "Number"){
-                    if(setting.header[col].hasOwnProperty('tofix')){
-                        val =parseFloat(val).toFixed(setting.header[col].tofix);
+                    if(setting.header[col].hasOwnProperty('decimalField')){
+                        var decimal = getDecimal(setting.header[col].decimalField);
+                        val =scMathUtil.roundToString(val,decimal);
+                        sheet.setFormatter(-1, col,getFormatter(decimal), GC.Spread.Sheets.SheetArea.viewport);
                     }else {
-                        val =parseFloat(val).toFixed(2);
+                        val =scMathUtil.roundToString(val,2);
                     }
                 }
                 sheet.setValue(row, col, val, ch);
@@ -358,6 +358,8 @@ var feeRateObject={
         }
         this.activateFeeRate = projectObj.project.FeeRate.getActivateFeeRate();
         this.datas = this.activateFeeRate.rates;
+        var rateColSetting = _.find(this.columns,{"id":"rate"});
+        rateColSetting?rateColSetting.format=getFormatter(getDecimal("feeRate")):"";
         this.mainViews = new GC.Spread.Views.DataView($('#divFee')[0],
             this.dataSource, this.columns, new GC.Spread.Views.Plugins.GridLayout(this.options));
         this.mainViews["rowClick"].addHandler(subRateObject.reFreshRateViews);
@@ -648,7 +650,7 @@ var feeRateObject={
        var selected = projectObj.project.mainTree.selected;
         projectObj.project.FeeRate.submitFeeRateFromBill(rate,selected.data,function (data) {
             selected.data.feeRateID=rate.ID.toString();
-            selected.data.feeRate=parseFloat(rate.rate).toFixed(feeRate_consts.decimal);
+            selected.data.feeRate=scMathUtil.roundToString(rate.rate,getDecimal("feeRate"));
             projectObj.mainController.refreshTreeNode([selected]);
             $("#fee_rate_tree").modal('hide');
         });

+ 46 - 11
web/building_saas/main/js/views/glj_view.js

@@ -18,10 +18,6 @@ var gljOprObj = {
     selectedGLJClass:null,
     parentNodeIds:{},
     activeTab:'#linkGLJ',
-    decimalSetting:{
-        marketPrice:2,
-        customQuantity:3
-    },
     setting: {
         header: [
             {headerName: "编码", headerWidth: 100, dataCode: "code", dataType: "String", formatter: "@"},
@@ -32,6 +28,7 @@ var gljOprObj = {
             {headerName: "定额消耗量", headerWidth: 80, dataCode: "rationItemQuantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},    // dataType: "Number", formatter: "0.00"
             {headerName: "自定义消耗量", headerWidth: 80, dataCode: "customQuantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},
             {headerName: "消耗量", headerWidth: 80, dataCode: "quantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},
+            {headerName: "总消耗量", headerWidth: 80, dataCode: "totalQuantity", dataType: "Number", hAlign: "right",decimalField:"glj.quantity"},
             {headerName: "基价单价", headerWidth: 80, dataCode: "basePrice", dataType: "Number", hAlign: "right",decimalField:"glj.unitPrice"},
             {headerName: "调整基价", headerWidth: 80, dataCode: "adjustPrice", dataType: "Number", hAlign: "right",decimalField:"glj.unitPrice"},
             {headerName: "市场单价", headerWidth: 80, dataCode: "marketPrice", dataType: "Number", hAlign: "right",decimalField:"glj.unitPrice"},
@@ -68,7 +65,7 @@ var gljOprObj = {
         header:[
             {headerName: "名称", headerWidth: 100, dataCode: "name", dataType: "String"},
             {headerName: "计算式", headerWidth: 120, dataCode: "regex", dataType: "String"},
-            {headerName: "结果(C)", headerWidth: 120, dataCode: "result", dataType: "Number",formatter:"0.0000",tofix:4},
+            {headerName: "结果(C)", headerWidth: 120, dataCode: "result", dataType: "Number",decimalField:"quantity_detail"},
             {headerName: "累加", headerWidth: 120, dataCode: "isSummation", dataType: "String",cellType:"checkBox"}
         ],
         view:{
@@ -541,6 +538,8 @@ var gljOprObj = {
      //   $('#dropdown').hide();
     },
     showRationGLJData:function (node) {
+        console.log("showRationGLJData");
+        console.log(+new Date());
         var gljList = [];
         var ration_glj = projectObj.project.ration_glj;
         node=node?node:projectObj.project.mainTree.selected;
@@ -551,12 +550,24 @@ var gljOprObj = {
         }
     },
     showRationGLJSheetData:function (init) {
-        this.sheet.getRange(0,-1,this.sheet.getRowCount(),-1).visible(true);
+        this.sheet.setRowCount(0);
+        console.log("showRationGLJSheetData---init")
+        console.log(+new Date())
+        //this.sheet.getRange(0,-1,this.sheet.getRowCount(),-1).visible(true); //这个方法导致加载缓慢
         this.sheetData=_.sortBy(this.sheetData,'type');
-        this.addMixRatioToShow();
+        console.log("addMixRatioToShow");
+        console.log(+new Date())
+        this.sumQuantity();//计算总消耗量
+        this.addMixRatioToShow();//显示组成物信息
+        console.log("start initRationTree");
+        console.log(+new Date());
         this.initRationTree(init);
-        sheetCommonObj.showData(this.sheet,this.setting,this.sheetData);
+        console.log("end initRationTree");
+        console.log(+new Date());
 
+        sheetCommonObj.showData(this.sheet,this.setting,this.sheetData);
+        console.log("end show");
+        console.log(+new Date())
     },
     initRationTree:function (init) {
         this.sheet.getRange(-1, 0, -1, 1).cellType(this.getTreeNodeCellType(this.sheetData));
@@ -569,7 +580,11 @@ var gljOprObj = {
                 }else {
                     collapsed = this.sheetData[i].collapsed==undefined?true:this.sheetData[i].collapsed;
                 }
-                this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).visible(!collapsed);// this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).locked(true);
+                if(collapsed==true){
+                    this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).visible(false);
+                }
+                //this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).visible(!collapsed);// this.sheet.getRange(i+1, -1, this.sheetData[i].subList.length, -1).locked(true);
+                //这个方法导致加载缓慢 试着在加载数据时隐藏行,看可不可行
             }
         }
     },
@@ -584,6 +599,25 @@ var gljOprObj = {
         this.sheetData=this.combineWithProjectGlj(gljList);
         this.showRationGLJSheetData(true);
     },
+    sumQuantity:function (node) {
+      if(this.sheetData.length>0){
+          node=node?node:projectObj.project.mainTree.selected;
+          let ration = node.data;
+          let quantity = ration.quantity;
+          quantity = (quantity==0||quantity==undefined||quantity==null||quantity=="")?1:quantity;
+          for(let glj of this.sheetData){
+              if(glj.isMixRatio==true){//如果是用于显示的组成物,则不用计算,跳过
+                  continue;
+              }
+              glj.totalQuantity = scMathUtil.roundToString(quantity*glj.quantity,getDecimal("glj.quantity"));
+              if(glj.hasOwnProperty('subList')){//需要计算glj下挂的组成物的总消耗量
+                  for(let subG of glj.subList){
+                      subG.totalQuantity = scMathUtil.roundToString(subG.rationItemQuantity*glj.totalQuantity,getDecimal("glj.quantity"));
+                  }
+              }
+          }
+      }
+    },
     addMixRatioToShow:function () {
         var newList=[];
         _.remove(this.sheetData,{'isMixRatio':true});
@@ -722,7 +756,8 @@ var gljOprObj = {
             if(args.editingText==null){
                 newval="";
             }else {
-                newval = number_util.checkNumberValue(args.editingText,this.decimalSetting[updateField]);
+                var decimal = updateField=='customQuantity'?getDecimal("glj.quantity"):getDecimal("glj.unitPrice");
+                newval = number_util.checkNumberValue(args.editingText,decimal);
                 if(newval==null){
                     me.sheet.getCell(args.row, args.col).value(recode[updateField]);
                     return;
@@ -1246,7 +1281,7 @@ $(function(){
 function getDecimal(fieldID,node) {
     if(node){
         return decimalObj.decimal(fieldID,node);
-    }else if(fieldID.indexOf(".")){
+    }else if(fieldID.indexOf(".")!=-1){
         var keyArray = fieldID.split(".");
         return decimalObj[keyArray[0]][keyArray[1]];
     }else {

+ 4 - 1
web/building_saas/main/js/views/main_tree_col.js

@@ -30,10 +30,10 @@ let MainTreeCol = {
         }
     },
     readOnly: {
+        // CSL, 2017-11-28
         subType: function (node){
             return (node.data.type != 2 && node.data.type != 3);
         },
-        // CSL, 2017-11-28
         calcProgramName: function (node) {
             if (
                 node.sourceType === projectObj.project.Ration.getSourceType() ||
@@ -41,6 +41,9 @@ let MainTreeCol = {
             ) return false
             else return true;
         },
+        commonUnitFee: function(node){
+            return !projectObj.project.calcProgram.isNullBill(node);
+        },
 
         bills: function (node) {
             return node.sourceType === projectObj.project.Bills.getSourceType();

+ 15 - 7
web/building_saas/main/js/views/project_view.js

@@ -119,7 +119,7 @@ var projectObj = {
         return value;
     },
     checkSpreadEditingText: function (editingText, colSetting) {
-        if (colSetting.data.field === 'quantity' || colSetting.data.field === 'feesIndex.common.unitFee') {
+        if (colSetting.data.field === 'quantity') {
             return this.checkFormulaValidField(editingText, colSetting);
         }
         else if (colSetting.data.field === 'programID') {
@@ -273,9 +273,10 @@ var projectObj = {
             else if(fieldName ==='feeRate'){
                 project.FeeRate.updateFeeRateFromBills(value,node,fieldName);
             }
-            else if (fieldName === 'quantity' || fieldName === 'marketUnitFee' || fieldName === 'programID' || fieldName === 'subType' || fieldName === 'calcBase'){
+            else if (fieldName === 'quantity' || fieldName === 'marketUnitFee' || fieldName === 'programID' ||
+                fieldName === 'subType' || fieldName === 'calcBase' || fieldName === 'feesIndex.common.unitFee'){
                 if (fieldName === 'quantity') {
-                    if (value) {value = value.toDecimal(decimalObj.decimal(fieldName,node))};
+                   if (value) {value = value.toDecimal(decimalObj.decimal(fieldName,node))};
                    if(project.quantity_detail.quantityEditChecking(value,node,fieldName)){
                        node.data.isFromDetail=0;
                        project.quantity_detail.cleanQuantityDetail(node,true);
@@ -283,16 +284,23 @@ var projectObj = {
                        projectObj.mainController.refreshTreeNode([node]);
                        return;
                    }
-                } else if (fieldName === 'marketUnitFee') {
+                }
+                else if (fieldName === 'marketUnitFee' || fieldName === 'feesIndex.common.unitFee') {
                     if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("unitPrice", node))};
-                } else if (fieldName === 'calcBase') {
+                }
+                else if (fieldName === 'calcBase') {
                     if (value) {value = parseFloat(value).toDecimal(decimalObj.decimal("totalPrice", node))};
                 };
 
                 node.changed = true;
-                node.data[fieldName] = value;
+                if (fieldName == 'feesIndex.common.unitFee'){
+                    project.calcProgram.initFeeField(node, 'common');
+                    node.data.feesIndex.common.unitFee = value;
+                }
+                else node.data[fieldName] = value;
                 project.calcProgram.calculate(node);
                 project.calcProgram.saveNode(node);
+                gljOprObj.showRationGLJSheetData();
             }
             else {
                 if (node.sourceType === project.Bills.getSourceType()) {
@@ -339,7 +347,7 @@ var projectObj = {
     checkMainSpread: function () {
         if (!this.mainSpread) {
             this.mainSpread = SheetDataHelper.createNewSpread($('#billsSpread')[0]);
-            this.mainSpread.getActiveSheet().selectionPolicy(GC.Spread.Sheets.SelectionPolicy.single);
+            this.mainSpread.getActiveSheet().selectionPolicy(GC.Spread.Sheets.SelectionPolicy.muliRange);
         }
     },
     refreshMainSpread: function () {

+ 1 - 1
web/building_saas/pm/html/project-management.html

@@ -5,7 +5,7 @@
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
-    <title>项目管理-Smartcost</title>
+    <title>项目管理-纵横云造价</title>
     <!-- inject:css -->
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/web/building_saas/css/main.css">

+ 1 - 1
web/users/html/login.html

@@ -4,7 +4,7 @@
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
     <meta http-equiv="x-ua-compatible" content="ie=edge">
-    <title>用户登录-Smartcost</title>
+    <title>用户登录-纵横云造价</title>
     <!-- inject:css -->
     <link rel="stylesheet" href="/lib/bootstrap/css/bootstrap.min.css">
     <link rel="stylesheet" href="/web/building_saas/css/main.css">