/**
 * 工料机汇总相关数据
 *
 * @author CaiAoLin
 * @date 2017/9/14
 * @version
 */
function ProjectGLJ() {
    this.datas = null;
    this.isLoading = false;
    this.quantityChangeMap=null;
    this.getRatioId = null;
}

/**
 * 加载数据
 *
 * @param {function} callback
 * @return {boolean}
 */
ProjectGLJ.prototype.loadData = function (callback = null,error=null) {
    let self = this;
    if (self.isLoading) {
        return false;
    }
    // 加载工料机数据
    $.ajax({
        url: '/glj/getData',
        type: 'post',
        dataType: 'json',
        data: {project_id: scUrlUtil.GetQueryString('project')},
        error: function () {
            // alert('数据传输错误');
            if(error) error();
        },
        beforeSend: function () {
            self.isLoading = true;
        },
        success: function (response) {
            self.isLoading = false;
            if (response.err === 1) {
                let msg = response.msg !== undefined && response.msg !== '' ? response.msg : '读取人材机数据失败!';
                alert(msg);
                if(error) error();
                return false;
            }
            self.refreshByDatas(response.data);
            // 回调函数
            if (callback !== null) {
                callback(response.data);
            }
            // 存入缓存
            projectObj.project.projectGLJ = self;
        }
    });
};

//更新项目工料机数据和缓存
ProjectGLJ.prototype.refreshByDatas = function(datas){
    this.datas = datas;
    this.calcQuantity();
};


ProjectGLJ.prototype.synLoadData = function () {
    return new Promise(function (resolve, reject) {
        projectObj.project.projectGLJ.loadData(function (data) {
            resolve(data)
        },function () {
            reject("获取工料机数据失败")
        })
    })
}

ProjectGLJ.prototype.loadToCache = function (data) {
    this.datas = data;
    projectObj.project.projectGLJ = this;
}


/**
 * 获取对应工料机数据
 *
 * @param {String} code
 * @return {Object}
 */
ProjectGLJ.prototype.getDataByID = function (ID) {//根据项目工料机ID取工料机信息
   return _.find(this.datas.gljList, {'id': ID});
};

// CSL, 2018-02-08 甲供、甲定。
ProjectGLJ.prototype.getGLJsBySupply = function (supplyTypeArr, gljTypeArr) {
    // 项目工料机采用了内部绑定数据源方式，能够双向同步，但同时带来难干预控制问题。supply值存在混杂情况，如：“2”和“部分甲供”同时存在。
    // 所以这里要合并处理。
    let mixSupply = [];
    for (let s of supplyTypeArr){
        switch (s) {
            case 1:
                mixSupply.push('部分甲供');
                break;
            case 2:
                mixSupply.push('完全甲供');
                break;
            case 3:
                mixSupply.push('甲定乙供');
                break;
            default:
                mixSupply.push('自行采购');
        }
    };
    mixSupply = mixSupply.concat(supplyTypeArr);

    return _.filter(this.datas.gljList, function (glj) {
        return mixSupply.includes(glj.supply) && gljTypeArr.includes(glj.type);
    });
};

ProjectGLJ.prototype.testGLJs = function () {
    let gljs = [];
    for (let glj of this.datas.gljList){
         let o = new Object();
         o.name = glj.name;
         o.supply = glj.supply;
         o.quantity = glj.quantity;
         o.supply_quantity = glj.supply_quantity;
         gljs.push(o);
    };
    return gljs;
};

/**
 * 修改工料机数据
 *
 * @param {Number} id
 * @param {Object} data
 * @return {boolean}
 */
ProjectGLJ.prototype.updateData = function (id, data) {
    let result = false;
    if (this.datas === null) {
        return result;
    }

    let gljList = this.datas.gljList;
    if (gljList === undefined) {
        return result;
    }

    // 查找对应的index
    let index = -1;
    for (let tmp in gljList) {
        if (gljList[tmp].id === id) {
            index = tmp;
            break;
        }
    }

    if (index < 0) {
        return result;
    }

    // 修改数据
    for (let tmpIndex in data) {
        if (tmpIndex.indexOf('_price') >= 0) {
            // 修改unit_price中的对象
            this.datas.gljList[index]['unit_price'][tmpIndex] = data[tmpIndex];
        } else {
            this.datas.gljList[index][tmpIndex] = data[tmpIndex];
        }
    }

};

/**
 * 加载缓存数据到spread
 *
 * @return {void}
 */
ProjectGLJ.prototype.loadCacheData = function (resort) {
    // 加载工料机数据
    let data = this.datas === null ? null : this.datas;
    if (data === null) {
        return;
    }
    jsonData = data.gljList !== undefined && data.gljList.length > 0 ? data.gljList : [];
    console.log("filter start");
    jsonData = filterProjectGLJ(jsonData);
    console.log("filter end");
    jsonData = sortProjectGLJ(jsonData);
    console.log("sort end");
    if(projectGLJSheet&&projectGLJSpread){
        setTimeout(spreadInit, 1);
         /*projectGLJSheet.setData(jsonData);
         projectGLJSpread.specialColumn(jsonData);*/
    }
};

ProjectGLJ.prototype.updatePriceFromRG = function (recode, updateField, newval,callback) {
    if (updateField == 'marketPrice') {
        this.updatePrice(recode, "market_price", newval,"rg",callback);
    }
    if (updateField == 'basePrice') {
        this.updatePrice(recode, "base_price", newval,"rg",callback);
    }
};

ProjectGLJ.prototype.updatePropertyFromMainSpread = function (node, updateField, newval,editingText) {
    if (updateField == "contain") {//更新含量和工程量时，要走定额更新的逻辑
        projectObj.project.Ration.updateContain(newval,node);
    }if(updateField == "quantity"){
        projectObj.project.quantity_detail.editMainTreeNodeQuantity(newval,node,updateField,editingText);
    } else {
        this.updateGLJProperty(node, updateField, newval);
    }
};


ProjectGLJ.prototype.updateGLJProperty = function (node, updateField, newval) {
    let rationTypeGLJ = node.data;
    let postData = {};
    if (rationTypeGLJ[updateField] == newval) {
        projectObj.mainController.refreshTreeNode([node]);
        return;
    }
    let data = {
        glj_id: rationTypeGLJ.GLJID,
        project_id: rationTypeGLJ.projectID,
        code: rationTypeGLJ.code,
        original_code: rationTypeGLJ.original_code,
        name: rationTypeGLJ.name,
        shortName: rationTypeGLJ.shortName,
        specs: rationTypeGLJ.specs,
        unit: rationTypeGLJ.unit,
        type: rationTypeGLJ.subType,
        type_of_work: rationTypeGLJ.subType,
        base_price: rationTypeGLJ.basePrice,
        market_price: rationTypeGLJ.basePrice,
        repositoryId: rationTypeGLJ.repositoryId,
        adjCoe: rationTypeGLJ.adjCoe,
        from: rationTypeGLJ.from ? rationTypeGLJ.from : 'std'//std:标准工料机库, cpt:补充工料机库
    };
    if (updateField == 'subType') {
        data.type = newval;
        data.type_of_work = newval;
        data.shortName = this.getShortNameByID(newval);
    } else {
        data[updateField] = newval;
    }
    postData.ration = {
        ID: rationTypeGLJ.ID,
        projectID: rationTypeGLJ.projectID
    };
    postData.updateData = data;
    $.bootstrapLoading.start();
    CommonAjax.post("/glj/modifyKeyValue", postData, function (result) {
        console.log(result);  //更新节点信息
        node.updateData[updateField] = newval;
        node.updateData.projectGLJID = result.id;
        node.updateData.code = result.code;
        node.updateData.basePrice = result.unit_price.base_price;
        node.updateData.marketUnitFee = result.unit_price.market_price;
        node.updateData.isAdd = result.unit_price.is_add;
        node.updateData.isEstimate = result.is_evaluate;
        node.updateData.shortName = result.unit_price.short_name;
        //触发计算并更新节点信息
        node.changed = true;
        projectObj.project.projectGLJ.loadData(function () {
            projectObj.project.calcProgram.calcAndSave(node);
            $.bootstrapLoading.end();
        });//重新加载项目工料机数据
        //上面两步都是异步操作，这句应该是要等上面两步做完了再执行的
    }, function (err) {
        $.bootstrapLoading.end();
    });

}

ProjectGLJ.prototype.getPriceDecimal = function (glj) {//价格的小数位数，有无组成物，取值不同
    if(gljUtil.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0){
         return getDecimal("glj.unitPriceHasMix");
    }else {
        return getDecimal('glj.unitPrice');
    }

};
ProjectGLJ.prototype.updateCalcMaterial =async function (projectGLJ,updateField,value,ext) {//只有添加、删除走这个方法
    let glj = _.find(this.datas.gljList,{'id':projectGLJ.id});
    if (glj) {
        if(glj.unit_price[updateField] == value){
            return;
        }
        if(updateField == 'calcMaterial'){
            ext=ext?ext:{};
            if(value == 1){//添加材料计算操作，把单位毛重/采购保管费率等数据复制一份
                ext['grossWeightCoe_n'] = glj.unit_price.grossWeightCoe;
                ext['purchaseStorageRate_n'] = glj.unit_price.purchaseStorageRate;
                ext['offSiteTransportLossRate_n'] = glj.unit_price.offSiteTransportLossRate;
                ext['handlingLossRate_n'] = glj.unit_price.handlingLossRate;
                ext['totalLoadingTimes'] = '1';
            }else if(value == 0){//删除操作，恢复单位毛重/采购保管费率等数据
                ext['supplyLocation'] = '';
                ext['originalPrice'] = '0';
                ext['unitFreight']='0';
                ext['totalLoadingTimes']='0';
                ext['offSiteTransportLoss']='0';
                ext['purchaseStorage']='0';
                ext['packageRecoverValue']='0';
            }
        }
        let data = {id: glj.unit_price.id,updateField:updateField ,value: value,unit_price_file_id:glj.unit_price.unit_price_file_id,ext:ext};
        $.bootstrapLoading.start();
        try {
            let result = await ajaxPost('/glj/updateCalcMaterial',data);
            glj.unit_price[updateField] = value;
            if(ext){
                for(let key in ext){
                    glj.unit_price[key] = ext[key];
                }
            }
            if(updateField == 'calcMaterial' && value ==0){///标记为0即删除材料计算标记，要删除其下挂的原价计算，运费计算，定额计算,消耗量重新计算
                let connect_key = gljUtil.getIndex(glj);
                _.remove(this.datas.originalList,{'connect_key':connect_key});
                _.remove(this.datas.freightList,{'connect_key':connect_key});
                this.calcQuantity();
                // to do 删除定额计算

            }
            projectGljObject.refreshDataSheet();
            materialCalcObj.showDatas();
        }catch (e){
            console.log(e)
        }finally {
            $.bootstrapLoading.end();
        }

    }
};

