ration.js 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. /**
  2. * Created by Mai on 2017/4/1.
  3. */
  4. var Ration = {
  5. createNew: function (project) {
  6. // 用户定义private方法
  7. var tools = {
  8. formatRationUpdateData: function (data) {
  9. let uData = JSON.parse(JSON.stringify(data));
  10. delete uData.feesIndex;
  11. delete uData.flagsIndex;
  12. // if (uData.fees) {
  13. // for (let fee of uData.fees) {
  14. // fee.unitFee = fee.unitFee.toFixed(2);
  15. // fee.totalFee = fee.totalFee.toFixed(2);
  16. // fee.tenderUnitFee = fee.tenderUnitFee.toFixed(2);
  17. // fee.tenderTotalFee = fee.tenderTotalFee.toFixed(2);
  18. // }
  19. // }
  20. return uData;
  21. }
  22. };
  23. // 所有通过this访问的属性,都不应在此单元外部进行写入操作
  24. var ration = function (proj) {
  25. this.project = proj;
  26. this.datas = null;
  27. var sourceType = ModuleNames.ration;
  28. this.getSourceType = function () {
  29. return sourceType;
  30. }
  31. proj.registerModule(ModuleNames.ration, this);
  32. var maxRationID = 0;
  33. this.getNewRationID = function () {
  34. return uuid.v1();
  35. //return maxRationID += 1;
  36. };
  37. this.maxRationID = function (maxID) {
  38. if (arguments.length === 0) {
  39. return maxRationID;
  40. } else {
  41. maxRationID = Math.max(maxID, maxRationID);
  42. }
  43. };
  44. };
  45. // prototype用于定义public方法
  46. ration.prototype.loadData = function (datas) {
  47. var that = this;
  48. this.datas = datas;
  49. // generate Fees & Flags Index,For View & Calculate
  50. this.datas.forEach(function (data) {
  51. data.feesIndex = getFeeIndex(data.fees);
  52. data.flagsIndex = {};
  53. data.flags.forEach(function (flag) {
  54. data.flagsIndex[flag.fieldName] = flag;
  55. });
  56. that.maxRationID(data.ID);
  57. });
  58. };
  59. ration.prototype.setMaxID = function (ID) {
  60. this.maxRationID(ID);
  61. }
  62. ration.prototype.addDatasToList = function (new_datas) {
  63. let me = this;
  64. if(me.datas && Array.isArray(me.datas)){
  65. for(let d of new_datas){
  66. me.datas.push(d);
  67. }
  68. }else {
  69. me.datas = new_datas;
  70. }
  71. };
  72. // refresh after update
  73. ration.prototype.doAfterUpdate = function(err, data){
  74. if(data.stateRefresh){
  75. this.refreshAdjustState(data);
  76. }
  77. if(data.quantityRefresh){
  78. this.refreshQuantity(data);
  79. }
  80. };
  81. ration.prototype.refreshAdjustState = function(data){
  82. this.refreshDatas(data,'adjustState');
  83. if(data.hasOwnProperty('name')){
  84. this.refreshDatas(data,'name')
  85. }
  86. };
  87. ration.prototype.refreshQuantity = function(data){
  88. this.refreshDatas(data,'quantity');
  89. };
  90. ration.prototype.refreshDatas = function(data,fieldName){
  91. var dataIndex = _.findIndex(this.datas,function(item) {
  92. return item.ID ==data.rationID;
  93. });
  94. this.datas[dataIndex][fieldName] = data[fieldName];
  95. if(fieldName=='quantity'){
  96. this.datas[dataIndex]['isFromDetail']=1
  97. }
  98. var controller = projectObj.mainController;
  99. var selected = controller.sheet.getSelections();
  100. var col = _.findIndex(project.projSetting.main_tree_col.cols,function (col) {
  101. return col.data.field ==fieldName;
  102. });
  103. controller.sheet.getCell(selected[0].row,col).value(data[fieldName]);
  104. };
  105. ration.prototype.getTempRationData = function (id, billsID, serialNo, rType) {
  106. var newData = {'ID': id, 'serialNo': serialNo, projectID: this.project.ID()};
  107. newData[project.masterField.ration] = billsID;
  108. newData['type'] = rType;
  109. if (rType == rationType.volumePrice){
  110. newData['subType'] = gljType.GENERAL_MATERIAL; // 默认的量价类型为材料
  111. newData['programID'] = projectInfoObj.projectInfo.property.engineering;
  112. };
  113. if(rType == rationType.install){//是安装增加费生成的定额
  114. newData['programID'] = projectInfoObj.projectInfo.property.engineering;
  115. }
  116. return newData;
  117. };
  118. ration.prototype.getBillsSortRation = function (billsID) { // 该方法只适用于叶子清单
  119. var rations = this.datas.filter(function (data) {
  120. return data[project.masterField.ration] === billsID;
  121. });
  122. rations.sort(function (x, y) {
  123. return x.serialNo - y.serialNo;
  124. });
  125. return rations;
  126. };
  127. // CSL, 2017-11-13 取任何清单(父清单、叶子清单)下的所有定额
  128. ration.prototype.getRationNodes = function (billNode) {
  129. if (billNode.sourceType != ModuleNames.bills) return [];
  130. let rations = [], IDs = [];
  131. function getSubBillsIDs(node) {
  132. if (!node) return;
  133. if (node.sourceType != ModuleNames.bills) return;
  134. if (!node.children || node.children.length == 0 || node.children[0].sourceType != ModuleNames.bills)
  135. IDs.push(node.data.ID)
  136. else
  137. getSubBillsIDs(node.children[0]);
  138. getSubBillsIDs(node.nextSibling);
  139. };
  140. if (billNode.source.children.length == 0)
  141. IDs.push(billNode.data.ID)
  142. else
  143. getSubBillsIDs(billNode.children[0]);
  144. for (let id of IDs){
  145. let subRations = this.datas.filter(function (data) {
  146. return data[project.masterField.ration] === id;
  147. });
  148. rations.push(...subRations);
  149. };
  150. rations.sort(function (x, y) {
  151. return x.serialNo - y.serialNo;
  152. });
  153. let rationNodes = [];
  154. for (let ration of rations){
  155. rationNodes.push(projectObj.project.mainTree.nodes['id_' + ration.ID]);
  156. }
  157. return rationNodes;
  158. };
  159. ration.prototype.getInsertRationData = function (billsID, preRation, rationType) {
  160. var br = this.getBillsSortRation(billsID);
  161. var updateData = [];
  162. if (preRation) {
  163. var preIndex = br.indexOf(preRation), i;
  164. updateData.push({updateType: 'ut_create', updateData: this.getTempRationData(this.getNewRationID(), billsID, preIndex < br.length - 1 ? br[preIndex + 1].serialNo : br[preIndex].serialNo + 1, rationType)});
  165. for (i = preIndex + 1; i < br.length; i++) {
  166. updateData.push({updateType: 'ut_update', updateData: this.getTempRationData(br[i].ID, billsID, i < br.length - 1 ? br[i+1].serialNo : br[i].serialNo + 1, br[i].type)});
  167. }
  168. } else {
  169. updateData.push({updateType: 'ut_create', updateData: this.getTempRationData(this.getNewRationID(), billsID, br.length > 0 ? br[br.length - 1].serialNo + 1 : 1, rationType)});
  170. }
  171. return updateData;
  172. };
  173. ration.prototype.getCounterData = function (count) {
  174. var updateData = {'projectID': this.project.ID()};
  175. if (count) {
  176. updateData[this.getSourceType()] = this.maxRationID() + count;
  177. } else {
  178. updateData[this.getSourceType()] = this.maxRationID() + 1;
  179. }
  180. return updateData;
  181. };
  182. ration.prototype.insertRation = function (billsID, preRation, rationType) {
  183. var br = this.getBillsSortRation(billsID);
  184. let insertData = this.getInsertRationData(billsID, preRation, rationType);
  185. this.project.pushNow('insertRation', [this.getSourceType(), this.project.projCounter()],
  186. [insertData, this.getCounterData()]);
  187. var newRation = null;
  188. let newID = -1;
  189. for(let data of insertData){
  190. if(data.updateType === 'ut_create'){
  191. newID = data.updateData.ID;
  192. }
  193. }
  194. if (preRation) {
  195. var preIndex = br.indexOf(preRation), i;
  196. newRation = this.getTempRationData(newID, billsID, preIndex < br.length - 1 ? br[preIndex + 1].serialNo : br[preIndex].serialNo + 1, rationType);
  197. this.datas.push(newRation);
  198. for (i = preIndex + 1; i < br.length; i++) {
  199. br[i].serialNo = i < br.length - 1 ? br [i + 1].serialNo : br[i].serialNo + 1;
  200. }
  201. } else {
  202. newRation = this.getTempRationData(newID, billsID, br.length > 0 ? br[br.length - 1].serialNo + 1 : 1, rationType);
  203. this.datas.push(newRation);
  204. }
  205. return newRation;
  206. };
  207. ration.prototype.insertStdRation = function (billsID, preRation, std) {
  208. var br = this.getBillsSortRation(billsID), updateData = this.getInsertRationData(billsID, preRation, rationType.ration), newRation = null, that = this;
  209. updateData.forEach(function (data) {
  210. if (data.updateType === 'ut_create') {
  211. data.updateData.code = std.code;
  212. data.updateData.name = std.name;
  213. data.updateData.caption = std.caption;
  214. data.updateData.unit = std.unit;
  215. data.updateData.libID = std.rationRepId;
  216. data.updateData.content = std.jobContent;
  217. if (std.chapter) {
  218. data.updateData.comments = std.chapter.explanation;
  219. data.updateData.ruleText = std.chapter.ruleText;
  220. }
  221. data.updateData.from = std.type === 'complementary' ? 'cpt' : 'std';
  222. data.updateData.programID = std.feeType;
  223. data.updateData.rationAssList = projectObj.project.ration_ass.CreateNewAss(std);
  224. // calculate ration Quantity
  225. that.CalculateQuantity(data.updateData);
  226. newRation = data.updateData;
  227. }
  228. });
  229. this.project.pushNow('insertRation', [this.getSourceType(), this.project.projCounter()], [updateData, this.getCounterData()]);
  230. //newRation.ID = this.getNewRationID();
  231. if (preRation) {
  232. var preIndex = br.indexOf(preRation), i;
  233. this.datas.push(newRation);
  234. for (i = preIndex + 1; i < br.length; i++) {
  235. br[i].serialNo = i < br.length - 1 ? br [i + 1].serialNo : br[i].serialNo + 1;
  236. }
  237. } else {
  238. this.datas.push(newRation);
  239. }
  240. return newRation;
  241. };
  242. ration.prototype.getDeleteData = function (rationData) {
  243. var updateData = [];
  244. updateData.push({'updateType': 'ut_delete', 'updateData': {'ID': rationData.ID, 'projectID': this.project.ID()}});
  245. return updateData;
  246. };
  247. ration.prototype.delete = function (ration) {
  248. var ration_glj =projectObj.project.ration_glj;
  249. this.project.pushNow('deleteRation', [this.getSourceType(),ration_glj.getSourceType()], [this.getDeleteData(ration),ration_glj.getDeleteDataByRation(ration)]);
  250. project.ration_glj.deleteByRation(ration);
  251. project.ration_coe.deleteByRation(ration);
  252. project.quantity_detail.deleteByRation(ration);
  253. project.ration_installation.deleteByRation(ration);
  254. this.datas.splice(this.datas.indexOf(ration), 1);
  255. };
  256. ration.prototype.removeByID = function(ID){
  257. _.remove(this.datas,{'ID':ID});
  258. };
  259. ration.prototype.getDeleteDataByBill = function (nodes) {
  260. let updateData = [];
  261. for (let node of nodes) {
  262. if (node.children.length > 0) {
  263. updateData = updateData.concat(this.getDeleteDataByBill(node.children));
  264. } else {
  265. let rations = this.getBillsSortRation(node.getID());
  266. for (let r of rations) {
  267. updateData.push({'updateType': 'ut_delete', 'updateData': {'ID': r.ID, 'projectID': this.project.ID()}});
  268. }
  269. }
  270. }
  271. return updateData;
  272. };
  273. ration.prototype.deleteByBills = function (nodes) {
  274. for (let node of nodes) {
  275. if (node.children.length > 0) {
  276. this.deleteByBills(node.children);
  277. } else {
  278. let rations = this.getBillsSortRation(node.getID());
  279. for (let r of rations) {
  280. this.datas.splice(this.datas.indexOf(r), 1);
  281. }
  282. }
  283. }
  284. }
  285. ration.prototype.getChangePosUpdateData = function (ration1, ration2) {
  286. var updateData = [];
  287. updateData.push({updateType: 'ut_update', updateData: this.getTempRationData(ration1.ID, ration1.billsItemID, ration2.serialNo)});
  288. updateData.push({updateType: 'ut_update', updateData: this.getTempRationData(ration2.ID, ration2.billsItemID, ration1.serialNo)});
  289. return updateData;
  290. };
  291. ration.prototype.changePos = function (ration1, ration2) {
  292. var updateData = this.getChangePosUpdateData(ration1, ration2);
  293. this.project.pushNow('insertRation', [this.getSourceType()], [updateData]);
  294. var preSerialNo = ration1.serialNo;
  295. ration1.serialNo = ration2.serialNo;
  296. ration2.serialNo = preSerialNo;
  297. };
  298. ration.prototype.updateField = function (ration, field, newValue) {
  299. calcFees.setFee(ration, field, newValue);
  300. let updateData = [];
  301. let data = {'ID': ration.ID, 'projectID': this.project.ID()};
  302. if (field === 'quantity') {
  303. data[field] = newValue;
  304. data.isFromDetail=0;
  305. // to do Calculate
  306. if (ration.fees) {
  307. data.fees = ration.fees;
  308. }
  309. } else if (field === 'feesIndex.common.unitFee') {
  310. // to do Calculate
  311. if (ration.fees) {
  312. data.fees = ration.fees;
  313. }
  314. } else {
  315. data[field] = newValue;
  316. }
  317. updateData.push({'updateType': 'ut_update', 'updateData': data});
  318. this.project.pushNow('updateBills', this.getSourceType(), updateData);
  319. };
  320. ration.prototype.updateRation = function (ration, updateNow) {
  321. let updateData = [];
  322. updateData.push({'updateType': 'ut_update', 'updateData': tools.formatRationUpdateData(ration)});
  323. if (updateNow) {
  324. this.project.pushNow('updateRations', this.getSourceType(), updateData);
  325. } else {
  326. this.project.push(this.getSourceType(), updateData);
  327. }
  328. };
  329. ration.prototype.FilterNumberFromUnit = function (unit) {
  330. let reg = new RegExp('^[0-9]+');
  331. if (reg.test(unit)) {
  332. return parseInt(unit.match(reg)[0]);
  333. } else {
  334. return 1;
  335. }
  336. };
  337. ration.prototype.CalculateQuantity = function (ration) {
  338. // calculate ration Quantity
  339. let quantity_decimal = getDecimal("ration.quantity");
  340. let process_decimal = getDecimal("process");
  341. if (optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToBillsQuan')) {
  342. let billsNode = this.project.Bills.tree.findNode(ration[this.project.masterField.ration]);
  343. let billsQuantity = billsNode.data.quantity ? billsNode.data.quantity : 0;
  344. billsQuantity=scMathUtil.roundForObj(billsQuantity,quantity_decimal);
  345. ration.quantityEXP="QDL";
  346. /* if (optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToRationUnit')) {
  347. ration.quantity = (billsQuantity / this.FilterNumberFromUnit(ration.unit)).toDecimal(quantity_decimal);
  348. } else {
  349. ration.quantity = billsQuantity.toDecimal(quantity_decimal);
  350. }*/
  351. ration.quantity = (billsQuantity / this.FilterNumberFromUnit(ration.unit)).toDecimal(quantity_decimal);//改成不管是否打勾都做转换
  352. ration.contain = scMathUtil.roundForObj(ration.quantity/billsQuantity,process_decimal);
  353. }
  354. };
  355. ration.prototype.updateRationCodes = function (recodes) {
  356. let libID = rationLibObj.getCurrentStdRationLibID();
  357. let libIDs = rationLibObj.getStdRationLibIDs();
  358. let firstLibID = rationLibObj.getFirstStdRationLibID();
  359. let engineering = projectInfoObj.projectInfo.property.engineering;
  360. let projectID = projectInfoObj.projectInfo.ID;
  361. let project = projectObj.project;
  362. let mainTree = project.mainTree;
  363. let nodeInfo =[];
  364. let refershNodes = [];
  365. if(libIDs == null){
  366. return;
  367. }
  368. for(let r of recodes){
  369. let needInstall = false;
  370. if(engineering==engineeringType.BUILD_IN) {//如果是安装工程,要看需不需要生成安装增加费
  371. needInstall = project.Bills.isFBFX(r.node);
  372. }
  373. r.value===null||r.value===undefined?"":r.value = r.value.replace(/[\s\r\n]/g, "");//去掉空格回车换行等字符
  374. nodeInfo.push({ID:r.node.data.ID,billsItemID:r.node.data.billsItemID,newCode:r.value,needInstall:needInstall});
  375. refershNodes.push(r.node);
  376. }
  377. let calQuantity = optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToBillsQuan');
  378. $.bootstrapLoading.start();
  379. CommonAjax.post("/ration/replaceRations",{nodeInfo:nodeInfo,libIDs:libIDs,firstLibID: firstLibID,projectID:projectID,calQuantity:calQuantity},function (data) {
  380. for(let recode of data){
  381. let node = mainTree.getNodeByID(recode.ration.ID);
  382. if(node) {
  383. for(let temkey in recode.ration){//更新缓存
  384. node.data[temkey] = recode.ration[temkey];
  385. }
  386. node.data.feesIndex = {};
  387. //删除定额节点下的主材和设备节点
  388. project.ration_glj.removeNodeByRation(recode.ration,projectObj.mainController);
  389. project.Ration.deleteSubListOfRation(recode.ration);//删除旧定额下的相关记录
  390. //添加新的记录
  391. project.ration_glj.addDatasToList(recode.ration_gljs);
  392. project.ration_coe.addDatasToList(recode.ration_coes);
  393. project.ration_installation.addDatasToList(recode.ration_installs);
  394. project.ration_glj.addToMainTree(recode.ration_gljs);
  395. }
  396. }
  397. project.projectGLJ.loadData(function () {
  398. gljOprObj.showDataIfRationSelect(projectObj.project.mainTree.selected,"-111111111");//这里第二个参数是为了使改前和改后selectedID不一样,删除了的话下方的定额工料机不会刷新
  399. project.calcProgram.calcNodesAndSave(refershNodes);
  400. projectObj.mainController.refreshTreeNode(refershNodes, true);
  401. $.bootstrapLoading.end();
  402. });
  403. if(data.length<recodes.length&&recodes[data.length].value!=null){//说明有部分定额编号没找到记录
  404. alert('当前库中找不到定额"' + recodes[data.length].value + '"');
  405. }
  406. })
  407. };
  408. ration.prototype.addMultiRation = function (items, callback) {
  409. let me = this;
  410. let project = projectObj.project, sheetController = projectObj.mainController;
  411. let engineering = projectInfoObj.projectInfo.property.engineering;
  412. let selected = project.mainTree.selected, newSource = null, newNode = null,pre=null,br=null;
  413. let billItemID = null,serialNo=1,nextID=null;
  414. let needInstall = false;
  415. let newDatas = [];
  416. if (selected === null) { return; }
  417. if (selected.sourceType === project.Bills.getSourceType() && selected.depth() > 0) {
  418. if (selected.source.children.length > 0) {
  419. alert('当前清单已有清单子项,不能套用定额。');
  420. } else if (selected.data.calcBase&&selected.data.calcBase!="") {
  421. alert('当前有基数计算不能插入定额/量价/工料机。');
  422. } else {
  423. if(selected.data.type === billType.FB){
  424. return;
  425. }
  426. billItemID = selected.source.getID();
  427. nextID = selected.tree.rootID();
  428. br = this.getBillsSortRation(billItemID);
  429. serialNo = br.length > 0 ? br[br.length - 1].serialNo + 1 : 1
  430. }
  431. } else if (selected.sourceType === project.Ration.getSourceType()) {
  432. billItemID = selected.getParentID();
  433. br = this.getBillsSortRation(billItemID);
  434. serialNo = selected.data.serialNo+1;
  435. nextID = selected.getNextSiblingID();
  436. pre = selected.source;
  437. };
  438. if(billItemID){
  439. let calQuantity = optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToBillsQuan');
  440. if(engineering==engineeringType.BUILD_IN) {//如果是安装工程,要看需不需要生成安装增加费
  441. let billsNode = project.mainTree.getNodeByID(billItemID);
  442. needInstall = project.Bills.isFBFX(billsNode);//在分部分项插入的定额才需要定额安装增加费
  443. }
  444. for(let i = 0; i < items.length; i++){
  445. let newData = me.getTempRationData(me.getNewRationID(), billItemID, serialNo, items[i].rationType);
  446. serialNo++;
  447. let brUpdate = [];
  448. //更新兄弟节点的序列号
  449. if (i ===0 && pre) {
  450. let preIndex = br.indexOf(pre), i;
  451. for (i = preIndex + 1; i < br.length; i++) {
  452. br[i].serialNo = i < br.length - 1 ? br [i + 1].serialNo + items.length - 1 : br[i].serialNo + items.length;
  453. brUpdate.push({projectID:newData.projectID,ID:br[i].ID,serialNo:br[i].serialNo});
  454. }
  455. }
  456. newDatas.push({itemQuery: items[i].itemQuery, newData: newData, firstLibID: rationLibObj.getFirstStdRationLibID(), calQuantity: calQuantity, brUpdate: brUpdate, needInstall: needInstall})
  457. }
  458. let showLoding = true;
  459. $.bootstrapLoading.start();
  460. //保证由于异步的关系loading界面被隐藏,比如清单指引插入清单定额时,endUpdate中提前隐藏了loading
  461. let interval =setInterval(function () {
  462. if(!$.bootstrapLoading.isLoading()&& showLoding){
  463. $.bootstrapLoading.start();
  464. clearInterval(interval);
  465. }
  466. else{
  467. clearInterval(interval);
  468. }
  469. }, 100);
  470. CommonAjax.post("/ration/addMultiRation",{newDatas: newDatas},function (rstData) {
  471. let newNodes = [];
  472. //更新缓存
  473. for(let data of rstData){
  474. me.datas.push(data.ration);
  475. project.ration_glj.addDatasToList(data.ration_gljs);
  476. project.ration_coe.addDatasToList(data.ration_coes);
  477. project.ration_installation.addDatasToList(data.ration_installs);
  478. //插入树节点
  479. newSource = data.ration;
  480. newNode = project.mainTree.insert(billItemID, nextID, newSource.ID);
  481. newNodes.push(newNode);
  482. nextID = project.mainTree.selected.getNextSiblingID();
  483. newNode.source = newSource;
  484. newNode.sourceType = project.Ration.getSourceType();
  485. newNode.data = newSource;
  486. ProjectController.syncDisplayNewNode(sheetController, newNode);
  487. }
  488. project.projectGLJ.loadData(function () {
  489. for(let data of rstData){
  490. project.ration_glj.addToMainTree(data.ration_gljs);
  491. }
  492. projectObj.mainController.refreshTreeNode(newNodes, false);
  493. if(project.Bills.isFBFX(newNodes[0])) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
  494. project.installation_fee.calcInstallationFee(function (isChange,rations) {
  495. if(isChange){
  496. rations = rations.concat(newNodes);
  497. project.calcProgram.calcNodesAndSave(rations);
  498. }else {
  499. project.calcProgram.calcNodesAndSave(newNodes);
  500. }
  501. });
  502. }else {
  503. project.calcProgram.calcNodesAndSave(newNodes);
  504. }
  505. if(callback){
  506. callback();
  507. }
  508. showLoding = false;
  509. $.bootstrapLoading.end();
  510. });
  511. })
  512. }
  513. };
  514. ration.prototype.addNewRation = function (itemQuery,rationType,callback=null,isEmpty=false) {
  515. let me = this;
  516. let project = projectObj.project, sheetController = projectObj.mainController;
  517. let engineering = projectInfoObj.projectInfo.property.engineering;
  518. let selected = project.mainTree.selected, newSource = null, newNode = null,pre=null,br=null;
  519. let billItemID = null,serialNo=1,nextID=null;
  520. let needInstall = false;
  521. if (selected === null) { return; }
  522. if (selected.sourceType === project.Bills.getSourceType() && selected.depth() > 0) {
  523. if(selected.data.type === billType.FB){
  524. return;
  525. }
  526. else if (selected.source.children.length > 0) {
  527. alert('当前清单已有清单子项,不能套用定额。');
  528. } else if (selected.data.calcBase&&selected.data.calcBase!="") {
  529. alert('当前有基数计算不能插入定额/量价/工料机。');
  530. } else {
  531. billItemID = selected.source.getID();
  532. nextID = selected.tree.rootID();
  533. br = this.getBillsSortRation(billItemID);
  534. serialNo = br.length > 0 ? br[br.length - 1].serialNo + 1 : 1
  535. }
  536. } else if (selected.sourceType === project.Ration.getSourceType()) {
  537. billItemID = selected.getParentID();
  538. br = this.getBillsSortRation(billItemID);
  539. serialNo = selected.data.serialNo+1;
  540. nextID = selected.getNextSiblingID();
  541. pre = selected.source;
  542. };
  543. if(billItemID){
  544. let newData = me.getTempRationData(me.getNewRationID(), billItemID, serialNo, rationType);
  545. let calQuantity = isEmpty===true?false:optionsOprObj.getOption(optionsOprObj.optionsTypes.GENERALOPTS, 'rationQuanACToBillsQuan');
  546. let brUpdate = [];
  547. //更新兄弟节点的序列号
  548. if (pre) {
  549. let preIndex = br.indexOf(pre), i;
  550. for (i = preIndex + 1; i < br.length; i++) {
  551. br[i].serialNo = i < br.length - 1 ? br [i + 1].serialNo : br[i].serialNo + 1;
  552. brUpdate.push({projectID:newData.projectID,ID:br[i].ID,serialNo:br[i].serialNo});
  553. }
  554. }
  555. if(engineering==engineeringType.BUILD_IN) {//如果是安装工程,要看需不需要生成安装增加费
  556. let billsNode = project.mainTree.getNodeByID(billItemID);
  557. needInstall = project.Bills.isFBFX(billsNode);//在分部分项插入的定额才需要定额安装增加费
  558. }
  559. $.bootstrapLoading.start();
  560. CommonAjax.post("/ration/addNewRation",{itemQuery:itemQuery,newData:newData,firstLibID: rationLibObj.getFirstStdRationLibID(),calQuantity:calQuantity,brUpdate:brUpdate,needInstall:needInstall},function (data) {
  561. //更新缓存
  562. me.datas.push(data.ration);
  563. project.ration_glj.addDatasToList(data.ration_gljs);
  564. project.ration_coe.addDatasToList(data.ration_coes);
  565. project.ration_installation.addDatasToList(data.ration_installs);
  566. //插入树节点
  567. newSource = data.ration;
  568. newNode = project.mainTree.insert(billItemID, nextID, newSource.ID);
  569. newNode.source = newSource;
  570. newNode.sourceType = project.Ration.getSourceType();
  571. newNode.data = newSource;
  572. project.projectGLJ.loadData(function () {
  573. ProjectController.syncDisplayNewNode(sheetController, newNode);
  574. project.ration_glj.addToMainTree(data.ration_gljs);
  575. projectObj.mainController.refreshTreeNode([newNode], false);
  576. project.calcProgram.calcAndSave(newNode,function () {
  577. if(project.Bills.isFBFX(newNode)) { //判断是否属于分部分项工程 ,是的话才需要做计取安装费计算
  578. installationFeeObj.calcInstallationFee();
  579. }
  580. });
  581. if(callback){
  582. callback();
  583. }
  584. $.bootstrapLoading.end();
  585. });
  586. })
  587. }
  588. };
  589. ration.prototype.deleteSubListOfRation = function(ration){
  590. projectObj.project.ration_glj.deleteByRation(ration);
  591. projectObj.project.ration_coe.deleteByRation(ration);
  592. projectObj.project.quantity_detail.deleteByRation(ration);
  593. projectObj.project.ration_installation.deleteByRation(ration);
  594. };
  595. ration.prototype.replaceRation = function (ration, std) {
  596. this.project.beginUpdate('replaceRation');
  597. // delete
  598. let ration_glj =projectObj.project.ration_glj;
  599. this.project.push(this.project.ration_glj.getSourceType(), this.project.ration_glj.getDeleteDataByRation(ration));
  600. this.deleteSubListOfRation(ration);
  601. // insertNewRation
  602. let updateData = [];
  603. ration.code = std.code;
  604. ration.name = std.name;
  605. ration.caption = std.caption;
  606. ration.unit = std.unit;
  607. ration.libID = std.rationRepId;
  608. ration.content = std.jobContent;
  609. ration.adjustState = '';
  610. if (std.chapter) {
  611. ration.comments = std.chapter.explanation;
  612. ration.ruleText = std.chapter.ruleText;
  613. }
  614. ration.from = std.type === 'complementary' ? 'cpt' : 'std';
  615. ration.programID = std.feeType;
  616. ration.rationAssList = projectObj.project.ration_ass.CreateNewAss(std);
  617. // calculate ration Quantity
  618. this.CalculateQuantity(ration);
  619. updateData.push({updateType: 'ut_update', updateData: ration});
  620. this.project.push(this.getSourceType(), updateData);
  621. this.project.endUpdate();
  622. };
  623. ration.prototype.updateContain=function (value,node) {
  624. let me = this;
  625. if(isNaN(value)){
  626. alert("当前输入的数据类型不正确,请重新输入");
  627. projectObj.mainController.refreshTreeNode([node]);
  628. return;
  629. }
  630. if(node.data.quantityEXP=="GCLMXHJ"){//如果定额工程量是来自工程量明细
  631. hintBox.infoBox('操作确认', '已有工程量明细,是否清空明细表?', 2, function () {
  632. node.data.isFromDetail=0;
  633. project.quantity_detail.cleanQuantityDetail(node,true);
  634. me.doContainUpdate(value,node);
  635. }, function () {
  636. projectObj.mainController.refreshTreeNode([node]);
  637. },['确定','取消'],false);
  638. }else {
  639. me.doContainUpdate(value,node);
  640. }
  641. };
  642. ration.prototype.doContainUpdate = function (value,node) {
  643. let billNode = node.parent;
  644. let contain = scMathUtil.roundForObj(value,getDecimal("process"));
  645. let billQuantity = billNode.data.quantity||billNode.data.quantity!=""?billNode.data.quantity:0;
  646. billQuantity = parseFloat(billQuantity);
  647. node.data.contain = contain;
  648. node.data.quantityEXP="QDL*"+contain;
  649. node.data.quantity=scMathUtil.roundForObj(billQuantity*contain,getDecimal("quantity",node));
  650. let times = parseInt(node.data.unit);
  651. if (!isNaN(times)) {
  652. node.data.quantityEXP+='*'+times;
  653. }
  654. // node.data.quantity = projectObj.project.quantity_detail.autoTransformQuantity(node.data.quantity,node);//按单位做转换
  655. node.changed = true;
  656. project.calcProgram.calcAndSave(node, function () {
  657. project.projectGLJ.calcQuantity();
  658. });
  659. projectObj.mainController.refreshTreeNode(node.children);//刷新子工料机树节点总消耗量
  660. };
  661. ration.prototype.addRationChecking=function(selected){
  662. if (selected) {// Vincent, 2018-01-02
  663. if(selected.sourceType === project.Ration.getSourceType()){ // 焦点行是定额/量价/工料机,有效显示。
  664. return false;
  665. }else if(selected.sourceType === project.Bills.getSourceType()){
  666. if(selected.data.type == billType.FX||selected.data.type == billType.BX){//焦点行是分项,有效显示。
  667. return false
  668. }
  669. if(selected.data.type == billType.BILL && selected.source.children.length === 0){//焦点行是清单,且没有子项,有效显示。
  670. return false
  671. }
  672. }
  673. }
  674. return true;
  675. };
  676. ration.prototype.canAdd = function (node) { // CSL.2018.07.23
  677. if (!node) return false;
  678. if (calcTools.isRationCategory(node)) return true;
  679. if (calcTools.isBill(node)){
  680. if (node.data.type == billType.FX || node.data.type == billType.BX) return true; // 分项、补项
  681. if (calcTools.isLeafBill(node)
  682. && (node.data.type != billType.DXFY)
  683. && (node.data.type != billType.FB)
  684. && !project.Bills.isMeasure(node)) return true; // 叶子清单项
  685. };
  686. return false;
  687. }
  688. ration.prototype.getAllInstallTypeRation = function () {//取所有计取安装增加费生成的定额
  689. return _.filter(this.datas,{'type':rationType.install});
  690. };
  691. ration.prototype.getLabourTotalFee=function(ration){//feesIndex.labour.totalFee 取定额的人工费合价
  692. if(ration.feesIndex&&ration.feesIndex.labour&&ration.feesIndex.labour.totalFee){
  693. return ration.feesIndex.labour.totalFee;
  694. }else {
  695. return 0;
  696. }
  697. };
  698. ration.prototype.getMaterialTotalFee=function(ration){//feesIndex.material.totalFee 取定额的材料费合价
  699. if(ration.feesIndex&&ration.feesIndex.material&&ration.feesIndex.material.totalFee){
  700. return ration.feesIndex.material.totalFee;
  701. }else {
  702. return 0;
  703. }
  704. } ;
  705. ration.prototype.getMachineTotalFee=function(ration){//feesIndex.machine.totalFee 取定额的机械费合价
  706. if(ration.feesIndex&&ration.feesIndex.machine&&ration.feesIndex.machine.totalFee){
  707. return ration.feesIndex.machine.totalFee;
  708. }else {
  709. return 0;
  710. }
  711. } ;
  712. //获取定额前缀
  713. ration.prototype.getRationPrefix = function(firstLibID, ration){
  714. if(firstLibID !== ration.libID){
  715. return rationPrefix.borrow;
  716. }
  717. if(ration.from && ration.from === rationFrom.cpt){
  718. return rationPrefix.complementary;
  719. }
  720. return rationPrefix.none;
  721. };
  722. return new ration(project);
  723. }
  724. };
  725. function FilterNumberFromUnit (unit) {
  726. let reg = new RegExp('^[0-9]+');
  727. if (reg.test(unit)) {
  728. return parseInt(unit.match(reg)[0]);
  729. } else {
  730. return 1;
  731. }
  732. };