gljUtil.js 16 KB

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