ProjectGLJ.prototype.calcAllMaterial = function (unitPriecs,needReCalc) {//当材料发生改变时重算所有计算材料的价格
    let priceMap = {};
    for(let unitPrice of unitPriecs){
        if(unitPrice && gljUtil.isDef(unitPrice.doc.market_price)) priceMap[unitPrice.projectGLJID] = unitPrice.doc.market_price;
    }
    let freightListMap =  _.groupBy(this.datas.freightList,'connect_key');//取运费计算项映射表
    let originalListMap = _.groupBy(this.datas.originalList,'connect_key');//取原价计算项映射表
    let sumFreightUpdateMap = {}; //存放所有材料下的运费更新信息;
    let sumOriginalUpdateMap = {};//存放所有材料下的原价更新信息;

    for(let g of this.datas.gljList){
        if(g.quantity !== 0 && g.quantity !== '0'  && g.unit_price.calcMaterial == 1&&!priceMap[g.id]){//工料机本身不包含在要计算的列表内
            //先判断要不要重算，只有包含相关工料机的定额的材料，才需要重新计算
            let fOrPDataMap = {};
            let tIndex = gljUtil.getIndex(g);
            //运费和原价中的工料机只要有一个包含该材料，就要重算
            if(freightListMap[tIndex]){ //运费重算
                let freightUpdateMap = {};
                for(let f of freightListMap[tIndex]){
                    if(f.conveyance != "自办运输") continue;//不是自办运输的不用管
                    let calf = ifNeedReCalc(f,priceMap,needReCalc);
                    if(calf){
                        let f_task = this.calcEachFreightOrPrice(f,"freight",priceMap);
                        if(f_task){
                            freightUpdateMap[f_task.ID] = f_task.doc;
                            sumFreightUpdateMap[f_task.ID] = f_task.doc;
                        }
                    }
                }
                if(!_.isEmpty(freightUpdateMap)) fOrPDataMap["freight"] = {update:freightUpdateMap};
            }
            //原价重算
            if(originalListMap[tIndex]){ //运费重算
                let originalUpdateMap = {};
                for(let o of originalListMap[tIndex]){
                    let calo = ifNeedReCalc(o,priceMap,needReCalc);
                    if(calo){
                        let o_task = this.calcEachFreightOrPrice(o,"price",priceMap);
                        if(o_task){
                            originalUpdateMap[o_task.ID] = o_task.doc;
                            sumOriginalUpdateMap[o_task.ID] = o_task.doc;
                        }
                    }
                }
                if(!_.isEmpty(originalUpdateMap)) fOrPDataMap["price"] = {update:originalUpdateMap};
            }
            //判断映射表是否为空，如果为空则说明不用计算
            if(!_.isEmpty(fOrPDataMap)){
                let t_unipPrice = this.materialCal(g.id,fOrPDataMap,g,freightListMap[tIndex],originalListMap[tIndex]);
                if(t_unipPrice && !_.isEmpty(t_unipPrice.doc)) unitPriecs.push(t_unipPrice);
            }
        }
    }
    let sumUpdateMap = {};
    if(!_.isEmpty(sumFreightUpdateMap))sumUpdateMap["freight"] = {update:sumFreightUpdateMap};
    if(!_.isEmpty(sumOriginalUpdateMap))sumUpdateMap["price"] = {update:sumOriginalUpdateMap};
    let ext = {};
    for(let u of unitPriecs){//计算受影响的综合电价
        ext[u.projectGLJID] = {marketPrice:u.doc.market_price}; //priceMap[unitPrice.projectGLJID] = unitPrice.doc.market_price;
    }
    let elecu = electrovalenceObj.clacNewElecPrice(ext);
    if(elecu) unitPriecs.push(elecu);

    return [unitPriecs,sumUpdateMap];


    function ifNeedReCalc(obj,IDMap,needReCalc = false) {
        let calcf = false;
        if(needReCalc == true) return true;//如果是通过修改费率等地方触发的，默认自动计算
        if(obj.ration_gljs){
            for(let rg of  obj.ration_gljs){
                if(IDMap[rg.projectGLJID]){//判断是否关联了该项目工料机
                    calcf = true;
                    break;
                }
            }
        }
        return calcf;
    }

};


ProjectGLJ.prototype.materialCal = function (id,dataMap,tglj,tfreightList,tpriceList) {
    let unitPriceHasMix = getDecimal("glj.unitPriceHasMix");
    let unitPirceDecimal = getDecimal("glj.unitPrice");
    let process = getDecimal("process");
    let glj = tglj?tglj: _.find(this.datas.gljList,{'id':id});
    let doc = dataMap['material']&&dataMap['material']['update']?dataMap['material']['update']:{};//材料的update结构不同，不用ID做key
    if(!glj) return;
    let unitPrice = {projectGLJID:glj.id,id:glj.unit_price.id,'unit_price_file_id':glj.unit_price.unit_price_file_id,doc:{}};
    //先计算原价
    let [originalPrice,supplyLocation,priceHeightFee] = this.priceCalc(glj,dataMap,tpriceList);
    doc['originalPrice'] = originalPrice+'';
    doc['supplyLocation'] = supplyLocation;
    doc['priceHeightFee'] = priceHeightFee;
    //再计算运费
    let grossWeightCoe_n = doc['grossWeightCoe_n']?doc['grossWeightCoe_n']:glj.unit_price.grossWeightCoe_n;
    grossWeightCoe_n = scMathUtil.roundForObj(grossWeightCoe_n,process);
    let [unitFreight,freightHeightFee] = this.freightCalc(glj,grossWeightCoe_n,dataMap,tfreightList);
    doc['unitFreight'] = unitFreight+'';
    doc['freightHeightFee'] = freightHeightFee+'';
    //计算场外运输损耗
    let sum_o_f = scMathUtil.roundForObj(originalPrice+unitFreight,process);//(原价+单位运费)
    let totalLoadingTimes = doc["totalLoadingTimes"]?doc["totalLoadingTimes"]:glj.unit_price.totalLoadingTimes;//装卸总次数
    let handlingLossRate_n = doc["handlingLossRate_n"]?doc["handlingLossRate_n"]:glj.unit_price.handlingLossRate_n;//每增加一次装卸损耗率%
    let offSiteTransportLossRate_n = doc["offSiteTransportLossRate_n"]?doc["offSiteTransportLossRate_n"]:glj.unit_price.offSiteTransportLossRate_n;//场外运输损耗率
    handlingLossRate_n = scMathUtil.roundForObj(handlingLossRate_n,unitPirceDecimal)/100;
    offSiteTransportLossRate_n = scMathUtil.roundForObj(offSiteTransportLossRate_n,unitPirceDecimal)/100;
    totalLoadingTimes = scMathUtil.roundForObj(totalLoadingTimes,unitPirceDecimal) - 1;//(装卸总次数-1)
    totalLoadingTimes = totalLoadingTimes < 0 ?0:totalLoadingTimes;//(装卸总次数-1) 结果小于0的时候，值设为0
    totalLoadingTimes = scMathUtil.roundForObj(totalLoadingTimes * handlingLossRate_n,process);//(装卸总次数-1)*每增加一次装卸损耗率%
    totalLoadingTimes = scMathUtil.roundForObj(totalLoadingTimes + offSiteTransportLossRate_n,process);//(装卸总次数-1)*每增加一次装卸损耗率%+场外运输损耗率%
    let offSiteTransportLoss = scMathUtil.roundForObj(sum_o_f*totalLoadingTimes,unitPirceDecimal); //场外运输损耗=(原价+单位运费)*((装卸总次数-1)*每增加一次装卸损耗率%+场外运输损耗率%)。
    doc['offSiteTransportLoss'] = offSiteTransportLoss+'';
    //计算采购及保管费
    let purchaseStorageRate_n =  doc["purchaseStorageRate_n"]?doc["purchaseStorageRate_n"]:glj.unit_price.purchaseStorageRate_n;//采购及保管费率%
    purchaseStorageRate_n = scMathUtil.roundForObj(purchaseStorageRate_n,unitPirceDecimal)/100;
    let purchaseStorage = scMathUtil.roundForObj(sum_o_f + offSiteTransportLoss,process)//(原价+单位运费+场外运输损耗)
    purchaseStorage = scMathUtil.roundForObj(purchaseStorage*purchaseStorageRate_n,unitPirceDecimal)//采购及保管费=(原价+单位运费+场外运输损耗)* 采购及保管费率%。
    doc['purchaseStorage'] = purchaseStorage+'';
    //再计算预算价
    let packageRecoverValue = doc['packageRecoverValue']?doc['packageRecoverValue']:glj.unit_price.packageRecoverValue;//包装品回收价值。
    packageRecoverValue = scMathUtil.roundForObj(packageRecoverValue,unitPirceDecimal);
    let market_price = scMathUtil.roundForObj(sum_o_f+offSiteTransportLoss,process);//原价+单位运费+场外运输损耗
    market_price = scMathUtil.roundForObj(market_price+purchaseStorage,process);//原价+单位运费+场外运输损耗+采购及保管费
    market_price = scMathUtil.roundForObj(market_price - packageRecoverValue,unitPriceHasMix)//预算价=原价+单位运费+场外运输损耗+采购及保管费-包装品回收价值。
    if(market_price>0) doc['market_price'] = market_price+'';//单机版预算价小于等于0的时候不更新
    let o_unit = glj.unit_price;
    for(let key in doc){
        if(o_unit[key]  == doc[key]) continue; //忽略一样的值
        unitPrice.doc[key] = doc[key];
    }
    return unitPrice
};

