/** * Created by chen on 2017/6/29. */ let mongoose = require('mongoose'); const uuidV1 = require('uuid/v1'); let consts = require('../../main/models/project_consts') let commonConsts = consts.commonConst; let _ = require("lodash"); let ration_glj = mongoose.model('ration_glj'); import GLJListModel from '../../glj/models/glj_list_model'; let std_glj_lib_gljList_model = mongoose.model('std_glj_lib_gljList'); let async_n = require("async"); let ration = mongoose.model('ration'); let ration_coe_facade = require('./ration_coe_facade'); let ration_coe = mongoose.model('ration_coe'); let std_ration_lib_ration_items = mongoose.model('std_ration_lib_ration_items'); let glj_calculate_facade = require('./glj_calculate_facade'); let glj_type_util = require('../../../public/cache/std_glj_type_util'); let quantity_detail_facade = require('../../main/facade/quantity_detail_facade'); let ration_installation_facade = require('../../main/facade/ration_installation_facade'); let logger = require("../../../logs/log_helper").logger; import stdgljutil from "../../../public/cache/std_glj_type_util"; import EngineeringLibModel from "../../users/models/engineering_lib_model"; import GljDao from "../../complementary_glj_lib/models/gljModel"; const complementaryGljModel = mongoose.model('complementary_glj_lib'); const stdGljModel = mongoose.model('std_glj_lib_gljList'); const gljClassModel = mongoose.model('std_glj_lib_gljClass'); const projectDao = require('../../pm/models/project_model').project; const compleClassModel = mongoose.model('complementary_glj_section'); let gljUtil = require('../../../public/gljUtil'); module.exports = { save: save, getData: getData, deleteByRation: deleteByRation, getQuantityByProjectGLJ: getQuantityByProjectGLJ, getLibInfo: getLibInfo, getGLJData: getGLJData, getGLJDataByCodes:getGLJDataByCodes, addGLJ: addGLJ, deleteRationGLJ:deleteRationGLJ, deleteGLJ:deleteGLJ, insertAddTypeGLJ:insertAddTypeGLJ, replaceGLJ: replaceGLJ, replaceGLJByData:replaceGLJByData, mReplaceGLJ: mReplaceGLJ, updateRationGLJByEdit: updateRationGLJByEdit, getGLJClass: getGLJClass, insertGLJAsRation: insertGLJAsRation, getRationTypeGLJQuantity:getRationTypeGLJQuantity, getInfoFromProjectGLJ:getInfoFromProjectGLJ, createNewRecord:createNewRecord, getGLJSearchInfo:getGLJSearchInfo, updateRationGLJFromDoc:updateRationGLJFromDoc, getGLJLibByEngineerID:getGLJLibByEngineerID, prepareExtData:prepareExtData } let operationMap = { 'ut_create': create_ration_glj, 'ut_update': update_ration_glj, 'ut_delete': delete_ration_glj }; let updateFunctionMap = { 'normalUpdate': normalUpdate }; /** * 根据项目工料机ID和项目ID取消耗量 * * @param {object} condition * @return Array */ async function getQuantityByProjectGLJ(condition) { let query = { 'projectID': condition.projectID, }; if(condition.projectGLJIDList){ query['projectGLJID'] = {$in: condition.projectGLJIDList}; } let startTime = +new Date(); let results = await ration_glj.find(query, ['projectGLJID', 'quantity', 'rationID'], {sort: {projectGLJID: 1}}); let rationList = _.uniq(_.map(results, 'rationID')); let getQuantity = +new Date(); console.log("取工料机消耗量时间-----"+(getQuantity - startTime)); let rationQuery = { 'projectID': condition.projectID, 'ID': {$in: rationList}, 'deleteInfo': null }; /* $and: [ {'projectID': condition.projectID}, {'ID': {$in: rationList}}, {'deleteInfo': null} ]*/ let rations = await ration.find(rationQuery, ['ID', 'quantity']); let rationsTime = +new Date(); console.log("取定额消耗量时间-----"+(rationsTime - getQuantity)); return combineQuantity(results, rations); } function combineQuantity(results, rations) { let resultList = []; let rationMap = _.indexBy(rations,'ID'); for(let r of results){ let tmp = { projectGLJID: r.projectGLJID, quantity: Number(r.quantity) } let ration = rationMap[r.rationID];//_.find(rations, {ID: r.rationID}) if (ration) { tmp.rationID = ration.ID; tmp.rationQuantity = ration.quantity ? Number(ration.quantity) : undefined; } resultList.push(tmp); } return resultList; return resultList; } function get_lib_glj_info(ration_glj) { return function (result, cb) { std_glj_lib_gljList_model.findOne({'ID': ration_glj.GLJID}, (err, glj) => { if (err) { cb(err, '') } else if (glj) { ration_glj.name = glj.name; ration_glj.code = glj.code; ration_glj.original_code = glj.code; ration_glj.unit = glj.unit; ration_glj.specs = glj.specs; ration_glj.basePrice = glj.basePrice; ration_glj.marketPrice = glj.basePrice; ration_glj.shortName = glj.shortName; ration_glj.type = glj.gljType; ration_glj.repositoryId = glj.repositoryId; ration_glj.adjCoe = glj.adjCoe; getInfoFromProjectGLJ(ration_glj).then(function (info) { if (info) { let tem = {}; tem.newRecode = createNewRecord(info); tem.showData = info; result.datas.push(tem); cb(null, result); } else { cb(new Error('get project glj error'), null); } }); } else { cb(null, result); } }) } } function createNewRecord(ration_glj) { let newRecoed = {}; newRecoed.ID = ration_glj.ID; newRecoed.projectID = ration_glj.projectID; newRecoed.GLJID = ration_glj.GLJID; newRecoed.rationID = ration_glj.rationID; newRecoed.rationItemQuantity = ration_glj.rationItemQuantity; newRecoed.quantity = ration_glj.quantity; newRecoed.name = ration_glj.name; newRecoed.code = ration_glj.code; newRecoed.original_code = ration_glj.original_code; newRecoed.unit = ration_glj.unit; newRecoed.specs = ration_glj.specs; newRecoed.from = ration_glj.from ? ration_glj.from : 'std'; newRecoed.createType = ration_glj.createType ? ration_glj.createType : 'normal'; newRecoed.shortName = ration_glj.shortName; newRecoed.billsItemID = ration_glj.billsItemID; newRecoed.type = ration_glj.type; newRecoed.model = ration_glj.model; newRecoed.repositoryId = ration_glj.repositoryId; newRecoed.projectGLJID = ration_glj.projectGLJID; newRecoed.adjCoe = ration_glj.adjCoe; return newRecoed } async function getInfoFromProjectGLJ(ration_glj,unitPriceFileId,ext) { let data = getGLJSearchInfo(ration_glj); try { let projectGljModel = new GLJListModel(); let result = await projectGljModel.addList(data,unitPriceFileId,ext); let typeString = result.type+""; ration_glj.marketPrice = result.unit_price.market_price; ration_glj.adjustPrice = result.unit_price.base_price; ration_glj.basePrice = result.unit_price.base_price; ration_glj.projectGLJID = result.id; if (typeString.startsWith("2")||typeString=='4'||typeString=='5') {//只有材料类型才显示是否暂估 ration_glj.isEstimate = result.is_evaluate; } if (result.hasOwnProperty('subList') && result.subList.length > 0) { ration_glj.subList = getMixRatioShowDatas(result.subList); } return ration_glj; } catch (err) { logger.err(err); return null; } } function getMixRatioShowDatas(subList) { var temRationGLJs = []; for (let pg of subList) { var tem = { projectGLJID: pg.id, code: pg.code, name: pg.name, specs: pg.specs, unit: pg.unit, shortName: pg.unit_price.short_name, rationItemQuantity: pg.ratio_data.consumption, basePrice: pg.unit_price.base_price, marketPrice: pg.unit_price.market_price, adjustPrice: pg.adjust_price, isEstimate: pg.is_evaluate, isMixRatio: true, isAdd: pg.unit_price.is_add, GLJID: pg.glj_id } temRationGLJs.push(tem); } temRationGLJs = _.sortBy(temRationGLJs, 'code'); return temRationGLJs; } function create_ration_glj(user_id, datas) { return function (callback) { let ration_glj_list = datas.ration_glj_list; var tasks = []; tasks.push(startingTask("get glj info")) for (let i = 0; i < ration_glj_list.length; i++) { ration_glj_list[i].ID = uuidV1(); tasks.push(get_lib_glj_info(ration_glj_list[i])) } async_n.waterfall(tasks, (err, results) => { if (err) { callback(err, results) } else { let newRecords = []; let showDatas = []; for (let r of results.datas) { if (r) { newRecords.push(r.newRecode); showDatas.push(r.showData); } } if (newRecords.length > 0) { ration_glj.insertMany(newRecords, (err, doc) => { if (err) { callback(err, null); } else { let returndata = { updateTpye: commonConsts.UT_CREATE, moduleName: 'ration_glj', data: { newRecords: newRecords, showDatas: showDatas } } callback(null, returndata) } }); } else { logger.info("can't find gljs") callback(null, null) } } }) } } function update_ration_glj(user_id, datas) { if (datas.updateFunction) { return updateFunctionMap[datas.updateFunction](user_id, datas); } else { return normalUpdate(user_id, datas); } } function normalUpdate(user_id, datas) { return function (callback) { ration_glj.update(datas.query, datas.doc, (err, result) => { if (err) { callback(err, ''); } else { let returndata = { moduleName: 'ration_glj', data: { updateTpye: commonConsts.UT_UPDATE, query: datas.query, doc: datas.doc } } callback(null, returndata) } }) } } async function doCustomQuantityUpdate(datas) { let result = await ration_glj.findOneAndUpdate(datas.query, datas.doc); let cal_result = await glj_calculate_facade.calculateQuantity({ projectID: datas.query.projectID, rationID: datas.query.rationID }); cal_result.glj_result.forEach(function (item) { if (!item.doc.hasOwnProperty('customQuantity')) { item.doc.customQuantity = null; } }); return cal_result; } function delete_ration_glj(user_id, datas) { return function (callback) { deleteByID(datas, callback); //callback(new Error("删除子数据失败!"),null) //这个方法已经不用,先注释,稳定后再删除 /* if (datas.deleteType == "RATION") { deleteByRation(datas, callback); } else if (datas.deleteType == "BILL") { deleteByBill(user_id, datas, callback); } else { deleteByID(datas, callback); }*/ } } function deleteByRation(datas, callback) { let data = datas.updateData; let tasks = []; tasks.push(deleteGLJList(data)); tasks.push(ration_coe_facade.delete_ration_coe(data)); tasks.push(quantity_detail_facade.deleteByRation(data)); tasks.push(ration_installation_facade.deleteByRation(data)); async_n.parallel(tasks, function (err, result) { commonCallback(callback, result, err) }) } function deleteGLJList(data) { return function (callback) { ration_glj.deleteMany({projectID: data.projectID, rationID: data.ID}, (err, result) => { commonCallback(callback, result, err) }); } } function deleteByBill(user_id, datas, callback) { let tasks = []; tasks.push(startingTask("deleteByBill")); tasks.push(getRationsByBill(datas)); tasks.push(deleteRationsbyBill(user_id, datas)); tasks.push(deleteByMultiRations(datas)); async_n.waterfall(tasks, function (err, results) { if (err) { callback(err, ''); } else { callback(null, results); } }) } function deleteByID(datas, callback) { deleteAndUpdateState(datas).then(function (result) { if (result.err) { callback(result.err, ''); } else { let returndata = { moduleName: 'ration_glj', data: { updateTpye: commonConsts.UT_DELETE, query: datas.query, adjustState: result.adjustState } } callback(null, returndata) } }) } async function deleteGLJ(IDs) { await ration_glj.deleteMany({'ID': {$in: IDs}}); } async function deleteAndUpdateState(datas) { let result = { err: null } try { await ration_glj.deleteOne(datas.query); let stateResult = await glj_calculate_facade.calculateQuantity({ projectID: datas.query.projectID, rationID: datas.doc.rationID }); result.adjustState = stateResult.adjustState; } catch (err) { result.err = err; } return result; } function startingTask(processName) { return function (asyncCallBack) { var result = { processName: processName, datas: [] }; asyncCallBack(null, result); }; } function getRationsByBill(datas) { return function (results, callback) { ration.find({ projectID: datas.updateData.projectID, billsItemID: datas.updateData.ID }, function (err, rations) { if (err) { callback(err, '') } else { results.rations = rations; callback(null, results) } }) } } function deleteRationsbyBill(user_id, datas) { return function (results, callback) { let deleteInfo = { deleteInfo: {deleted: true, deleteDateTime: new Date(), deleteBy: user_id} }; ration.update({ projectID: datas.updateData.projectID, billsItemID: datas.updateData.ID }, deleteInfo, {multi: true}, (err, deleteresults) => { if (err) { callback(err, ''); } else { callback(null, results); } }); } } function deleteByMultiRations(datas) { return function (results, deleteCallBack) { var delete_tasks = []; var deleteOne = function (ration) { return function (callback) { ration_glj.deleteMany({projectID: ration.projectID, rationID: ration.ID}, function (err, result) { commonCallback(callback, result, err) }); } } let rations = results.rations; for (let i = 0; i < rations.length; i++) { delete_tasks.push(deleteOne(rations[i]._doc)); delete_tasks.push(ration_coe_facade.delete_ration_coe(rations[i]._doc)); delete_tasks.push(quantity_detail_facade.deleteByRation(rations[i]._doc)); delete_tasks.push(ration_installation_facade.deleteByRation(rations[i]._doc)); } delete_tasks.push(quantity_detail_facade.deleteByBill(datas.updateData)); async_n.parallel(delete_tasks, (err, results) => { if (err) { deleteCallBack(err, '') } else { deleteCallBack(null, results) } }) } } /* function deleteByRation(doc) { return function (callback){ ration_glj.deleteMany({projectID: doc.updateData.projectID, rationID: doc.updateData.ID},callback); } } */ function save(user_id, datas, callback) { let operations = []; if (_.isArray(datas)) { for (let i = 0; i < datas.length; i++) { operations.push(operationMap[datas[i].updateType](user_id, datas[i])); } } else { operations.push(operationMap[datas.updateType](user_id, datas)); } async_n.parallel(operations, function (err, results) { if (err) { callback(err, ''); } else { if (results.length == 1) { callback(null, results[0]) } else { callback(null, results) } } }) } async function getLibInfo(req) { let gljLibId = null, engineerID, sessionCompilation = req.session.sessionCompilation; engineerID = req.params.engineerID; if(engineerID){ gljLibId = await getGLJLibByEngineerID(engineerID); }else { throw new Error("工程专业ID为空!"); } let data = { userID: req.session.sessionUser.id, gljLibId: gljLibId, compilationId: sessionCompilation._id }; return data; } async function getGLJLibByEngineerID (engineerID) { let engineeringLibModel = new EngineeringLibModel() ; let engineeringInfo = await engineeringLibModel.findDataByCondition({'_id': engineerID}); let gljLibId = engineeringInfo.glj_lib.length > 0 && typeof engineeringInfo.glj_lib !== 'undefined' ? engineeringInfo.glj_lib[0].id : null; return gljLibId } function getGLJData(info, callback) { let gljDao = new GljDao(); let datas = {}; let gljDistTypeCache = stdgljutil.getStdGljTypeCacheObj().toArray(); datas.distTypeTree = gljDistTypeCache; async_n.parallel([ async function (cb) { try { datas.treeData = await gljDao.getMixedTree(info.gljLibId, info.userID, info.compilationId); cb(null); } catch (err) { cb(err); } }, function (cb) { gljDao.getGljItems(info.gljLibId, info.userID, info.compilationId, function (err, data) { if (err) { cb(err); } else { datas.stdGLJ = data.stdGljs; datas.complementaryGLJs = data.complementaryGljs; cb(null); } }); } ], function (err) { if (err) { callback(true, null); } else { callback(false, datas); } }) } function getGLJSearchInfo(ration_glj) { let data = { glj_id: ration_glj.GLJID, project_id: ration_glj.projectID, code: ration_glj.code, original_code: ration_glj.original_code, name: ration_glj.name, //shortName: ration_glj.shortName, specs: ration_glj.specs, unit: ration_glj.unit, type: ration_glj.subType ? ration_glj.subType : ration_glj.type,//如果有subType,则是通过插入定额级的工料机进来的 model: ration_glj.model, type_of_work: ration_glj.subType ? ration_glj.subType : ration_glj.type, base_price: ration_glj.basePrice, market_price: ration_glj.marketPrice, repositoryId: ration_glj.repositoryId, adjCoe: ration_glj.adjCoe, materialType:ration_glj.materialType, materialCoe:ration_glj.materialCoe, grossWeightCoe:ration_glj.grossWeightCoe, purchaseStorageRate:ration_glj.purchaseStorageRate, offSiteTransportLossRate:ration_glj.offSiteTransportLossRate, handlingLossRate:ration_glj.handlingLossRate, from: ration_glj.from ? ration_glj.from : 'std'//std:标准工料机库, cpt:补充工料机库 }; let glj_type_object = glj_type_util.getStdGljTypeCacheObj(); let type = glj_type_object.getItemById(data.type); data.shortName = type.shortName; if (data.from == 'cpt') {//从补充工料机来的数据即为新增数据 data.is_add = 1; } return data; } async function prepareExtData(projectID,compilation) { let ext , unitFileId ; let property = await projectDao.getProjectProperty(projectID); ext = projectDao.getExtendData(property,compilation); unitFileId = property.unitPriceFile !== undefined ? property.unitPriceFile.id : 0; return [unitFileId,ext]; } async function addGLJ(rgList,compilation) { if (rgList.length <= 0) return {}; let newRecodes = await insertAddTypeGLJ(rgList,compilation); let stateResult = await glj_calculate_facade.calculateQuantity({ projectID: rgList[0].projectID, rationID: rgList[0].rationID }); let result = { newRecodes: newRecodes, showData: rgList, adjustState: stateResult.adjustState }; return result; } async function insertAddTypeGLJ(rgList,compilation) { let newRecodes = [],GLJMap=null; let [unitFileId,ext] = await prepareExtData(rgList[0].projectID,compilation); for (let g of rgList) { let projectGljModel = new GLJListModel(); let result = await projectGljModel.addList(getGLJSearchInfo(g),unitFileId,ext); let typeString = result.type+''; g.marketPrice = result.unit_price.market_price; g.adjustPrice = result.unit_price.base_price; g.basePrice = result.unit_price.base_price; g.isAdd = result.unit_price.is_add; g.projectGLJID = result.id; if (typeString.startsWith("2")||typeString=='4'||typeString=='5') {//只有材料类型才显示是否暂估 g.isEstimate = result.is_evaluate; } g.ID = uuidV1(); if (result.hasOwnProperty('subList') && result.subList.length > 0) { g.subList = getMixRatioShowDatas(result.subList); //对于混凝土,砂浆,配合比,组成物还要插入定额工料机 if(gljUtil.isConcreteType(g.type)){ if(GLJMap == null){ let oldGLJList = await ration_glj.find({'rationID':g.rationID}); GLJMap = _.indexBy(oldGLJList,"projectGLJID"); } addMixRatioToRationGLJ(g,result.subList,newRecodes,GLJMap); } } newRecodes.push(createNewRecord(g)); } await ration_glj.insertMany(newRecodes); return newRecodes; } async function deleteRationGLJ(data){ let deleteIDs = [data.ID]; if(gljUtil.isConcreteType(data.type)){//如果是混凝土、砂浆、配合比,还要删除没有被引用的组成物工料机 let projectGljModel = new GLJListModel(); let rationGLJList = await ration_glj.find({'rationID':data.rationID}); let unitFileId = await projectDao.getUnitPriceFileId(data.projectID); let projectGLJMap = {},referenceMap={}; let deleteMix = []; for(let r of rationGLJList){ projectGLJMap[r.projectGLJID] = r; if(gljUtil.isConcreteType(r.type)){ if(r.ID == data.ID){//是要删除的工料机 deleteMix = await projectGljModel.getCompositionGLJByData(r,unitFileId); }else { let comList = await projectGljModel.getCompositionGLJByData(r,unitFileId); for(let c of comList){ referenceMap[c.id] = c; } } } } for(let d of deleteMix){ //删除不属于其它的组成物并且定额消耗为0 if(referenceMap[d.id]) continue; if(projectGLJMap[d.id]&&(projectGLJMap[d.id].rationItemQuantity == '0'||projectGLJMap[d.id].rationItemQuantity == 0)){ deleteIDs.push(projectGLJMap[d.id].ID); } } await ration_glj.deleteMany({'ID': {"$in": deleteIDs}}); } else{ await ration_glj.deleteOne({ID:data.ID}); } let calcResult = await glj_calculate_facade.calculateQuantity({ projectID: data.projectID, rationID: data.rationID }); calcResult.deleteList = deleteIDs; return calcResult; } function addMixRatioToRationGLJ(g,subList,newRecodes,GLJMap){ let newMap = {}; for(let mr of subList ){ //先查找该定额下是否已经有了工料机了,有就不用再插入了 newMap[mr.id] = mr;//新增的定额工料机映射表 if(GLJMap[mr.id]||_.find(newRecodes,{'projectGLJID':mr.id})) continue; //没有的情况下,生成一条定额工料机计录 let newMr = { projectID:g.projectID, GLJID:mr.glj_id, rationID:g.rationID, rationItemQuantity:0, quantity:0, name:mr.name, code:mr.code, original_code:mr.original_code, unit:mr.unit, specs:mr.specs, from:mr.from, createType:g.createType, shortName:mr.unit_price.short_name, billsItemID:g.billsItemID, type:mr.type, model:mr.model, repositoryId:g.repositoryId, projectGLJID:mr.id, adjCoe:mr.adjCoe }; newMr.ID = uuidV1(); newRecodes.push(newMr); } return newMap; } async function replaceGLJByData(data,compilation) { let projectGljModel = new GLJListModel(); let [unitFileId,ext] = await prepareExtData(data.projectID,compilation); let result = await projectGljModel.addList(getGLJSearchInfo(data),unitFileId,ext); let typeString = result.type+''; data.projectGLJID = result.id; // CompositionGLJ=await this.getCompositionGLJByData(data,unitPriceFileId); let [newRecodes,deleteList] = await replaceMixRatio(data,result,unitFileId); let updateResult = await ration_glj.findOneAndUpdate({ID: data.ID, projectID: data.projectID}, data);//更新定额工料机 //组装回传数据 data.marketPrice = result.unit_price.market_price; data.adjustPrice = result.unit_price.base_price; data.basePrice = result.unit_price.base_price; data.isAdd = result.unit_price.is_add; if (typeString.startsWith("2")||typeString=='4'||typeString=='5') {//只有材料类型才显示是否暂估 data.isEstimate = result.is_evaluate; } if (result.hasOwnProperty('subList') && result.subList.length > 0) { data.subList = getMixRatioShowDatas(result.subList); } return {data:data,newRecodes:newRecodes,deleteList:deleteList}; } async function replaceMixRatio(g,result,unitFileId){ let newRecodes=[],deleteList = []; if(gljUtil.isConcreteType(g.type)||gljUtil.isCommercialConcreteType(g.type)){//混凝土大类,商品混凝土属于相同大类,替换前和替换后只判断一个就好了 let IDMap = {}, projectGLJMap = {},referenceMap={},concreteList=[],newMap={}; let projectGljModel = new GLJListModel(); let rationGLJList = await ration_glj.find({'rationID':g.rationID}); for(let r of rationGLJList){ IDMap[r.ID] = r; projectGLJMap[r.projectGLJID] = r; if(gljUtil.isConcreteType(r.type)&&r.ID!=g.ID) concreteList.push(r) //除了本身,记录一下其它混凝土类型 } if (result.hasOwnProperty('subList') && result.subList.length > 0){ newMap = addMixRatioToRationGLJ(g,result.subList,newRecodes,projectGLJMap);//先生成要添加的工料机 } let oldMixList = await projectGljModel.getCompositionGLJByData(IDMap[g.ID],unitFileId); for(let c of concreteList){//找出要删除的子定额工料机(没人引用,并且定额消耗量为0) let temList = await projectGljModel.getCompositionGLJByData(c,unitFileId); for(let t of temList){ referenceMap[t.id] = t; } } for(let o of oldMixList){ if(newMap[o.id]||referenceMap[o.id]) continue;//如果两个地方有一个存在,那么就不用删除 //没有被其它地方引用并且定额消耗量为0,就删除对应的定额工料机 if(projectGLJMap[o.id] && (projectGLJMap[o.id].rationItemQuantity == '0'||projectGLJMap[o.id].rationItemQuantity == 0)) deleteList.push(projectGLJMap[o.id].ID) } } if(deleteList.length > 0) await ration_glj.deleteMany({'ID': {"$in": deleteList}});//删除定额工料机 if(newRecodes.length > 0) await ration_glj.insertMany(newRecodes); return [newRecodes,deleteList] } async function replaceGLJ(data,compilation) { let rdata = {}; let r_result =await replaceGLJByData(data,compilation); data = r_result.data; let stateResult = await glj_calculate_facade.calculateQuantity({ projectID: data.projectID, rationID: data.rationID }, null,true); rdata.data = data; rdata.adjustState = stateResult.adjustState; rdata.name = stateResult.rationName; rdata.newRecodes = r_result.newRecodes; rdata.deleteList = r_result.deleteList; rdata.glj_result = stateResult.glj_result; return rdata; } async function replaceMixRatioForMReplace(tasks,result,unitFileId) { let allNewRecodes = [],allDeleteList=[]; for(let t of tasks){ let tem = _.cloneDeep(t.updateOne.update); tem.ID = t.updateOne.filter.ID; tem.rationID = t.updateOne.filter.rationID; delete t.updateOne.filter.rationID; let [newRecodes,deleteList] = await replaceMixRatio(tem,result,unitFileId); allNewRecodes = allNewRecodes.concat(newRecodes); allDeleteList = allDeleteList.concat(deleteList); } return {newRecodes:allNewRecodes,deleteList:allDeleteList} } async function mReplaceGLJ(data,compilation) { let mresult = {},mixResult = null,noNeedCal=true; let projectGljModel = new GLJListModel(); let [unitFileId,ext] = await prepareExtData(data.doc.projectID,compilation); // let result = await projectGljModel.addList(getGLJSearchInfo(data.doc),unitFileId,ext); let typeString = result.type+''; let newDoc = {}; newDoc.projectGLJID = result.id; let rationList = [];//await ration_glj.distinct('rationID', data.query); for(let t of data.tasks){ rationList.push(t.updateOne.filter.rationID); t.updateOne.update.projectGLJID = result.id;//更新项目工料机ID } if(gljUtil.isConcreteType(result.unit_price.type)) { mixResult = await replaceMixRatioForMReplace(data.tasks,result,unitFileId); noNeedCal = null; } await ration_glj.bulkWrite(data.tasks); newDoc.marketPrice = result.unit_price.market_price; newDoc.adjustPrice = result.unit_price.base_price; newDoc.basePrice = result.unit_price.base_price; newDoc.isAdd = result.unit_price.is_add; if (typeString.startsWith("2")||typeString=='4'||typeString=='5') {//只有材料类型才显示是否暂估 newDoc.isEstimate = result.is_evaluate; } if (result.hasOwnProperty('subList') && result.subList.length > 0) { newDoc.subList = getMixRatioShowDatas(result.subList); } let [stateList,glj_result] = await changAdjustState(data, rationList,noNeedCal); data.doc = newDoc; mresult.data = data; mresult.stateList = stateList; mresult.newRecodes = mixResult?mixResult.newRecodes:[]; mresult.deleteList = mixResult?mixResult.deleteList:[]; mresult.glj_result = glj_result; return mresult } async function updateRationGLJByEdit(data) { var doc = data.doc; var result; if (doc.hasOwnProperty('customQuantity')) { result = await doCustomQuantityUpdate(data) } else { result = await doRationGLJUpdate(data); } return result; } async function updateRationGLJFromDoc(rg,doc,priceInfo) { let gljListModel = new GLJListModel(); let projectGLJ = getGLJSearchInfo(rg); for (let key in doc) { projectGLJ[key] = doc[key] } projectGLJ.base_price = priceInfo.base_price; projectGLJ.market_price = priceInfo.market_price; let projcetGLJ_n = await gljListModel.modifyGLJ(projectGLJ, rg); doc.code = projcetGLJ_n.code; doc.projectGLJID = projcetGLJ_n.id; if (projcetGLJ_n.unit_price.is_add == 1) { doc.createType = 'replace'; doc.rcode = projcetGLJ_n.original_code; } else { doc.createType = 'normal'; doc.rcode = ''; } await ration_glj.findOneAndUpdate({ID:rg.ID}, doc); return [projcetGLJ_n,doc] } async function doRationGLJUpdate(data) { let resutl = {}; let priceInfo = data.priceInfo; let rg = await ration_glj.findOne(data.query); let [projcetGLJ_n,doc] = await updateRationGLJFromDoc(rg,data.doc,priceInfo); //取价格 let gljListModel = new GLJListModel(); gljListModel.getGLJPrice(projcetGLJ_n); doc.basePrice = projcetGLJ_n.unit_price.base_price; doc.marketPrice = projcetGLJ_n.unit_price.market_price; doc.adjustPrice = projcetGLJ_n.adjust_price; doc.isAdd = projcetGLJ_n.unit_price.is_add; resutl.doc = doc; let stateResult = await glj_calculate_facade.calculateQuantity({ projectID: data.query.projectID, rationID: data.query.rationID },null,true); resutl.adjustState = stateResult.adjustState; resutl.name = stateResult.rationName; return resutl; } async function getGLJClass(info, data) { let result = { exist: false } //检查补充工料机中是否已经存在一样的记录了 let condition = { userId: info.userID, compilationId: info.compilationId, code: data.code, name: data.name, unit: data.unit, gljType: data.type, basePrice: data.basePrice } if (data.specs != null && data.specs != undefined && data.specs != '') { condition['specs'] = data.specs; } let glj = await complementaryGljModel.find(condition); if (glj.length > 0) { //如果已存在就直接返回,不用再新增了 result.exist = true; return result } //查找工料机类型树 let items = await compleClassModel.find({ userId: info.userID, compilationId: info.compilationId }); result.items = items; return result; } async function insertGLJAsRation(data,compilation) { let gljList = data.gljList; if (data.hasOwnProperty("selectedSerialNo")) { //如果需要,更新序列号。 let query = { projectID: data.projectID, billsItemID: data.billsItemID, serialNo: {$gt: data.selectedSerialNo} } await ration.update(query, {$inc: {serialNo: gljList.length}}, {multi: true}); } let [unitFileId,ext] = await prepareExtData(data.projectID,compilation); for (let glj of gljList) { let p_glj = getGLJSearchInfo(glj); let projectGljModel = new GLJListModel(); let result = await projectGljModel.addList(p_glj,unitFileId,ext);//逐条添加到项目工料机 let typeString = result.type+''; glj.marketPrice = result.unit_price.market_price; glj.adjustPrice = result.unit_price.base_price; glj.basePrice = result.unit_price.base_price; glj.isAdd = result.unit_price.is_add; glj.projectGLJID = result.id; if (typeString.startsWith("2")||typeString=='4'||typeString=='5') {//只有材料类型才显示是否暂估 glj.isEstimate = result.is_evaluate; } } await ration.insertMany(gljList); return gljList; } async function getRationTypeGLJQuantity(projectID) { let rations = await ration.find({'projectID': projectID,'type':3,'deleteInfo': null}, ['ID', 'projectGLJID','quantity']); return rations; } async function changAdjustState(data, rationList,noNeedCal) { let stateList = [],glj_result=[]; for (let r of rationList) { let stateResult = await glj_calculate_facade.calculateQuantity({ projectID: data.query.projectID, rationID: r }, noNeedCal,true); if(stateResult){ stateList.push({rationID: r, adjustState: stateResult.adjustState,name:stateResult.rationName}); glj_result = glj_result.concat(stateResult.glj_result) } } return [stateList,glj_result]; } async function getGLJDataByCodes(data,compilation) { let gljLibId = await getGLJLibByEngineerID(data.engineerID); let gljDatas = []; if(gljLibId){ let stdList = await std_glj_lib_gljList_model.find({'repositoryId':gljLibId,code:{'$in':data.codes}}); if(stdList.length > 0){ let property = await projectDao.getProjectProperty(data.projectID); let ext = projectDao.getExtendData(property,compilation);//多单价处理 for(let s of stdList){ let tem = JSON.parse(JSON.stringify(s)); if(ext && ext.priceField && tem && tem.priceProperty){ tem.basePrice = tem.priceProperty[ext.priceField]; } gljDatas.push(tem); } } } return gljDatas } async function testError() { throw new Error('test Error'); } function getData(projectID, callback) { ration_glj.find({'projectID': projectID}, (err, datas) => { if (err) { callback(1, '', null); } else { callback(0, consts.projectConst.RATION_GLJ, datas); } }) } function commonCallback(callback, result, err) { if (err) { callback(err, ''); } else { callback(null, result); } }