/** * 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{ 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); } }