ProjectGLJ.prototype.freightCalc= function (glj,grossWeightCoe_n,dataMap,tfreightList) {
    let process = getDecimal("process");
    let unitPirce = getDecimal("glj.unitPrice");
    let unitPriceHasMix = getDecimal("glj.unitPriceHasMix");//这里暂时没用到
    let sum = 0;
    let height_sum=0;
    let freightList = tfreightList?tfreightList:_.filter(this.datas.freightList,{"connect_key":gljUtil.getIndex(glj)});
    if(dataMap["freight"] && dataMap["freight"]["add"])  freightList = freightList.concat(dataMap["freight"]["add"]); //把添加的加进去
    for(let f of freightList){
        let unitFreight = f.unitFreight,kmDistance = f.kmDistance,freightIncreaseRate = f.freightIncreaseRate,unitLoadingFee= f.unitLoadingFee,loadingTimes = f.loadingTimes,otherFee = f.otherFee,weightCoe = f.weightCoe,conveyance = f.conveyance,calcType=f.calcType,materialType=f.materialType;
        let heightFee= f.heightFee?f.heightFee:0;  
        if(dataMap["freight"] && dataMap["freight"]["update"]){//覆盖更新的数据
            let t = dataMap["freight"]["update"][f.ID];
            if(t){
                if(t['unitFreight']) unitFreight = t['unitFreight'];
                if(t['kmDistance']) kmDistance = t['kmDistance'];
                if(t['freightIncreaseRate']) freightIncreaseRate = t['freightIncreaseRate'];
                if(t['unitLoadingFee']) unitLoadingFee = t['unitLoadingFee'];
                if(t['loadingTimes']) loadingTimes = t['loadingTimes'];
                if(t['otherFee']) otherFee = t['otherFee'];
                if(t['weightCoe']) weightCoe = t['weightCoe'];
                if(t['conveyance']) conveyance = t['conveyance'];
                if(t['calcType']) calcType = t['calcType'];
                if(t['materialType']) materialType = t['materialType'];
                if(t['heightFee']) heightFee = t['heightFee'];
            }
        }
        if(dataMap["freight"] && dataMap["freight"]["delete"]){//忽略删除的数据
            if(dataMap["freight"]["delete"][f.ID]) continue;
        }
        //开始计算
        freightIncreaseRate = scMathUtil.roundForObj(freightIncreaseRate,unitPirce);
        freightIncreaseRate = scMathUtil.roundForObj(1+freightIncreaseRate/100,process);//(1+运距增加率%)
        unitFreight = scMathUtil.roundForObj(unitFreight,unitPirce);
        kmDistance = scMathUtil.roundForObj(kmDistance,unitPirce);
        heightFee = scMathUtil.roundForObj(heightFee,unitPirce);

        let t = getPrice(unitFreight,kmDistance,conveyance,calcType,materialType,process);//单位运价×km运距
        t = scMathUtil.roundForObj(t*freightIncreaseRate,process);//单位运价×km运距×(1+运距增加率%)
        unitLoadingFee = scMathUtil.roundForObj(unitLoadingFee,unitPirce);
        loadingTimes = scMathUtil.roundForObj(loadingTimes,unitPirce);
        let s = scMathUtil.roundForObj(unitLoadingFee*loadingTimes,process);//装卸费单价×装卸次数
        t = scMathUtil.roundForObj(t + s,process);//单位运价×km运距×(1+运距增加率%)+装卸费单价×装卸次数
        if(gljUtil.isDef(materialType)&&materialType != "") t = scMathUtil.roundForObj(t/1.09,process);  //内蒙古要除以税率1.09; 当材料类型有值时，说明是内蒙古计算
        otherFee = scMathUtil.roundForObj(otherFee,unitPirce);
        t = scMathUtil.roundForObj(t+otherFee,process);//单位运价×km运距×(1+运距增加率%)+装卸费单价×装卸次数+其它费用
        if(conveyance !== "自办运输") t = scMathUtil.roundForObj(t*grossWeightCoe_n,process); //(单位运价×km运距×(1+运距增加率%)+装卸费单价×装卸次数+其它费用)×单位毛重”。 单位毛重:毛重系数
        weightCoe = scMathUtil.roundForObj(weightCoe,unitPirce);
        t = scMathUtil.roundForObj(t*weightCoe,process);//(单位运价×km运距×(1+运距增加率%)+装卸费单价×装卸次数+其它费用)×单位毛重×加权系数
        sum = scMathUtil.roundForObj(sum + t,process);
        heightFee = scMathUtil.roundForObj(heightFee*weightCoe,process);
        height_sum = scMathUtil.roundForObj(height_sum + heightFee,process);
    }
    if(freightList.length == 0){//如果运费计算表没有数据，则读取输入的或单价文件的值
        let doc = dataMap['material']&&dataMap['material']['update']?dataMap['material']['update']:{};
        sum = doc['unitFreight']?doc['unitFreight']:glj.unit_price.unitFreight;
    }
    return [scMathUtil.roundForObj(sum,unitPirce),scMathUtil.roundForObj(height_sum,unitPirce)];


    function getPrice(unitFreight,kmDistance,conveyance,calcType,materialType,process){
        if(gljUtil.isDef(materialType)&&materialType != "") return materialCalcObj.calNeiMengTotalFreight(kmDistance,materialType);
        //如果运输方式为自办运输，则直接返回单位运价即可;
        let price = conveyance == "自办运输" ? scMathUtil.roundForObj(unitFreight,process):scMathUtil.roundForObj(unitFreight * kmDistance,process);//单位运价×km运距
        return price
    }


};

ProjectGLJ.prototype.priceCalc = function (glj,dataMap,tpriceList) {
    let process = getDecimal("process");
    let unitPirce = getDecimal("glj.unitPrice");
    let unitPriceHasMix = getDecimal("glj.unitPriceHasMix");
    let original_price = 0;
    let sumFeightFee = 0;
    let supplyList = [];
    let supplyLocation = "";
    let priceList = tpriceList?tpriceList:_.filter(this.datas.originalList,{"connect_key":gljUtil.getIndex(glj)});
    if(dataMap["price"] && dataMap["price"]["add"])  priceList = priceList.concat(dataMap["price"]["add"]); //把添加的加进去
    for(let p of priceList){
        let supplyPrice = p.supplyPrice ,coe = p.coe,supplyLocation=p.supplyLocation;
        let heightFee = p.heightFee?p.heightFee:0;
        if(dataMap["price"] && dataMap["price"]["update"]){//覆盖更新的数据
            let t = dataMap["price"]["update"][p.ID];
            if(t && t["supplyPrice"]) supplyPrice =t["supplyPrice"];
            if(t && t["coe"]) coe =t["coe"];
            if(t && t["supplyLocation"]) supplyLocation = t["supplyLocation"];
            if(t && t["heightFee"]) heightFee = t["heightFee"];
        }
        if(dataMap["price"] && dataMap["price"]["delete"]){//忽略删除的数据
            if(dataMap["price"]["delete"][p.ID]) continue;
        }
        supplyPrice = scMathUtil.roundForObj(supplyPrice,unitPirce);
        coe = scMathUtil.roundForObj(coe,unitPirce);
        heightFee = scMathUtil.roundForObj(heightFee,unitPirce);
        let t_p = scMathUtil.roundForObj(supplyPrice *  coe,process);
        let t_h = scMathUtil.roundForObj(heightFee *  coe,process);
        original_price=scMathUtil.roundForObj(original_price+t_p,process);
        sumFeightFee = scMathUtil.roundForObj(sumFeightFee+t_h,process);
        supplyList.push(supplyLocation);
    }
    supplyLocation = supplyList.join(',');
    if(priceList.length == 0){//如果原价计算表没有数据，则读取输入的或单价文件的值
        let doc = dataMap['material']&&dataMap['material']['update']?dataMap['material']['update']:{};
        original_price = doc['originalPrice']!==undefined?doc['originalPrice']:glj.unit_price.originalPrice;
        supplyLocation = doc['supplyLocation']!==undefined?doc['supplyLocation']:glj.unit_price.supplyLocation;
    }
    return [scMathUtil.roundForObj(original_price,unitPriceHasMix),supplyLocation,scMathUtil.roundForObj(sumFeightFee,unitPirce)];
};


