| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642 | /** * Created by chen on 2017/7/20. *//** * Created by chen on 2017/7/10. */let mongoose = require('mongoose');let consts = require('../../main/models/project_consts');let commonConsts = consts.commonConst;let _=require("lodash");let async_n = require("async");let quantity_detail_model = mongoose.model('quantity_detail');const uuidV1 = require('uuid/v1');let ration_model = mongoose.model('ration');let bill_model=mongoose.model("bills");const scMathUtil = require('../../../public/scMathUtil').getUtil();module.exports={    save:save,    getData:getData,    deleteByRation:deleteByRation,    deleteByBill:deleteByBill,    quantityEditChecking:quantityEditChecking,};let operationMap={    'ut_create':create_quantity_detail,    'ut_update':update_quantity_detail,    'ut_delete':delete_quantity_detail};let updateFunctionMap = {    'normalUpdate':normalUpdate,    'updateQuantityRegex':updateQuantityRegex,    'insertRecode':insertRecode}function create_quantity_detail(user_id,datas) {    return function (callback) {        let doc = datas.doc;        doc.ID = uuidV1();        if(doc.hasOwnProperty('regex')){            insertRecodeWithReg(doc).then(function (resultObject) {                if(resultObject.err){                    callback(null,{                        moduleName:consts.projectConst.QUANTITY_DETAIL,                        err:{                            message:result.err.message                        }                    });                } else {                    callback(null,resultObject.return_list);                }            })        }else {            createNormalRecode(doc,callback)        }    }}function insertRecode(user_id,datas) {    return function (callback) {        let doc = datas.doc;        doc.ID = uuidV1();        doInsertRecode(doc).then(function (result) {            //console.log(result);            if(result.err){                callback(result.err,'')            }else {                callback(null,result.returndata)            }        })    }}async function doInsertRecode(doc) {    let result={        err:null    }    try{        let query = {            projectID:doc.projectID,            seq : { $gte: doc.seq }        }        if(doc.hasOwnProperty('rationID')){            query.rationID = doc.rationID;        }else {            query.billID = doc.billID;        }        let quantity_detail_List = await getDatailList(doc,{data:{}});        let update_task = getUpdateReferenceTask(quantity_detail_List,doc.seq,1);        await quantity_detail_model.update(query,{$inc:{seq:1}},{multi: true});        if(update_task.length>0){            await quantity_detail_model.bulkWrite(generateUpdateTaks(update_task));        }        let newrecode = await quantity_detail_model.create(doc);        let returndata ={            updateTpye:commonConsts.UT_CREATE,            moduleName:consts.projectConst.QUANTITY_DETAIL,            data:{                doc:newrecode,                resort:true,                update_task:update_task            }        };        result.returndata =returndata        return result;    }catch (error){        console.log(error)        result.err;        return result    }}function getUpdateReferenceTask(quantity_detail_List,seq,re) {    let update_task=[];    for(let q of quantity_detail_List){        let need_update =false;        let newReg = q.regex;        let newReferenceIndex;        if(q.referenceIndexs.length>0){            for (let i =0;i< q.referenceIndexs.length;i++){                if(q.referenceIndexs[i]>seq){                    newReg = replaceAll('C'+q.referenceIndexs[i],'C'+(q.referenceIndexs[i]+re),newReg);                    newReg = replaceAll('c'+q.referenceIndexs[i],'c'+(q.referenceIndexs[i]+re),newReg);                    q.referenceIndexs[i] +=re;                    need_update = true;                }            }        }        if(need_update){            newReferenceIndex = q.referenceIndexs;            let task ={                query:{                    ID:q.ID,                    projectID:q.projectID                },                doc:{                    regex:newReg,                    referenceIndexs:newReferenceIndex                }            }            update_task.push(task);        }    }    return update_task;}function createNormalRecode(doc,callback) {    quantity_detail_model.create(doc,(err,result)=>{        if(err){            callback(err,null);        }else {            console.log(result);            let returndata ={                updateTpye:commonConsts.UT_CREATE,                moduleName:consts.projectConst.QUANTITY_DETAIL,                data:result            }            callback(null,returndata)        }    });}async function insertRecodeWithReg (doc) {    let returnObjec={        err:null,        return_list:[]    }    try {        let returnData={            moduleName:'',            data:{                updateTpye:commonConsts.UT_UPDATE,            }        }        let regex = doc.regex.toUpperCase();        let referenceIndexs = doc.referenceIndexs;        let detailList = await getDatailList(doc,returnData);        doc.result =getEvalResult(referenceIndexs,detailList,regex);        let refreshQuantity =false;        if(doc.refreshQuantity==true){            refreshQuantity = true;        }        delete doc.refreshQuantity;        let newRecode = await quantity_detail_model.create(doc) ;        detailList.push(newRecode);        if(refreshQuantity==true){            returnData.data.quantity = await summateResuts(doc,detailList);            returnData.data.quantityRefresh = true;            returnObjec.return_list.push(returnData);        }        returnObjec.return_list.push({            updateTpye:commonConsts.UT_CREATE,            moduleName:consts.projectConst.QUANTITY_DETAIL,            data:newRecode        });        return returnObjec;    }catch (error){        returnObjec.err = new Error('输入的表达式有误,请重新输入!');        console.log(error)        return returnObjec;    }}function normalUpdate(user_id,datas) {    return function(callback) {        if(datas.doc.hasOwnProperty('isSummation')){            doIsSummationUpdate(datas.query,datas.doc).then(function (sresult) {                let returndata ={                    moduleName:consts.projectConst.QUANTITY_DETAIL,                    data:{                        updateTpye:commonConsts.UT_UPDATE,                        query:datas.query,                        doc:datas.doc                    }                }                let retrunArr = [];                retrunArr.push(returndata);                if(sresult){                    retrunArr.push(sresult);                }                callback(null,retrunArr);            })        }else {            updateRecored(datas.query,datas.doc,callback);        }    }}function updateQuantityRegex(user_id,datas) {    return function(callback){        doRegexUpdate(datas).then(function (result) {            if(result.err){                callback(null,{                    moduleName:consts.projectConst.QUANTITY_DETAIL,                    err:{                        message:result.err.message                    }                });            }else {                callback(null,result.rList);            }        })    }}async function doIsSummationUpdate(query,doc) {    try {        let returnData={            moduleName:'',            data:{                updateTpye:commonConsts.UT_UPDATE,            }        }        let  refreshQuantity=false;        if(query.refreshQuantity==true){            refreshQuantity=true;        }        delete query.refreshQuantity;        let updateDoc = await quantity_detail_model.update(query,doc);        let detailList = await getDatailList(query,returnData);        if(refreshQuantity==true){            let quantity = await summateResuts(query,detailList);            returnData.data.quantity = quantity;            returnData.data.quantityRefresh = true;            return returnData;        }else {            return null;        }    }catch (error){        console.log(error)    }}async function getDatailList(query,resultObject) {    let detailList = [];    if(query.hasOwnProperty('rationID')){        detailList = await quantity_detail_model.find({'projectID':query.projectID,'rationID':query.rationID}).sort('seq').exec();        resultObject.moduleName = consts.projectConst.RATION;        resultObject.data.rationID=query.rationID;    }else {        detailList = await quantity_detail_model.find({'projectID':query.projectID,'billID':query.billID}).sort('seq').exec();        resultObject.moduleName = consts.projectConst.BILLS;        resultObject.data.billID=query.billID;    }    return detailList;}async function doRegexUpdate(datas) {    let resultObjec ={        err:null,        rList:[]    }    try {        let detailList = [];        let quantityResult ={            moduleName:'',            data:{                updateTpye:commonConsts.UT_UPDATE,                quantityRefresh:true            }        }        if(datas.query.hasOwnProperty('rationID')){            detailList = await quantity_detail_model.find({'projectID':datas.query.projectID,'rationID':datas.query.rationID}).sort('seq').exec();            quantityResult.moduleName = consts.projectConst.RATION;            quantityResult.data.rationID = datas.query.rationID;        }else {            detailList = await quantity_detail_model.find({'projectID':datas.query.projectID,'billID':datas.query.billID}).sort('seq').exec();            quantityResult.data.billID = datas.query.billID;            quantityResult.moduleName = consts.projectConst.BILLS;        }        let regex;        let result;        if(datas.doc.regex==null){            result=0            datas.doc.referenceIndexs=[];        }else {            regex = datas.doc.regex.toUpperCase();            let referenceIndexs = datas.doc.referenceIndexs;            result =getEvalResult(referenceIndexs,detailList,regex);        }        detailList[datas.query.index].result =result;        detailList[datas.query.index].regex=datas.doc.regex;        detailList[datas.query.index].referenceIndexs =datas.doc.referenceIndexs;        let updateTasks =[];        datas.doc.result=result;        updateTasks.push({            query:{                ID:datas.query.ID,                projectID:datas.query.projectID            },            doc:datas.doc        })        updateReferenceRecode(datas.query.index+1,detailList,updateTasks);        let updateEdit = await quantity_detail_model.bulkWrite(generateUpdateTaks(updateTasks));        resultObjec.rList.push(gernerateResultList(updateTasks));        if(datas.query.refreshQuantity==true){            quantityResult.data.quantity = await summateResuts(datas.query,detailList);            resultObjec.rList.push(quantityResult);        }        return resultObjec;    }catch (error){        console.log(error);        resultObjec.err=error;        return resultObjec    }}function gernerateResultList(updateTasks) {    let returndata ={        moduleName:consts.projectConst.QUANTITY_DETAIL,        data:{            updateTpye:commonConsts.UT_UPDATE,            refreshList:updateTasks        }    }    return returndata;}function updateReferenceRecode(index,detailList,updateTasks) {    for(let d of detailList){        if(_.includes(d.referenceIndexs,index)){            let tResult = getEvalResult(d.referenceIndexs,detailList,d.regex);            let t = {                query:{                    ID:d.ID,                    projectID:d.projectID                },                doc:{                    result:tResult                }            };            d.result = tResult;            updateTasks.push(t);            updateReferenceRecode(d.seq+1,detailList,updateTasks);        }    }}async function summateResuts (query,detailList) {    let quantity = 0;    for(let d of detailList){        if(d.isSummation==1){            let result = d.result==null||d.result==undefined?0:d.result            quantity+=result;        }    }    quantity = quantity.toFixed(4);    if(query.hasOwnProperty('rationID')){        await ration_model.update({'ID':query.rationID,'projectID':query.projectID,deleteInfo: null},{quantity:quantity,isFromDetail:1});    }else {        await bill_model.update({'ID':query.billID,'projectID':query.projectID,deleteInfo: null},{quantity:quantity,isFromDetail:1});    }    return quantity}function  getEvalResult(referenceIndexs,detailList,regex) {    try {        for(let i of referenceIndexs){            regex = replaceReference(i,detailList,regex)        }        console.log('replace all C reference -----'+regex);        regex =replaceSqr(regex);        console.log('replace all sqar reference -----'+regex);        return scMathUtil.roundTo(eval(regex), -4);    }catch (error){        console.log(error);        throw new Error('输入的表达式有误,请重新输入!');    }}function  generateUpdateTaks(updateTasks) {    var tasks=[];    for(let u of updateTasks){        let t ={            updateOne:{                filter:u.query,                update: u.doc            }        }        tasks.push(t);    }    return tasks;}function replaceReference(index,detailList,str) {    str=str.toUpperCase();    let rstr= detailList[index-1].regex==null?'0':'('+detailList[index-1].regex+')';    str=replaceAll('C'+index,rstr,str);    if(detailList[index-1].referenceIndexs.length>0){        for (let i of detailList[index-1].referenceIndexs){            str =replaceReference(i,detailList,str);        }    }    return str;}function replaceAll (FindText, RepText,str) {    let regExp = new RegExp(FindText, "g");    return str.replace(regExp, RepText);}function replaceSqr(text) {    var squarRegex = /\([^\^]+\)\^\d+/g;    var sqararr = text.match(squarRegex);    var squarRegex2 = /C[0-9]+\^\d+|[0-9]+([.]{1}[0-9]+){0,1}\^\d+/g; //匹配没有括号的    var sqararr2=text.match(squarRegex2);    if(sqararr){        text=converSqrByArr(sqararr,text);    }    if(sqararr2){        text=converSqrByArr(sqararr2,text);    }    return text;}function converSqrByArr (sqararr,text) {    var temp = text;    sqararr.forEach(function (item) {        var arr = item.split('\^');        var y = parseInt(arr[1]);        var x_arr = [];        for (var i = 0; i < y; i++) {            x_arr.push(arr[0]);        }        var temStr = x_arr.join('*');        temp = temp.replace(item, temStr);    });    return temp;};function updateRecored(query,doc,callback) {    quantity_detail_model.update(query,doc,(err,result)=>{        if(err){            callback(err,'');        }else {            let returndata ={                moduleName:consts.projectConst.QUANTITY_DETAIL,                data:{                    updateTpye:commonConsts.UT_UPDATE,                    query:query,                    doc:doc                }            }            callback(null,returndata);        }    })}function update_quantity_detail(user_id,datas) {    if(datas.updateFunction){        return updateFunctionMap[datas.updateFunction](user_id,datas);    }else {        return normalUpdate(user_id,datas);    }}function delete_quantity_detail(user_id,datas) {    return function (callback) {        doQuantityDelete(datas.doc).then(function (result) {            if(result.err){                callback(result.err,'')            }else {                callback(null,result.returndata)            }        });    }}async function doQuantityDelete(doc) {;    let result={        err:null    }    try{        let query = {            projectID:doc.projectID,            seq : { $gt: doc.seq }        }        if(doc.hasOwnProperty('rationID')){            query.rationID = doc.rationID;        }else {            query.billID = doc.billID;        }        let quantity_detail_List = await getDatailList(doc,{data:{}});        let update_task = getUpdateReferenceTask(quantity_detail_List,doc.seq,-1);        await quantity_detail_model.update(query,{$inc:{seq:-1}},{multi: true});        if(update_task.length>0){            await quantity_detail_model.bulkWrite(generateUpdateTaks(update_task));        }        await quantity_detail_model.deleteOne({ID:doc.ID,projectID:doc.projectID});        let returndata ={            moduleName:consts.projectConst.QUANTITY_DETAIL,            data:{                doc:doc,                resort:true,                update_task:update_task,                updateTpye:commonConsts.UT_DELETE            }        };        result.returndata =returndata        return result;    }catch (error){        console.log(error)        result.err;        return result    }}function getData(projectID, callback) {    quantity_detail_model.find({'projectID':projectID}).sort('seq').exec((err,datas)=>{        if(err){            callback(1, '', null);        }else {            callback(0, consts.projectConst.QUANTITY_DETAIL, datas);        }    })}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)            }        }    })}function deleteByRation(data) {    return function (callback) {        quantity_detail_model.deleteMany({projectID: data.projectID, rationID: data.ID},(err,result)=>{            commonCallback(callback,result,err);        });    }}function deleteByBill(data) {    return function (callback) {        console.log({projectID: data.projectID, billID: data.ID});        quantity_detail_model.deleteMany({projectID: data.projectID, billID: data.ID},(err,result)=>{            commonCallback(callback,result,err);        });    }}function quantityEditChecking(doc,type,functions) {    if(doc.updateType == commonConsts.UT_UPDATE&&doc.updateData.hasOwnProperty('isFromDetail')&&doc.updateData.isFromDetail==0) {        if(type=='bills'){            functions.push(deleteByBill(doc.updateData));        }else if(type=='ration'){            functions.push(deleteByRation(doc.updateData));        }    }}function commonCallback(callback,result,err) {    if(err){        callback(err,'');    }else {        callback(null,result);    }}
 |