| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460 | /** * Created by zhang on 2018/2/9. */let mongoose = require('mongoose');import SearchDao from '../../complementary_ration_lib/models/searchModel';const scMathUtil = require('../../../public/scMathUtil').getUtil();let ration_glj_facade = require("../../ration_glj/facade/ration_glj_facade");let quantity_detail = require("../facade/quantity_detail_facade");let ration_glj = mongoose.model('ration_glj');let ration_coe = mongoose.model('ration_coe');let ration_model = require('../models/ration');let bill_model = require('../models/bills');let decimal_facade = require('./decimal_facade');let installationFeeModel = mongoose.model("installation_fee");let rationInstallationModel = mongoose.model('ration_installation');const uuidV1 = require('uuid/v1');let std_glj_lib_gljList_model = mongoose.model('std_glj_lib_gljList');let complementary_glj_model =  mongoose.model('complementary_glj_lib');let coeMolde = mongoose.model('std_ration_lib_coe_list');let _= require('lodash');const projectDao = require('../../pm/models/project_model').project;let projectModel = mongoose.model('projects');module.exports = {    replaceRations: replaceRations,    addNewRation:addNewRation,    addMultiRation: addMultiRation};async function addNewRation(data) {    let query = data.itemQuery;    let stdRation = null;    let startTime = +new Date();    if(query){        let searchDao = new SearchDao();        stdRation = await searchDao.getRationItem(query.userID,[query.rationRepId],query.code, query.ID);        //data.newData.code = query.code;    }    let stdRationTime = +new Date();    console.log("取std定额时间-------------------------------"+(stdRationTime - startTime));    if(data.brUpdate.length>0){        await updateSerialNo(data.brUpdate);    }    let newRation =await insertNewRation(data.newData,data.firstLibID,stdRation,data.calQuantity);    let addRationGLJTime = +new Date();    console.log("插入新定额时间-------------------------------"+(addRationGLJTime - stdRationTime));    if(stdRation){        return await addRationSubList(stdRation,newRation,data.needInstall);    }else {        return {ration:newRation};    }}async function addMultiRation(datas) {    let rst = [];    for(let data of datas){        let r = await addNewRation(data);        rst.push(r);    }    return rst;}async function  updateSerialNo(serialNoUpdate){    let tasks=[];    for(let data of serialNoUpdate){        let task={            updateOne:{                filter:{                    ID:data.ID,                    projectID:data.projectID                },                update :{                    serialNo:data.serialNo                }            }        };        tasks.push(task);    }    await ration_model.model.bulkWrite(tasks);}async function insertNewRation(newData,firstLibID,std,calQuantity) {//插入新的定额    let startTime = +new Date();    if(std){        newData.code = std.code;        newData.name = std.name;        newData.caption = std.caption;        newData.unit = std.unit;        newData.libID = std.rationRepId;        newData.content = std.jobContent;        newData.annotation = std.annotation;        if (std.chapter) {            newData.comments = std.chapter.explanation;            newData.ruleText = std.chapter.ruleText;        }        newData.prefix = '';        newData.from = std.type === 'complementary' ? 'cpt' : 'std';        if(firstLibID !== std.rationRepId){//借            newData.prefix = '借';        }        else if(std.rationRepId === firstLibID && newData.from === 'cpt') {            newData.prefix = '补';        }        newData.programID = std.feeType;        newData.rationAssList =  createRationAss(std);        // calculate ration Quantity    }    if(calQuantity){        await CalculateQuantity(newData,newData.billsItemID,newData.projectID);    }    let addRationGLJTime = +new Date();    console.log("计算消耗量时间-------------------------------"+(addRationGLJTime - startTime));    console.log(newData);    let newRation = await ration_model.model.create(newData);    return newRation;    /*ration_model.model.create(newData);    return newData;*/}async function replaceRations(userID,data) {    let searchDao = new SearchDao();    let recodes = [];    for(let recode of data.nodeInfo){        let stdRation = await searchDao.getRationItem(userID,data.libIDs,recode.newCode, null);        let newRecode = await replaceRation(recode,stdRation,data.firstLibID,data.projectID,data.calQuantity);        if(newRecode){            recodes.push(newRecode);        }else {            break;        }    }    return recodes;}async function replaceRation(nodeInfo,stdRation,firstLibID,projectID,calQuantity) {    if(nodeInfo.newCode == null||nodeInfo.newCode ==""){//说明是删除编号,则要变成一条空定额        await deleRationSubRecode(projectID,nodeInfo.ID);//删除定额下挂的各种数据,如定额工料机等        return await setEmptyRation(projectID,nodeInfo.ID);    }else if(stdRation){        await deleRationSubRecode(projectID,nodeInfo.ID);//删除定额下挂的各种数据,如定额工料机等        let newRation = await updateRation(stdRation,firstLibID,nodeInfo.ID,nodeInfo.billsItemID,projectID,calQuantity);//生成并插入新的定额        return await addRationSubList(stdRation,newRation,nodeInfo.needInstall);    }else {        return null;    }}async function addRationSubList(stdRation,newRation,needInstall) {    let startTime = +new Date();    let ration_gljs = await addRationGLJ(stdRation,newRation);    let addRationGLJTime = +new Date();    console.log("添加定额工料机时间-----"+(addRationGLJTime - startTime));    let ration_coes = await addRationCoe(stdRation,newRation);    let addRationCoeTime = +new Date();    console.log("添加定额coe时间-----"+(addRationCoeTime - addRationGLJTime));    let ration_installs = [];    if(needInstall){        ration_installs =  await addRationInstallFee(stdRation,newRation);    }    let addRationInstallFeeTime = +new Date();    console.log("添加定额install时间-----"+(addRationInstallFeeTime - addRationCoeTime));    return {ration:newRation,ration_gljs:ration_gljs,ration_coes:ration_coes,ration_installs:ration_installs};}async function addRationInstallFee(std,newRation) {    let install_fee_list = [];    if(std.hasOwnProperty('rationInstList') && std.rationInstList.length > 0){        let installFee = await installationFeeModel.findOne({'projectID': newRation.projectID});        for(let ri of std.rationInstList){            let feeItem = _.find(installFee.installFeeItem,{'ID':ri.feeItemId});            let section = _.find(installFee.installSection,{'ID':ri.sectionId});            if(feeItem&§ion){                let tem_r_i = {                    libID:installFee.libID,                    projectID:newRation.projectID,                    rationID:newRation.ID,                    feeItemId:feeItem.ID,                    sectionId:section.ID,                    itemName:feeItem.feeItem,                    feeType:feeItem.feeType,                    sectionName:section.name,                    unifiedSetting:1,                    ruleId:''                };                if(feeItem.isCal==1&§ion.feeRuleId&§ion.feeRuleId!=''){//勾选记取时并且有规则ID时才读取                    let feeRule = _.find(installFee.feeRule,{'ID':section.feeRuleId});                    if(feeRule){                        tem_r_i.ruleId = feeRule.ID;                    }                }                tem_r_i.ID = uuidV1();                install_fee_list.push(tem_r_i);            }        }        if(install_fee_list.length>0){            await rationInstallationModel.insertMany(install_fee_list);        }    }    return install_fee_list;}async function addRationCoe(std,newRation) {    let ration_coe_list = [];    let seq = 0;    if(std.hasOwnProperty('rationCoeList')&&std.rationCoeList.length>0){//添加标准库的工料机        for(let sub of std.rationCoeList){            let libCoe = await coeMolde.findOne({'libID':std.rationRepId,'ID':sub.ID,"$or": [{"isDeleted": null}, {"isDeleted": false}]});//std.rationRepId;            if(libCoe){                let newCoe = {};                newCoe.ID = uuidV1();                newCoe.coeID = sub.ID;                newCoe.seq = seq;                newCoe.name = libCoe.name;                newCoe.content = libCoe.content;                newCoe.isAdjust=0;                newCoe.coes = libCoe.coes;                newCoe.rationID = newRation.ID;                newCoe.projectID = newRation.projectID;                seq++;                ration_coe_list.push(newCoe);            }        }    }    let lastCoe ={        coeID:-1,        name : '自定义系数',        content:'人工×1,材料×1,机械×1,主材×1,设备×1',        isAdjust:0,        seq:seq,        rationID : newRation.ID,        projectID : newRation.projectID    };    lastCoe.ID = uuidV1();    lastCoe.coes = getCustomerCoeData();    ration_coe_list.push(lastCoe);    await ration_coe.insertMany(ration_coe_list);    return ration_coe_list;}function getCustomerCoeData() {    var coeList = [];    coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'定额'});    coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'人工'});    coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'材料'});    coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'机械'});    coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'主材'});    coeList.push({ amount:1, operator:'*', gljCode:null, coeType:'设备'});    return coeList;};async function addRationGLJ(std,newRation) {    let newRationGLJList = [];    let rationGLJShowList = [];    let unitPriceFileId = await projectDao.getUnitPriceFileId(newRation.projectID);    let sum=0;    let first = +new Date();    if(std.hasOwnProperty('rationGljList') && std.rationGljList.length > 0){        let stdGLJID =[];//标准工料机ID数组        let cptGLJID=[];//补充工料机ID数组            //let stdGLJID = _.map(std.rationGljList,'gljId');        for(let tem_g  of std.rationGljList){             if(tem_g.type == 'complementary'){                cptGLJID.push(tem_g.gljId);             }else {                stdGLJID.push(tem_g.gljId);             }        }       let stdGLJList = stdGLJID.length > 0 ? await std_glj_lib_gljList_model.find({'ID':{'$in':stdGLJID}}):[];//速度优化-------先一次性取出所有的工料机列表       let stdGLJMap = _.indexBy(stdGLJList, 'ID');       let cptGLJList =  cptGLJID.length > 0 ? await complementary_glj_model.find({'userId':std.userId,'ID':{'$in':cptGLJID}}):[];       let cptGLJMap = _.indexBy(cptGLJList, 'ID');        let stdGLJMapTime = +new Date();        console.log("找到工料机映射表时间-------------------------------"+(stdGLJMapTime - first));        for(let sub of std.rationGljList){            let newGLJ = {};            newGLJ.ID = uuidV1();            newGLJ.projectID = newRation.projectID;            newGLJ.GLJID = sub.gljId;            newGLJ.rationID = newRation.ID;            newGLJ.billsItemID = newRation.billsItemID;            newGLJ.rationItemQuantity = sub.consumeAmt;            newGLJ.quantity = sub.consumeAmt;            newGLJ.glj_repository_id = std.rationRepId;            let std_glj = null;            if(sub.type == 'complementary'){//有可能来自标准工料机库或补充工料机库                std_glj = cptGLJMap[sub.gljId];                newGLJ.from = 'cpt';            }else {               std_glj = stdGLJMap[sub.gljId];               newGLJ.from = 'std';            }            let std_gljTime = +new Date();            if(std_glj){                newGLJ.name = std_glj.name;                newGLJ.code = std_glj.code;                newGLJ.original_code = std_glj.code;                newGLJ.unit = std_glj.unit;                newGLJ.specs = std_glj.specs;                newGLJ.model = std_glj.model;                newGLJ.basePrice = std_glj.basePrice;                newGLJ.marketPrice = std_glj.basePrice;                newGLJ.shortName = std_glj.shortName;                newGLJ.type = std_glj.gljType;                newGLJ.repositoryId = std_glj.repositoryId;                newGLJ.adjCoe = std_glj.adjCoe;                newGLJ.materialType = std_glj.materialType;                newGLJ.materialCoe = std_glj.materialCoe;                newGLJ.createType = 'normal';                let info = await  ration_glj_facade.getInfoFromProjectGLJ(newGLJ,unitPriceFileId);                newGLJ = ration_glj_facade.createNewRecord(info);                newRationGLJList.push(newGLJ);                rationGLJShowList.push(info);            }            let InfoFromProjectGLJ = +new Date();            console.log("找到项目工料机时间-------------------------------"+(InfoFromProjectGLJ - std_gljTime));        }    }    let before = +new Date();    console.log("总查询时间为-------------------------------"+(before-first));    if(newRationGLJList.length>0){        await ration_glj.insertMany(newRationGLJList);    }    let after = +new Date();    console.log("实际插入时间为-------------------------------"+(after-before));    console.log("总操作时间为-------------------------------"+(after-first));    return rationGLJShowList;}async function deleRationSubRecode(projectID,rationID) {//删除挂在定额下的数据,如工程量明细,定额工料机等    let delete_query={projectID: projectID, rationID: rationID};    //删除工程量明细    await quantity_detail.deleteByQuery(delete_query) ;    await ration_coe.deleteMany(delete_query);//删除附注条件    await ration_glj.deleteMany(delete_query);//删除定额工料机    await rationInstallationModel.deleteMany(delete_query);//删除安装增加费}async function  updateRation(std,firstLibID,rationID,billsItemID,projectID,calQuantity) {    // insertNewRation    let ration ={};    ration.code = std.code;    ration.name = std.name;    ration.caption = std.caption;    ration.unit = std.unit;    ration.libID = std.rationRepId;    ration.content = std.jobContent;    ration.adjustState = '';    ration.isFromDetail=0;    ration.isSubcontract=false;    ration.fees=[];    if (std.chapter) {        ration.comments = std.chapter.explanation;        ration.ruleText = std.chapter.ruleText;    }    ration.from = std.type === 'complementary' ? 'cpt' : 'std';    //定额前缀 none:0, complementary:1, borrow: 2    ration.prefix = '';    //借用优先级比补充高    if(std.rationRepId !== parseInt(firstLibID)){//借用        ration.prefix = '借';    }    else if(std.rationRepId === firstLibID && ration.from === 'cpt') {        ration.prefix = '补';    }    if(std.feeType == undefined || std.feeType == null || std.feeType ==''){//定额取费专业为空的情况下,取项目属性中的定额取费专业ID        ration.programID = await getProgramForProject(projectID);    }else {        ration.programID = std.feeType;    }    ration.rationAssList = createRationAss(std);//生成辅助定额    if(calQuantity){       await CalculateQuantity(ration,billsItemID,projectID);    }     let unsetObject = {         "marketUnitFee":1,         'marketTotalFee':1,         "maskName":1     }    let newRation = await ration_model.model.findOneAndUpdate({ID:rationID,projectID:projectID},{"$set":ration,"$unset":unsetObject},{new: true});//;    return newRation;}async function setEmptyRation(projectID,rationID){    let ration ={};    ration.code = "";    ration.name = "";    ration.caption = "";    ration.unit = "";    ration.libID = null;    ration.content = "";    ration.adjustState = '';    ration.isFromDetail=0;    ration.isSubcontract=false;    ration.fees=[];    ration.comments = "";    ration.ruleText = "";    ration.quantity="";    ration.contain="";    ration.quantityEXP="";    ration.from = 'std';    //定额前缀 none:0, complementary:1, borrow: 2    ration.prefix = '';    ration.rationAssList = [];    ration.marketUnitFee ="";    ration.marketTotalFee ="";    ration.maskName = "";    ration.targetTotalFee ='';    ration.targetUnitFee = "";    ration.deleteInfo = null;    ration.quantityCoe = {};    ration.rationQuantityCoe="";    ration.tenderQuantity = "";    ration.programID = null;    let newRation = await ration_model.model.findOneAndUpdate({ID:rationID,projectID:projectID},{"$set":ration},{new: true});//;    return {ration:newRation,ration_gljs:[],ration_coes:[],ration_installs:[]};}function createRationAss(std) {    let  rationAssList = [];//生成辅助定额    if(std.hasOwnProperty('rationAssList')&&std.rationAssList.length>0){        for(let i=0;i<std.rationAssList.length;i++){            let ass = std.rationAssList[i];            ass.actualValue = ass.stdValue;            rationAssList.push(ass);        }    }    return rationAssList;}async function CalculateQuantity (ration,billsItemID,projectID) {    // calculate ration Quantity    let project = await projectModel.findOne({ID:projectID});    let decimalObject =await decimal_facade.getProjectDecimal(projectID,project);    let quantity_decimal = (decimalObject&&decimalObject.ration&&decimalObject.ration.quantity)?decimalObject.ration.quantity:3;    let pbill = await bill_model.model.findOne({projectID:projectID,ID:billsItemID});    let billsQuantity = pbill.quantity ? pbill.quantity : 0;    let bill_decimal = await decimal_facade.getBillsQuantityDecimal(projectID,pbill.unit,project);    billsQuantity=scMathUtil.roundForObj(billsQuantity,bill_decimal);    ration.quantityEXP="QDL";    ration.quantity = scMathUtil.roundForObj(billsQuantity / FilterNumberFromUnit(ration.unit),quantity_decimal);//不管是否打勾都做转换    ration.contain =  scMathUtil.roundForObj(ration.quantity/billsQuantity,6);};async function getProgramForProject(projectID){    let project = await projectModel.findOne({ID:projectID});    return project.property.engineering;}function FilterNumberFromUnit (unit) {    let reg = new RegExp('^[0-9]+');    if (reg.test(unit)) {        return parseInt(unit.match(reg)[0]);    } else {        return 1;    }};
 |