ProjectGLJ.prototype.m_updateUnitPrice = function (datas,isFromFeeRate) {//批量更新
    let me = this;
    let gljList = [];
    for(let d of datas){
        let g = updateUnit(d.projectGLJID,d);
        if(g) gljList.push(g);
    }
    if(isFromFeeRate == false)this.calcQuantity();
    //刷新项目工料机表显示
    projectGljObject.refreshDataSheet();
    //重新计算相关节点

    /*  2019-10-29  这里改成修改材料计算后先不自动计算，先在项目属性上做标记，切换到其它标签页时才做自动计算

        let nodes = me.getImpactRationNodes(gljList);//取到因为改变工料机价格而受影响的定额
        projectObj.project.calcProgram.calcNodesAndSave(nodes);//触发计算程序

    */

    //刷新定额工料机
    gljOprObj.refreshView();
    //socket推送更新信息
    projectGljObject.onUnitFileChange(isFromFeeRate?false:true);//如果是从更新费率过来的，不用在项目属性上做标记，费率那里已经自动计算所有节点了

    return gljList

    function updateUnit(id,unitPrice) {
        let glj = _.find(me.datas.gljList,{'id':id});
        if(glj && !_.isEmpty(unitPrice.doc)){
            for(let key in unitPrice.doc){
                glj.unit_price[key] = unitPrice.doc[key];
            }
        }
        return glj;
    }
};

ProjectGLJ.prototype.updateUnitPrice = function(id,unitPrice){
    this.m_updateUnitPrice([unitPrice]);
};

ProjectGLJ.prototype.addPriceCalc = async function (datas,pgljID) {
    await this.updateMaterialCalcTasks(pgljID,datas,"add","price");
};

ProjectGLJ.prototype.updateMaterialCalc = async function (datas) {
    let updateDatas=[];
    try {
        for(let d of datas){
            let unitPrice = this.materialCal(d.id,{material:{update:d.doc}});
            if(_.isEmpty(unitPrice.doc)) continue;
            updateDatas.push(unitPrice);
        }
        if(updateDatas.length ==0 ) return;
        let [unitPrices,sumMap] = this.calcAllMaterial(updateDatas);
        sumMap = {"unitPrice":unitPrices};
        $.bootstrapLoading.start();
        let result =  await ajaxPost('/glj/updateMaterialCalcTasks',sumMap);
        this.refreshMaterialCalcCache(sumMap);
        materialCalcObj.showDatas();
    }catch (e){
        console.log(e)
    }finally {
        $.bootstrapLoading.end();
    }

};

ProjectGLJ.prototype.updateMaterialCalcTasks =async function(pgljID,dataMap,actionType,model){
    //为了统一接口， 参数dataMap 在添加操作时是一个数组，在修改的时候是一个ID - doc 映射表;
    try {
        let actionMap={};
        let calMap = {};
        actionMap[actionType] = dataMap;
        calMap[model] = actionMap;//{freight:{update:updateMap}
        let unitPrice = this.materialCal(pgljID,calMap);//计算当前这一条材料
        let [unitPrices,sumMap] = this.calcAllMaterial([unitPrice]);//计算完一条材料后，还要计算因为这条材料而受影响的其它所有材料
        if(actionType == "update") {//更新情况
            if (sumMap[model] && sumMap[model][actionType]) {//这一步，合并需要提交后台修改的数据
                let tt = sumMap[model][actionType];
                for(let key in dataMap) {
                  tt[key] = dataMap[key];
                }
            } else {
                sumMap[model] = actionMap;
            }
        }else {
            sumMap[model] = actionMap;
        }
        sumMap["unitPrice"] = unitPrices;

        $.bootstrapLoading.start();
        let result = await ajaxPost('/glj/updateMaterialCalcTasks',sumMap);
        this.refreshMaterialCalcCache(sumMap);
        materialCalcObj.showDatas();
    }catch (e){
        console.log(e)
    }finally {
        $.bootstrapLoading.end();
    }
};

ProjectGLJ.prototype.updateUserFreight =async function (data) {
    try {
        $.bootstrapLoading.start();
        let result = await ajaxPost('/glj/updateUserFreight',data);
        if(data.action == "add"){
            for(let f of data.freights){
                materialCalcObj.userFreightList.push(f);
            }
        }
        if(data.action == "update"){
            for(let u of materialCalcObj.userFreightList){
                if(u.ID == data.ID){
                    gljUtil.updateProperty(u,data.doc);
                }
            }
        }
        materialCalcObj.showFreightDatas();
    }catch (e){
        console.log(e)
    }finally {
        $.bootstrapLoading.end();
    }
};

ProjectGLJ.prototype.getUserFreights = async function () {//初始化车船税选择
    try {
        let result =  await ajaxGet("/glj/getUserFreights");
        return result;
    }catch (e){
        console.log(e)
    }
};

ProjectGLJ.prototype.refreshEctrovalenceCache = function (updateMap) {
    let elec = updateMap["electrovalence"];
    if(elec){
        let actionType = elec.actionType;
        if(actionType == "add"){
            projectObj.project.projectGLJ.datas.com_electrovalence = elec.doc;
        }else if(actionType == "update"){
            projectObj.project.projectGLJ.datas.com_electrovalence.gljList = elec.doc.gljList;
        }
    }

    if(updateMap["unitPrice"]) {
        if(Array.isArray(updateMap["unitPrice"])){
            this.m_updateUnitPrice(updateMap["unitPrice"]);
        }else {
            this.m_updateUnitPrice([updateMap["unitPrice"]]);
        }
    }
};


ProjectGLJ.prototype.refreshMaterialCalcCache = function (updateMap,isFromFeeRate = false){//从费率计算过来的时候，费率那里已经做了自动计算所有节点了
  let gljList = []; 
  if(updateMap["freight"]) updateList(this.datas.freightList,updateMap["freight"]);
   if(updateMap["price"]) updateList(this.datas.originalList,updateMap["price"]);
   if(updateMap["unitPrice"]) {
      if(Array.isArray(updateMap["unitPrice"])){
        gljList =  this.m_updateUnitPrice(updateMap["unitPrice"],isFromFeeRate);
      }else {
        gljList =  this.m_updateUnitPrice([updateMap["unitPrice"]],isFromFeeRate);
      }
   }
   return gljList;

    function updateList(list,updateMap) {
       if(updateMap["update"]){
           let map = updateMap["update"];
           for(let o of list){
               if(map[o.ID]){
                   gljUtil.updateProperty(o,map[o.ID]);
               }
           }
       }

       if(updateMap["add"]){
           for(let a of updateMap["add"]){
               list.push(a);
           }
       }

       if(updateMap["delete"]){
           for(let ID in updateMap["delete"]){
               _.remove(list,{'ID':ID});
           }
       }
    }
};



ProjectGLJ.prototype.updatePriceCalc = async function (datas,pgljID) {
    let updateMap = {};
    for(let d of datas){
        updateMap[d.ID] = d.doc;
    }
    await this.updateMaterialCalcTasks(pgljID,updateMap,"update","price");
};


ProjectGLJ.prototype.addFreightCalc = async function (datas,pgljID) {
    await this.updateMaterialCalcTasks(pgljID,datas,"add","freight");
};

ProjectGLJ.prototype.updateFreightCalc = async function (datas,pgljID){
    let updateMap = {};
    for(let d of datas){
        updateMap[d.ID] = d.doc;
    }
    await this.updateMaterialCalcTasks(pgljID,updateMap,"update","freight");
};


ProjectGLJ.prototype.addMaterialRation = async function (code,type,parentID,connect_key){
        let libIDs = rationLibObj.getStdRationLibIDs();
        let defaultLibID = rationLibObj.getDefaultStdRationLibID();
        let selectedLib =  sessionStorage.getItem("stdRationLib");
        selectedLib&&selectedLib!='undefined'?libIDs.unshift(selectedLib):libIDs.unshift(defaultLibID);
        let datas = {userID: userID,defaultLibID:defaultLibID, rationRepIds: libIDs, code: code,type:type,parentID:parentID,quantityDecimal:getDecimal("ration.quantity"),connect_key:connect_key,projectID:projectObj.project.ID()};
        datas.actionType="add";
        await this.updateMaterialRation(datas);
};

ProjectGLJ.prototype.changeAssistProductionFeeRate = async function (newFeeRate) {
    $.bootstrapLoading.start();
    try {
        await ajaxPost("/glj/changeAssistProductionFeeRate",{unitFileID:projectObj.project.property.unitPriceFile.id,assistProductionFeeRate:newFeeRate});
        this.datas.constData.assistProductionFeeRate = newFeeRate;
        //todo  调用材料计算方法，所有材料重算一遍
        let [unitPrices,sumMap] = this.calcAllMaterial([],true);
        sumMap["unitPrice"] = unitPrices;
        let result = await ajaxPost('/glj/updateMaterialCalcTasks',sumMap);
        this.refreshMaterialCalcCache(sumMap);
        materialCalcObj.showDatas();
    }catch (err){
        console.log(err);
    }finally {
        $.bootstrapLoading.end();
    }
};

ProjectGLJ.prototype.calcAllMaterialWhenChange = async function(){//当费率单价等改变时，重新计算所有材料  返回价格有变化的项目工料机
  let gljList = [];
  try {
    let [unitPrices,sumMap] = this.calcAllMaterial([],true);
    if(unitPrices.length > 0){
      sumMap["unitPrice"] = unitPrices;
      let result = await ajaxPost('/glj/updateMaterialCalcTasks',sumMap);
      gljList = this.refreshMaterialCalcCache(sumMap,true);
      materialCalcObj.showDatas(); 
    }
  }catch (err){
      console.log(err);
  }
  return gljList
}

ProjectGLJ.prototype.loadFreightAndOriginalData = function(originalList,freightList){
  if(freightList) this.datas.freightList = freightList;
  if(originalList) this.datas.originalList = originalList;
};

