gljUtil.js 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. /**
  2. * Created by zhang on 2018/6/7.
  3. */
  4. let gljUtil = {
  5. calcProjectGLJQuantity:function (projectGLJDatas,rationGLJDatas,rationDatas,billsDatas,q_decimal,_,scMathUtil,isReport) {
  6. let project_gljs = projectGLJDatas.gljList;
  7. let mixRatioMap = projectGLJDatas.mixRatioMap;
  8. let rations = rationDatas;
  9. let rationMap = _.indexBy(rations,'ID');
  10. let billsMap = _.indexBy(billsDatas,'ID');
  11. let quantityMap={};
  12. let rationGljGroup = _.groupBy(rationGLJDatas,'projectGLJID');
  13. let IDarray = this.getSubdivisionAndTechBillsLeavesID(billsDatas);//分别取分部分项和技术措施项目的所有叶子清单ID
  14. let billIDs = IDarray[0],tech_billIDS = IDarray[1];
  15. let sField = "subdivisionQuantity";
  16. let tField = "techQuantity";
  17. let qField = "quantity";
  18. for(let pglj of project_gljs ){
  19. let pg_index = this.getIndex(pglj,this.gljKeyArray);
  20. pglj[sField] = 0;
  21. pglj[tField] = 0;
  22. pglj[qField] = 0;
  23. let gljGroup = rationGljGroup[pglj.id]?rationGljGroup[pglj.id]:[];//定额工料机没有,有可能是定额类型的工料机
  24. let result = this.getQuantityPerGLJ(gljGroup,rations,rationMap,pglj,billIDs,tech_billIDS,billsMap,q_decimal,_,scMathUtil);
  25. pglj[sField] = result.subdivisionQuantity;
  26. pglj[tField] = result.techQuantity;
  27. pglj[qField] = result.quantity;
  28. pglj.tenderQuantity = result.tenderQuantity;
  29. quantityMap[pg_index] = pglj;
  30. }
  31. //计算做为组成物的消耗量
  32. for(let pkey in mixRatioMap){
  33. let mixRatioList = mixRatioMap[pkey];
  34. for(let m of mixRatioList){
  35. let m_index = this.getIndex(m,this.gljKeyArray);
  36. let m_glj = quantityMap[m_index];
  37. let p_glj = quantityMap[pkey];
  38. if(m_glj&&p_glj){
  39. let quantity = scMathUtil.roundForObj(parseFloat(p_glj[qField])*parseFloat(m.consumption),q_decimal);
  40. let tenderQuantity = scMathUtil.roundForObj(parseFloat(p_glj.tenderQuantity)*parseFloat(m.consumption),q_decimal);
  41. let techQuantity = scMathUtil.roundForObj(parseFloat(p_glj[tField])*parseFloat(m.consumption),q_decimal);
  42. let subdivisionQuantity = scMathUtil.roundForObj(parseFloat(p_glj[sField])*parseFloat(m.consumption),q_decimal);
  43. m_glj[qField] = scMathUtil.roundForObj(parseFloat(m_glj[qField])+quantity,q_decimal);
  44. m_glj.tenderQuantity = scMathUtil.roundForObj(parseFloat(m_glj.tenderQuantity)+tenderQuantity,q_decimal);
  45. m_glj[tField] = scMathUtil.roundForObj(parseFloat(m_glj[tField])+techQuantity,q_decimal);
  46. m_glj[sField] = scMathUtil.roundForObj(parseFloat(m_glj[sField])+subdivisionQuantity,q_decimal);
  47. }
  48. }
  49. }
  50. if (isReport) {
  51. for(let pglj of project_gljs ){
  52. pglj[qField] = pglj.tenderQuantity;
  53. }
  54. }
  55. },
  56. getQuantityPerGLJ : function (ration_glj_list,rations,rationMap,pglj,billIDs,tech_billIDS,billsMap,q_decimal,_,scMathUtil) {
  57. let result={};
  58. let quantity_sum=0;//工料机汇总消耗量
  59. let sum = 0;//分部分项总消耗量
  60. let tech_sum = 0;//技术措施总消耗量
  61. let tender_qantity_sum = 0;
  62. for(let rg of ration_glj_list){
  63. let tem_ration = rationMap[rg.rationID];
  64. if(tem_ration){
  65. if(!billsMap[tem_ration.billsItemID]) continue;//如果定额工料的父项没有找到,则忽略
  66. }
  67. let r_quantity = tem_ration?scMathUtil.roundForObj(tem_ration.quantity,q_decimal):0;
  68. let glj_quantity = scMathUtil.roundForObj(rg.quantity, q_decimal);
  69. let tender_r_quantity = r_quantity;
  70. let tender_glj_quantity = glj_quantity;
  71. if(!r_quantity){
  72. continue;
  73. }
  74. if(!pglj.is_adjust_price){
  75. tender_glj_quantity = this.getRationGLJTenderQuantity(rg,tem_ration,q_decimal,scMathUtil);
  76. tender_r_quantity = this.getRationTenderQuantity(tem_ration,q_decimal,scMathUtil);
  77. }
  78. let total = scMathUtil.roundForObj(glj_quantity*r_quantity, q_decimal);
  79. let tender_total = scMathUtil.roundForObj(tender_glj_quantity*tender_r_quantity, q_decimal);
  80. quantity_sum = scMathUtil.roundForObj(quantity_sum+total,q_decimal);
  81. tender_qantity_sum = scMathUtil.roundForObj(tender_qantity_sum+tender_total,q_decimal);
  82. if(_.includes(billIDs,rg.billsItemID)){//计算分部分项
  83. sum = scMathUtil.roundForObj(sum+total,q_decimal);
  84. }
  85. if(_.includes(tech_billIDS,rg.billsItemID)){//计算技术措施项目消耗量
  86. tech_sum = scMathUtil.roundForObj(tech_sum+total,q_decimal);
  87. }
  88. }
  89. //2019-11-07 定额类型工料机已经屏蔽,如果打开,记得加上调价后的消耗量
  90. for(let ra of rations){//计算定额类型工料机的消耗量
  91. if(!billsMap[ra.billsItemID]) continue;//如果定额工料的父项没有找到,则忽略
  92. if(ra.type == this.rationType.gljRation&&ra.projectGLJID===pglj.id){
  93. let r_quantity = scMathUtil.roundForObj(ra.quantity,q_decimal);
  94. r_quantity = r_quantity?r_quantity:0;
  95. let tender_r_quantity = r_quantity;
  96. if(!pglj.is_adjust_price){
  97. tender_r_quantity = this.getRationTenderQuantity(ra,q_decimal,scMathUtil);
  98. }
  99. quantity_sum = scMathUtil.roundForObj(quantity_sum+r_quantity,q_decimal);
  100. tender_qantity_sum = scMathUtil.roundForObj(tender_qantity_sum+tender_r_quantity,q_decimal);
  101. if(_.includes(billIDs,ra.billsItemID)){//计算分部分项
  102. sum = scMathUtil.roundForObj(sum+r_quantity,q_decimal);
  103. }
  104. if(_.includes(tech_billIDS,ra.billsItemID)){//计算技术措施项目消耗量
  105. tech_sum = scMathUtil.roundForObj(tech_sum+r_quantity,q_decimal);
  106. }
  107. }
  108. }
  109. result.subdivisionQuantity = sum;
  110. result.techQuantity = tech_sum;
  111. result.quantity = quantity_sum;
  112. result.tenderQuantity = tender_qantity_sum;
  113. return result;
  114. },
  115. getRationGLJTenderQuantity:function (ration_glj,ration,q_decimal,scMathUtil,projectGLJ) {
  116. let coeMap = {
  117. 1:'labour', //人工
  118. 2:'material',//材料
  119. 3:'machine',//机械
  120. 4:'main', //主材
  121. 5:'equipment'//设备
  122. };
  123. let typeString = ration_glj.type +"";
  124. let coeField = "";
  125. for(let key in coeMap){
  126. if(typeString.indexOf(key) == 0){
  127. coeField = coeMap[key];
  128. break;
  129. }
  130. }
  131. let coe = 1;
  132. if(projectGLJ && projectGLJ.is_adjust_price == 0){
  133. coe = ration.quantityCoe&&this.isNotEmpty(ration.quantityCoe[coeField])?ration.quantityCoe[coeField]:1;
  134. coe = parseFloat(coe);
  135. }else{
  136. coe = 1;
  137. }
  138. if (coe == 0) coe = 1;
  139. let glj_quantity = scMathUtil.roundForObj(ration_glj.quantity, q_decimal);
  140. return scMathUtil.roundForObj(glj_quantity * coe,q_decimal);
  141. },
  142. getRationTenderQuantity:function (ration,q_decimal,scMathUtil) {
  143. let rationQuantityCoe = this.isNotEmpty(ration.rationQuantityCoe)?ration.rationQuantityCoe:1;
  144. rationQuantityCoe = parseFloat(rationQuantityCoe);
  145. if (rationQuantityCoe == 0) rationQuantityCoe = 1;
  146. let r_quantity = ration?scMathUtil.roundForObj(ration.quantity,q_decimal):0;
  147. return scMathUtil.roundForObj(r_quantity * rationQuantityCoe,q_decimal);
  148. },
  149. isNotEmpty:function (str) {
  150. return this.isDef(str) && str!="";
  151. },
  152. getSubdivisionAndTechBillsLeavesID:function (billsDatas) {//分别取分部分项和技术措施项目的所有叶子清单ID
  153. if(typeof (projectObj) !== 'undefined'){//存在,说明在前端调用
  154. return [projectObj.project.Bills.getSubdivisionProjectLeavesID(),projectObj.project.Bills.getTechLeavesID()];
  155. }
  156. let parentMap ={};
  157. let subdivisionBillID = null,techBillID = null,sIDs = [],tIDS = [];
  158. for(let b of billsDatas){
  159. if(parentMap[b.ParentID]){
  160. parentMap[b.ParentID].push(b);
  161. }else {
  162. parentMap[b.ParentID]= [b];
  163. }
  164. let flag = this.getFlag(b);
  165. if(this.isDef(flag)&&flag.flag == this.fixedFlag.SUB_ENGINERRING){
  166. subdivisionBillID = b.ID;
  167. }
  168. if(this.isDef(flag)&&flag.flag == this.fixedFlag.CONSTRUCTION_TECH){
  169. techBillID = b.ID;
  170. }
  171. }
  172. getLeaveIDs(subdivisionBillID,parentMap,sIDs);
  173. getLeaveIDs(techBillID,parentMap,tIDS);
  174. return [sIDs,tIDS];
  175. function getLeaveIDs(ID,parentM,leaveIDs) {
  176. if(parentM[ID] && parentM[ID].length > 0){
  177. let children = parentM[ID];
  178. for(let c of children){
  179. if(parentM[c.ID]){
  180. getLeaveIDs(c.ID,parentM,leaveIDs);
  181. }else {
  182. leaveIDs.push(c.ID);
  183. }
  184. }
  185. }
  186. }
  187. },
  188. getFlag:function (b) {
  189. return _.find(b.flags,{"fieldName":"fixed"});
  190. },
  191. getGLJPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil,tenderCoe, isReport) {
  192. let result = {};
  193. if(isReport){
  194. result.marketPrice = this.getMarketPrice(glj,projectGLJDatas,calcOptions,decimalObj,isRadio,_,scMathUtil,tenderCoe);
  195. }else {
  196. result.marketPrice = this.getMarketPrice(glj,projectGLJDatas,calcOptions,decimalObj,isRadio,_,scMathUtil);
  197. result.tenderPrice = this.getMarketPrice(glj,projectGLJDatas,calcOptions,decimalObj,isRadio,_,scMathUtil,tenderCoe);
  198. }
  199. if(this.calcPriceDiff(glj,calcOptions)==true){//计取价差
  200. result.basePrice = this.getBasePrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
  201. result.adjustPrice = this.getAdjustPrice(glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil);
  202. }else {//不计价差
  203. result.basePrice = result.marketPrice;
  204. result.adjustPrice = result.marketPrice;
  205. }
  206. return result;
  207. },
  208. getMarketPrice:function (glj,projectGLJDatas,calcOptions,decimalObj,isRadio,_,scMathUtil,tenderCoe) {
  209. let price_decimal = decimalObj.glj.unitPrice;
  210. let price_hasM_decimal = decimalObj.glj.unitPriceHasMix?decimalObj.glj.unitPriceHasMix:decimalObj.glj.unitPrice;
  211. let quantity_decimal = decimalObj.glj.quantity;
  212. let process_decimal = decimalObj.process;
  213. let priceCoe = this.isDef(tenderCoe)?tenderCoe:1;
  214. if (priceCoe == '0' || priceCoe == 0) priceCoe = 1; // 这里加个保护
  215. if (['GLF', 'LR', 'FXF'].includes(glj.code)) priceCoe = 1; // 类型是“企业管理费”、“利润”、“一般风险费”的,不应调整单价。
  216. if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
  217. let p =0;
  218. for(let ratio of glj.ratio_data){
  219. let rIndex = gljUtil.getIndex(ratio);
  220. let tem = null;
  221. if(projectGLJDatas.gljMap){
  222. tem = projectGLJDatas.gljMap[rIndex]
  223. }
  224. if(!tem){
  225. tem = _.find(projectGLJDatas.gljList,function(item){
  226. return rIndex == gljUtil.getIndex(item)
  227. });
  228. }
  229. if(tem){
  230. let tem_marketPrice = this.getMarketPrice(tem,projectGLJDatas,calcOptions,decimalObj,true,_,scMathUtil); //let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
  231. let temP = scMathUtil.roundForObj(
  232. scMathUtil.roundForObj(tem_marketPrice * priceCoe, price_decimal) *
  233. scMathUtil.roundForObj(ratio.consumption,quantity_decimal), process_decimal);
  234. p = scMathUtil.roundForObj(temP + p, process_decimal);
  235. }
  236. }
  237. return scMathUtil.roundForObj(p,price_hasM_decimal);
  238. }else {
  239. let tem_decimal =price_decimal; //isRadio==true?process_decimal:price_decimal;
  240. let tem_price = scMathUtil.roundForObj(glj.unit_price.market_price,price_decimal);
  241. return scMathUtil.roundForObj(tem_price*priceCoe,tem_decimal);
  242. }
  243. },
  244. getBasePrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
  245. let price_decimal = decimalObj.glj.unitPrice;
  246. let price_hasM_decimal = decimalObj.glj.unitPriceHasMix?decimalObj.glj.unitPriceHasMix:decimalObj.glj.unitPrice;
  247. let quantity_decimal = decimalObj.glj.quantity;
  248. let process_decimal = decimalObj.process;
  249. if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班等有组成物的材料,价格需根据组成物计算得出。
  250. //2018-09-07 需求修改,定额价不按组成物的量和价实时计算出来,直接取单价文件中的定额价
  251. /* let p =0;
  252. for(let ratio of glj.ratio_data){
  253. let tem = _.find( projectGLJDatas.gljList,{
  254. 'code': ratio.code,
  255. 'name': ratio.name,
  256. 'specs':ratio.specs,
  257. 'type': ratio.type,
  258. 'unit': ratio.unit
  259. });
  260. if(tem){
  261. let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
  262. let temP = scMathUtil.roundForObj(priceData.basePrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
  263. p = scMathUtil.roundForObj(temP + p,process_decimal);
  264. }
  265. }
  266. return scMathUtil.roundForObj(p,price_hasM_decimal);*/
  267. return scMathUtil.roundForObj(glj.unit_price.base_price,price_hasM_decimal);
  268. }else {
  269. let tem_decimal =price_decimal; //isRadio==true?process_decimal:price_decimal;
  270. return scMathUtil.roundForObj(glj.unit_price.base_price,tem_decimal);
  271. }
  272. },
  273. //这个函数isRadio目前看来没有用,如果后续改了方法,导致isRadio的值会影响结果的话,需要调整调用这个方法的地方.
  274. getAdjustPrice:function (glj,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,isRadio,_,scMathUtil) {
  275. let decimal = decimalObj.glj.unitPrice;
  276. let price_hasM_decimal = decimalObj.glj.unitPriceHasMix?decimalObj.glj.unitPriceHasMix:decimalObj.glj.unitPrice;
  277. let quantity_decimal = decimalObj.glj.quantity;
  278. let process_decimal = decimalObj.process;
  279. let tem_decimal = isRadio==true?process_decimal:decimal;
  280. if (glj.unit_price.type == this.gljType.LABOUR || glj.unit_price.type == this.gljType.MACHINE_LABOUR) {//人工、机上人工,调整价根据定额价*调整系数计算得出。
  281. let labour = _.find(labourCoeDatas.coes,{'ID':glj.adjCoe});
  282. let coe = labour && labour.coe ? labour.coe : 1;
  283. return scMathUtil.roundForObj(parseFloat(coe * scMathUtil.roundForObj(glj.unit_price.base_price,decimal)), decimal);
  284. } else if (this.notEditType.indexOf(glj.unit_price.type)!=-1&&glj.ratio_data.length>0) {//对于混凝土、配合比、砂浆、机械台班,调整价根据组成物计算得出。
  285. let p =0;
  286. for(let ratio of glj.ratio_data){
  287. let rIndex = gljUtil.getIndex(ratio);
  288. let tem = null;
  289. if(projectGLJDatas.gljMap){
  290. tem = projectGLJDatas.gljMap[rIndex]
  291. }
  292. if(!tem){
  293. tem = _.find(projectGLJDatas.gljList,function(item){
  294. return rIndex == gljUtil.getIndex(item);
  295. });
  296. }
  297. if(tem){
  298. let priceData=this.getGLJPrice(tem,projectGLJDatas,calcOptions,labourCoeDatas,decimalObj,true,_,scMathUtil);
  299. let temP = scMathUtil.roundForObj(priceData.adjustPrice*scMathUtil.roundForObj(ratio.consumption,quantity_decimal),process_decimal);
  300. p = scMathUtil.roundForObj(temP + p,process_decimal);
  301. }
  302. }
  303. return scMathUtil.roundForObj(p,price_hasM_decimal);
  304. } else {//对于其他普通材料等,无调整系数,调整价=定额价。
  305. return scMathUtil.roundForObj(glj.unit_price.base_price,decimal)
  306. }
  307. },
  308. calcPriceDiff:function (glj,calcOptions) {
  309. if(glj.is_evaluate==1){//先按是否暂估判断
  310. return calcOptions.calc_est;
  311. }
  312. if(glj.type == this.gljType.MAIN_MATERIAL || glj.type == this.gljType.EQUIPMENT){//再判断是否是主材和设备
  313. return calcOptions.calc_main;
  314. }
  315. if(glj.unit_price.is_add==1){//再判断是否新增
  316. return calcOptions.calc_add;
  317. }
  318. return true;
  319. },
  320. isFlag : function (v) {
  321. return this.isDef(v.flagsIndex) && this.isDef(v.flagsIndex.fixed) && this.isDef(v.flagsIndex.fixed.flag);
  322. },
  323. isDef:function (v) {
  324. return v !== undefined && v !== null;
  325. },
  326. nullString(key){
  327. return (key === undefined || key === null || key === '') ? 'null' : key
  328. },
  329. getIndex(obj, pops){
  330. let t_index = '';
  331. let k_arr = [];
  332. if(!pops) pops = this.gljKeyArray;
  333. if(pops.length === 5){
  334. return `${this.nullString(obj[pops[0]])}|-|${this.nullString(obj[pops[1]])}|-|${this.nullString(obj[pops[2]])}|-|${this.nullString(obj[pops[3]])}|-|${this.nullString(obj[pops[4]])}`
  335. }else{
  336. for (let p of pops) {
  337. let tmpK = (obj[p] == undefined || obj[p] == null || obj[p] == '') ? 'null' : obj[p];
  338. k_arr.push(tmpK);
  339. }
  340. t_index = k_arr.join("|-|");
  341. return t_index;
  342. }
  343. },
  344. getGljTypeSeq:function () {
  345. let gljType = this.gljType;
  346. return [gljType.LABOUR,gljType.MAIN_MATERIAL,gljType.CONCRETE,gljType.MORTAR,gljType.MIX_RATIO,gljType.COMMERCIAL_CONCRETE,
  347. gljType.COMMERCIAL_MORTAR,gljType.GENERAL_MATERIAL,gljType.OTHER_MATERIAL,gljType.GENERAL_MACHINE,gljType.INSTRUMENT,gljType.OTHER_MACHINE_USED,
  348. gljType.MACHINE_COMPOSITION,gljType.MACHINE_LABOUR,gljType.FUEL_POWER_FEE,gljType.DEPRECIATION_FEE,gljType.INSPECTION_FEE,gljType.MAINTENANCE,
  349. gljType.DISMANTLING_FREIGHT_FEE,gljType.VERIFICATION_FEE,gljType.OTHER_FEE,gljType.EQUIPMENT,gljType.MANAGEMENT_FEE,gljType.PROFIT,gljType.GENERAL_RISK_FEE]
  350. },
  351. sortRationGLJ:function (list,std) {
  352. list = _.sortByAll(list, [function (item) {
  353. let typeField = std == true?"gljType":"type";
  354. return _.indexOf(gljUtil.getGljTypeSeq(),item[typeField])
  355. }, "code"]);
  356. return list;
  357. },
  358. getTotalQuantity:function(glj,ration,rd,gd){
  359. if(ration){
  360. let quantity = ration.quantity;
  361. quantity = (quantity == 0 || quantity == undefined || quantity == null || quantity == "") ? 0 : quantity;
  362. quantity = scMathUtil.roundForObj(quantity, rd);//计算前进行4舍5入
  363. glj.quantity = scMathUtil.roundForObj(glj.quantity, gd);
  364. let pglj = calcTools.getProjectGLJ(glj);
  365. glj.tenderQuantity = this.getRationGLJTenderQuantity(glj, ration, gd, scMathUtil,pglj);
  366. return scMathUtil.roundForObj(quantity * glj.quantity, gd)+'';
  367. }
  368. },
  369. getEngineerCostData:function(property,bills,fixedFlag,scMathUtil){
  370. let priceIndex = {
  371. name:"工程造价指标",
  372. attrs:[],
  373. children:[],
  374. };
  375. let fixMap = {};
  376. let buildingArea = this.getBuildArea(property.engineerFeatures); //tender.property.projectFeature?getItemValueBykey(tender.property.projectFeature,"buildingArea"):1;//建筑面积
  377. for(let b of bills){
  378. if(b.flags && b.flags.length > 0){
  379. let f = _.find(b.flags,{"fieldName":"fixed"});
  380. if(f) fixMap[f.flag] = this.getTotalFee(b,scMathUtil,property.decimal);
  381. }
  382. }
  383. //计算其他组织措施费 = 施工组织措施项目下的子项,除了 安全文明施工费、建设工程竣工档案编制费以外的项
  384. let CONSTRUCTION_ORGANIZATION = fixMap[fixedFlag.CONSTRUCTION_ORGANIZATION]?fixMap[fixedFlag.CONSTRUCTION_ORGANIZATION]:0;
  385. let SAFETY_CONSTRUCTION = fixMap[fixedFlag.SAFETY_CONSTRUCTION]?fixMap[fixedFlag.SAFETY_CONSTRUCTION]:0;
  386. let PROJECT_COMPLETE_ARCH_FEE = fixMap[fixedFlag.PROJECT_COMPLETE_ARCH_FEE]? fixMap[fixedFlag.PROJECT_COMPLETE_ARCH_FEE]:0;
  387. let other_org_fee = CONSTRUCTION_ORGANIZATION - SAFETY_CONSTRUCTION - PROJECT_COMPLETE_ARCH_FEE;
  388. other_org_fee = other_org_fee >0 ?other_org_fee:0;
  389. let engineerCost = fixMap[fixedFlag.ENGINEERINGCOST]?fixMap[fixedFlag.ENGINEERINGCOST]:1;
  390. priceIndex.children.push(this.getEngineerFlag("分部分项工程费",fixMap[fixedFlag.SUB_ENGINERRING],engineerCost,buildingArea,scMathUtil));
  391. priceIndex.children.push(this.getEngineerFlag("技术措施费",fixMap[fixedFlag.CONSTRUCTION_TECH],engineerCost,buildingArea,scMathUtil));
  392. priceIndex.children.push(this.getEngineerFlag("安全文明施工费",fixMap[fixedFlag.SAFETY_CONSTRUCTION],engineerCost,buildingArea,scMathUtil));
  393. priceIndex.children.push(this.getEngineerFlag("建设工程竣工档案编制费",fixMap[fixedFlag.PROJECT_COMPLETE_ARCH_FEE],engineerCost,buildingArea,scMathUtil));
  394. priceIndex.children.push(this.getEngineerFlag("其他组织措施费",other_org_fee,engineerCost,buildingArea,scMathUtil));
  395. priceIndex.children.push(this.getEngineerFlag("暂列金额",fixMap[fixedFlag.PROVISIONAL],engineerCost,buildingArea,scMathUtil));
  396. priceIndex.children.push(this.getEngineerFlag("专业工程暂估价",fixMap[fixedFlag.ENGINEERING_ESITIMATE],engineerCost,buildingArea,scMathUtil));
  397. priceIndex.children.push(this.getEngineerFlag("计日工",fixMap[fixedFlag.DAYWORK],engineerCost,buildingArea,scMathUtil));
  398. priceIndex.children.push(this.getEngineerFlag("总承包服务费",fixMap[fixedFlag.TURN_KEY_CONTRACT],engineerCost,buildingArea,scMathUtil));
  399. priceIndex.children.push(this.getEngineerFlag("索赔与现场签证",fixMap[fixedFlag.CLAIM_VISA],engineerCost,buildingArea,scMathUtil));
  400. priceIndex.children.push(this.getEngineerFlag("规费",fixMap[fixedFlag.CHARGE],engineerCost,buildingArea,scMathUtil));
  401. priceIndex.children.push(this.getEngineerFlag("税金",fixMap[fixedFlag.TAX],engineerCost,buildingArea,scMathUtil));
  402. priceIndex.children.push(this.getEngineerFlag("工程造价",fixMap[fixedFlag.ENGINEERINGCOST],engineerCost,buildingArea,scMathUtil));
  403. return priceIndex;
  404. },
  405. getBuildArea:function (features) {
  406. if(features){
  407. let areas = [];
  408. for(let f of features){
  409. if(f.index == true && f.value && f.value !=="" && this.IsNumber(f.value)) areas.push(f.value);
  410. }
  411. return areas.length==0?1:areas;
  412. }
  413. return 1
  414. },
  415. getEngineerFlag: function (name,totalCost,engineerCost,buildingArea,scMathUtil) {
  416. totalCost = totalCost?totalCost:0;
  417. let flag = {
  418. name:name,
  419. attrs:[
  420. {name: "金额", value: scMathUtil.roundToString(totalCost,3)},
  421. {name: "单方造价", value: scMathUtil.roundToString(this.calcUnitB(totalCost,buildingArea,scMathUtil),2)},
  422. {name: "占造价比例", value: scMathUtil.roundToString(totalCost/engineerCost * 100,2)},
  423. ],
  424. };
  425. return flag;
  426. },
  427. getTotalFee:function (b,scMathUtil,decimal) {
  428. let total = 0;
  429. if(b.fees && b.fees.length > 0){
  430. for(let f of b.fees){
  431. if(f.fieldName == "common"){
  432. total = scMathUtil.roundForObj(f.tenderTotalFee,decimal?decimal.bills.totalPrice:getDecimal("bills.totalPrice"));
  433. }
  434. }
  435. }
  436. return total;
  437. },
  438. IsNumber : function(pstrVal){
  439. let dblNo = Number.NaN;
  440. dblNo = new Number(pstrVal);
  441. if (isNaN(dblNo)) return false;
  442. return true;
  443. },
  444. calcUnitB:function (total,building,scMathUtil,coe,decimal = 3) {
  445. if(Array.isArray(building)){
  446. for(let b of building){
  447. total = scMathUtil.roundForObj(total/b,6);
  448. }
  449. }else {
  450. total = scMathUtil.roundForObj(total/building,6);
  451. }
  452. coe = gljUtil.isDef(coe)?coe:1;
  453. return scMathUtil.roundForObj(total*coe,decimal);
  454. },
  455. getEconomicDatas:function(engineerFeatures,economics,billsList,fixedFlag,_,scMathUtil,decimal){
  456. let datas = [];
  457. let [bills,totalFee] = gljUtil.getIndexBills(billsList,fixedFlag,_,scMathUtil,decimal);
  458. let billsGroup = _.groupBy(bills,'economicType');
  459. if(!economics) return datas;
  460. for(let e of economics){
  461. let tem = {
  462. name:e.name,
  463. exportName:e.exportName,
  464. cost:0,
  465. unitCost:0,
  466. per:0
  467. };
  468. if(billsGroup[e.name]) setEconomics(billsGroup[e.name],totalFee,tem);
  469. datas.push(tem);
  470. }
  471. function setEconomics(items,engineerCost,data) {
  472. let cost = 0;
  473. let priceDe = decimal?decimal.bills.totalPrice:getDecimal("bills.totalPrice");//getDecimal("bills.totalPrice");
  474. for(let i of items){
  475. i.totalFee = scMathUtil.roundForObj(i.totalFee,priceDe);
  476. cost = scMathUtil.roundForObj(cost + i.totalFee,decimal?decimal.process:getDecimal("process"))//getDecimal("process");
  477. }
  478. data.cost = scMathUtil.roundForObj(cost,priceDe);
  479. data.unitCost = gljUtil.calUnitWidthCoe(data.cost,true,engineerFeatures,_,scMathUtil);//noNeedCoe = true 这里不需要乘以系数
  480. data.per = engineerCost?scMathUtil.roundForObj(data.cost/engineerCost * 100,2):0;
  481. }
  482. return datas;
  483. },
  484. calUnitWidthCoe:function (total,noNeedCoe,engineerFeatures,_,scMathUtil) {
  485. let areas = gljUtil.getBuildArea(engineerFeatures);
  486. let f = _.find(engineerFeatures,{index:true});
  487. return f && noNeedCoe!==true?gljUtil.calcUnitB(total,areas,scMathUtil,f.coe):gljUtil.calcUnitB(total,areas,scMathUtil);
  488. },
  489. getIndexBills:function (bills,fixedFlag,_,scMathUtil,decimal) {
  490. let parentMap = {},datas = [],totalCost = 0;
  491. let FBFX_b = null,teh_b = null,costNode=null;
  492. for(let b of bills) {
  493. parentMap[b.ParentID] ? parentMap[b.ParentID].push(b) : parentMap[b.ParentID] = [b];//有添加,无则生成
  494. if(b.flags && b.flags.length > 0){
  495. let f = _.find(b.flags,{"fieldName":"fixed"});
  496. if(!f) continue;
  497. if(f.flag == fixedFlag.SUB_ENGINERRING) FBFX_b = b;//过滤出分部分项工程;
  498. if(f.flag == fixedFlag.CONSTRUCTION_TECH) teh_b = b;//过滤出技术措施项目;
  499. if(f.flag == fixedFlag.ENGINEERINGCOST) costNode = b;//过滤出工程造价项目;
  500. }
  501. }
  502. if(FBFX_b) getChildren(FBFX_b,parentMap,datas);
  503. if(teh_b) getChildren(teh_b,parentMap,datas);
  504. if(costNode) totalCost = gljUtil.getTotalFee(costNode,scMathUtil,decimal);
  505. for(let td of datas){
  506. if(parentMap[td.ID]){
  507. td.economicType = "";
  508. td.quantityIndexType = "";
  509. td.quantityIndexUnit = "";
  510. td.quantityIndexCoe = "";
  511. }
  512. }
  513. return [datas,totalCost];
  514. function getChildren(d,map,arr) {
  515. let tem = {
  516. ID:d.ID,
  517. ParentID:d.ParentID,
  518. code:d.code,
  519. name:d.name,
  520. unit:d.unit,
  521. quantity:d.quantity,
  522. totalFee:gljUtil.getTotalFee(d,scMathUtil,decimal),
  523. economicType:d.economicType,
  524. quantityIndexType:d.quantityIndexType,
  525. quantityIndexUnit:d.quantityIndexUnit,
  526. quantityIndexCoe:d.quantityIndexCoe,
  527. };
  528. arr.push(tem);
  529. if(map[d.ID]){
  530. for(let s of map[d.ID]){
  531. getChildren(s,map,arr)
  532. }
  533. }
  534. }
  535. },
  536. getMainMaterialDatas:function (projectProperty,engineerFeatures,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil) {
  537. let datas = [];
  538. let materialGroup = _.groupBy(projectGLJData.gljList,'materialIndexType');
  539. if(!materials) return datas;
  540. for(let m of materials){
  541. let tem = {
  542. name:m.name,
  543. unit:m.unit,
  544. exportName:m.exportName,
  545. unitPrice:0,
  546. quantity:0,
  547. unitIndex:0
  548. };
  549. if(materialGroup[m.name]) setMainMaterial(materialGroup[m.name],tem);
  550. datas.push(tem);
  551. }
  552. function setMainMaterial(gljs,data) {
  553. let quantity = 0 ,unitPrice=0;
  554. for(let g of gljs){
  555. if(!g.tenderQuantity || g.tenderQuantity=="") continue;
  556. let tenderCoe = gljUtil.getTenderPriceCoe(g,projectProperty);
  557. let marketPrice = gljUtil.getMarketPrice(g,projectGLJData,calcOptions,decimalObj,false,_,scMathUtil,tenderCoe); // gljOprObj.setGLJPrice(tem,g);
  558. let materialIndexCoe = g.materialIndexCoe?scMathUtil.roundForObj(g.materialIndexCoe,decimalObj.process):0;
  559. let t_quantity = scMathUtil.roundForObj(g.tenderQuantity * materialIndexCoe,decimalObj.process);
  560. quantity = scMathUtil.roundForObj(t_quantity + quantity,decimalObj.process);
  561. let temPrice = scMathUtil.roundForObj(g.tenderQuantity * marketPrice,decimalObj.process);
  562. unitPrice = scMathUtil.roundForObj(temPrice + unitPrice,decimalObj.process);
  563. }
  564. data.quantity = scMathUtil.roundForObj(quantity,2);
  565. if(data.quantity) data.unitPrice = scMathUtil.roundForObj(unitPrice/data.quantity,2);
  566. data.unitIndex = gljUtil.calUnitWidthCoe(data.quantity,false,engineerFeatures,_,scMathUtil);
  567. }
  568. return datas;
  569. },
  570. getQuantityDatas:function (engineerFeatures,mainQuantities,billsList,fixedFlag,_,scMathUtil,decimal) {//主要工程量指标
  571. let datas = [];
  572. let [bills,totalFee] = gljUtil.getIndexBills(billsList,fixedFlag,_,scMathUtil,decimal);//bills,fixedFlag,_,scMathUtil
  573. let billsGroup = _.groupBy(bills,'quantityIndexType');
  574. if(!mainQuantities) return datas;
  575. for(let m of mainQuantities){
  576. let tem = {
  577. name : m.name,
  578. quantityIndexUnit:m.unit,
  579. exportName:m.exportName,
  580. quantity:0
  581. };
  582. console.log(m.coe);
  583. if(billsGroup[m.name]) setQuantities(billsGroup[m.name],tem);
  584. datas.push(tem);
  585. }
  586. function setQuantities(items,data) {
  587. let quantity = 0;
  588. for (let i of items){
  589. let coe = i.quantityIndexCoe && i.quantityIndexCoe!=""?parseFloat(i.quantityIndexCoe):0;
  590. i.quantity = scMathUtil.roundForObj(parseFloat(i.quantity)*coe,decimal.process);
  591. quantity = scMathUtil.roundForObj(quantity + i.quantity,decimal.process);
  592. }
  593. data.quantity = gljUtil.calUnitWidthCoe(quantity,false,engineerFeatures,_,scMathUtil);
  594. //主要工程量指标另外加了一个系数
  595. let f = _.find(engineerFeatures,{index:true});
  596. if(f){
  597. let quantityCoe = gljUtil.isDef(f.quantityCoe)?f.quantityCoe:1;
  598. data.quantity = scMathUtil.roundForObj(data.quantity*quantityCoe,3);
  599. }
  600. }
  601. return datas;
  602. },
  603. getTenderPriceCoe : function(glj,tproperty){
  604. let tenderCoe = 1;
  605. let property = tproperty?tproperty:projectObj.project.property;
  606. if (!glj.is_adjust_price&&property.tenderSetting && isDef(property.tenderSetting.gljPriceTenderCoe) ){
  607. tenderCoe = parseFloat(property.tenderSetting.gljPriceTenderCoe);
  608. if (tenderCoe == 0) tenderCoe = 1;
  609. }
  610. return tenderCoe;
  611. function isDef (v) {
  612. return v !== undefined && v !== null;
  613. }
  614. },
  615. setProperty:function(Obj,updateData) {
  616. for(let ukey in updateData){
  617. if(_.isObject(updateData[ukey]) && _.isObject(Obj[ukey])&&!_.isArray(updateData[ukey])){
  618. setProperty(Obj[ukey],updateData[ukey]);
  619. }else {
  620. Obj[ukey] = updateData[ukey];
  621. }
  622. }
  623. },
  624. sortProjectGLJ:function(jsonData) {
  625. if (jsonData.length > 0) {
  626. jsonData = _.sortByAll(jsonData, [function (item) {
  627. let unit_price = item.unit_price?item.unit_price:item;
  628. return _.indexOf(gljTypeSeq,unit_price.type);
  629. }, 'code']);
  630. }
  631. return jsonData
  632. },
  633. getInfoMarketPrice:function (info,taxType) {
  634. //1: 一般计税 2: 简易计税
  635. let fieldArray=['noTaxPrice'];//一般计税 - 不含税价 || 简易计税 - 含税价
  636. taxType == "1" ? fieldArray.push("taxPrice"):fieldArray.unshift("taxPrice");
  637. //一个放后面,一个放前面
  638. let infoPrice = info[fieldArray[0]];
  639. if(!this.isDef(infoPrice)) infoPrice= info[fieldArray[1]];//信息价只有一个价格(含税价/不含税价),则不分计税方式,套用仅有的价格。
  640. return parseFloat(infoPrice);
  641. },
  642. calcMarketPriceByInfoPrice:function(infoPrice,purchaseFeeRate,decimal,tscMathUtil){
  643. if(!purchaseFeeRate) return infoPrice;
  644. tscMathUtil = tscMathUtil||scMathUtil
  645. return tscMathUtil.roundForObj(infoPrice*(1+purchaseFeeRate/100), decimal)
  646. },
  647. getPirceInfoDatas: function (projectGLJList, contractor_list, labourCoeDatas, projectProperty, _, scMathUtil) {
  648. let datas = [];
  649. let pgljList = projectGLJList;
  650. let contractorList = contractor_list;
  651. let calcOptions=projectProperty.calcOptions;
  652. let decimalObj = projectProperty.decimal;
  653. let billsDecimal = decimalObj.bills.totalPrice;
  654. let gljMap = _.indexBy(pgljList, 'id');
  655. for (let e of contractorList) {
  656. let t = {
  657. ID: e.ID,
  658. projectID: e.projectID,
  659. is_related: e.is_related, //关联,1关,0不关
  660. projectGLJID: e.projectGLJID, //关联工料机ID
  661. seq: e.seq, //序号
  662. code: e.code,
  663. name: e.name,
  664. specs: e.specs,
  665. unit: e.unit,
  666. type: e.type,
  667. marketPrice: e.market_price,
  668. quantity: e.quantity,
  669. remark: e.remark,
  670. supply: e.supply,
  671. riskCoe: e.riskCoe,
  672. is_evaluate: 0,
  673. standardPrice: e.standardPrice
  674. };
  675. let pglj = gljMap[e.projectGLJID];
  676. /*
  677. if (e.is_related && pglj) {
  678. gljOprObj.setGLJPrice(t, pglj);
  679. t.vender = pglj.vender;
  680. t.supply = pglj.supply;
  681. t.is_evaluate = pglj.is_evaluate;
  682. t.quantity = pglj.quantity;
  683. }
  684. /*/
  685. if (e.is_related && pglj) {
  686. let tenderCoe = gljUtil.getTenderPriceCoe(pglj,projectProperty);
  687. let result = gljUtil.getGLJPrice(pglj, {gljList:pgljList}, calcOptions, labourCoeDatas, decimalObj, false, _, scMathUtil, tenderCoe);
  688. t.marketPrice = result.marketPrice;
  689. t.tenderPrice = result.tenderPrice;
  690. t.basePrice = result.basePrice;
  691. t.adjustPrice = result.adjustPrice;
  692. t.marketUnitFee = t.marketPrice;//更新树节点市场单价列的值
  693. t.taxRate = pglj.unit_price.taxRate;//税率
  694. t.vender = pglj.vender;
  695. t.supply = pglj.supply;
  696. t.quantity = pglj.quantity;
  697. t.is_evaluate = pglj.is_evaluate;
  698. }
  699. //*/
  700. t.totalPrice = scMathUtil.roundForObj(parseFloat(t.quantity) * parseFloat(t.marketPrice), billsDecimal);
  701. datas.push(t);
  702. }
  703. return _.sortByAll(datas, 'code');
  704. },
  705. getPriceCoeDatas: function (projectGLJList, contractor_list, totalFee, projectProperty,_,scMathUtil) {
  706. let datas = [];
  707. let pgljList = projectGLJList ;
  708. let contractorList = contractor_list ;
  709. let decimalObj = projectProperty.decimal;
  710. let calcOptions=projectProperty.calcOptions;
  711. let billsDecimal = decimalObj.bills.totalPrice ;
  712. let gljMap = _.indexBy(pgljList, 'id');
  713. for (let e of contractorList) {
  714. let t = {
  715. ID: e.ID,
  716. projectID: e.projectID,
  717. is_related: e.is_related, //关联,1关,0不关
  718. projectGLJID: e.projectGLJID, //关联工料机ID
  719. seq: e.seq, //序号
  720. code: e.code,
  721. name: e.name,
  722. specs: e.specs,
  723. unit: e.unit,
  724. type: e.type,
  725. marketPrice: e.market_price,
  726. quantity: e.quantity,
  727. remark: e.remark,
  728. supply: e.supply,
  729. is_evaluate: 0,
  730. FO: e.FO,
  731. FI: e.FI
  732. };
  733. let pglj = gljMap[e.projectGLJID];
  734. if (e.is_related && pglj) {
  735. let tenderCoe = gljUtil.getTenderPriceCoe(pglj,projectProperty);
  736. t.marketPrice = gljUtil.getMarketPrice(pglj,{gljList:pgljList},calcOptions,decimalObj,false,_,scMathUtil,tenderCoe);
  737. t.vender = pglj.vender;
  738. t.supply = pglj.supply;
  739. t.quantity = pglj.quantity;
  740. t.is_evaluate = pglj.is_evaluate;
  741. }
  742. t.totalPrice = scMathUtil.roundForObj(parseFloat(t.quantity) * parseFloat(t.marketPrice), billsDecimal);
  743. if (totalFee !== 0) t.varWeight = scMathUtil.roundForObj(t.totalPrice / totalFee, 2);
  744. datas.push(t);
  745. }
  746. return _.sortByAll(datas, 'code');
  747. },
  748. fixedFlag : {
  749. // 分部分项工程
  750. SUB_ENGINERRING: 1,
  751. // 措施项目
  752. MEASURE: 2,
  753. // 施工技术措施项目
  754. CONSTRUCTION_TECH: 3
  755. },
  756. gljType : {
  757. LABOUR: 1, // 人工
  758. // ==============材料类型 ↓=================
  759. GENERAL_MATERIAL: 201, // 普通材料
  760. CONCRETE: 202, // 混凝土
  761. MORTAR: 203, // 砂浆
  762. MIX_RATIO: 204, // 配合比
  763. COMMERCIAL_CONCRETE: 205, // 商品混凝土
  764. COMMERCIAL_MORTAR: 206, // 商品砂浆
  765. OTHER_MATERIAL: 207, // 其它材料
  766. // ==============材料类型 ↑=================
  767. // ==============机械类型 ↓=================
  768. GENERAL_MACHINE: 301, // 机械台班
  769. MACHINE_COMPOSITION: 302, // 机械组成物
  770. MACHINE_LABOUR: 303, // 机上人工
  771. INSTRUMENT: 304, // 仪器仪表
  772. FUEL_POWER_FEE:305, // 燃料动力费
  773. DEPRECIATION_FEE:306, // 折旧费
  774. INSPECTION_FEE:307, // 检修费
  775. MAINTENANCE:308, // 维护费
  776. DISMANTLING_FREIGHT_FEE:309, // 安拆费及场外运费
  777. VERIFICATION_FEE:310, // 校验费
  778. OTHER_FEE:311, // 其他费用
  779. OTHER_MACHINE_USED:312, // 其他施工机具使用费
  780. // ==============机械类型 ↑=================
  781. MAIN_MATERIAL: 4, // 主材
  782. EQUIPMENT: 5, // 设备
  783. MANAGEMENT_FEE: 6, // 企业管理费
  784. PROFIT: 7, // 利润
  785. GENERAL_RISK_FEE: 8 // 一般风险费
  786. },
  787. extraType:[6,7,8],//一些其它的工料机类型
  788. notEditType : [202,203,204,301,304,4],
  789. gljKeyArray : ['code','name','specs','unit','type'],
  790. materialKeyArray:['code','name','specs','unit'],
  791. rationType : {
  792. ration: 1,
  793. volumePrice: 2,
  794. gljRation: 3,
  795. install:4
  796. },
  797. hasCompMaterial:[202, 203, 204],//有组成物的材料
  798. hasCompMachine:[301],//有组成物的机械
  799. machineComposition:[302,303]//可以做为机械组成物的类型
  800. }
  801. if(typeof module !== 'undefined'){
  802. module.exports = gljUtil;
  803. }