equipment_purchase_view.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. let unitOptions = ['m', 'm2', 'm3', 'km', 't', 'kg', '台班', '工日', '昼夜', '元', '项', '处', '个', '件',
  2. '根', '组', '系统', '台', '套', '株', '丛', '缸', '支', '只', '块', '座', '对', '份', '樘', '攒', '榀']
  3. let equipmentPurchaseObj = {
  4. IDMap:{},
  5. parentMap:{},
  6. setting:{
  7. header: [
  8. {headerName: "编号", headerWidth: 160, dataCode: "code", dataType: "String",formatter: "@",spanRows: [2]},
  9. {headerName: "设备名称", headerWidth: 200, dataCode: "name", dataType: "String",spanRows: [2]},
  10. {headerName: "单位", headerWidth: 60, dataCode: "unit", dataType: "String",hAlign: "center",cellType:'comboBox',editable:true,options:unitOptions,spanRows: [2]},
  11. {headerName: ["设备价格","设备原价"], headerWidth: 160, dataCode: "originalPrice", hAlign: "right", dataType: "Number",validator:'number',spanCols: [4,1]},
  12. {headerName: ["","设备运杂费"], headerWidth: 160, dataCode: "freight", hAlign: "right", dataType: "Number",validator:'number',spanCols: [0,1]},
  13. {headerName: ["","备品备件费"], headerWidth: 160, dataCode: "sparePartCost", hAlign: "right", dataType: "Number",validator:'number',spanCols: [0,1]},
  14. {headerName: ["","单价"], headerWidth: 160, dataCode: "unitPrice", hAlign: "right", dataType: "Number",validator:'number',spanCols: [0,1]},
  15. {headerName: "数量", headerWidth: 160, dataCode: "quantity", hAlign: "right", dataType: "Number",validator:'number',spanRows: [2]},
  16. {headerName: "合价", headerWidth: 160, dataCode: "totalPrice", hAlign: "right", dataType: "Number",spanRows: [2]},
  17. ],
  18. headRows:2,
  19. view: {
  20. lockColumns: ["totalPrice",'unitPrice'],
  21. rowHeaderWidth:40,
  22. }
  23. },
  24. sheet:null,
  25. initSpread:function () {
  26. if(this.sheet == null){
  27. this.spread = SheetDataHelper.createNewSpread($("#equipmentSpread")[0]);
  28. sheetCommonObj.spreadDefaultStyle(this.spread);
  29. this.sheet = this.spread.getSheet(0);
  30. sheetCommonObj.initSheet(this.sheet, this.setting, 0);
  31. this.sheet.bind(GC.Spread.Sheets.Events.ValueChanged,this.onValueChange);
  32. this.sheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onSheetRangeChange);
  33. this.sheet.bind(GC.Spread.Sheets.Events.EditStarting, this.onEditStarting);
  34. this.sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e,args) {
  35. args.sheet.repaint();
  36. equipmentPurchaseObj.checkBtn();
  37. });
  38. if (projectReadOnly) {
  39. sheetCommonObj.disableSpread(this.spread);
  40. } else {
  41. this.initRightClick();
  42. }
  43. }
  44. },
  45. checkBtn:function(){
  46. let me = equipmentPurchaseObj;
  47. let selected = me.getSelected();
  48. let preNode = me.getPreNode(selected);
  49. let afterNode = me.getAfterNode(selected);
  50. //工具栏按钮的有效性
  51. me.validateBtn($('#equipment_upMove'),preNode);
  52. me.validateBtn($('#equipment_downMove'),afterNode);
  53. me.validateBtn($('#equipment_upLevel'),selected && selected.ParentID !=='-1');
  54. me.validateBtn($('#equipment_downLevel'),preNode);
  55. },
  56. validateBtn:function(btn,validate){
  57. if(validate){
  58. btn.removeClass('disabled');
  59. }else{
  60. btn.addClass('disabled');
  61. }
  62. },
  63. getTreeData:function(){
  64. let treeData = [];
  65. let roots = this.parentMap['-1'];
  66. let me = this;
  67. getChildren(roots,treeData);
  68. return treeData;
  69. function getChildren(nodes,data){
  70. if(nodes){
  71. for(let n of nodes){
  72. data.push(n);
  73. getChildren(me.parentMap[n.ID],data)
  74. }
  75. }
  76. }
  77. },
  78. getSelected:function(){
  79. let sel = this.sheet.getSelections()[0];
  80. let row = sel.row == -1 || sel.row == "" ? 0 : sel.row;
  81. if(this.data && this.data.length>0){
  82. return this.data[row];
  83. }
  84. return null;
  85. },
  86. getParentNode:function(node){
  87. if(node.ParentID === '-1') return null;
  88. return this.IDMap[node.ParentID];
  89. },
  90. //取前兄弟节点
  91. getPreNode:function(node){
  92. if(node){
  93. let nodes = this.parentMap[node.ParentID];
  94. let index = nodes.indexOf(node);
  95. return nodes[index-1]
  96. }
  97. return null;
  98. },
  99. //取后兄弟节点
  100. getAfterNode:function(node){
  101. if(node){
  102. let nodes = this.parentMap[node.ParentID];
  103. let index = nodes.indexOf(node);
  104. return nodes[index+1]
  105. }
  106. return null;
  107. },
  108. //取所有后兄弟节点
  109. getAllAfterNodes:function(node){
  110. let brothers = this.parentMap[node.ParentID];
  111. let index = brothers.indexOf(node);
  112. if(brothers.length >= index + 2){
  113. return brothers.slice(index+1);
  114. }
  115. return [];
  116. },
  117. //插入为最后一个子节点的序号
  118. getLastChildrenSeq:function(node){
  119. let seq = 1;
  120. let children = this.parentMap[node.ID];
  121. if(children && children.length > 0){
  122. return children[children.length-1].seq +1
  123. }
  124. return seq;
  125. },
  126. showData:function(){
  127. let equipment_purchase = projectObj.project.equipment_purchase;
  128. this.sourceData = equipment_purchase.datas;
  129. let data = this.sourceData.equipments;
  130. this.IDMap = {};
  131. this.parentMap = {};
  132. data = _.sortBy(data,'seq');
  133. for(let d of data){
  134. let node = ({...d,collapsed:false})
  135. this.IDMap[node.ID] = node;
  136. this.parentMap[node.ParentID] ?this.parentMap[node.ParentID].push(node):this.parentMap[node.ParentID]=[node];
  137. }
  138. let treeData = this.getTreeData();
  139. this.data = treeData;
  140. sheetCommonObj.showTreeData(this.sheet, this.setting,treeData);
  141. this.checkBtn();
  142. $('#equipment_total').text(this.sourceData.total);
  143. },
  144. onEditStarting: function (sender, args) {
  145. let me = equipmentPurchaseObj;
  146. let row = args.row;
  147. let col = args.col;
  148. if (me.editChecking(row, col) == false) {
  149. args.cancel = true;
  150. }
  151. },
  152. editChecking:function (row,col) {
  153. let me = equipmentPurchaseObj
  154. let dataCode = me.setting.header[col].dataCode;
  155. let equipment = me.data[row];
  156. let children = me.parentMap[equipment.ID];
  157. if(children && children.length>0){//父节点只有这三列才能编辑
  158. return dataCode === 'unit'||dataCode === 'name'||dataCode === 'code'
  159. }
  160. return true;
  161. },
  162. onValueChange:function (e,info) {
  163. let me = equipmentPurchaseObj,row = info.row, col = info.col;
  164. let dataCode = me.setting.header[col].dataCode;
  165. let value = info.newValue;
  166. let equipment = me.data[row];
  167. if (value&&! sheetCommonObj.checkData(col,me.setting,value)) {
  168. alert('输入的数据类型不对,请重新输入!');
  169. return me.showData();
  170. }
  171. let data = {doc:{},ID:equipment.ID};
  172. if(dataCode == 'quantity' || dataCode == 'originalPrice'|| dataCode == 'freight'|| dataCode == 'sparePartCost'){
  173. value = me.calcTotalPrice(value,dataCode,data.doc,equipment);
  174. }
  175. if(equipment[dataCode] == value) return me.showData();
  176. data.doc[dataCode] = value;
  177. me.updateEquipments([data]);
  178. },
  179. //计算父节点
  180. calcParent:function(updateData){
  181. let me = this;
  182. let temIDMap = {};
  183. let temParentMap = {};
  184. for(let d of updateData){
  185. if(d.doc){
  186. temIDMap[d.ID] = d;
  187. if(d.doc.ParentID){
  188. temParentMap[d.doc.ParentID]?temParentMap[d.doc.ParentID].push(d):temParentMap[d.doc.ParentID]=[d];
  189. }
  190. }
  191. }
  192. for(let d of this.data){
  193. let children = this.parentMap[d.ID];
  194. let newChildren = temParentMap[d.ID];
  195. if((children&&children.length > 0) || (newChildren && newChildren.length > 0)){
  196. let totalPrice = getTotalPrice(d.ID);
  197. if(d.totalPrice !== totalPrice) updateData.push({ID:d.ID,doc: {totalPrice,unitPrice:'',sparePartCost:'',freight:'',originalPrice:'',quantity:''} })
  198. }
  199. }
  200. function getTotalPrice(ID){
  201. let sum = 0;
  202. let children = me.parentMap[ID];
  203. let newChildren = temParentMap[ID];
  204. if((children&&children.length > 0) || (newChildren && newChildren.length > 0)){
  205. if(children&&children.length > 0){
  206. for(let c of children){
  207. let newChild = temIDMap[c.ID];
  208. if(newChild && newChild.doc){
  209. if(newChild.doc.ParentID && newChild.doc.ParentID!=ID) continue;//升级操作时,子节点可能已经不是它的子节点了
  210. }
  211. let totalPrice = getTotalPrice(c.ID);
  212. sum = scMathUtil.roundForObj(sum + totalPrice,getDecimal('process'));
  213. }
  214. }
  215. if(newChildren && newChildren.length > 0){
  216. for(let c of newChildren){
  217. let totalPrice = getTotalPrice(c.ID);
  218. sum = scMathUtil.roundForObj(sum + totalPrice,getDecimal('process'));
  219. }
  220. }
  221. return scMathUtil.roundForObj(sum,getDecimal('glj.unitPrice'));
  222. }
  223. let tem = temIDMap[ID];
  224. if(tem && tem.doc){
  225. let doc = tem.doc;
  226. if(gljUtil.isDef(doc.totalPrice)) return doc.totalPrice;
  227. }
  228. return me.IDMap[ID].totalPrice?scMathUtil.roundForObj(me.IDMap[ID].totalPrice,getDecimal('glj.unitPrice')):0
  229. }
  230. },
  231. calcTotalPrice:function(newValue = 0,dataCode,doc,equipment){
  232. //设备原价
  233. let originalPrice = equipment.originalPrice?scMathUtil.roundForObj(equipment.originalPrice,getDecimal('glj.unitPrice')):0;
  234. //设备运杂费
  235. let freight = equipment.freight?scMathUtil.roundForObj(equipment.freight,getDecimal('glj.unitPrice')):0;
  236. //备品备件费
  237. let sparePartCost = equipment.sparePartCost?scMathUtil.roundForObj(equipment.sparePartCost,getDecimal('glj.quantity')):0;
  238. let quantity = equipment.quantity?scMathUtil.roundForObj(equipment.quantity,getDecimal('glj.quantity')):0;
  239. let unitPrice = 0;
  240. if(gljUtil.isDef(doc.originalPrice)) originalPrice = doc.originalPrice;
  241. if(gljUtil.isDef(doc.freight)) freight = doc.freight;
  242. if(gljUtil.isDef(doc.sparePartCost)) sparePartCost = doc.sparePartCost;
  243. if(gljUtil.isDef(doc.quantity)) quantity = doc.quantity;
  244. if(dataCode === 'quantity') {
  245. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.quantity'));
  246. quantity = newValue;
  247. }
  248. if(dataCode === 'originalPrice') {
  249. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.unitPrice'));
  250. originalPrice = newValue;
  251. }
  252. if(dataCode === 'freight') {
  253. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.unitPrice'));
  254. freight = newValue;
  255. }
  256. if(dataCode === 'sparePartCost') {
  257. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.unitPrice'));
  258. sparePartCost = newValue;
  259. }
  260. unitPrice = scMathUtil.roundForObj(originalPrice + freight,getDecimal('process'));
  261. unitPrice = scMathUtil.roundForObj(unitPrice + sparePartCost,getDecimal('glj.unitPrice'));
  262. doc.unitPrice = unitPrice;
  263. doc.totalPrice = scMathUtil.roundForObj(quantity * unitPrice,getDecimal('glj.unitPrice'));
  264. return newValue;
  265. },
  266. //计算序列号,返回要改变的兄弟节点数据
  267. calcSeq:function(ParentID,seq){
  268. let data = [];
  269. let nodes = this.parentMap[ParentID];
  270. let temSeq = seq+1;
  271. if(nodes && nodes.length > 0){
  272. for(let n of nodes){
  273. if(n.seq >= seq){
  274. data.push({doc:{seq:temSeq},ID:n.ID})
  275. temSeq+=1;
  276. }
  277. }
  278. }
  279. return data;
  280. },
  281. onSheetRangeChange:function(e,args){
  282. let updateMap = {};
  283. let updateData = []
  284. let me = equipmentPurchaseObj;
  285. for(let c of args.changedCells){
  286. let dataCode = me.setting.header[c.col].dataCode;
  287. let value= args.sheet.getCell(c.row, c.col).text();
  288. let equipment = me.data[c.row];
  289. if (me.editChecking(c.row, c.col) == false) {
  290. continue
  291. }
  292. if (value&&!sheetCommonObj.checkData(c.col,me.setting,value)) {
  293. alert('输入的数据类型不对,请重新输入!');
  294. me.showData();
  295. return ;
  296. }
  297. let tem = updateMap[equipment.ID]?updateMap[equipment.ID]:{};
  298. if(dataCode == 'quantity' || dataCode == 'originalPrice'|| dataCode == 'freight'|| dataCode == 'sparePartCost'){
  299. value = me.calcTotalPrice(value,dataCode,tem,equipment);
  300. }
  301. tem[dataCode] = value;
  302. updateMap[equipment.ID] = tem;
  303. }
  304. for(let ID in updateMap){
  305. let data = {doc:updateMap[ID],ID:ID};
  306. updateData.push(data);
  307. }
  308. updateData.length > 0? me.updateEquipments(updateData): me.showData();
  309. },
  310. newEquipment:function(ParentID='-1',seq=0){
  311. return {ID:uuid.v1(),ParentID,seq}
  312. },
  313. sumTotal: function(updateData){
  314. let dataMap = {};
  315. let temParentMap = {};
  316. let total = 0;
  317. for(let d of updateData){
  318. if(d.doc){
  319. dataMap[d.ID] = d;
  320. if(d.doc.ParentID){
  321. temParentMap[d.doc.ParentID]?temParentMap[d.doc.ParentID].push(d):temParentMap[d.doc.ParentID]=[d];
  322. }
  323. }
  324. }
  325. for(let d of this.data){
  326. //累加所有底层节点就行
  327. if(!this.parentMap[d.ID] && !temParentMap[d.ID] ){
  328. let totalPrice = d.totalPrice?scMathUtil.roundForObj(d.totalPrice,getDecimal('glj.unitPrice')):0;
  329. let data = dataMap[d.ID];
  330. if(data && gljUtil.isDef(data.doc.totalPrice))totalPrice = data.doc.totalPrice;
  331. total =scMathUtil.roundForObj(total + totalPrice,getDecimal('glj.unitPrice'))
  332. }
  333. }
  334. return total;
  335. },
  336. //上移
  337. moveUp:async function(node){
  338. let preNode = this.getPreNode(node);
  339. if(preNode){
  340. let updateData = [];
  341. updateData.push({doc:{seq:node.seq},ID:preNode.ID});
  342. updateData.push({doc:{seq:preNode.seq},ID:node.ID});
  343. await this.updateEquipments(updateData);
  344. }
  345. },
  346. updateEquipments:async function(updateData){
  347. try {
  348. this.calcParent(updateData);
  349. $.bootstrapLoading.start();
  350. let projectID = projectObj.project.ID();
  351. let total = this.sumTotal(updateData);
  352. await ajaxPost('/equipmentPurchase/updateEquipments', { projectID, updateData,total });
  353. for(let data of updateData){
  354. if(data.type === 'insert'){
  355. this.sourceData.equipments.push(...data.documents);
  356. }else{
  357. let equipment = _.find(this.sourceData.equipments,{ID:data.ID});
  358. if(equipment){
  359. Object.assign(equipment,data.doc);
  360. }
  361. }
  362. }
  363. projectObj.project.equipment_purchase.datas.total = total;
  364. } catch (error) {
  365. console.log(error);
  366. alert('更新失败,请重试');
  367. }
  368. this.showData();
  369. $.bootstrapLoading.end();
  370. },
  371. insertEquipments:async function(equipments){
  372. try {
  373. $.bootstrapLoading.start();
  374. let projectID = projectObj.project.ID();
  375. await ajaxPost('/equipmentPurchase/insertData', { projectID, equipments });
  376. this.sourceData.equipments.push(...equipments)
  377. this.showData();
  378. } catch (error) {
  379. alert('插入失败,请重试');
  380. }
  381. $.bootstrapLoading.end();
  382. },
  383. deleteEquipment:async function(ID){
  384. try {
  385. let projectID = projectObj.project.ID();
  386. await ajaxPost('/equipmentPurchase/deleteEquipment', { projectID, ID });
  387. _.remove( this.sourceData.equipments,{ID});
  388. this.showData();
  389. } catch (error) {
  390. alert('删除失败,请重试');
  391. }
  392. },
  393. registerInputContextMenuItem:function(){
  394. const insertEquipmentHtml = `<span>插入&nbsp;&nbsp;<input id='insert-equipment-number' class="menu-input" type="text" value="1" onfocus="this.select()">&nbsp;&nbsp;行</span>`;
  395. let me = this;
  396. return sheetCommonObj.registerInputContextMenuItem('insertEquipment', insertEquipmentHtml, 'fa-sign-in', async function () {
  397. const number = +$('#insert-equipment-number').val();
  398. if (!number) {
  399. return;
  400. }
  401. const newData = [];
  402. let row = me.rightClickTarget.row;
  403. let seq = 0;
  404. let ParentID = '-1';
  405. let brotherNodes = [];
  406. if(row == undefined){//没有选中节点的情况,添加到最后
  407. brotherNodes = me.parentMap['-1'];
  408. if(brotherNodes && brotherNodes.length > 0){
  409. seq = brotherNodes[brotherNodes.length -1].seq;
  410. }
  411. }else{
  412. let node = me.data[row];//选中节点时插入为选中的下一行
  413. seq = node.seq;
  414. ParentID = node.ParentID;
  415. }
  416. for (let i = 0; i < number; i++) {
  417. seq+=1;
  418. newData.push(me.newEquipment(ParentID,seq));
  419. }
  420. let updateData = me.calcSeq(ParentID,seq);
  421. updateData.push({documents:newData,type:'insert'});
  422. me.updateEquipments(updateData)
  423. });
  424. },
  425. initRightClick: function () {
  426. let me = this;
  427. $.contextMenu({
  428. selector: '#equipmentSpread',
  429. build: function ($trigger, e) {
  430. me.rightClickTarget = SheetDataHelper.safeRightClickSelection($trigger, e, me.spread);
  431. me.checkBtn();
  432. return me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.viewport ||
  433. me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
  434. },
  435. items: {
  436. "insert": {
  437. type: me.registerInputContextMenuItem(),
  438. disabled: function () {
  439. return false;
  440. },
  441. /* callback: function (key, opt) {
  442. me.insertEquipments([me.newEquipment()])
  443. } */
  444. },
  445. "delete": {
  446. name: "删除",
  447. icon: 'fa-times',
  448. disabled: function () {
  449. return me.rightClickTarget.row === undefined;
  450. },
  451. callback: function (key, opt) {
  452. let row = me.rightClickTarget.row;
  453. me.deleteEquipment(me.data[row].ID);
  454. //me.preApplyInfoPrice(row);
  455. }
  456. }
  457. }
  458. });
  459. },
  460. }
  461. $(function () {
  462. $('#tab_equipment_purchase').on('shown.bs.tab', function (e) {
  463. sessionStorage.setItem('mainTab', '#tab_equipment_purchase');
  464. $(e.relatedTarget.hash).removeClass('active');
  465. equipmentPurchaseObj.initSpread();
  466. equipmentPurchaseObj.showData();
  467. })
  468. //降级
  469. $('#equipment_downLevel').click(function(){
  470. let me = equipmentPurchaseObj;
  471. let selected = me.getSelected();
  472. if(selected){
  473. let preNode = me.getPreNode(selected);
  474. if(preNode){
  475. let seq = me.getLastChildrenSeq(preNode);
  476. me.updateEquipments([{doc:{ParentID:preNode.ID,seq},ID:selected.ID}])
  477. }
  478. }
  479. })
  480. //升级 - 后兄弟节点变成子节点
  481. $('#equipment_upLevel').click(function(){
  482. let me = equipmentPurchaseObj;
  483. let selected = me.getSelected();
  484. if(selected){
  485. let parentNode = me.getParentNode(selected);
  486. if(parentNode){
  487. let seq = parentNode.seq+1;
  488. let updateData = me.calcSeq(parentNode.ParentID,seq);
  489. updateData.push({doc:{ParentID:parentNode.ParentID,seq},ID:selected.ID})
  490. let brothers = me.getAllAfterNodes(selected);
  491. let subSeq = 0;
  492. //后兄弟节点变成子节点
  493. for(let b of brothers){
  494. subSeq+=1;
  495. updateData.push({doc:{ParentID:selected.ID,seq:subSeq},ID:b.ID})
  496. }
  497. me.updateEquipments(updateData)
  498. }
  499. }
  500. })
  501. //上移
  502. $('#equipment_upMove').click(async function (){
  503. let me = equipmentPurchaseObj;
  504. let selected = me.getSelected();
  505. if(selected){
  506. let sel = me.sheet.getSelections()[0];
  507. await me.moveUp(selected);
  508. me.sheet.setSelection(sel.row -1 , sel.col, sel.rowCount, sel.colCount);
  509. }
  510. })
  511. //下移
  512. $('#equipment_downMove').click(async function(){
  513. let me = equipmentPurchaseObj;
  514. let selected = me.getSelected();
  515. if(selected){
  516. let sel = me.sheet.getSelections()[0];
  517. let node = me.getAfterNode(selected);
  518. if(node){
  519. await me.moveUp(node);
  520. me.sheet.setSelection(sel.row +1 , sel.col, sel.rowCount, sel.colCount);
  521. }
  522. }
  523. })
  524. })