ProjectGLJ.prototype.updateMaterialRation = async function (datas){
    try {
        let lists = datas.type == "freight"?this.datas.freightList:this.datas.originalList;
        $.bootstrapLoading.start();
        let result =  await ajaxPost('/ration/updateMaterialRation',datas);
        if(datas.actionType=="add" && result.projectGLJList){
          this.loadNewProjectGLJToCaches(result.projectGLJList,true);
          this.loadFreightAndOriginalData(result.originalList,result.freightList);  //这一步已经更新了运费和原价数据
        } 
        if(datas.actionType == "delete"){
           let parent = _.find(lists,{ID:datas.parentID}) ;
           if(parent){
               _.remove(parent.rations,{ID:datas.rationID});
               _.remove(parent.ration_gljs,{rationID:datas.rationID});
           }
        }
        if(datas.actionType == "update"){
            let parent = _.find(lists,{ID:datas.parentID}) ;
            let ration = parent?_.find(parent.rations,{ID:datas.rationID}):null;
            if(ration){
                if(datas.field == "code" && result.projectGLJList){
                    this.loadNewProjectGLJToCaches(result.projectGLJList,true);
                    this.loadFreightAndOriginalData(result.originalList,result.freightList); 
                }else {
                    ration[datas.field] = datas.value;
                    if(datas.ext){
                        for(let key in datas.ext){
                            ration[key] = datas.ext[key];
                        }
                    }
                }
                if(datas.ration_gljs){//更新定额工料机数量
                    let gljMap = _.indexBy(parent.ration_gljs,"ID");
                    for(let g of datas.ration_gljs){
                        if(gljMap[g.ID]) gljMap[g.ID].quantity = g.quantity;
                    }
                }
            }
        }
    }catch (e){
        console.log(e)
    }finally {
       //materialCalcObj.showDatas();
        this.calcMaterialRation(datas.parentID,datas.type);
        $.bootstrapLoading.end();
    }
};

ProjectGLJ.prototype.getHighlandFee = function (feeType) {
    let rates = projectObj.project.FeeRate.getActivateFeeRate().rates;
    let matchType = false;
    let rate = 0;
    //获取高原取费类别，是先按feeType取顶层的费率，然后取子项中的“高原地区施工增加费”
    if(!feeType||feeType=="") return 0;//空时为0
    let hightlandRate = null;
    let topParentID = null;
    for(let r of rates){//费率是按顺序排的，所以先取到顶层，之后的就是目标了。
        if(matchType && r.ParentID == topParentID) break; //如果feeType已经匹配过了，又经过了下一个顶层节点，那说明该feeType下没有高原费率
        if(r.name == feeType){
            matchType = true;
            topParentID = r.ParentID;
        }
        if(matchType && r.name == "高原地区施工增加费"){
            //顶层先匹配上了，第一个就是要找的费率
            hightlandRate = r;
            break;
        }
    }
    if(hightlandRate){
        rate = scMathUtil.roundForObj(hightlandRate.rate,getDecimal("feeRate"));
    }
    return rate*0.01
};

ProjectGLJ.prototype.calcEachFreightOrPrice = function (temp,type,priceMap,needUpdate=false) {//
    if(temp){
         if(type == "freight" && temp.conveyance !="自办运输") return null;
        let sum =0;
        let heightFee = 0;
        let gljMap = {};
        let expList = [];
        let decimal = type == "freight"?getDecimal("glj.unitPrice"):getDecimal("glj.unitPriceHasMix");
        //因为材料计算的数据是保存在单价文件里的，有可能存在共享的情况，这样的话就不能用单价文件里的项目工料机ID来匹配，要用5大项匹配
        let pgljMap = {};
        if(needUpdate==false && (!temp.rations || temp.rations.length == 0))return null;//没有定额时不计算
        for(let pg of this.datas.gljList){
            pgljMap[gljUtil.getIndex(pg)] = pg
        }
        if(temp.ration_gljs){
            for(let g of temp.ration_gljs){
                gljMap[g.rationID]?gljMap[g.rationID].push(g):gljMap[g.rationID]=[g];
            }
        }
        if(temp.rations) {
            for(let r of temp.rations){
                let [tsum,thei,exp] = calcRation(r,gljMap[r.ID],pgljMap,priceMap);
                heightFee = scMathUtil.roundForObj(heightFee+thei,6);
                sum = scMathUtil.roundForObj(sum + tsum,6);
                expList.push(exp);
            }
        }
        sum = scMathUtil.roundForObj(sum,decimal)+"";
        if(type == "freight"){
          let exp = expList.length == 0?`${temp.otherFee}x${temp.weightCoe}`:`((${expList.join("+")})+${temp.otherFee})x${temp.weightCoe}`
          let ndoc = {};
          if(temp.unitFreight != sum) ndoc['unitFreight'] = sum;
          if(temp.exp != exp) ndoc['exp'] = exp;
          if(temp.heightFee != heightFee) ndoc['heightFee'] = heightFee;
          if(!_.isEmpty(ndoc)) return {ID:temp.ID,doc:ndoc};
        }
        if(type == "price" && temp.supplyPrice !=sum) return {ID:temp.ID,doc:{supplyPrice:sum,heightFee:heightFee}}
    }
    return null;


    function calcRation(ration,gljs,pMap,priceMap){
        let result = 0;
        let heightFee = 0;
        let exp = "";
        if(gljs){
            let processDecimal = getDecimal("process");
            let hightFeeRate = projectObj.project.projectGLJ.getHighlandFee(ration.feeType);//高原取费类别费率
            let assFeeRate = scMathUtil.roundForObj(projectObj.project.projectGLJ.datas.constData.assistProductionFeeRate,getDecimal("feeRate")) * 0.01;//辅助生产间接费费率
            let laberSum = 0;
            let machineSum = 0;
            let assList=[];
            let expList = [];
            let rationQuantity = scMathUtil.roundForObj(ration.quantity,getDecimal("ration.quantity"));
            for(let g of gljs){
                gljOprObj.setGLJPrice(g,pMap[gljUtil.getIndex(g)]);
                if(priceMap && priceMap[g.projectGLJID]) g.marketPrice = scMathUtil.roundForObj(priceMap[g.projectGLJID]);
                let quantity = scMathUtil.roundForObj(g.quantity,getDecimal("glj.quantity"));
                let t = scMathUtil.roundForObj(quantity * g.marketPrice * rationQuantity,processDecimal);//市场价
                let r_price = gljUtil.getAssUsedPrice(g);//浙江定额时特殊处理，这里取市场价
                let rt = scMathUtil.roundForObj(quantity * r_price * rationQuantity,processDecimal);//定额价
                let calString = `${quantity}x${r_price}x${rationQuantity}`;  
                if(g.type == gljUtil.gljType.LABOUR){
                  laberSum = scMathUtil.roundForObj(laberSum+rt,processDecimal);
                  assList.push(`${calString}x${assFeeRate*100}%`) 
                } 
                if(gljUtil.getMainType(g.type) == 3) machineSum = scMathUtil.roundForObj(machineSum+rt,processDecimal); 
               
                expList.push(`${quantity}x${g.marketPrice}x${rationQuantity}`); 
                result = scMathUtil.roundForObj(result + t,processDecimal);
            }
            let as = scMathUtil.roundForObj(laberSum * assFeeRate,processDecimal);//人工消耗量*定额价*定额工程量*辅助生产间接费费率
            let tt = scMathUtil.roundForObj(laberSum + machineSum,processDecimal);//人工定额消耗量*定额价*定额工程量+机械定额消耗量*定额价*定额工程量
            let hs = scMathUtil.roundForObj(tt*hightFeeRate,processDecimal);//（人工定额消耗量*定额价*定额工程量+机械定额消耗量*定额价*定额工程量）*高原取费类别费率
            exp = expList.join("+");
            if(hightFeeRate!=0) exp += `+${tt}x${hightFeeRate*100}%`;
            if(assFeeRate!=0 && assList.length > 0) exp += '+'+assList.join("+");
            result = scMathUtil.roundForObj(as + result,processDecimal);
            result = scMathUtil.roundForObj(hs + result,processDecimal);
            heightFee = hs;
        }
        return  [result,heightFee,exp];
    }





};

ProjectGLJ.prototype.calcMaterialAssQuantity = function (parent,ration,newAssList) {
    let updateList = [];
    let assList = calcAssList(newAssList);
    for(let glj of parent.ration_gljs){
        if(glj.rationID == ration.ID){
            updateList.push(calcAssGljQuantity(glj,assList));
        }
    }

    return updateList;


    function calcAssGljQuantity(g,assList) {
        g.quantity = scMathUtil.roundForObj(g.rationItemQuantity,getDecimal("glj.quantity"));
        for(let a of assList){
            let ass = a.ass;
            let matchGlj = null;
            for(let aglj of ass.rationGljList){
                if(aglj.gljId == g.GLJID){
                    matchGlj = aglj;
                    break;
                }
            }
            if(matchGlj){
                let calQuantity =scMathUtil.roundForObj(matchGlj.consumeAmt*a.times,6);
                g.quantity =  scMathUtil.roundForObj(calQuantity + g.quantity,getDecimal("glj.quantity"))+"";
            }
        }
        return {ID:g.ID,quantity:g.quantity}
    }

    function calcAssList(rationAssList){
        let calAss = [];
        for(let ass of rationAssList){
            let times = calculateTimes(ass);
            if(times!=0){
                calAss.push({ass:ass.assRation,times:times});
            }
        }
        return calAss;
    }

    function calculateTimes(ass){
        if(ass.name.indexOf("运距") == -1) return 0;//只计算运距;
        let times =(ass.actualValue-ass.stdValue)/ass.stepValue;
        let r = false;
        if(times<0){
            r=true;
            times=times*-1;
        }
        if(ass.carryBit=='四舍五入'){
            times = _.round(times,ass.decimal);
        }else if (ass.carryBit=='进一'){
            times =_.ceil(times,ass.decimal);
        }else if(ass.carryBit == '舍一'){
            times = _.floor(times,ass.decimal);
        }
        if(r){
            times=times*-1;
        }
        return scMathUtil.roundTo(times,-6);
    }
};


ProjectGLJ.prototype.calcMaterialRation = function(ID,type){//计算带定额的运费或者原价
    let lists = type == "freight"?this.datas.freightList:this.datas.originalList;
    let temp = _.find(lists,{ID:ID});
    if(temp){
        let task = this.calcEachFreightOrPrice(temp,type);
        let material = materialCalcObj.getMaterialSelected();
        if(task && material){
            if(type == "freight") projectObj.project.projectGLJ.updateFreightCalc([task],material.id);
            if(type == "price") projectObj.project.projectGLJ.updatePriceCalc([task],material.id);
        }else {
            materialCalcObj.showDatas();
        }
    }
};

ProjectGLJ.prototype.deletePriceCalc = async function (ID,pgljID) {
    let map = {};
    map[ID] = true;
    await this.updateMaterialCalcTasks(pgljID,map,"delete","price");
};

ProjectGLJ.prototype.deleteFreightCalc = async function (ID,pgljID) {
    let map = {};
    map[ID] = true;
    await this.updateMaterialCalcTasks(pgljID,map,"delete","freight");
};

ProjectGLJ.prototype.updatePrice = function (recode, updateField, newval,from,cb) {
    let me = this;
    let projectGljs = this.datas.gljList;
    let pgljID = from=="rg"?recode.projectGLJID:recode.id;//和定额工料机统一接口，项目工料机ID取值不一样
    let glj = _.find(projectGljs, {'id': pgljID});
    if (glj) {
        if(glj.unit_price[updateField] == newval){
            return;
        }
        newval = scMathUtil.roundForObj(newval,this.getPriceDecimal(glj));
        let data = {id: glj.unit_price.id, field: updateField, newval: newval,project_id:glj.project_id,unit_price_file_id:glj.unit_price.unit_price_file_id};

        if(updateField == 'market_price' && (this.datas.mixRatioConnectData[gljUtil.getIndex(glj)] || glj.name == "电网电")){//计算是否有受影响的综合电价
            let uobj = {};
            uobj[glj.id] = {marketPrice:newval};
            let ext =electrovalenceObj.clacNewElecPrice(uobj);
            if(ext) data.ext = ext;
        }
        let callback =async function (result) {
            if (updateField == 'base_price') {
                glj.unit_price.base_price = newval;
                me.setAdjustPrice(glj);
            } else {
                glj.unit_price.market_price = newval;
            }
            let elec_glj = null;
            if(data.ext){
                 elec_glj = _.find(projectGljs, {'id': data.ext.projectGLJID});
                if(elec_glj) elec_glj.unit_price.market_price = data.ext.doc.market_price;
            }
            //更新回传的父节点项目工料机价格
           let gljs = me.getProjectGLJs(result);
          //  me.refreshRationGLJPrice(glj);//刷新定额工料机列表的记录
            let materialGljList  =await me.calcAllMaterialWhenChange()
            gljs= gljs.concat(materialGljList);

            projectGljObject.refreshDataSheet();//更新工料机汇总缓存和显示
            //projectObj.project.projectGLJ.loadCacheData();
            gljOprObj.showRationGLJSheetData();
            me.refreshTreeNodePriceIfNeed(glj);//刷新造价书中主树上的定额工料机;
            gljs.push(glj);
            if(elec_glj) gljs.push(elec_glj);
            let nodes = me.getImpactRationNodes(gljs);//取到因为改变工料机价格而受影响的定额
            projectObj.project.calcProgram.calcNodesAndSave(nodes);//触发计算程序
            if(materialGljList.length==0)projectGljObject.onUnitFileChange(result);
            if(cb){
                cb(gljs);
            }
            $.bootstrapLoading.end();
        }
        $.bootstrapLoading.start();
        CommonAjax.post("/glj/updatePrice", data, callback, function (err) {
            $.bootstrapLoading.end();
        });
    } else {
        gljOprObj.showRationGLJSheetData();
    }
};

ProjectGLJ.prototype.batchUpdateGLJProperty = function (updateMap,callback) {
    let me = this;
    //更新是否暂估和供货方式时，要做特殊处理
    $.bootstrapLoading.start();
    CommonAjax.post("/glj/batchUpdateGLJProperty", updateMap,function (result) {
        $.bootstrapLoading.end();
        let supplyChangeIDs = [],evaluate_gljs = [],rationNodes = [];
        for(let idKey in updateMap){
            let gljID = parseInt(idKey);
            let glj = me.getByID(gljID);
            let doc = updateMap[idKey];
            for(let property in doc){
                glj[property] = doc[property];
            }
            if(doc.hasOwnProperty("supply")||doc.hasOwnProperty("supply_quantity")){
                supplyChangeIDs.push(gljID);
            }
            if(doc.hasOwnProperty("is_evaluate")){
                evaluate_gljs.push(glj);
            }
        }
        if(supplyChangeIDs.length>0){
            let temRationNodes = calcTools.getRationsByProjectGLJ(supplyChangeIDs);
            if (temRationNodes.length > 0) rationNodes = rationNodes.concat(temRationNodes);
        }
        if(evaluate_gljs.length > 0){
            let [impactRationNodes,impactGLJs] = me.batchChangeIsEvaluate(evaluate_gljs);
            rationNodes = rationNodes.concat(impactRationNodes);
        }

        if(rationNodes.length > 0){
            rationNodes = _.uniq(rationNodes,'data');
            projectObj.project.calcProgram.calcNodesAndSave(rationNodes, function () {
                projectObj.mainController.refreshTreeNode(projectObj.project.mainTree.roots);
            });
        }

        if(callback){
            callback();
        }

    })


};

ProjectGLJ.prototype.batchUpdatePrice = function (changeInfo,sheetName,callback) {
    let me = this;
    let projectGljs = me.datas.gljList;
    let updateData = [];
    let newValueMap = {};
    let gljs=[];
    let setting = sheetName =="materialTreeSheet"?projectGljObject.materialSetting:projectGljObject.projectGljSetting;
    if(changeInfo.length<=0){
        callback?callback():'';
        return
    }
    for(let ci of changeInfo){
        let dataCode = setting.header[ci.col].dataCode;
        let recode = sheetName =="materialTreeSheet"?projectGljObject.materialTree.items[ci.row].data:projectGljObject.projectGljSheetData[ci.row];
        if(dataCode=='basePrice'||dataCode=='marketPrice'){
            let editField = dataCode === 'basePrice'?"base_price":"market_price";
            let glj = _.find(projectGljs, {'id': recode.id});
            let newValue = ci.value;
            if(glj&&glj.unit_price[editField]!=newValue){
                newValue= scMathUtil.roundForObj(ci.value,this.getPriceDecimal(glj));
                updateData.push({unit_price: glj.unit_price, field: editField, newval: newValue,project_id:glj.project_id});
                newValueMap[glj.id]={field:editField,value:newValue};
                gljs.push(glj);
            }
        }
    }
    if(updateData.length > 0){
        $.bootstrapLoading.start();
        CommonAjax.post("/glj/batchUpdatePrices", updateData,async function (result) {
            let parentData = [];
            //更新缓存
            for(let g of gljs){
                g.unit_price[newValueMap[g.id].field] = newValueMap[g.id].value;
                me.refreshTreeNodePriceIfNeed(g);//刷新造价书中主树上的定额工料机;
            }
            //更新父工料机价格
            for(let r of result){
                let pdata = r.updateOne.filter;
                let set = r.updateOne.update.$set;
                for(let skey in set){
                    pdata[skey] = set[skey];
                }
                parentData.push(pdata);
            }
            let pgljs = me.getProjectGLJs(parentData);
            gljs = gljs.concat(pgljs);
            let materialGljList  = await me.calcAllMaterialWhenChange();
            gljs = gljs.concat(materialGljList);
            let nodes = me.getImpactRationNodes(gljs);//取到因为改变工料机价格而受影响的定额
            projectObj.project.calcProgram.calcNodesAndSave(nodes);//触发计算程序
            gljOprObj.showRationGLJSheetData();
            if(materialGljList.length == 0) projectGljObject.onUnitFileChange(gljs);
            if(callback){
                callback(gljs);
            }
            $.bootstrapLoading.end();
        }, function (err) {
            $.bootstrapLoading.end();
        });
    }
};

ProjectGLJ.prototype.batchUpdateConsumption = function (updateData,updateMap,callback) {
    let me = this;
    $.bootstrapLoading.start();
    CommonAjax.post("/glj/batchUpdateConsumption", updateData, function (result) {
        let unitPriceMap = {}, mu=null, parentID   = null;
        for(let u of updateData){
            if(u.type == 'mix_ratio'){
                mu = u;
            }else if(u.type == 'unitPrice'){
                unitPriceMap[u.projectGLJID] = u.doc;
                if(u.isParent) parentID = u.projectGLJID;
            }
        }
        if(!_.isEmpty(unitPriceMap)){
            for(let g of me.datas.gljList) {
                if(unitPriceMap[g.id]){
                    gljUtil.setProperty(g.unit_price,unitPriceMap[g.id]);
                }
                if(parentID == g.id) updateMixRatio(g,mu,me);
            }
        }
        me.calcQuantity();

        if(callback){
            callback();
        }
        $.bootstrapLoading.end();
    },function () {
        $.bootstrapLoading.end();
    })

   function updateMixRatio(parent,u,me) {
       let tem = updateMap[u.query.id];
       tem.record.consumption = u.doc.consumption;//更新组成物表格的缓存
       let subData = _.find(parent.ratio_data,{"id":u.query.id});
       if(subData){
           subData.consumption = u.doc.consumption;
       }
       let m_list = me.datas.mixRatioMap[gljUtil.getIndex(parent)];
       let m_ratioData = _.find(m_list,{"id":u.query.id});
       if(m_ratioData){
           m_ratioData.consumption = u.doc.consumption;
       }
   }
};

