equipment_purchase_view.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  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.SelectionChanged, function (e,args) {
  34. args.sheet.repaint();
  35. equipmentPurchaseObj.checkBtn();
  36. });
  37. if (projectReadOnly) {
  38. sheetCommonObj.disableSpread(this.spread);
  39. } else {
  40. this.initRightClick();
  41. }
  42. }
  43. },
  44. checkBtn:function(){
  45. let me = equipmentPurchaseObj;
  46. let selected = me.getSelected();
  47. let preNode = me.getPreNode(selected);
  48. let afterNode = me.getAfterNode(selected);
  49. //工具栏按钮的有效性
  50. me.validateBtn($('#equipment_upMove'),preNode);
  51. me.validateBtn($('#equipment_downMove'),afterNode);
  52. me.validateBtn($('#equipment_upLevel'),selected && selected.ParentID !=='-1');
  53. me.validateBtn($('#equipment_downLevel'),preNode);
  54. },
  55. validateBtn:function(btn,validate){
  56. if(validate){
  57. btn.removeClass('disabled');
  58. }else{
  59. btn.addClass('disabled');
  60. }
  61. },
  62. getTreeData:function(){
  63. let treeData = [];
  64. let roots = this.parentMap['-1'];
  65. let me = this;
  66. getChildren(roots,treeData);
  67. return treeData;
  68. function getChildren(nodes,data){
  69. if(nodes){
  70. for(let n of nodes){
  71. data.push(n);
  72. getChildren(me.parentMap[n.ID],data)
  73. }
  74. }
  75. }
  76. },
  77. getSelected:function(){
  78. let sel = this.sheet.getSelections()[0];
  79. let row = sel.row == -1 || sel.row == "" ? 0 : sel.row;
  80. if(this.data && this.data.length>0){
  81. return this.data[row];
  82. }
  83. return null;
  84. },
  85. getParentNode:function(node){
  86. if(node.ParentID === '-1') return null;
  87. return this.IDMap[node.ParentID];
  88. },
  89. //取前兄弟节点
  90. getPreNode:function(node){
  91. if(node){
  92. let nodes = this.parentMap[node.ParentID];
  93. let index = nodes.indexOf(node);
  94. return nodes[index-1]
  95. }
  96. return null;
  97. },
  98. //取后兄弟节点
  99. getAfterNode:function(node){
  100. if(node){
  101. let nodes = this.parentMap[node.ParentID];
  102. let index = nodes.indexOf(node);
  103. return nodes[index+1]
  104. }
  105. return null;
  106. },
  107. //取所有后兄弟节点
  108. getAllAfterNodes:function(node){
  109. let brothers = this.parentMap[node.ParentID];
  110. let index = brothers.indexOf(node);
  111. if(brothers.length >= index + 2){
  112. return brothers.slice(index+1);
  113. }
  114. return [];
  115. },
  116. //插入为最后一个子节点的序号
  117. getLastChildrenSeq:function(node){
  118. let seq = 1;
  119. let children = this.parentMap[node.ID];
  120. if(children && children.length > 0){
  121. return children[children.length-1].seq +1
  122. }
  123. return seq;
  124. },
  125. showData:function(){
  126. let equipment_purchase = projectObj.project.equipment_purchase;
  127. this.sourceData = equipment_purchase.datas;
  128. let data = this.sourceData.equipments;
  129. this.IDMap = {};
  130. this.parentMap = {};
  131. data = _.sortBy(data,'seq');
  132. for(let d of data){
  133. let node = ({...d,collapsed:false})
  134. this.IDMap[node.ID] = node;
  135. this.parentMap[node.ParentID] ?this.parentMap[node.ParentID].push(node):this.parentMap[node.ParentID]=[node];
  136. }
  137. let treeData = this.getTreeData();
  138. this.data = treeData;
  139. sheetCommonObj.showTreeData(this.sheet, this.setting,treeData);
  140. this.checkBtn();
  141. $('#equipment_total').text(this.sourceData.total);
  142. },
  143. onValueChange:function (e,info) {
  144. let me = equipmentPurchaseObj,row = info.row, col = info.col;
  145. let dataCode = me.setting.header[col].dataCode;
  146. let value = info.newValue;
  147. let equipment = me.data[row];
  148. if (value&&! sheetCommonObj.checkData(col,me.setting,value)) {
  149. alert('输入的数据类型不对,请重新输入!');
  150. return me.showData();
  151. }
  152. let data = {doc:{},ID:equipment.ID};
  153. if(dataCode == 'quantity' || dataCode == 'originalPrice'|| dataCode == 'freight'|| dataCode == 'sparePartCost'){
  154. value = me.calcTotalPrice(value,dataCode,data.doc,equipment);
  155. }
  156. if(equipment[dataCode] == value) return me.showData();
  157. data.doc[dataCode] = value;
  158. me.updateEquipments([data]);
  159. },
  160. calcTotalPrice:function(newValue=0,dataCode,doc,equipment){
  161. //设备原价
  162. let originalPrice = equipment.originalPrice?scMathUtil.roundForObj(equipment.originalPrice,getDecimal('glj.unitPrice')):0;
  163. //设备运杂费
  164. let freight = equipment.freight?scMathUtil.roundForObj(equipment.freight,getDecimal('glj.unitPrice')):0;
  165. //备品备件费
  166. let sparePartCost = equipment.sparePartCost?scMathUtil.roundForObj(equipment.sparePartCost,getDecimal('glj.quantity')):0;
  167. let quantity = equipment.quantity?scMathUtil.roundForObj(equipment.quantity,getDecimal('glj.quantity')):0;
  168. let unitPrice = 0;
  169. if(gljUtil.isDef(doc.originalPrice)) originalPrice = doc.originalPrice;
  170. if(gljUtil.isDef(doc.freight)) freight = doc.freight;
  171. if(gljUtil.isDef(doc.sparePartCost)) sparePartCost = doc.sparePartCost;
  172. if(gljUtil.isDef(doc.quantity)) quantity = doc.quantity;
  173. if(dataCode === 'quantity') {
  174. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.quantity'));
  175. quantity = newValue;
  176. }
  177. if(dataCode === 'originalPrice') {
  178. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.unitPrice'));
  179. originalPrice = newValue;
  180. }
  181. if(dataCode === 'freight') {
  182. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.unitPrice'));
  183. freight = newValue;
  184. }
  185. if(dataCode === 'sparePartCost') {
  186. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.unitPrice'));
  187. sparePartCost = newValue;
  188. }
  189. unitPrice = scMathUtil.roundForObj(originalPrice + freight,getDecimal('glj.unitPrice'));
  190. unitPrice = scMathUtil.roundForObj(unitPrice + sparePartCost,getDecimal('glj.unitPrice'));
  191. doc.unitPrice = unitPrice;
  192. doc.totalPrice = scMathUtil.roundForObj(quantity * unitPrice,getDecimal('glj.unitPrice'));
  193. return newValue;
  194. },
  195. //计算序列号,返回要改变的兄弟节点数据
  196. calcSeq:function(ParentID,seq){
  197. let data = [];
  198. let nodes = this.parentMap[ParentID];
  199. let temSeq = seq+1;
  200. if(nodes && nodes.length > 0){
  201. for(let n of nodes){
  202. if(n.seq >= seq){
  203. data.push({doc:{seq:temSeq},ID:n.ID})
  204. temSeq+=1;
  205. }
  206. }
  207. }
  208. return data;
  209. },
  210. onSheetRangeChange:function(e,args){
  211. let updateMap = {};
  212. let updateData = []
  213. let me = equipmentPurchaseObj;
  214. for(let c of args.changedCells){
  215. let dataCode = me.setting.header[c.col].dataCode;
  216. let value= args.sheet.getCell(c.row, c.col).text();
  217. let equipment = me.data[c.row];
  218. if (value&&!sheetCommonObj.checkData(c.col,me.setting,value)) {
  219. alert('输入的数据类型不对,请重新输入!');
  220. me.showData();
  221. return ;
  222. }
  223. let tem = updateMap[equipment.ID]?updateMap[equipment.ID]:{};
  224. if(dataCode == 'quantity' || dataCode == 'originalPrice'|| dataCode == 'freight'|| dataCode == 'sparePartCost'){
  225. value = me.calcTotalPrice(value,dataCode,tem,equipment);
  226. }
  227. tem[dataCode] = value;
  228. updateMap[equipment.ID] = tem;
  229. }
  230. for(let ID in updateMap){
  231. let data = {doc:updateMap[ID],ID:ID};
  232. updateData.push(data);
  233. }
  234. if(updateData.length > 0) me.updateEquipments(updateData);
  235. },
  236. newEquipment:function(ParentID='-1',seq=0){
  237. return {ID:uuid.v1(),ParentID,seq}
  238. },
  239. sumTotal: function(updateData){
  240. let dataMap = _.indexBy(updateData, 'ID');
  241. let total = 0;
  242. for(let d of this.data){
  243. let totalPrice = d.totalPrice?scMathUtil.roundForObj(d.totalPrice,getDecimal('glj.unitPrice')):0;
  244. let data = dataMap[d.ID];
  245. if(data && gljUtil.isDef(data.doc.totalPrice))totalPrice = data.doc.totalPrice;
  246. total =scMathUtil.roundForObj(total + totalPrice,getDecimal('glj.unitPrice'))
  247. }
  248. return total;
  249. },
  250. //上移
  251. moveUp:async function(node){
  252. let preNode = this.getPreNode(node);
  253. if(preNode){
  254. let updateData = [];
  255. updateData.push({doc:{seq:node.seq},ID:preNode.ID});
  256. updateData.push({doc:{seq:preNode.seq},ID:node.ID});
  257. await this.updateEquipments(updateData);
  258. }
  259. },
  260. updateEquipments:async function(updateData){
  261. try {
  262. $.bootstrapLoading.start();
  263. let projectID = projectObj.project.ID();
  264. let total = this.sumTotal(updateData);
  265. await ajaxPost('/equipmentPurchase/updateEquipments', { projectID, updateData,total });
  266. for(let data of updateData){
  267. if(data.type === 'insert'){
  268. this.sourceData.equipments.push(...data.documents);
  269. }else{
  270. let equipment = _.find(this.sourceData.equipments,{ID:data.ID});
  271. if(equipment){
  272. Object.assign(equipment,data.doc);
  273. }
  274. }
  275. }
  276. projectObj.project.equipment_purchase.datas.total = total;
  277. } catch (error) {
  278. alert('更新失败,请重试');
  279. }
  280. this.showData();
  281. $.bootstrapLoading.end();
  282. },
  283. insertEquipments:async function(equipments){
  284. try {
  285. $.bootstrapLoading.start();
  286. let projectID = projectObj.project.ID();
  287. await ajaxPost('/equipmentPurchase/insertData', { projectID, equipments });
  288. this.sourceData.equipments.push(...equipments)
  289. this.showData();
  290. } catch (error) {
  291. alert('插入失败,请重试');
  292. }
  293. $.bootstrapLoading.end();
  294. },
  295. deleteEquipment:async function(ID){
  296. try {
  297. let projectID = projectObj.project.ID();
  298. await ajaxPost('/equipmentPurchase/deleteEquipment', { projectID, ID });
  299. _.remove( this.sourceData.equipments,{ID});
  300. this.showData();
  301. } catch (error) {
  302. alert('删除失败,请重试');
  303. }
  304. },
  305. registerInputContextMenuItem:function(){
  306. const insertEquipmentHtml = `<span>插入&nbsp;&nbsp;<input id='insert-equipment-number' class="menu-input" type="text" value="1" onfocus="this.select()">&nbsp;&nbsp;行</span>`;
  307. let me = this;
  308. return sheetCommonObj.registerInputContextMenuItem('insertEquipment', insertEquipmentHtml, 'fa-sign-in', async function () {
  309. const number = +$('#insert-equipment-number').val();
  310. if (!number) {
  311. return;
  312. }
  313. const newData = [];
  314. let row = me.rightClickTarget.row;
  315. let seq = 0;
  316. let ParentID = '-1';
  317. let brotherNodes = [];
  318. if(row == undefined){//没有选中节点的情况,添加到最后
  319. brotherNodes = me.parentMap['-1'];
  320. if(brotherNodes && brotherNodes.length > 0){
  321. seq = brotherNodes[brotherNodes.length -1].seq;
  322. }
  323. }else{
  324. let node = me.data[row];//选中节点时插入为选中的下一行
  325. seq = node.seq;
  326. ParentID = node.ParentID;
  327. }
  328. for (let i = 0; i < number; i++) {
  329. seq+=1;
  330. newData.push(me.newEquipment(ParentID,seq));
  331. }
  332. let updateData = me.calcSeq(ParentID,seq);
  333. updateData.push({documents:newData,type:'insert'});
  334. me.updateEquipments(updateData)
  335. });
  336. },
  337. initRightClick: function () {
  338. let me = this;
  339. $.contextMenu({
  340. selector: '#equipmentSpread',
  341. build: function ($trigger, e) {
  342. me.rightClickTarget = SheetDataHelper.safeRightClickSelection($trigger, e, me.spread);
  343. me.checkBtn();
  344. return me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.viewport ||
  345. me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
  346. },
  347. items: {
  348. "insert": {
  349. type: me.registerInputContextMenuItem(),
  350. disabled: function () {
  351. return false;
  352. },
  353. /* callback: function (key, opt) {
  354. me.insertEquipments([me.newEquipment()])
  355. } */
  356. },
  357. "delete": {
  358. name: "删除",
  359. icon: 'fa-times',
  360. disabled: function () {
  361. return me.rightClickTarget.row === undefined;
  362. },
  363. callback: function (key, opt) {
  364. let row = me.rightClickTarget.row;
  365. me.deleteEquipment(me.data[row].ID);
  366. //me.preApplyInfoPrice(row);
  367. }
  368. }
  369. }
  370. });
  371. },
  372. }
  373. $(function () {
  374. $('#tab_equipment_purchase').on('shown.bs.tab', function (e) {
  375. sessionStorage.setItem('mainTab', '#tab_equipment_purchase');
  376. $(e.relatedTarget.hash).removeClass('active');
  377. equipmentPurchaseObj.initSpread();
  378. equipmentPurchaseObj.showData();
  379. })
  380. //降级
  381. $('#equipment_downLevel').click(function(){
  382. let me = equipmentPurchaseObj;
  383. let selected = me.getSelected();
  384. if(selected){
  385. let preNode = me.getPreNode(selected);
  386. if(preNode){
  387. let seq = me.getLastChildrenSeq(preNode);
  388. me.updateEquipments([{doc:{ParentID:preNode.ID,seq},ID:selected.ID}])
  389. }
  390. }
  391. })
  392. //升级 - 后兄弟节点变成子节点
  393. $('#equipment_upLevel').click(function(){
  394. let me = equipmentPurchaseObj;
  395. let selected = me.getSelected();
  396. if(selected){
  397. let parentNode = me.getParentNode(selected);
  398. if(parentNode){
  399. let seq = parentNode.seq+1;
  400. let updateData = me.calcSeq(parentNode.ParentID,seq);
  401. updateData.push({doc:{ParentID:parentNode.ParentID,seq},ID:selected.ID})
  402. let brothers = me.getAllAfterNodes(selected);
  403. let subSeq = 0;
  404. //后兄弟节点变成子节点
  405. for(let b of brothers){
  406. subSeq+=1;
  407. updateData.push({doc:{ParentID:selected.ID,seq:subSeq},ID:b.ID})
  408. }
  409. me.updateEquipments(updateData)
  410. }
  411. }
  412. })
  413. //上移
  414. $('#equipment_upMove').click(async function (){
  415. let me = equipmentPurchaseObj;
  416. let selected = me.getSelected();
  417. if(selected){
  418. let sel = me.sheet.getSelections()[0];
  419. await me.moveUp(selected);
  420. me.sheet.setSelection(sel.row -1 , sel.col, sel.rowCount, sel.colCount);
  421. }
  422. })
  423. //下移
  424. $('#equipment_downMove').click(async function(){
  425. let me = equipmentPurchaseObj;
  426. let selected = me.getSelected();
  427. if(selected){
  428. let sel = me.sheet.getSelections()[0];
  429. let node = me.getAfterNode(selected);
  430. if(node){
  431. await me.moveUp(node);
  432. me.sheet.setSelection(sel.row +1 , sel.col, sel.rowCount, sel.colCount);
  433. }
  434. }
  435. })
  436. })