

/**
 * 工料机汇总相关数据
 *
 * @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) {
    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('数据传输错误');
        },
        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);
                return false;
            }
            self.refreshByDatas(response.data);
            // 回调函数
            if (callback !== null) {
                callback(response.data);
            }
            // 存入缓存
            projectObj.project.projectGLJ = self;
        }
    });
};

ProjectGLJ.prototype.loadDataSync = async function () {
    if (this.isLoading) {
        return false;
    }
    this.isLoading = true;
    const project_id = projectObj.project.ID();
    try {
        const rst = await ajaxPost('/glj/getData', { project_id }, true);
        this.isLoading = false;
        this.refreshByDatas(rst);
        projectObj.project.projectGLJ = this;
    } catch (err) {
        this.isLoading = false;
        throw new Error('获取项目人材机数据错误');
    }
    
}

//更新项目工料机数据和缓存
ProjectGLJ.prototype.refreshByDatas = function(datas){
    this.datas = datas;
    this.calcQuantity();
    this.datas.gljMap =  {};
    for(let g of this.datas.gljList){
        this.datas.gljMap[gljUtil.getIndex(g)]=g;
     }
};


ProjectGLJ.prototype.loadToCache = function (data) {
    this.datas = data;
    this.datas.gljMap =  {};
    for(let g of this.datas.gljList){
       this.datas.gljMap[gljUtil.getIndex(g)]=g;
    }

}

/**
 * 获取对应工料机数据
 *
 * @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",null,callback);
    }
    if (updateField == 'basePrice') {
        this.updatePrice(recode, "base_price", newval,"rg",null,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);  //更新节点信息
        rationTypeGLJ[updateField] = newval;
        rationTypeGLJ.projectGLJID = result.id;
        rationTypeGLJ.code = result.code;
        rationTypeGLJ.basePrice = result.unit_price.base_price;
        rationTypeGLJ.marketUnitFee = result.unit_price.market_price;
        rationTypeGLJ.isAdd = result.unit_price.is_add;
        rationTypeGLJ.isEstimate = result.is_evaluate;
        rationTypeGLJ.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.doAfterPriceChange=function(gljs){
    //更新回传的父节点项目工料机价格

    projectGljObject.refreshDataSheet(true);//更新工料机汇总缓存和显示
    gljOprObj.showRationGLJSheetData();
    let nodes = this.getImpactRationNodes(gljs);//取到因为改变工料机价格而受影响的定额
    projectObj.project.calcProgram.calcNodesAndSave(nodes, async function () {
        await OVER_HEIGHT.reCalcOverHeightFee();
        await itemIncreaseFeeObj.calcItemIncreaseFeeByNodes(nodes);
    });//触发计算程序
    projectGljObject.onUnitFileChange(gljs);
}


ProjectGLJ.prototype.updatePrice = function (recode, updateField, newval,from,tdoc,cb) {
    let me = this;
    let projectGljs = this.datas.gljList;
    let pgljID = from=="rg"?recode.projectGLJID:recode.id;//和定额工料机统一接口，项目工料机ID取值不一样
    let glj = _.find(projectGljs, {'id': pgljID});
    let udoc = tdoc?tdoc:{"priceFrom":""};//20200728 新增价格来源，默认为空
    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') data.udoc=udoc;
        let callback = function (data) {
            if (updateField == 'base_price') {
                glj.unit_price.base_price = newval;
                me.setAdjustPrice(glj);
            } else {
                glj.unit_price.market_price = newval;
                gljUtil.setProperty(glj.unit_price,udoc);
            }
            //更新回传的父节点项目工料机价格
            let gljs = me.getProjectGLJs(data);
            gljs.push(glj);
            me.refreshTreeNodePriceIfNeed(glj);//刷新造价书中主树上的定额工料机;
            projectObj.project.projectGLJ.doAfterPriceChange(gljs);//更新工料机汇总缓存和显示
            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 = [];
        console.log(updateMap);
        let needCalcQuantity = false;
        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(doc.hasOwnProperty("is_adjust_price")) needCalcQuantity = true;
        }
        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(needCalcQuantity) me.calcQuantity();
        if(callback){
            callback();
        }

    })


};

ProjectGLJ.prototype.mutiApplyInfoPrice = async function(pgljMap,condition,priceFrom) {
  try {
    $.bootstrapLoading.start();
    let taxType = projectObj.project.property.taxType;
    let projectGLJMap = await ajaxPost("/infoPrice/mutiApplyInfoPrice",{pgljMap:pgljMap,condition:condition,taxType:taxType,decimal:getDecimal('glj.unitPrice'),priceFrom:priceFrom});
    let parentKeyMap = {};
    let gljs = [];
    if(!_.isEmpty(projectGLJMap)){
      for(let id in projectGLJMap){//先整理出受影响的父工料机
        let mixRatioKey = projectGLJMap[id].index;
        let parentArray = this.datas.mixRatioConnectData[mixRatioKey];
        if(!parentArray) continue;
        for(pk of parentArray){
          parentKeyMap[pk] = true;
        }
      }
      for(let glj of this.datas.gljList){
        if(projectGLJMap[glj.id]){
          gljUtil.setProperty(glj.unit_price,projectGLJMap[glj.id].doc);
          gljs.push(glj);
        }else if(parentKeyMap[gljUtil.getIndex(glj)]){
          gljs.push(glj);
        }
      }
      this.doAfterPriceChange(gljs);
    }
  } catch (error) {
    console.log(error);
  }
  $.bootstrapLoading.end();
}

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, 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);
            me.doAfterPriceChange(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 parent = updateData[updateData.length - 1];
        let parentGlj = me.getByConKey(parent.connect_key);
        for(let u of updateData){
            if(u.type == 'mix_ratio'){
                let tem = updateMap[u.query.id];
                tem.record.consumption = u.doc.consumption;//更新组成物表格的缓存
                let subData = _.find(parentGlj.ratio_data,{"id":u.query.id});
                if(subData){
                    subData.consumption = u.doc.consumption;
                }
                let m_list = me.datas.mixRatioMap[parent.connect_key];
                let m_ratioData = _.find(m_list,{"id":u.query.id});
                if(m_ratioData){
                    m_ratioData.consumption = u.doc.consumption;
                }
            }
        }
        parentGlj.unit_price.market_price =  parent.market_price;
        parentGlj.unit_price.base_price =  parent.base_price;
        me.calcQuantity();

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


};

ProjectGLJ.prototype.pGljUpdate= function (data,callback) {
    let me = this;
    let glj = me.getByID(data.id);
    if(data.field == 'taxRate'){
        data.field = "unit_price.taxRate";
        data.id = glj.unit_price.id;
    }
    $.bootstrapLoading.start();
    CommonAjax.specialPost( '/glj/update',data,function (result) {
        let impactList = [];
        _.set(glj,data.field,data.value);//更新缓存
       // 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(data.field == "is_adjust_price") me.calcQuantity();
        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.addMixRatio = function(selections,callback){
    let gljList = [],allGLJ = gljOprObj.AllRecode;
    $("#glj_tree_div").modal('hide');
    if(selections.length == 0) {
        return;
    }
    for(let glj of allGLJ){
        let i_key = gljOprObj.getIndex(glj, gljLibKeyArray);
        if(_.includes(selections,i_key)){
            let pglj = {
                project_id: projectObj.project.ID(),
                glj_id: glj.ID,
                name: glj.name,
                code: glj.code,
                original_code: glj.code,
                unit: glj.unit,
                specs: glj.specs,
                base_price: glj.basePrice,
                market_price: glj.basePrice,
                shortName: glj.shortName,
                type: glj.gljType,
                model:glj.model,
                adjCoe: glj.adjCoe,
                from:'std',
                repositoryId:glj.repositoryId,
                materialType:glj.materialType,
                materialCoe:glj.materialCoe,
                materialIndexType:glj.materialIndexType,
                materialIndexUnit:glj.materialIndexUnit,
                materialIndexCoe:glj.materialIndexCoe
            };
            if (glj.hasOwnProperty("compilationId")) {
                pglj.from = "cpt";
                if (glj.code.indexOf('-') != -1) {//这条工料机是用户通过修改名称、规格、型号等保存到补充工料机库的
                    pglj.original_code = glj.code.split('-')[0];//取-前的编号作为原始编号
                }
            }
            gljList.push(pglj);
        }
    }
    gljList = _.sortByAll(gljList, ['type', 'code']);
    if(gljList.length == 0) return;
    let praentInfo = {
        unit_price_file_id:projectObj.project.property.unitPriceFile.id,
        connect_key:gljOprObj.getIndex(projectGljObject.selectedProjectGLJ,gljKeyArray)
    };
    $.bootstrapLoading.start();
    CommonAjax.post("/glj/add-ratio", {gljList:gljList,parentInfo:praentInfo}, function (data) {
        $.bootstrapLoading.end();
        if(callback){
            callback(data);
        }
    }, function () {
        $.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;
    return gljUtil.getMarketPrice(glj,proGLJ.datas,calcOptions,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 tenderCoe = this.getTenderPriceCoe(glj);
    return gljUtil.getMarketPrice(glj,proGLJ.datas,calcOptions,decimalObj,isRadio,_,scMathUtil,tenderCoe);
};

ProjectGLJ.prototype.getTenderPriceCoe = function(glj,tproperty){
    return gljUtil.getTenderPriceCoe(glj,tproperty);
};

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; //判断该工料机是否已经存在，是的话不用再次添加
    //查看是否有组成物，有组成物的话先添加组成物信息
    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);
    this.datas.gljMap[gljUtil.getIndex(data)]= data;
    IDMap[data.id] = data;
    return data;
};

class EvaluateList {
    constructor (project) {
        this.project = project;
        this.datas = [];
        project.registerModule(ModuleNames.evaluate_list, this);
    };
    loadData (datas) {
        this.datas = datas;
    };
}

class BidEvaluationList {
    constructor (project) {
        this.project = project;
        this.datas = [];
        project.registerModule(ModuleNames.bid_evaluation_list, this);
    };
    loadData (datas) {
        this.datas = datas;
    };
}

class ContractorList {
    constructor (project) {
        this.project = project;
        this.datas = [];
        project.registerModule(ModuleNames.contractor_list, this);
    };
    loadData (datas) {
        this.datas = datas;
    };
}