| 
					
				 | 
			
			
				@@ -0,0 +1,237 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Created by chen on 2017/7/12. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let mongoose = require('mongoose'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let _=require("lodash"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let ration_glj = mongoose.model('ration_glj'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let ration = mongoose.model('ration'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let ration_coe = mongoose.model('ration_coe'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let std_ration_lib_ration_items = mongoose.model('std_ration_lib_ration_items'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+module.exports={ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    calculateQuantity:calculateQuantity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//辅助定额调整、替换工料机、标准附注条件调整、添加工料机、自定义消耗量(包括删除工料机)、自定义乘系数、市场单价调整 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+let stateSeq ={ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ass:1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    replase:2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    coe:3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    add:4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cusQuantity:5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cusCoe:6, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    adjMak:7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+async function calculateQuantity(query,isMarkPriceAjust){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         let  result ={ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             glj_result:[], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             rationID:query.rationID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         let impactRation = await ration.findOne({projectID:query.projectID,ID:query.rationID}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         let gljList = await ration_glj.find(query)//{projectID:query.projectID,rationID:query.rationID} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         let coeList = await ration_coe.find({projectID:query.projectID,rationID:query.rationID}).sort('seq').exec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         let assList=[]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         let assRation = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         let adjustState=[]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         if(impactRation._doc.hasOwnProperty("rationAssList")&&impactRation.rationAssList.length>0){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             for(let i=0;i<impactRation.rationAssList.length;i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 let times = calculateTimes(impactRation.rationAssList[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 if(times!=0){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     assRation = await  std_ration_lib_ration_items.findOne({rationRepId:impactRation.libID,code:impactRation.rationAssList[i].assistCode}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     assList.push({times:times,assRation:assRation}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     adjustState.push({index:stateSeq.ass,content:impactRation.rationAssList[i].name+" "+impactRation.rationAssList[i].actualValue+" : +"+impactRation.rationAssList[i].assistCode+"x"+times}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         for(let i =0;i<gljList.length;i++ ){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             let r = await calculateQuantityPerGLJ(gljList[i],impactRation,coeList,assList,adjustState,isMarkPriceAjust); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             result.glj_result.push(r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         console.log(result.glj_result); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(isMarkPriceAjust==null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            await ration_glj.bulkWrite(generateUpdateTasks(result.glj_result)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         adjustState= _.sortByOrder(adjustState, ['index'], ['asc']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         adjustState=_.map(adjustState, _.property('content')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         let adjustStateString = adjustState.join(';'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         await ration.update({projectID:query.projectID,ID:query.rationID},{adjustState:adjustStateString}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         result.adjustState=adjustStateString; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }catch (err){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        console.log(err); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function generateUpdateTasks(result) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let tasks = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for(let i =0;i<result.length;i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let task= { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            updateOne: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                filter: result[i].query, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                update: result[i].doc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tasks.push(task); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return tasks; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+async function calculateQuantityPerGLJ(glj,ration,coeList,assList,adjustState,isMarkPriceAjust) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let quantity =  glj.quantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let result={ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        query:{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ID:glj.ID, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            projectID:glj.projectID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        doc:{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            quantity: quantity, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            customQuantity:glj.customQuantity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(isMarkPriceAjust==null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(!glj._doc.hasOwnProperty('customQuantity')||glj.customQuantity==null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                quantity =glj.rationItemQuantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                quantity =calculateAss(quantity,assList,glj); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                quantity = calculateQuantityByCoes(quantity,coeList,glj); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                quantity = glj.customQuantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let customerCoe = _.last(coeList); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(customerCoe.isAdjust==1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                quantity = calculateQuantityByCustomerCoes(quantity,customerCoe,glj); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            result.doc.quantity =quantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        generateAdjustState(glj,coeList,adjustState); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }catch (err){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw err; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function calculateAss(quantity,assList,glj) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for(let i=0;i<assList.length;i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let assglj = _.find(assList[i].assRation.rationGljList,function (aglj) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return aglj.gljId == glj.GLJID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(assglj){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let calQuantity = assglj.consumeAmt*assList[i].times; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            quantity += calQuantity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return quantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function generateAdjustState(glj,coeList,adjustState) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   //替换工料机 and  添加工料机 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // to do 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //标准附注条件调整 + 自定义乘系数 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for(let i=0;i<coeList.length;i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(coeList[i].isAdjust==1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(i==coeList.length-1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                adjustState.push({index:stateSeq.cusCoe,content:coeList[i].content}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                adjustState.push({index:stateSeq.coe,content:"调 : "+coeList[i].content}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ //自定义消耗量 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(glj._doc.hasOwnProperty('customQuantity')){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if(glj.customQuantity!==null){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            adjustState.push({index:stateSeq.cusQuantity,content:glj.code+'量'+glj.customQuantity}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //市场单价调整 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(glj._doc.hasOwnProperty('marketPriceAdjust')&&glj.marketPriceAdjust!=0){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //0101005价66.00 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        adjustState.push({index:stateSeq.adjMak,content:glj.code+'价'+glj.marketPriceAdjust}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return adjustState; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function calculateTimes(ass){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let times =(ass.actualValue-ass.stdValue)/ass.stepValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(ass.carryBit=='四舍五入'){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        times = _.round(times,ass.decimal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }else if (ass.carryBit=='进一'){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        times =_.ceil(times,ass.decimal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return times; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function calculateQuantityByCoes(quantity,coeList,glj){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let coeQuantity = quantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(coeList.length>1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for(let i=0;i<coeList.length-1;i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            coeQuantity = everyCoe(coeQuantity,coeList[i],glj); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return coeQuantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function everyCoe(quantity,coe,glj) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let coeQuantity = quantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(coe.isAdjust==1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for(let i=0;i<coe.coes.length;i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(coe.coes[i].coeType=='单个'&&coe.coes[i].gljCode==glj.code){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                coeQuantity = getCalculateResult(coeQuantity,coe.coes[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if(coe.coes[i].coeType=='定额'){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                coeQuantity = getCalculateResult(coeQuantity,coe.coes[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }else if(coe.coes[i].coeType==glj.gljDistType){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                coeQuantity = getCalculateResult(coeQuantity,coe.coes[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return coeQuantity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function calculateQuantityByCustomerCoes(quantify,coe,glj) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let rationAmount = coe.coes[0].amount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(_.every(coe.coes,'amount',rationAmount)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return getCalculateResult(quantify, coe.coes[0]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for(let i=1;i<coe.coes.length;i++){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if(coe.coes[i].coeType.search(glj.gljDistType)!=-1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return getCalculateResult(quantify,coe.coes[i]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return quantify 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function getCalculateResult(quantify,c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let q = quantify; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    switch (c.operator){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case '+' : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            q = q + c.amount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case '-' : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            q = q - c.amount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case '*' : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            q = q * c.amount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case '/' : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            q = q / c.amount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case '=' : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             q = c.amount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return q; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |