|  | @@ -7,6 +7,7 @@ module.exports = {
 | 
	
		
			
				|  |  |      removeProjectMark:removeProjectMark,
 | 
	
		
			
				|  |  |      updateNodes:updateNodes,
 | 
	
		
			
				|  |  |      calcInstallationFee:calcInstallationFee,
 | 
	
		
			
				|  |  | +    calcOverHeightFee: calcOverHeightFee,
 | 
	
		
			
				|  |  |      saveProperty: saveProperty,
 | 
	
		
			
				|  |  |      getDefaultColSetting: getDefaultColSetting,
 | 
	
		
			
				|  |  |      markProjectsToChange:markProjectsToChange,
 | 
	
	
		
			
				|  | @@ -40,6 +41,7 @@ let mainQuantityLib = mongoose.model('std_main_quantity_lib');
 | 
	
		
			
				|  |  |  let materialLib = mongoose.model('std_material_lib');
 | 
	
		
			
				|  |  |  import fixedFlag from '../../common/const/bills_fixed';
 | 
	
		
			
				|  |  |  const scMathUtil = require('../../../public/scMathUtil').getUtil();
 | 
	
		
			
				|  |  | +const billsLibDao = require("../../bills_lib/models/bills_lib_interfaces");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  async function calcInstallationFee(data) {
 | 
	
		
			
				|  |  |      let result={};
 | 
	
	
		
			
				|  | @@ -149,6 +151,113 @@ function generateTasks(data,userID) {
 | 
	
		
			
				|  |  |      return tasks;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * 计取超高降效费,可能包含更新清单、更新定额、新增清单、新增定额及其子数据、删除定额及其子数据
 | 
	
		
			
				|  |  | + * @param {Object} data - {updateData: {ration: [],..}, addData: {ration: [],...}, deleteData: {ration: [],...}}
 | 
	
		
			
				|  |  | + * @return {Object} - {bills: Array, rationGLJ: Array}
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +async function calcOverHeightFee(data) {
 | 
	
		
			
				|  |  | +    // 更新数据
 | 
	
		
			
				|  |  | +    async function update({ project, bills, ration }) {
 | 
	
		
			
				|  |  | +        const tasks = [];
 | 
	
		
			
				|  |  | +        // 更新项目
 | 
	
		
			
				|  |  | +        if (project && project.ID) {
 | 
	
		
			
				|  |  | +            const projectTask = projectsModel.update({ ID: project.ID }, 
 | 
	
		
			
				|  |  | +                { 'property.overHeightOption': project.overHeightOption, 'property.overHeightSpecificID': project.overHeightSpecificID });
 | 
	
		
			
				|  |  | +            tasks.push(projectTask);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // 更新清单和定额的超高降效列
 | 
	
		
			
				|  |  | +        const models = [];
 | 
	
		
			
				|  |  | +        if (bills.length) {
 | 
	
		
			
				|  |  | +            models.push({ model: bill_model.model, items: bills });
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (ration.length) {
 | 
	
		
			
				|  |  | +            models.push({ model: ration_model.model, items: ration });
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        models.forEach(modelData => {
 | 
	
		
			
				|  |  | +            const bulkTask = modelData.items.map(item => (
 | 
	
		
			
				|  |  | +                {
 | 
	
		
			
				|  |  | +                    updateOne: {
 | 
	
		
			
				|  |  | +                        filter: { ID: item.ID },
 | 
	
		
			
				|  |  | +                        update: { overHeight: item.overHeight }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }));
 | 
	
		
			
				|  |  | +            const task = modelData.model.bulkWrite(bulkTask);
 | 
	
		
			
				|  |  | +            tasks.push(task);;
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        if (!tasks.length) {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        await Promise.all(tasks);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    // 插入数据
 | 
	
		
			
				|  |  | +    async function add({ bills, ration, rationGLJ}) {
 | 
	
		
			
				|  |  | +        const tasks = [];
 | 
	
		
			
				|  |  | +        // 匹配标准清单,加上工作内容等数据
 | 
	
		
			
				|  |  | +        for (const billsItem of bills) {
 | 
	
		
			
				|  |  | +            let stdBills = await billsLibDao.getStdBillsByCode(billsItem);
 | 
	
		
			
				|  |  | +            stdBills = stdBills ? stdBills._doc : null;
 | 
	
		
			
				|  |  | +            if (stdBills) {
 | 
	
		
			
				|  |  | +                // 获取项目清单所需要的数据
 | 
	
		
			
				|  |  | +                const projectBillsData = billsLibDao.getDataToProjectBills(stdBills);
 | 
	
		
			
				|  |  | +                Object.assign(billsItem, projectBillsData);
 | 
	
		
			
				|  |  | +            } else {
 | 
	
		
			
				|  |  | +                delete billsItem.billsLibId;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            billsItem.code += '001';
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // 新增清单
 | 
	
		
			
				|  |  | +        if (bills.length) {
 | 
	
		
			
				|  |  | +            tasks.push(bill_model.model.insertMany(bills));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // 新增定额
 | 
	
		
			
				|  |  | +        if (ration.length) {
 | 
	
		
			
				|  |  | +            tasks.push(ration_model.model.insertMany(ration));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // 完整的定额人材机数据
 | 
	
		
			
				|  |  | +        let completeRationGLJList = [];
 | 
	
		
			
				|  |  | +        if (rationGLJ.length) {
 | 
	
		
			
				|  |  | +            // 定额人材机需要新增项目人材机、单价文件、且返回完整的定额人材机数据
 | 
	
		
			
				|  |  | +            const rationGLJTasks = rationGLJ.map(glj => addInstallationGLJ(glj));
 | 
	
		
			
				|  |  | +            completeRationGLJList = await Promise.all(rationGLJTasks);
 | 
	
		
			
				|  |  | +            // 新增定额人材机
 | 
	
		
			
				|  |  | +            tasks.push(ration_glj_model.insertMany(completeRationGLJList));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // 返回新的清单和定额人材机数据
 | 
	
		
			
				|  |  | +        const rst = {
 | 
	
		
			
				|  |  | +            bills,
 | 
	
		
			
				|  |  | +            rationGLJ: completeRationGLJList,
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (!tasks.length) {
 | 
	
		
			
				|  |  | +            return rst;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        await Promise.all(tasks);
 | 
	
		
			
				|  |  | +        return rst;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    // 删除数据
 | 
	
		
			
				|  |  | +    async function del({ ration }) {
 | 
	
		
			
				|  |  | +        const tasks = [];
 | 
	
		
			
				|  |  | +        const rationIDList = ration.map(item => item.ID);
 | 
	
		
			
				|  |  | +        if (!rationIDList.length) {
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // 删除定额数据
 | 
	
		
			
				|  |  | +        const rationTask = ration_model.model.deleteMany({ ID: {$in: rationIDList} });
 | 
	
		
			
				|  |  | +        tasks.push(rationTask);
 | 
	
		
			
				|  |  | +        // 删除定额人材机数据
 | 
	
		
			
				|  |  | +        const rationGLJTask = ration_glj_model.deleteMany({ rationID: {$in: rationIDList} });
 | 
	
		
			
				|  |  | +        tasks.push(rationGLJTask);
 | 
	
		
			
				|  |  | +        await Promise.all(tasks);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    // 处理任务
 | 
	
		
			
				|  |  | +    const { updateData, addData, deleteData } = data;
 | 
	
		
			
				|  |  | +    const updateTask = update(updateData);
 | 
	
		
			
				|  |  | +    const addTask = add(addData);
 | 
	
		
			
				|  |  | +    const delTask = del(deleteData);
 | 
	
		
			
				|  |  | +    const [updateRst, addRst, delRst] = await Promise.all([updateTask, addTask, delTask]);
 | 
	
		
			
				|  |  | +    return addRst;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  async function updateNodes(datas){
 | 
	
		
			
				|  |  |      let nodeGroups = _.groupBy(datas,'type');
 | 
	
		
			
				|  |  |      let rationTasks = [];
 |