ProjectGLJ.prototype.pGljUpdate= function (data,callback) {
    let me = this;
    $.bootstrapLoading.start();
    CommonAjax.specialPost( '/glj/update',data,function (result) {
        let glj = me.getByID(data.id);//更新缓存
        let impactList = [];
        glj[data.field] = data.value;
        if(data.extend&&data.extend!=""){
            let extend = JSON.parse(data.extend);
            for (let key in extend) {
                glj[key] = extend[key];
            }
        }
        if(data.field == 'is_evaluate'){
            impactList =  me.changeIsEvaluate(data.id);
        }
        if(callback){
            callback(impactList);
        }
        $.bootstrapLoading.end();
    });
};

ProjectGLJ.prototype.getRatioData=function(id,callback){
    this.getRatioId = id;
    if(id){
        CommonAjax.specialPost( '/glj/get-ratio',{id: id, project_id: scUrlUtil.GetQueryString('project')},function (response) {
            let ratios = JSON.parse(response.data);
            if(callback){
                callback(ratios);
            }
        },function () {//取不到组成物的情况
            callback([]);
        })
    }else {
        if(callback){
            callback([]);
        }
    }
};

ProjectGLJ.prototype.changeFile = function (changeData,callback) {
    $.bootstrapLoading.start();
    CommonAjax.specialPost('/glj/change-file',changeData,function (response) {
        projectObj.project.property.unitPriceFile = response.unitFile;
        projectObj.project.projectGLJ.loadData(function () {
            if(callback){
                callback();
            }
            $.bootstrapLoading.end();
        });
    }, function (err) {
        if($.bootstrapLoading.isLoading()){
            $.bootstrapLoading.end();
        }
        alert(err.msg);
    });
};

ProjectGLJ.prototype.changeVvTaxFile = async function (newVvTaxFileID,callback) {
    $.bootstrapLoading.start();
    try {
        await ajaxPost("/glj/changeVvTaxFile",{unitFileID:projectObj.project.property.unitPriceFile.id,newVvTaxFileID:newVvTaxFileID});
        await this.synLoadData();
        projectGljObject.refreshDataSheet();
        gljOprObj.refreshView();
        projectObj.project.ration_glj.reCalcWhenVvTaxChange();
        projectGljObject.onUnitFileChange();
    }catch (err){
        console.log(err);
    }finally {
        $.bootstrapLoading.end();
    }
};

ProjectGLJ.prototype.checkUnitFileName = function(newVal,callback){
    let property = projectObj.project.projectInfo.property;
    let data = {
        name:newVal,
        rootProjectID:property.rootProjectID
    }
    CommonAjax.post('/glj/checkUnitFileName', data, function (data) {
        callback(data);
    });
};

ProjectGLJ.prototype.saveAs = function (saveData,callback) {
    $.bootstrapLoading.start();
    CommonAjax.specialPost('/glj/save-as',saveData,function () {
        projectObj.project.projectGLJ.loadData(function () {
            if(callback){
                callback();
            }
            $.bootstrapLoading.end();
        });
    },function (response) {
        let msg = response.msg !== undefined && response.msg !== '' ? response.msg : '另存为失败!';
        $("#save-as-tips").text(msg).show();
        $.bootstrapLoading.end();
    });


};

//更新是否暂估
ProjectGLJ.prototype.changeIsEvaluate=function (id){
    let projectGLJ = projectObj.project.projectGLJ;
    let datas = projectGLJ.datas;
    let gljList = datas.gljList;
    let glj = _.find(gljList, {'id': id});
    if(glj){//与批量更新调用相同的方法
     /*   let con_key = gljOprObj.getIndex(glj,gljKeyArray);
        let pratioM =datas.mixRatioConnectData[con_key];//找到父key
        let conditions = [];
        if(pratioM&&pratioM.length>0){
            for(let p_key of pratioM ){
                conditions.push(gljOprObj.getConditionByKey(p_key));
            }
        }
        let gljs = projectGLJ.getProjectGLJs(conditions,false);
        gljs.push(glj);
        let nodes = projectGLJ.getImpactRationNodes(gljs);//取到因为改变工料机价格而受影响的定额
        //更新对应的工料机类型的定额
        let rations =_.filter(projectObj.project.Ration.datas,{'type':rationType.gljRation,'projectGLJID':glj.id});
        let ration_nodes = [];
        for(r of rations){
            if(r){
                r.isEstimate =glj.is_evaluate?1:0;
                let ration_node = projectObj.project.mainTree.getNodeByID(r.ID);
                ration_node?ration_nodes.push(ration_node):'';
            }
        }
        let ration_glj_nodes = projectGLJ.getMainAndEquGLJNodeByID(glj.id);//取显示在造价书界面上的主材和设备节点
        for(rg of ration_glj_nodes){
            rg.data.isEstimate =glj.is_evaluate?1:0;
            ration_nodes.push(rg);
        }
        ration_nodes.length>0?projectObj.mainController.refreshTreeNode(ration_nodes):"";*/
        let [nodes,gljs] = projectGLJ.batchChangeIsEvaluate([glj]);
        projectObj.project.calcProgram.calcNodesAndSave(nodes);//触发计算程序
        return gljs;
    }
};

/**
 * 批量更新是否暂估
 *传入项目工料机数组
 */

ProjectGLJ.prototype.batchChangeIsEvaluate=function (gljs){
    let impactGLJs = [], changeArray =_.map(gljs,'id'),changeMap = _.indexBy(gljs,'id');;
    for(let glj of gljs){
        let con_key = gljOprObj.getIndex(glj,gljKeyArray);
        let pratioM =this.datas.mixRatioConnectData[con_key];//找到父key
        let conditions = [];
        if(pratioM&&pratioM.length>0){
            for(let p_key of pratioM ){
                conditions.push(gljOprObj.getConditionByKey(p_key));
            }
        }
        let tem_gljs = this.getProjectGLJs(conditions,false);
        if(tem_gljs.length > 0) impactGLJs = impactGLJs.concat(tem_gljs);
    }
    impactGLJs = impactGLJs.concat(gljs);
    impactGLJs =  _.uniq(impactGLJs,'id');//去重复

    let impactRationNodes = this.getImpactRationNodes(impactGLJs);
    let neeRefreshNode = [];
    //更新对应的工料机类型的定额
    for(let item of projectObj.project.Ration.datas){
        if(item.type == rationType.gljRation && changeArray.indexOf(item.projectGLJID) != -1){
            let tem_g = changeMap[item.projectGLJID];
            item.isEstimate =tem_g.is_evaluate?1:0;
            let ration_node = projectObj.project.mainTree.getNodeByID(item.ID);
            neeRefreshNode?neeRefreshNode.push(ration_node):'';
        }
    }
    let ration_glj_nodes = this.getMainAndEquGLJNodeByID(changeArray);//取显示在造价书界面上的主材和设备节点
    for(let rg of ration_glj_nodes){
        let tem_g = changeMap[rg.data.projectGLJID];
        rg.data.isEstimate =tem_g.is_evaluate?1:0;
        neeRefreshNode.push(rg);
    }
    neeRefreshNode.length>0?projectObj.mainController.refreshTreeNode(neeRefreshNode):"";
    return [impactRationNodes,impactGLJs];
};

ProjectGLJ.prototype.getByID = function (ID) {
    return _.find(this.datas.gljList,{'id':ID});
};

ProjectGLJ.prototype.getByConKey = function (conkey) {//根据5个连接属性取对应的工料机
    return _.find(this.datas.gljList,function (item) {
        let tem_key = gljOprObj.getIndex(item,gljKeyArray);
        return tem_key == conkey
    })
};


ProjectGLJ.prototype.refreshTreeNodePriceIfNeed = function (data) {
    if ((data.unit_price.type == gljType.MAIN_MATERIAL || data.unit_price.type == gljType.EQUIPMENT) && projectObj.project.projectInfo.property.displaySetting.disPlayMainMaterial == true) {
        let me = this;
        var nodes = _.filter(projectObj.project.mainTree.items, function (tem) {
            if (tem.sourceType == ModuleNames.ration_glj && tem.data.projectGLJID == data.id) {
                tem.data.marketUnitFee = me.getMarketPrice(data);//data.unit_price.market_price;
                tem.data.marketPrice = me.getMarketPrice(data);//data.unit_price.market_price;
                return true;
            }
        })
        projectObj.mainController.refreshTreeNode(nodes);
    }
}

ProjectGLJ.prototype.getMainAndEquGLJNodeByID = function (id) {//通过ID取显示到主树上的主材和设备节点
    let nodes = [];
    let ids = [];
    if(Array.isArray(id)){
        ids = id;
    }else {
        ids = [id];
    }
    if(projectObj.project.projectInfo.property.displaySetting.disPlayMainMaterial == true){
         nodes = _.filter(projectObj.project.mainTree.items, function (tem) {
            return tem.sourceType == ModuleNames.ration_glj && ids.indexOf(tem.data.projectGLJID)  !== -1
        })
    }
    return nodes;
};

