gljUtil.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /**
  2. * Created by zhang on 2018/6/7.
  3. */
  4. let gljUtil = {
  5. calcProjectGLJQuantity:function (projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil) {
  6. let project_gljs = projectGLJDatas.gljList;
  7. let mixRatioMap = projectGLJDatas.mixRatioMap;
  8. let rations = rationDatas;
  9. let rationMap = _.indexBy(rations,'ID');
  10. let quantityMap={};
  11. let rationGljGroup = _.groupBy(rationGLJDatas,'projectGLJID');
  12. let IDarray = this.getSubdivisionAndTechBillsLeavesID(billsDatas);//分别取分部分项和技术措施项目的所有叶子清单ID
  13. let billIDs = IDarray[0],tech_billIDS = IDarray[1];
  14. for(let pglj of project_gljs ){
  15. let pg_index = this.getIndex(pglj,this.gljKeyArray);
  16. pglj.subdivisionQuantity = 0;
  17. pglj.techQuantity = 0;
  18. pglj.quantity = 0;
  19. let gljGroup = rationGljGroup[pglj.id]?rationGljGroup[pglj.id]:[];//定额工料机没有,有可能是定额类型的工料机
  20. let result = this.getQuantityPerGLJ(gljGroup,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil);
  21. pglj.subdivisionQuantity = result.subdivisionQuantity;
  22. pglj.techQuantity = result.techQuantity;
  23. pglj.quantity = result.quantity;
  24. quantityMap[pg_index] = pglj;
  25. }
  26. //计算做为组成物的消耗量
  27. for(let pkey in mixRatioMap){
  28. let mixRatioList = mixRatioMap[pkey];
  29. for(let m of mixRatioList){
  30. let m_index = this.getIndex(m,this.gljKeyArray);
  31. let m_glj = quantityMap[m_index];
  32. let p_glj = quantityMap[pkey];
  33. if(m_glj&&p_glj){
  34. let quantity = scMathUtil.roundForObj(p_glj.quantity*parseFloat(m.consumption),q_decimal);
  35. let techQuantity = scMathUtil.roundForObj(p_glj.techQuantity*parseFloat(m.consumption),q_decimal);
  36. let subdivisionQuantity = scMathUtil.roundForObj(p_glj.subdivisionQuantity*parseFloat(m.consumption),q_decimal);
  37. m_glj.quantity = scMathUtil.roundForObj(m_glj.quantity+quantity,q_decimal);
  38. m_glj.techQuantity = scMathUtil.roundForObj(m_glj.techQuantity+techQuantity,q_decimal);
  39. m_glj.subdivisionQuantity = scMathUtil.roundForObj(m_glj.subdivisionQuantity+subdivisionQuantity,q_decimal);
  40. }
  41. }
  42. }
  43. },
  44. getQuantityPerGLJ : function (ration_glj_list,rations,rationMap,pglj,billIDs,tech_billIDS,q_decimal,_,scMathUtil) {
  45. let result={};
  46. let quantity_sum=0;//工料机汇总消耗量
  47. let sum = 0;//分部分项总消耗量
  48. let tech_sum = 0;//技术措施总消耗量
  49. for(let rg of ration_glj_list){
  50. let tem_ration = rationMap[rg.rationID];
  51. let r_quantity = tem_ration?scMathUtil.roundForObj(tem_ration.quantity,q_decimal):0;
  52. let glj_quantity = scMathUtil.roundForObj(rg.quantity, q_decimal);
  53. if(!r_quantity){
  54. continue;
  55. }
  56. let total = scMathUtil.roundForObj(glj_quantity*r_quantity, q_decimal);
  57. quantity_sum = scMathUtil.roundForObj(quantity_sum+total,q_decimal);
  58. if(_.includes(billIDs,rg.billsItemID)){//计算分部分项
  59. sum = scMathUtil.roundForObj(sum+total,q_decimal);
  60. }
  61. if(_.includes(tech_billIDS,rg.billsItemID)){//计算技术措施项目消耗量
  62. tech_sum = scMathUtil.roundForObj(tech_sum+total,q_decimal);
  63. }
  64. }
  65. for(let ra of rations){//计算定额类型工料机的消耗量
  66. if(ra.type == this.rationType.gljRation&&ra.projectGLJID===pglj.id){
  67. let r_quantity = scMathUtil.roundForObj(ra.quantity,q_decimal);
  68. r_quantity = r_quantity?r_quantity:0;
  69. quantity_sum = scMathUtil.roundForObj(quantity_sum+r_quantity,q_decimal);
  70. if(_.includes(billIDs,ra.billsItemID)){//计算分部分项
  71. sum = scMathUtil.roundForObj(sum+r_quantity,q_decimal);
  72. }
  73. if(_.includes(tech_billIDS,ra.billsItemID)){//计算技术措施项目消耗量
  74. tech_sum = scMathUtil.roundForObj(tech_sum+r_quantity,q_decimal);
  75. }
  76. }
  77. }
  78. result.subdivisionQuantity = sum;
  79. result.techQuantity = tech_sum;
  80. result.quantity = quantity_sum;
  81. return result;
  82. },
  83. getSubdivisionAndTechBillsLeavesID:function (billsDatas) {//分别取分部分项和技术措施项目的所有叶子清单ID
  84. if(typeof (projectObj) !== 'undefined'){//存在,说明在前端调用
  85. return [projectObj.project.Bills.getSubdivisionProjectLeavesID(),projectObj.project.Bills.getTechLeavesID()];
  86. }
  87. let parentMap ={};
  88. let subdivisionBillID = null,techBillID = null,sIDs = [],tIDS = [];
  89. for(let b of billsDatas){
  90. if(parentMap[b.ParentID]){
  91. parentMap[b.ParentID].push(b);
  92. }else {
  93. parentMap[b.ParentID]= [b];
  94. }
  95. let flag = this.getFlag(b);
  96. if(this.isDef(flag)&&flag.flag == this.fixedFlag.SUB_ENGINERRING){
  97. subdivisionBillID = b.ID;
  98. }
  99. if(this.isDef(flag)&&flag.flag == this.fixedFlag.CONSTRUCTION_TECH){
  100. techBillID = b.ID;
  101. }
  102. }
  103. getLeaveIDs(subdivisionBillID,parentMap,sIDs);
  104. getLeaveIDs(techBillID,parentMap,tIDS);
  105. return [sIDs,tIDS];
  106. function getLeaveIDs(ID,parentM,leaveIDs) {
  107. if(parentM[ID] && parentM[ID].length > 0){
  108. let children = parentM[ID];
  109. for(let c of children){
  110. if(parentM[c.ID]){
  111. getLeaveIDs(c.ID,parentM,leaveIDs);
  112. }else {
  113. leaveIDs.push(c.ID);
  114. }
  115. }
  116. }
  117. }
  118. },
  119. getFlag:function (b) {
  120. return _.find(b.flags,{"fieldName":"fixed"});
  121. },
  122. getGLJPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
  123. let result = {};
  124. result.marketPrice = this.getMarketPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
  125. if(this.calcPriceDiff(glj,calcOptions)==true){//计取价差
  126. result.basePrice = this.getBasePrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
  127. result.adjustPrice = this.getAdjustPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
  128. }else {//不计价差
  129. result.basePrice = result.marketPrice;
  130. result.adjustPrice = result.marketPrice;
  131. }
  132. return result;
  133. },
  134. getMarketPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
  135. let price_decimal = decimalObj.glj.unitPrice;
  136. let quantity_decimal = decimalObj.glj.quantity;
  137. let process_decimal = decimalObj.process;
  138. if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
  139. let p =0;
  140. for(let ratio of glj.ratio_data){
  141. let tem = _.find(projectGLJDatas.gljList,{
  142. 'code': ratio.code,
  143. 'name': ratio.name,
  144. 'specs':ratio.specs,
  145. 'type': ratio.type,
  146. 'unit': ratio.unit
  147. });
  148. if(tem){
  149. let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
  150. p+=scMathUtil.roundForObj(priceData.marketPrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
  151. }
  152. }
  153. return scMathUtil.roundForObj(p,price_decimal);
  154. }else {
  155. let tem_decimal = isRadio==true?process_decimal:price_decimal;
  156. return scMathUtil.roundForObj(glj.unit_price.market_price,tem_decimal);
  157. }
  158. },
  159. getBasePrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
  160. let price_decimal = decimalObj.glj.unitPrice;
  161. let quantity_decimal = decimalObj.glj.quantity;
  162. let process_decimal = decimalObj.process;
  163. if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
  164. let p =0;
  165. for(let ratio of glj.ratio_data){
  166. let tem = _.find( projectGLJDatas.gljList,{
  167. 'code': ratio.code,
  168. 'name': ratio.name,
  169. 'specs':ratio.specs,
  170. 'type': ratio.type,
  171. 'unit': ratio.unit
  172. });
  173. if(tem){
  174. let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
  175. p+=scMathUtil.roundForObj(priceData.basePrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
  176. }
  177. }
  178. return scMathUtil.roundForObj(p,price_decimal);
  179. }else {
  180. let tem_decimal = isRadio==true?process_decimal:price_decimal;
  181. return scMathUtil.roundForObj(glj.unit_price.base_price,tem_decimal);
  182. }
  183. },
  184. getAdjustPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
  185. let decimal = decimalObj.glj.unitPrice;
  186. let quantity_decimal = decimalObj.glj.quantity;
  187. let process_decimal = decimalObj.process;
  188. let tem_decimal = isRadio==true?process_decimal:decimal;
  189. if (glj.unit_price.type == this.gljType.LABOUR || glj.unit_price.type == this.gljType.MACHINE_LABOUR) {//人工、机上人工,调整价根据定额价*调整系数计算得出。
  190. let labour = _.find(labourCoeDatas.coes,{'ID':glj.adjCoe});
  191. let coe = labour && labour.coe ? labour.coe : 1;
  192. return scMathUtil.roundTo(parseFloat(coe * scMathUtil.roundForObj(glj.unit_price.base_price,tem_decimal)), -tem_decimal);
  193. } else if (notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班,调整价根据组成物计算得出。
  194. let p =0;
  195. for(let ratio of glj.ratio_data){
  196. let tem = _.find( projectGLJDatas.gljList,{
  197. 'code': ratio.code,
  198. 'name': ratio.name,
  199. 'specs':ratio.specs,
  200. 'type': ratio.type,
  201. 'unit': ratio.unit
  202. })
  203. if(tem){
  204. let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
  205. p+=scMathUtil.roundForObj(priceData.adjustPrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
  206. }
  207. }
  208. return scMathUtil.roundForObj(p,decimal);
  209. } else {//对于其他普通材料等,无调整系数,调整价=定额价。
  210. return glj.unit_price.base_price
  211. }
  212. },
  213. calcPriceDiff:function (glj,calcOptions) {
  214. if(glj.is_evaluate==1){//先按是否暂估判断
  215. return calcOptions.calc_est;
  216. }
  217. if(glj.type==gljType.MAIN_MATERIAL||glj.type==gljType.EQUIPMENT){//再判断是否是主材和设备
  218. return calcOptions.calc_main;
  219. }
  220. if(glj.unit_price.is_add==1){//再判断是否新增
  221. return calcOptions.calc_add;
  222. }
  223. return true;
  224. },
  225. isFlag : function (v) {
  226. return this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed) && this.isDef(v.flagsIndex.fixed.flag);
  227. }
  228. ,
  229. isDef:function (v) {
  230. return v !== undefined && v !== null;
  231. },
  232. getIndex(obj, pops){
  233. let t_index = '';
  234. let k_arr = [];
  235. for (let p of pops) {
  236. let tmpK = (obj[p] == undefined || obj[p] == null || obj[p] == '') ? 'null' : obj[p];
  237. k_arr.push(tmpK);
  238. }
  239. t_index = k_arr.join("|-|");
  240. return t_index;
  241. },
  242. fixedFlag : {
  243. // 分部分项工程
  244. SUB_ENGINERRING: 1,
  245. // 措施项目
  246. MEASURE: 2,
  247. // 施工技术措施项目
  248. CONSTRUCTION_TECH: 3
  249. },
  250. gljType : {
  251. // 人工
  252. LABOUR: 1,
  253. // ==============材料类型=================
  254. // 普通材料
  255. GENERAL_MATERIAL: 201,
  256. // 混凝土
  257. CONCRETE: 202,
  258. // 砂浆
  259. MORTAR: 203,
  260. // 配合比
  261. MIX_RATIO: 204,
  262. // 商品混凝土
  263. COMMERCIAL_CONCRETE: 205,
  264. // 商品砂浆
  265. COMMERCIAL_MORTAR: 206,
  266. // ==============材料类型=================
  267. // ==============机械类型=================
  268. // 机械台班
  269. GENERAL_MACHINE: 301,
  270. // 机械组成物
  271. MACHINE_COMPOSITION: 302,
  272. // 机上人工
  273. MACHINE_LABOUR: 303,
  274. // ==============机械类型=================
  275. // 主材
  276. MAIN_MATERIAL: 4,
  277. // 设备
  278. EQUIPMENT: 5
  279. },
  280. notEditType : [202, 203,204, 301, 4],
  281. gljKeyArray : ['code','name','specs','unit','type'],
  282. rationType : {
  283. ration: 1,
  284. volumePrice: 2,
  285. gljRation: 3,
  286. install:4
  287. }
  288. }