//根据工料机，取得所有受影响的定额节点
ProjectGLJ.prototype.getImpactRationNodes = function (gljs) {
    let nodes = [];
    let rationMap = {};
    let idArray = _.map(gljs,'id');
    let gljMap = _.indexBy(gljs,'id');
    //先根据项目工料机ID，找到受影响定额的ID
    let ration_glj_list = projectObj.project.ration_glj.datas; //取定额工料机数据
    for (let rg of ration_glj_list) {
        if (_.indexOf(idArray,rg.projectGLJID)!=-1) {
            rationMap[rg.rationID] = true;  //取所有定额ID，用MAP方式去重
        }
    }
    for (let item of projectObj.project.mainTree.items) {
        if (item.sourceType == ModuleNames.ration) {
            if (item.data.type == rationType.gljRation) {//取定额类型的工料机
                let tem_g = gljMap[item.data.projectGLJID];
                if(tem_g){
                    item.data.marketUnitFee = this.getMarketPrice(tem_g);//这里要按计算的市场价为准，不能直接取
                    item.data.marketPrice = this.getMarketPrice(tem_g);
                    nodes.push(item);
                }
            } else if (rationMap[item.data.ID] == true) {  //受影响的定额
                nodes.push(item)
            }
        }
    }
    return nodes;
};


ProjectGLJ.prototype.refreshRationGLJPrice = function (glj) {
    for (let ration_glj of gljOprObj.sheetData) {
        if (ration_glj.projectGLJID == glj.id) {
            ration_glj.basePrice = this.getBasePrice(glj);
            ration_glj.marketPrice = this.getMarketPrice(glj);
            ration_glj.adjustPrice = this.getAdjustPrice(glj);
        }
    }
}

ProjectGLJ.prototype.refreshRationTypeGLJ = function (glj) {

}

ProjectGLJ.prototype.getProjectGLJs = function (data,refreshPrice=true) {
    let parentGlj = [];
    //
    let projectGljs = this.datas.gljList;
    let indexList = gljKeyArray;
    for (let d of data) {
        if (d) {
            let glj = _.find(projectGljs, function (item) {
                return gljOprObj.getIndex(item,indexList) == gljOprObj.getIndex(d,indexList);
            });
            if (glj) {
                if(refreshPrice==true){
                    d.base_price?glj.unit_price.base_price = d.base_price:'';
                    d.market_price?glj.unit_price.market_price = d.market_price:'';
                    this.setAdjustPrice(glj);
                    this.refreshRationGLJPrice(glj);
                    this.refreshTreeNodePriceIfNeed(glj);
                }
                parentGlj.push(glj);
            }
        }
    }
    return parentGlj;
}

ProjectGLJ.prototype.setAdjustPrice = function (glj) {
    switch (glj.unit_price.type + '') {
        // 人工: 调整基价=基价单价*调整系数
        case GLJTypeConst.LABOUR:
        case GLJTypeConst.MACHINE_LABOUR:
            glj.adjust_price = this.getAdjustPrice(glj);
            break;
        // 机械类型的算法
        case GLJTypeConst.MACHINE:
            console.log('机械');
            break;
        // 材料、主材、设备
        default:
            glj.adjust_price = glj.unit_price.base_price;
    }
}

ProjectGLJ.prototype.getAdjustPrice = function (glj,isRadio) {
    let proGLJ =  projectObj.project.projectGLJ;
    let calcOptions=projectObj.project.projectInfo.property.calcOptions;
    let decimalObj = projectObj.project.projectInfo.property.decimal;
    let labourCoeDatas =  projectObj.project.labourCoe.datas;
    return gljUtil.getAdjustPrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
};

ProjectGLJ.prototype.getBasePrice = function(glj,isRadio){
    let proGLJ =  projectObj.project.projectGLJ;
    let calcOptions=projectObj.project.projectInfo.property.calcOptions;
    let decimalObj = projectObj.project.projectInfo.property.decimal;
    let labourCoeDatas =  projectObj.project.labourCoe.datas;
    return gljUtil.getBasePrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
};


ProjectGLJ.prototype.getMarketPrice = function (glj,isRadio) {
    let proGLJ =  projectObj.project.projectGLJ;
    let calcOptions=projectObj.project.projectInfo.property.calcOptions;
    let decimalObj = projectObj.project.projectInfo.property.decimal;
    let labourCoeDatas =  projectObj.project.labourCoe.datas;
    return gljUtil.getMarketPrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
};

ProjectGLJ.prototype.getTenderMarketPrice = function (glj,isRadio) {
    let proGLJ =  projectObj.project.projectGLJ;
    let calcOptions=projectObj.project.projectInfo.property.calcOptions;
    let decimalObj = projectObj.project.projectInfo.property.decimal;
    let labourCoeDatas =  projectObj.project.labourCoe.datas;
    let tenderCoe = 1;
    if (projectObj.project.property.tenderSetting && gljUtil.isDef(projectObj.project.property.tenderSetting.gljPriceTenderCoe) ){
        tenderCoe = parseFloat(projectObj.project.property.tenderSetting.gljPriceTenderCoe);
    }
    return gljUtil.getMarketPrice(glj,proGLJ.datas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,tenderCoe);
};

ProjectGLJ.prototype.isEstimateType = function(type){
    let typeString = type + "";
    if (typeString.startsWith("2")||typeString=='4'||typeString=='5') {//只有材料、主材、设备类型才显示是否暂估
       return type;
    }
    return false;
};

ProjectGLJ.prototype.getShortNameByID = function (ID) {
    let gljTypeMap = this.datas.constData.gljTypeMap;
    return gljTypeMap["typeId" + ID]?gljTypeMap["typeId" + ID].shortName:'';
};

ProjectGLJ.prototype.calcQuantity  = function (init=false){
    let project_gljs = this.datas.gljList;
    let changeArray=[];
    let rationGLJDatas = projectObj.project.ration_glj.datas;
    let rationDatas = projectObj.project.Ration.datas;
    let billsDatas = projectObj.project.Bills.datas;

    gljUtil.calcProjectGLJQuantity(this.datas,rationGLJDatas,rationDatas,billsDatas,getDecimal("glj.quantity"),_,scMathUtil);

    if(init == true || this.quantityChangeMap == null){//如果是初始化，建立一个映射表
        this.quantityChangeMap = {};
        for(let pglj of project_gljs){
            this.quantityChangeMap[pglj.id] = pglj.quantity;
        }
    }else if(this.quantityChangeMap != null){
        for(let pglj of project_gljs){
            if(this.quantityChangeMap[pglj.id] != undefined|| this.quantityChangeMap[pglj.id] != null){
                if(this.quantityChangeMap[pglj.id] !=  pglj.quantity){
                    changeArray.push(pglj);
                    this.quantityChangeMap[pglj.id] = pglj.quantity;
                }
            }else { //映射表没有，说明是新添加的项目工料机
                changeArray.push(pglj);
                this.quantityChangeMap[pglj.id] = pglj.quantity;
            }
        }
    }
    changeArray.length > 0 && projectGljObject.calcPartASupplyFeeByProjectGLJs ?projectGljObject.calcPartASupplyFeeByProjectGLJs(changeArray):'';
};

ProjectGLJ.prototype.calcTenderQuantity  = function (){
    let rationGLJDatas = projectObj.project.ration_glj.datas;
    let rationDatas = projectObj.project.Ration.datas;
    let billsDatas = projectObj.project.Bills.datas;
    gljUtil.calcProjectGLJQuantity(this.datas,rationGLJDatas,rationDatas,billsDatas,getDecimal("glj.quantity"),_,scMathUtil,true);
};

ProjectGLJ.prototype.loadNewProjectGLJToCaches = function (datas,calquantity = false) {
    if(!datas) return;
    let gljIDMap = {};
    for (let d of datas){
        if(d) this.loadNewProjectGLJToCache(d,gljIDMap);
    }
    if(datas.length > 0 &&  calquantity)  this.calcQuantity();
};

ProjectGLJ.prototype.loadNewProjectGLJToCache = function (data,tIDMap) {//把新插入的项目工料机数据增加至缓存中
    if(!data) return;
    let project_gljs = this.datas.gljList;
    let unitPriceMap = this.datas.unitPriceMap;
    let mixRatioMap = this.datas.mixRatioMap;
    let mixRatioConnectData = this.datas.mixRatioConnectData;
    let IDMap = !_.isEmpty(tIDMap)?tIDMap:_.indexBy(project_gljs,'id');
    let tem =  IDMap[data.id];
    if(tem) return tem; //判断该工料机是否已经存在，是的话不用再次添加
    //查看是否有组成物，有组成物的话先添加组成物信息
    data.ratio_data=[];
    if(data.subList && data.subList.length){
        for(let s of data.subList){
            let ratio = s.ratio_data;
            data.ratio_data.push(ratio);
            mixRatioMap[ratio.connect_key]?mixRatioMap[ratio.connect_key].push(ratio):mixRatioMap[ratio.connect_key] = [ratio];
            let rIndex = gljUtil.getIndex(ratio);
            mixRatioConnectData[rIndex]?mixRatioConnectData[rIndex].push(ratio.connect_key):mixRatioConnectData[rIndex] = [ratio.connect_key];
            this.loadNewProjectGLJToCache(s,IDMap);
        }
        delete data.subList;
    }
    //添加unitPriceMap
    let uIndex = gljUtil.getIndex(data.unit_price);
    if(!unitPriceMap[uIndex])  unitPriceMap[uIndex] = data.unit_price;
    this.datas.gljList.push(data);
    IDMap[data.id] = data;
    return data;
};