material_list.js 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249
  1. 'use strict';
  2. /**
  3. * 材料调差 - 调差清单
  4. *
  5. * @author EllisRan
  6. * @date 2019/10/25
  7. * @version
  8. */
  9. function getStageId() {
  10. return window.location.pathname.split('/')[5];
  11. }
  12. function findNotJoinLeafXmj(x, type = '') {
  13. if (type === 'index') {
  14. return notJoinList.findIndex(function (item) {
  15. return item.gcl_id === x.gcl_id && item.xmj_id === x.id && (x.mx_id === undefined || (x.mx_id !== undefined && x.mx_id === item.mx_id));
  16. });
  17. }
  18. return notJoinList.find(function (item) {
  19. return item.gcl_id === x.gcl_id && item.xmj_id === x.id && (x.mx_id === undefined || (x.mx_id !== undefined && x.mx_id === item.mx_id));
  20. });
  21. }
  22. function getMpSpreadByMBData(id) {
  23. const info = materialBillsData.find(function (item) {
  24. return item.id === parseInt(id);
  25. });
  26. return info ? info.m_spread : 0;
  27. }
  28. function getMaterialListByLeafXmj(gcl_id, xmj_id, mx_id = null) {
  29. const list = [];
  30. for (const ml of materialListData) {
  31. if (gcl_id === ml.gcl_id && xmj_id === ml.xmj_id && (mx_id === null || mx_id === ml.mx_id)) {
  32. list.push(ml);
  33. }
  34. }
  35. return list;
  36. }
  37. function calcOneBQJC(xmj) {
  38. let jiacha = 0;
  39. const notx = findNotJoinLeafXmj(xmj);
  40. if (notx === undefined) {
  41. const list = xmj.mx_id !== undefined ? getMaterialListByLeafXmj(xmj.gcl_id, xmj.id, xmj.mx_id) : getMaterialListByLeafXmj(xmj.gcl_id, xmj.id);
  42. for (const l of list) {
  43. jiacha = ZhCalc.add(jiacha, ZhCalc.mul(ZhCalc.mul(xmj.gather_qty, l.quantity), getMpSpreadByMBData(l.mb_id)));
  44. }
  45. }
  46. return ZhCalc.round(jiacha, materialDecimal.tp);
  47. }
  48. function getPasteHint (str, row = '') {
  49. let returnObj = str;
  50. if (row) {
  51. returnObj.msg = '清单第' + (row+1) + '行' + (str.msg ? str.msg : str);
  52. }
  53. return returnObj;
  54. }
  55. // 重新计算列表的价差
  56. function calculateJiaCha(data, index) {
  57. // 计算单条的
  58. if (index) {
  59. const gcld = data[index]
  60. let total_jiacha = 0;
  61. for (const [index, xmj] of gcld.leafXmjs.entries()) {
  62. const jiacha = calcOneBQJC(xmj);
  63. gcld.leafXmjs[index].jiacha = jiacha !== 0 ? jiacha : null;
  64. total_jiacha += jiacha;
  65. }
  66. gcld.total_jiacha = ZhCalc.round(total_jiacha, materialDecimal.tp)
  67. } else {
  68. for(const gcld of data) {
  69. let total_jiacha = 0;
  70. for (const [index, xmj] of gcld.leafXmjs.entries()) {
  71. const jiacha = calcOneBQJC(xmj);
  72. gcld.leafXmjs[index].jiacha = jiacha !== 0 ? jiacha : null;
  73. total_jiacha += jiacha;
  74. }
  75. gcld.total_jiacha = ZhCalc.round(total_jiacha, materialDecimal.tp)
  76. }
  77. }
  78. }
  79. const is_numeric = (value) => {
  80. if (typeof(value) === 'object') {
  81. return false;
  82. } else {
  83. return !Number.isNaN(Number(value)) && value.toString().trim() !== '';
  84. }
  85. };
  86. $(document).ready(() => {
  87. function TipCellType()
  88. {
  89. }
  90. TipCellType.prototype = new GC.Spread.Sheets.CellTypes.ColumnHeader();
  91. TipCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
  92. return { x: x, y: y, row: context.row, col: context.col, cellRect: cellRect, sheetArea: context.sheetArea, sheet: context.sheet };
  93. };
  94. TipCellType.prototype.processMouseEnter = function (hitInfo){
  95. if (!this._toolTipElement) {
  96. var div = document.createElement("div");
  97. $(div).css("position", "absolute")
  98. .css("border", "1px #C0C0C0 solid")
  99. .css("box-shadow", "1px 2px 5px rgba(0,0,0,0.4)")
  100. .css("font", "9pt Arial")
  101. .css("background", "#fff")
  102. // .css("color", "#fff")
  103. .css("z-index", "1000")
  104. .css("padding", 5);
  105. this._toolTipElement = div;
  106. }
  107. $(this._toolTipElement).text("单位数量:每一单位清单下所需工料消耗量。")
  108. .css("top", hitInfo.y + 15)
  109. .css("left", hitInfo.x - 15);
  110. $(this._toolTipElement).hide();
  111. // document.body.insertBefore(this._toolTipElement, null);
  112. $('#material-spread-div').append(this._toolTipElement, null);
  113. $(this._toolTipElement).show("fast");
  114. };
  115. TipCellType.prototype.processMouseLeave = function (hitInfo) {
  116. if (this._toolTipElement) {
  117. // document.body.removeChild(this._toolTipElement);
  118. // $('#material-spread-div').removeChild(this._toolTipElement);
  119. this._toolTipElement.remove();
  120. this._toolTipElement = null;
  121. }
  122. };
  123. autoFlashHeight();
  124. // 清单table
  125. const ledgerSpread = SpreadJsObj.createNewSpread($('#ledger-spread')[0]);
  126. const ledgerSpreadSetting = {
  127. cols: [
  128. {title: '清单编号', colSpan: '1', rowSpan: '2', field: 'b_code', hAlign: 0, width: 90, formatter: '@'},
  129. {title: '名称', colSpan: '1', rowSpan: '2', field: 'name', hAlign: 0, width: 220, formatter: '@'},
  130. {title: '单位', colSpan: '1', rowSpan: '2', field: 'unit', hAlign: 1, width: 80, formatter: '@'},
  131. {title: '单价', colSpan: '1', rowSpan: '2', field: 'unit_price', hAlign: 2, width: 110, type: 'Number'},
  132. {title: '本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 110, type: 'Number'},
  133. {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 110, type: 'Number'},
  134. {title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 110, type: 'Number'},
  135. {title: '本期完成金额', colSpan: '1', rowSpan: '2', field: 'gather_tp', hAlign: 2, width: 110, type: 'Number'},
  136. {title: '本期价差', colSpan: '1', rowSpan: '2', field: 'total_jiacha', hAlign:3, width: 110, type: 'Number'}
  137. ],
  138. emptyRows: 0,
  139. headRows: 2,
  140. headRowHeight: [25, 25],
  141. defaultRowHeight: 21,
  142. headerFont: '12px 微软雅黑',
  143. font: '12px 微软雅黑',
  144. readOnly: true,
  145. };
  146. // let gclGatherData = gclGatherModel.gatherGclData()
  147. // 获取项目节数据
  148. function loadLeafXmjData(iGclRow) {
  149. const gcl = gclGatherData[iGclRow];
  150. if (gcl) {
  151. for (const [index, xmj] of gcl.leafXmjs.entries()) {
  152. const jiacha = calcOneBQJC(xmj);
  153. gcl.leafXmjs[index].jiacha = jiacha !== 0 ? ZhCalc.round(jiacha, materialDecimal.tp) : null;
  154. }
  155. const leafXmjs = gcl.leafXmjs.filter(item => {
  156. return item.qc_qty || item.contract_qty
  157. });
  158. console.log(leafXmjs);
  159. SpreadJsObj.loadSheetData(leafXmjSpread.getActiveSheet(), SpreadJsObj.DataType.Data, leafXmjs);
  160. // 对清单调差工料table的单位数量进行改变
  161. materialSpreadSetting.cols[materialSpreadSetting.cols.length - 2].title = '|' + gcl.unit + '数量 �';
  162. // SpreadJsObj.initSheet(materialSpread.getActiveSheet(), materialSpreadSetting);
  163. } else {
  164. SpreadJsObj.loadSheetData(leafXmjSpread.getActiveSheet(), SpreadJsObj.DataType.Data, []);
  165. }
  166. SpreadJsObj.initSheet(materialSpread.getActiveSheet(), materialSpreadSetting);
  167. }
  168. SpreadJsObj.initSheet(ledgerSpread.getActiveSheet(), ledgerSpreadSetting);
  169. // 项目明细table
  170. const leafXmjSpread = SpreadJsObj.createNewSpread($('#leaf-xmj-spread')[0]);
  171. const leafXmjSpreadSetting = {
  172. cols: [
  173. {title: '项目节|编号', colSpan: '2|1', rowSpan: '1|1', field: 'code', hAlign: 0, width: 80, formatter: '@'},
  174. {title: '|项目节名称', colSpan: '|1', rowSpan: '|1', field: 'jldy', hAlign: 0, width: 100, formatter: '@'},
  175. {title: '计量单元|计量单元', colSpan: '2|1', rowSpan: '1|1', field: 'bwmx', hAlign: 0, width: 100, formatter: '@'},
  176. {title: '|复核数量', colSpan: '|1', rowSpan: '|1', field: 'quantity', hAlign: 0, width: 80, type: 'Number'},
  177. {title: '部位信息|单位工程', colSpan: '3|1', rowSpan: '1|1', field: 'dwgc', hAlign: 0, width: 100, formatter: '@'},
  178. {title: '|分部工程', colSpan: '|1', rowSpan: '|1', field: 'fbgc', hAlign: 0, width: 100, formatter: '@'},
  179. {title: '|分项工程', colSpan: '|1', rowSpan: '|1', field: 'fxgc', hAlign: 0, width: 180, formatter: '@'},
  180. {title: '本期计量数量|合同', colSpan: '3|1', rowSpan: '1|1', field: 'contract_qty', hAlign: 2, width: 60, type: 'Number'},
  181. {title: '|数量变更', colSpan: '|1', rowSpan: '|1', field: 'qc_qty', hAlign: 2, width: 80, type: 'Number'},
  182. {title: '|小计', colSpan: '|1', rowSpan: '|1', field: 'gather_qty', hAlign: 2, width: 60, type: 'Number'},
  183. {title: '本期价差', colSpan: '1', rowSpan: '2', field: 'jiacha', hAlign: 2, width: 80, type: 'Number'},
  184. ],
  185. emptyRows: 0,
  186. headRows: 2,
  187. headRowHeight: [25, 25],
  188. defaultRowHeight: 21,
  189. headerFont: '12px 微软雅黑',
  190. font: '12px 微软雅黑',
  191. readOnly: true,
  192. };
  193. // 加载清单数据 - 暂时统一加载,如有需要,切换成动态加载并缓存
  194. postData(window.location.pathname + '/load', {}, async function (result) {
  195. ledger = result.ledger;
  196. curLedgerData = result.curLedgerData;
  197. pos = result.pos;
  198. curPosData = result.curPosData;
  199. materialListData = result.materialListData;
  200. const gclList = result.gclList;
  201. notJoinList = result.materialNotJoinListData;
  202. materialChecklistData = result.materialChecklistData;
  203. // 解析清单汇总数据
  204. gclGatherModel.loadLedgerData(ledger, curLedgerData);
  205. gclGatherModel.loadPosData(pos, curPosData);
  206. gclGatherData = gclGatherModel.gatherGclData();
  207. console.log(gclGatherData);
  208. if (openMaterialChecklist) {
  209. const hadBillsidList = _.uniq(_.map(gclList, 'gcl_id'));
  210. console.log(hadBillsidList);
  211. // 判断是否有修订影响到本次数据,并有几率修改清单设置页的值
  212. const pushData = [];
  213. const updateData = [];
  214. for (const hb of hadBillsidList) {
  215. const gcl = _.find(gclGatherData, function (item) {
  216. return item.leafXmjs && item.leafXmjs.length > 0 && _.findIndex(item.leafXmjs, { gcl_id : hb }) !== -1;
  217. });
  218. if (gcl) {
  219. const mc = _.find(materialChecklistData, { b_code: gcl.b_code, name: gcl.name, unit: gcl.unit, unit_price: gcl.unit_price });
  220. // const newOrder = _.indexOf(gclGatherData, gcl);
  221. // console.log(newOrder);
  222. if (!mc && _.findIndex(pushData, { b_code: gcl.b_code, name: gcl.name, unit: gcl.unit, unit_price: gcl.unit_price }) === -1) {
  223. pushData.push({ b_code: gcl.b_code, name: gcl.name, unit: gcl.unit, unit_price: gcl.unit_price, quantity: (gcl.quantity ? gcl.quantity : null), total_price: (gcl.total_price ? gcl.total_price : null), had_bills: 1 });
  224. }
  225. }
  226. }
  227. const removeData = [];
  228. for (const mc of materialChecklistData) {
  229. const gcl = _.find(gclGatherData, { b_code: mc.b_code, name: mc.name, unit: mc.unit, unit_price: mc.unit_price });
  230. // 判断是否已不存在工料清单,台账修改过后删除之
  231. if (!gcl) {
  232. removeData.push(mc.id);
  233. } else {
  234. // 更新had_bills值
  235. const updateObj = { id: mc.id };
  236. const gcl_ids = gcl.leafXmjs ? _.uniq(_.map(gcl.leafXmjs, 'gcl_id')) : [];
  237. const jiaoji = _.intersection(gcl_ids, hadBillsidList);
  238. if (mc.had_bills === 1) {
  239. if (jiaoji.length === 0) {
  240. updateObj.mid = materialID;
  241. updateObj.had_bills = 0;
  242. // updateData.push({ id: mc.id, mid: materialID, had_bills: 0 });
  243. }
  244. } else if (mc.had_bills === 0) {
  245. if (jiaoji.length !== 0) {
  246. updateObj.had_bills = 1;
  247. }
  248. }
  249. // 更新工程量及台账金额
  250. if (mc.quantity !== (gcl.quantity ? gcl.quantity : null)) {
  251. updateObj.quantity = gcl.quantity ? gcl.quantity : null;
  252. updateObj.total_price = gcl.total_price ? gcl.total_price : null;
  253. }
  254. if(!_.isEqual(updateObj,{ id: mc.id })) updateData.push(updateObj);
  255. }
  256. }
  257. console.log(pushData, removeData, updateData);
  258. if (pushData.length > 0 || removeData.length > 0 || updateData.length > 0) {
  259. // materialChecklistData = await postDataAsync('/tender/'+ tenderID +'/measure/material/'+ stage_order +'/checklist/save', { type: 'resetChecklist', pushData, removeData, updateData })
  260. }
  261. gclGatherData = gclGatherData.filter(item => {
  262. return item.qc_qty || item.contract_qty
  263. });
  264. // 取交集
  265. gclGatherData = _.filter(gclGatherData, function (item) {
  266. return _.find(materialChecklistData, { b_code: item.b_code, name: item.name, unit: item.unit, unit_price: item.unit_price });
  267. });
  268. } else {
  269. gclGatherData = gclGatherData.filter(item => {
  270. return item.qc_qty || item.contract_qty
  271. });
  272. }
  273. calculateJiaCha(gclGatherData);
  274. SpreadJsObj.initSheet(leafXmjSpread.getActiveSheet(), leafXmjSpreadSetting);
  275. // 加载清单数据
  276. SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), SpreadJsObj.DataType.Data, gclGatherData);
  277. loadLeafXmjData(0);
  278. loadMaterialData(0, 0);
  279. const sheet = materialSpread.getActiveSheet();
  280. sheet.suspendPaint();
  281. sheet.setCellType(1, 3, new TipCellType(), spreadNS.SheetArea.colHeader);
  282. sheet.resumePaint();
  283. checkNotJoinMaterialData();
  284. });
  285. // const leafXmjCol = {
  286. // getValue: {
  287. // jiacha: function (data) {
  288. // let sum = 0;
  289. // const sheet = leafXmjSpread.getActiveSheet();
  290. // const select = SpreadJsObj.getSelectObject(sheet);
  291. // const notx = findNotJoinLeafXmj(select);
  292. // if (notx === undefined) {
  293. // for(const ml of materialList) {
  294. // sum = ZhCalc.round(ZhCalc.add(sum, ZhCalc.mul(ZhCalc.mul(data.gather_qty, ml.quantity), getMpSpreadByMBData(ml.mb_id))), 2);
  295. // }
  296. // }
  297. // return sum !== 0 ? sum : null;
  298. // }
  299. // }
  300. // };
  301. // SpreadJsObj.initSpreadSettingEvents(leafXmjSpreadSetting, leafXmjCol);
  302. // 调差清单工料table
  303. const materialSpread = SpreadJsObj.createNewSpread($('#material-spread')[0]);
  304. const materialSpreadSetting = {
  305. cols: [
  306. {title: '清单工料含量|编号', colSpan: '5|1', rowSpan: '1|1', field: 'code', hAlign: 0, width: 80, formatter: '@', readOnly: true},
  307. {title: '|名称', colSpan: '|1', rowSpan: '|1', field: 'name', hAlign: 0, width: 100, formatter: '@', readOnly: true},
  308. {title: '|单位', colSpan: '|1', rowSpan: '|1', field: 'unit', hAlign: 1, width: 60, formatter: '@', readOnly: true},
  309. {title: '|数量 �', colSpan: '|1', rowSpan: '|1', field: 'quantity', hAlign: 2, width: 80, type: 'Number', readOnly: 'readOnly.isEdit'},
  310. {title: '|计算式', colSpan: '1', rowSpan: '|1', field: 'expr', hAlign: 2, width: 120, formatter: '@', readOnly: 'readOnly.isEdit'},
  311. ],
  312. emptyRows: 0,
  313. headRows: 2,
  314. headRowHeight: [25, 25],
  315. defaultRowHeight: 21,
  316. headerFont: '12px 微软雅黑',
  317. font: '12px 微软雅黑',
  318. };
  319. const materialBase = {
  320. isEdit: function (data, type = 'normal') {
  321. // 是否本期添加的工料
  322. // return data.order === stage_order && !openMaterialChecklist;
  323. let flag = true;
  324. if (type === 'del') {
  325. flag = data.order === stage_order;
  326. }
  327. return flag && !openMaterialChecklist;
  328. }
  329. };
  330. const materialCol = {
  331. readOnly: {
  332. isEdit: function (data) {
  333. // const sheet = leafXmjSpread.getActiveSheet();
  334. // const select = SpreadJsObj.getSelectObject(sheet);
  335. // const notx = findNotJoinLeafXmj(select);
  336. // return !(!readOnly && notx === undefined && materialBase.isEdit(data));
  337. return !(!readOnly && materialBase.isEdit(data));
  338. },
  339. },
  340. };
  341. SpreadJsObj.initSpreadSettingEvents(materialSpreadSetting, materialCol);
  342. // 获取项目节数据
  343. let materialList = [];
  344. function loadMaterialData(iGclRow, iLXmjRow) {
  345. const gcl = gclGatherData[iGclRow];
  346. const leafXmjs = gcl && gcl.leafXmjs ? gcl.leafXmjs.filter(item => {
  347. return item.qc_qty || item.contract_qty
  348. }) : null;
  349. console.log(gcl, leafXmjs);
  350. if (leafXmjs) {
  351. const xmj = leafXmjs[iLXmjRow];
  352. console.log(xmj, iLXmjRow);
  353. materialList = [];
  354. for (const m of materialListData) {
  355. if (m.gcl_id === xmj.gcl_id && m.xmj_id === xmj.id && ((xmj.mx_id !==undefined && m.mx_id === xmj.mx_id) || xmj.mx_id === undefined)) {
  356. materialList.push(m);
  357. }
  358. }
  359. console.log(xmj, materialList);
  360. SpreadJsObj.loadSheetData(materialSpread.getActiveSheet(), SpreadJsObj.DataType.Data, materialList);
  361. } else {
  362. SpreadJsObj.loadSheetData(materialSpread.getActiveSheet(), SpreadJsObj.DataType.Data, []);
  363. }
  364. // SpreadJsObj.reLoadSheetData(leafXmjSpread.getActiveSheet());
  365. }
  366. // SpreadJsObj.locateTreeNode(ledgerSpread.getActiveSheet(), )
  367. // loadLeafXmjData(0);
  368. // loadMaterialData(0, 0);
  369. // const sheet = materialSpread.getActiveSheet();
  370. // sheet.suspendPaint();
  371. // sheet.setCellType(1, 3, new TipCellType(), spreadNS.SheetArea.colHeader);
  372. // sheet.resumePaint();
  373. // 不参与调差数据值变灰
  374. function checkNotJoinMaterialData() {
  375. const sheet = ledgerSpread.getActiveSheet();
  376. const select = SpreadJsObj.getSelectObject(sheet);
  377. const index = gclGatherData.indexOf(select);
  378. if (index !== -1) {
  379. const xmj = gclGatherData[index].leafXmjs.filter(item => {
  380. return item.qc_qty || item.contract_qty
  381. });
  382. const leafXmjSheet = leafXmjSpread.getActiveSheet();
  383. for (const [iRow,x] of xmj.entries()) {
  384. const notx = findNotJoinLeafXmj(x);
  385. const color = notx === undefined ? '' : '#d6d8db';
  386. leafXmjSheet.getRange(iRow, -1, 1, -1).backColor(color);
  387. }
  388. }
  389. }
  390. // checkNotJoinMaterialData();
  391. // 对添加工料表格赋值
  392. function changeMaterialTable() {
  393. $('#materialBills tr').removeClass('table-secondary');
  394. $('#materialBills').find('input').removeAttr('disabled');
  395. $('#materialBills').find('input').prop('checked', false);
  396. for (const [index, ml] of materialList.entries()) {
  397. const mbIndex = materialBillsData.findIndex(function (item) {
  398. return item.id === ml.mb_id;
  399. });
  400. if (mbIndex !== -1) {
  401. $('#materialBills tr').eq(mbIndex).addClass('table-secondary');
  402. $('#materialBills').find('input').eq(mbIndex).attr('disabled', true);
  403. $('#materialBills').find('input').eq(mbIndex).prop('checked', true);
  404. }
  405. }
  406. }
  407. // 添加调差工料
  408. $('#add_material_bill').click(function () {
  409. // 获取已选工料
  410. $('#materialBills').find('input:disabled').prop('checked', false);
  411. const selectList = $('#materialBills').find('input:checked');
  412. if (selectList.length === 0) {
  413. toastr.warning('请选择调差工料');
  414. $('#materialBills').find('input:disabled').prop('checked', true);
  415. return false;
  416. }
  417. const mb_id = [];
  418. for (let s = 0; s < selectList.length; s++) {
  419. mb_id.push($('#materialBills').find('input:checked').eq(s).val());
  420. }
  421. // 获取当前项目节或部位明细id
  422. const sheet = ledgerSpread.getActiveSheet();
  423. const select = SpreadJsObj.getSelectObject(sheet);
  424. const index = gclGatherData.indexOf(select);
  425. const leafXmjSheet = leafXmjSpread.getActiveSheet();
  426. const leafXmjSelect = SpreadJsObj.getSelectObject(leafXmjSheet);
  427. const gcl = gclGatherData[index].leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
  428. const leafXmjIndex = gcl.indexOf(leafXmjSelect);
  429. // const xmj = gcl[leafXmjIndex];
  430. // const data = {
  431. // xmj_id: xmj.id,
  432. // gcl_id: xmj.gcl_id,
  433. // mx_id: xmj.mx_id !== undefined ? xmj.mx_id : '',
  434. // mb_id: mb_id,
  435. // gather_qty: xmj.gather_qty,
  436. // };
  437. const datas = [];
  438. for (const xmj of gcl) {
  439. const notx = findNotJoinLeafXmj(xmj);
  440. const data = {
  441. xmj_id: xmj.id,
  442. gcl_id: xmj.gcl_id,
  443. mx_id: xmj.mx_id !== undefined ? xmj.mx_id : '',
  444. gather_qty: xmj.gather_qty,
  445. is_join: notx === undefined ? 1 : 0,
  446. };
  447. datas.push(data);
  448. }
  449. // 上传到数据库
  450. console.log(datas, gcl, mb_id);
  451. postData(window.location.pathname + '/save', {type: 'adds', postData: {xmjs: datas, mbIds: mb_id}}, function (result) {
  452. materialListData = result;
  453. // toastr.success('已成功应用');
  454. calculateJiaCha(gclGatherData);
  455. // const index = gclGatherData.indexOf(ledgerSelect);
  456. loadLeafXmjData(index);
  457. // const xmjSheet = leafXmjSpread.getActiveSheet();
  458. // const xmjSelect = SpreadJsObj.getSelectObject(xmjSheet);
  459. // const xmjIndex = gclGatherData[index].leafXmjs.indexOf(xmjSelect);
  460. loadMaterialData(index, leafXmjIndex);
  461. SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), index);
  462. $('#addgl').modal('hide');
  463. });
  464. // postData(window.location.pathname + '/save', {type: 'add', postData: data}, function (result) {
  465. // // 添加到materialList里
  466. // materialListData = result;
  467. // loadMaterialData(index, leafXmjIndex);
  468. // $('#addgl').modal('hide');
  469. // });
  470. $('#materialBills').find('input:disabled').prop('checked', true);
  471. });
  472. if (!readOnly) {
  473. const leafXmjSpreadObj = {
  474. getSelect : function () {
  475. const sheet = ledgerSpread.getActiveSheet();
  476. const select = SpreadJsObj.getSelectObject(sheet);
  477. const index = gclGatherData.indexOf(select);
  478. const leafXmjSheet = leafXmjSpread.getActiveSheet();
  479. const leafXmjSelect = SpreadJsObj.getSelectObject(leafXmjSheet);
  480. const iRow = gclGatherData[index].leafXmjs.indexOf(leafXmjSelect);
  481. const leafXmjs = gclGatherData[index].leafXmjs.filter(item => {
  482. return item.qc_qty || item.contract_qty
  483. });
  484. const nRow = leafXmjs.indexOf(leafXmjSelect);
  485. return [index, iRow, nRow, leafXmjSheet, leafXmjSelect];
  486. },
  487. checkJoinMaterial: function (type) {
  488. const [iGclRow, iRow, nRow, sheet, select] = leafXmjSpreadObj.getSelect();
  489. const color = type === 'join' ? '' : '#d6d8db';
  490. const data = {
  491. type: type,
  492. select: type === 'join' ? findNotJoinLeafXmj(select) : select,
  493. };
  494. console.log(iGclRow, iRow, nRow, select);
  495. console.log(materialList);
  496. // 添加到
  497. postData(window.location.pathname + '/save', data, function (result) {
  498. if (type === 'join') {
  499. const index = findNotJoinLeafXmj(select, 'index');
  500. notJoinList.splice(index, 1);
  501. } else {
  502. notJoinList.push(result);
  503. }
  504. gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(select);
  505. calculateJiaCha(gclGatherData, iGclRow);
  506. SpreadJsObj.reLoadRowData(sheet, nRow);
  507. sheet.getRange(nRow, -1, 1, -1).backColor(color);
  508. loadMaterialData(iGclRow, 0);
  509. SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
  510. });
  511. },
  512. }
  513. // leafXmj右键功能
  514. $.contextMenu({
  515. selector: '#leaf-xmj-spread',
  516. build: function ($trigger, e) {
  517. const target = SpreadJsObj.safeRightClickSelection($trigger, e, leafXmjSpread);
  518. return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
  519. },
  520. items: {
  521. 'stop': {
  522. name: '不参与调差',
  523. icon: 'fa-remove',
  524. callback: function (key, opt) {
  525. leafXmjSpreadObj.checkJoinMaterial('notjoin');
  526. },
  527. visible: function (key, opt) {
  528. const sheet = leafXmjSpread.getActiveSheet();
  529. const select = SpreadJsObj.getSelectObject(sheet);
  530. const sel = sheet.getSelections()[0];
  531. const notx = findNotJoinLeafXmj(select);
  532. if (!select || sel.rowCount !== 1) {
  533. return false;
  534. }
  535. if (!readOnly && select && notx === undefined) {
  536. return true;
  537. } else {
  538. return false;
  539. }
  540. }
  541. },
  542. 'start': {
  543. name: '参与调差',
  544. icon: 'fa-sign-in',
  545. callback: function (key, opt) {
  546. leafXmjSpreadObj.checkJoinMaterial('join');
  547. },
  548. visible: function (key, opt) {
  549. const sheet = leafXmjSpread.getActiveSheet();
  550. const select = SpreadJsObj.getSelectObject(sheet);
  551. const sel = sheet.getSelections()[0];
  552. const notx = findNotJoinLeafXmj(select);
  553. if (!select || sel.rowCount !== 1) {
  554. return false;
  555. }
  556. if (!readOnly && select && notx === undefined) {
  557. return false;
  558. } else {
  559. return true;
  560. }
  561. },
  562. }
  563. }
  564. });
  565. // material-spread右键功能
  566. const materialSpreadObj = {
  567. del: function () {
  568. const materialSheet = materialSpread.getActiveSheet();
  569. const materialSelect = SpreadJsObj.getSelectObject(materialSheet);
  570. const sheet = ledgerSpread.getActiveSheet();
  571. const select = SpreadJsObj.getSelectObject(sheet);
  572. const index = gclGatherData.indexOf(select);
  573. const leafXmjSheet = leafXmjSpread.getActiveSheet();
  574. const leafXmjSelect = SpreadJsObj.getSelectObject(leafXmjSheet);
  575. const gcl = gclGatherData[index].leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
  576. const leafXmjIndex = gcl.indexOf(leafXmjSelect);
  577. const datas = [];
  578. for (const xmj of gcl) {
  579. const data = {
  580. xmj_id: xmj.id,
  581. gcl_id: xmj.gcl_id,
  582. mx_id: xmj.mx_id !== undefined ? xmj.mx_id : '',
  583. };
  584. datas.push(data);
  585. }
  586. console.log(datas, materialSelect.mb_id);
  587. postData(window.location.pathname + '/save', {type: 'dels', postData: { xmjs: datas, mb_id: materialSelect.mb_id }}, function (result) {
  588. materialListData = result;
  589. calculateJiaCha(gclGatherData);
  590. // const index = gclGatherData.indexOf(ledgerSelect);
  591. loadLeafXmjData(index);
  592. // const xmjSheet = leafXmjSpread.getActiveSheet();
  593. // const xmjSelect = SpreadJsObj.getSelectObject(xmjSheet);
  594. // const xmjIndex = gclGatherData[index].leafXmjs.indexOf(xmjSelect);
  595. loadMaterialData(index, leafXmjIndex);
  596. SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), index);
  597. });
  598. // postData(window.location.pathname + '/save', {type: 'del', id: select.id, mb_id: select.mb_id}, function (result) {
  599. // const index = materialList.indexOf(select);
  600. // materialList.splice(index, 1);
  601. // sheet.deleteRows(index, 1);
  602. // SpreadJsObj.reLoadSheetData(materialSpread.getActiveSheet());
  603. // const sel = sheet.getSelections();
  604. // sheet.setSelection(index > 0 ? index - 1 : 0, sel.length > 0 ? sel[0].col : 0, 1, 1);
  605. // const materialListIndex = materialListData.indexOf(select);
  606. // materialListData.splice(materialListIndex, 1);
  607. // const [iGclRow, iRow, lsheet, lselect] = leafXmjSpreadObj.getSelect();
  608. // gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(lselect);
  609. // calculateJiaCha(gclGatherData, iGclRow);
  610. // SpreadJsObj.reLoadRowData(lsheet, iRow);
  611. // SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
  612. // });
  613. },
  614. deletePress: function (sheet) {
  615. return;
  616. },
  617. editStarting: function (e, info) {
  618. const col = info.sheet.zh_setting.cols[info.col];
  619. const select = SpreadJsObj.getSelectObject(info.sheet);
  620. if (col.field === 'quantity') {
  621. if (select.expr && select.expr !== '') {
  622. info.sheet.getCell(info.row, info.col).text(select.expr);
  623. }
  624. }
  625. },
  626. editEnded: function (e, info) {
  627. if (info.sheet.zh_setting) {
  628. const select = SpreadJsObj.getSelectObject(info.sheet);
  629. const col = info.sheet.zh_setting.cols[info.col];
  630. // 未改变值则不提交
  631. // const validText = info.editingText ? (typeof(info.editingText) === 'String' ? info.editingText.replace('\n', '') : info.editingText) : null;
  632. // const validText = is_numeric(info.editingText) ? parseFloat(info.editingText) : (info.editingText ? trimInvalidChar(info.editingText) : null);
  633. // let orgValue = select[col.field];
  634. const validText = info.editingText ? info.editingText.replace('\n', '') : null;
  635. let orgValue;
  636. if (col.field === 'quantity') {
  637. orgValue = validText && validText !== ''
  638. ? _.toNumber(validText) ? select.quantity : select.expr
  639. : (select.expr && select.expr !== '') ? select.expr : select.quantity;
  640. } else {
  641. orgValue = select[col.field];
  642. }
  643. if (orgValue == validText || ((!orgValue || orgValue === '') && (validText === '' || validText === null))) {
  644. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  645. return;
  646. }
  647. const exprQuantity = {
  648. expr: '',
  649. quantity: 0,
  650. };
  651. const [valid, msg] = materialSpreadObj._checkExpr(validText, exprQuantity);
  652. if (!valid) {
  653. toastr.error(msg);
  654. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  655. return;
  656. }
  657. if (isNaN(exprQuantity.quantity)) {
  658. toastr.error('不能输入其它非数字类型字符');
  659. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  660. return;
  661. }
  662. const num = parseFloat(exprQuantity.quantity);
  663. if (num < 0 || !/^\d+(\.\d{1,6})?$/.test(num)) {
  664. // toastr.error('数量值必须大于0并且小于6位小数的浮点数');
  665. // SpreadJsObj.reLoadRowData(info.sheet, info.row);
  666. // return;
  667. toastr.warning('已保留6位小数');
  668. exprQuantity.quantity = ZhCalc.round(num, 6);
  669. }
  670. // 更新至服务器
  671. const ledgerSheet = ledgerSpread.getActiveSheet();
  672. const ledgerSelect = SpreadJsObj.getSelectObject(ledgerSheet);
  673. const index = gclGatherData.indexOf(ledgerSelect);
  674. const gcl = gclGatherData[index].leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
  675. const xmjSheet = leafXmjSpread.getActiveSheet();
  676. const xmjSelect = SpreadJsObj.getSelectObject(xmjSheet);
  677. const xmjIndex = gcl.indexOf(xmjSelect);
  678. const datas = [];
  679. for (const xmj of gcl) {
  680. const data = {
  681. xmj_id: xmj.id,
  682. gcl_id: xmj.gcl_id,
  683. mx_id: xmj.mx_id !== undefined ? xmj.mx_id : '',
  684. };
  685. datas.push(data);
  686. }
  687. console.log(exprQuantity, datas, select.mb_id);
  688. postData(window.location.pathname + '/save', { type:'updates', updateData: { xmjs: datas, expr: exprQuantity.expr, quantity: exprQuantity.quantity, mb_id: select.mb_id } }, function (result) {
  689. materialListData = result;
  690. calculateJiaCha(gclGatherData);
  691. // const index = gclGatherData.indexOf(ledgerSelect);
  692. loadLeafXmjData(index);
  693. // const xmjSheet = leafXmjSpread.getActiveSheet();
  694. // const xmjSelect = SpreadJsObj.getSelectObject(xmjSheet);
  695. // const xmjIndex = gclGatherData[index].leafXmjs.indexOf(xmjSelect);
  696. loadMaterialData(index, xmjIndex);
  697. SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), index);
  698. materialSpread.getActiveSheet().setSelection(info.row + 1, info.col, 1, 1);
  699. }, function () {
  700. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  701. });
  702. // postData(window.location.pathname + '/save', { type:'update', updateData: { id:select.id, quantity: validText, mb_id: select.mb_id } }, function (result) {
  703. // const materialListIndex = materialListData.indexOf(select);
  704. // const index = materialList.indexOf(select);
  705. // select[col.field] = validText;
  706. // materialListData.splice(materialListIndex, 1, select);
  707. // materialList.indexOf(index, 1, select);
  708. // SpreadJsObj.reLoadRowData(info.sheet, info.row);
  709. // const [iGclRow, iRow, sheet, lselect] = leafXmjSpreadObj.getSelect();
  710. // gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(lselect);
  711. // calculateJiaCha(gclGatherData, iGclRow)
  712. // SpreadJsObj.reLoadRowData(sheet, iRow);
  713. // SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
  714. // }, function () {
  715. // SpreadJsObj.reLoadRowData(info.sheet, info.row);
  716. // });
  717. }
  718. },
  719. clipboardPasted(e, info) {
  720. const hint = {
  721. cellError: {type: 'error', msg: '粘贴内容超出了表格范围'},
  722. numberExpr: {type: 'error', msg: '不能粘贴其它非数字类型字符'},
  723. numberCan: {type: 'warning', msg: '已保留6位小数'},
  724. };
  725. const range = info.cellRange;
  726. const sortData = info.sheet.zh_data || [];
  727. if (range.row + range.rowCount > sortData.length) {
  728. toastMessageUniq(hint.cellError);
  729. SpreadJsObj.reLoadSheetHeader(materialSpread.getActiveSheet());
  730. SpreadJsObj.reLoadSheetData(materialSpread.getActiveSheet());
  731. return;
  732. }
  733. if (sortData.length > 0 && range.col + range.colCount > 5) {
  734. toastMessageUniq(hint.cellError);
  735. SpreadJsObj.reLoadSheetHeader(materialSpread.getActiveSheet());
  736. SpreadJsObj.reLoadSheetData(materialSpread.getActiveSheet());
  737. return;
  738. }
  739. const data = [];
  740. for (let iRow = 0; iRow < range.rowCount; iRow++) {
  741. let bPaste = true;
  742. const curRow = range.row + iRow;
  743. const materialData = { id: sortData[curRow].id, mb_id: sortData[curRow].mb_id };
  744. const hintRow = range.rowCount > 1 ? curRow : '';
  745. let sameCol = 0;
  746. for (let iCol = 0; iCol < range.colCount; iCol++) {
  747. const curCol = range.col + iCol;
  748. const colSetting = info.sheet.zh_setting.cols[curCol];
  749. if (!colSetting) continue;
  750. // let validText = info.sheet.getText(curRow, curCol);
  751. // validText = is_numeric(validText) ? parseFloat(validText) : (validText ? trimInvalidChar(validText) : null);
  752. const validText = info.sheet.getText(curRow, curCol).replace('\n', '');
  753. const orgValue = sortData[curRow][colSetting.field];
  754. if (orgValue == validText || ((!orgValue || orgValue === '') && (validText === ''))) {
  755. sameCol++;
  756. if (range.colCount === sameCol) {
  757. bPaste = false;
  758. }
  759. continue;
  760. }
  761. const exprQuantity = {
  762. expr: '',
  763. quantity: 0,
  764. };
  765. const [valid, msg] = materialSpreadObj._checkExpr(validText, exprQuantity);
  766. if (!valid) {
  767. toastMessageUniq(getPasteHint(msg, hintRow));
  768. bPaste = false;
  769. continue;
  770. }
  771. if (isNaN(exprQuantity.quantity)) {
  772. toastMessageUniq(getPasteHint(hint.numberExpr, hintRow));
  773. bPaste = false;
  774. continue;
  775. }
  776. const num = parseFloat(exprQuantity.quantity);
  777. if (num < 0 || !/^\d+(\.\d{1,6})?$/.test(num)) {
  778. toastMessageUniq(getPasteHint(hint.numberCan, hintRow));
  779. // bPaste = false;
  780. // continue;
  781. exprQuantity.quantity = ZhCalc.round(num, 6);
  782. }
  783. // materialData[colSetting.field] = validText;
  784. materialData.expr = exprQuantity.expr;
  785. materialData.quantity = exprQuantity.quantity;
  786. }
  787. if (bPaste) {
  788. data.push(materialData);
  789. // rowData.push(curRow);
  790. } else {
  791. SpreadJsObj.reLoadRowData(info.sheet, curRow);
  792. }
  793. }
  794. if (data.length === 0) {
  795. SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
  796. return;
  797. }
  798. const ledgerSheet = ledgerSpread.getActiveSheet();
  799. const ledgerSelect = SpreadJsObj.getSelectObject(ledgerSheet);
  800. const index = gclGatherData.indexOf(ledgerSelect);
  801. const gcl = gclGatherData[index].leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
  802. const xmjSheet = leafXmjSpread.getActiveSheet();
  803. const xmjSelect = SpreadJsObj.getSelectObject(xmjSheet);
  804. const xmjIndex = gcl.indexOf(xmjSelect);
  805. const datas = [];
  806. for (const xmj of gcl) {
  807. const data2 = {
  808. xmj_id: xmj.id,
  809. gcl_id: xmj.gcl_id,
  810. mx_id: xmj.mx_id !== undefined ? xmj.mx_id : '',
  811. };
  812. datas.push(data2);
  813. }
  814. console.log(data, datas);
  815. // 更新至服务器
  816. postData(window.location.pathname + '/save', { type:'pastes', updateData: { xmjs: datas, pasteData: data } }, function (result) {
  817. materialListData = result;
  818. calculateJiaCha(gclGatherData);
  819. // const index = gclGatherData.indexOf(ledgerSelect);
  820. loadLeafXmjData(index);
  821. // const xmjSheet = leafXmjSpread.getActiveSheet();
  822. // const xmjSelect = SpreadJsObj.getSelectObject(xmjSheet);
  823. // const xmjIndex = gclGatherData[index].leafXmjs.indexOf(xmjSelect);
  824. loadMaterialData(index, xmjIndex);
  825. SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), index);
  826. materialSpread.getActiveSheet().setSelection(info.cellRange.row, info.cellRange.col, info.cellRange.rowCount, info.cellRange.colCount);
  827. }, function () {
  828. SpreadJsObj.reLoadRowData(info.sheet, info.row);
  829. });
  830. // postData(window.location.pathname + '/save', { type:'paste', updateData: data }, function (result) {
  831. // materialListData = result;
  832. // const [iGclRow, iRow, sheet, lselect] = leafXmjSpreadObj.getSelect();
  833. // gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(lselect);
  834. // calculateJiaCha(gclGatherData, iGclRow);
  835. // SpreadJsObj.reLoadRowData(sheet, iRow);
  836. // SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
  837. // }, function () {
  838. // SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
  839. // });
  840. },
  841. _checkExprValid(expr) {
  842. if (!expr) return [true, null];
  843. const param = [];
  844. let num = '', base = '';
  845. for (let i = 0, iLen = expr.length; i < iLen; i++) {
  846. if (/^[\d\.%]+/.test(expr[i])) {
  847. if (base !== '') {
  848. param.push({type: 'base', value: base});
  849. base = '';
  850. }
  851. num = num + expr[i];
  852. } else if (expr[i] === '(') {
  853. if (num !== '') {
  854. param.push({type: 'num', value: num});
  855. num = '';
  856. }
  857. if (base !== '') {
  858. param.push({type: 'base', value: base});
  859. base = '';
  860. }
  861. param.push({type: 'left', value: '('});
  862. } else if (expr[i] === ')') {
  863. if (num !== '') {
  864. param.push({type: 'num', value: num});
  865. num = '';
  866. }
  867. if (base !== '') {
  868. param.push({type: 'base', value: base});
  869. base = '';
  870. }
  871. param.push({type: 'right', value: ')'});
  872. } else if (/^[\+\-*\/]/.test(expr[i])) {
  873. if (num !== '') {
  874. param.push({type: 'num', value: num});
  875. num = '';
  876. }
  877. if (base !== '') {
  878. param.push({type: 'base', value: base});
  879. base = '';
  880. }
  881. param.push({type: 'calc', value: expr[i]});
  882. } else {
  883. return [false, '输入的表达式含有非法字符: ' + expr[i]];
  884. }
  885. }
  886. if (num !== '') {
  887. param.push({type: 'num', value: num});
  888. num = '';
  889. }
  890. if (base !== '') {
  891. param.push({type: 'base', value: base});
  892. base = '';
  893. }
  894. if (param.length === 0) return true;
  895. if (param.length > 1) {
  896. if (param[0].value === '-') {
  897. param[1].value = '-' + param[1];
  898. }
  899. param.unshift();
  900. }
  901. const iLen = param.length;
  902. let iLeftCount = 0, iRightCount = 0;
  903. for (const [i, p] of param.entries()) {
  904. if (p.type === 'calc') {
  905. if (i === 0 || i === iLen - 1)
  906. return [false, '输入的表达式非法:计算符号' + p.value + '前后应有数字'];
  907. }
  908. if (p.type === 'num') {
  909. num = p.value.replace('%', '');
  910. if (p.value.length - num.length > 1)
  911. return [false, '输入的表达式非法:' + p.value + '不是一个有效的数字'];
  912. num = _.toNumber(num);
  913. if (num === undefined || num === null || _.isNaN(num))
  914. return [false, '输入的表达式非法:' + p.value + '不是一个有效的数字'];
  915. if (i > 0) {
  916. if (param[i - 1].type !== 'calc' && param[i - 1].type !== 'left') {
  917. return [false, '输入的表达式非法:' + p.value + '前应有运算符'];
  918. } else if (param[i - 1].value === '/' && num === 0) {
  919. return [false, '输入的表达式非法:请勿除0'];
  920. }
  921. }
  922. }
  923. if (p.type === 'base') {
  924. if (i > 0 && (param[i - 1].type === 'num' || param[i - 1].type === 'right'))
  925. return [false, '输入的表达式非法:' + p.value + '前应有运算符'];
  926. }
  927. if (p.type === 'left') {
  928. iLeftCount += 1;
  929. if (i !== 0 && param[i-1].type !== 'calc')
  930. return [false, '输入的表达式非法:(前应有运算符'];
  931. }
  932. if (p.type === 'right') {
  933. iRightCount += 1;
  934. if (i !== iLen - 1 && param[i+1].type !== 'calc')
  935. return [false, '输入的表达式非法:)后应有运算符'];
  936. if (iRightCount > iLeftCount)
  937. return [false, '输入的表达式非法:")"前无对应的"("'];
  938. }
  939. }
  940. if (iLeftCount > iRightCount)
  941. return [false, '输入的表达式非法:"("后无对应的")"'];
  942. return [true, ''];
  943. },
  944. _checkExpr: function (text, data) {
  945. if (text) {
  946. const num = _.toNumber(text);
  947. if (num) {
  948. data.quantity = num;
  949. data.expr = '';
  950. } else {
  951. const expr = $.trim(text).replace('\t', '').replace('=', '').toLowerCase();
  952. const [valid, msg] = this._checkExprValid(expr);
  953. if (!valid) return [valid, msg];
  954. data.expr = expr;
  955. data.quantity = ZhCalc.calcExpr.calcExprStrRpn(expr);
  956. // const ce = new CalcEvalMin();
  957. // data.quantity = ce.eval(expr);
  958. // console.log(data.quantity);
  959. }
  960. } else {
  961. data.quantity = 0;
  962. data.expr = '';
  963. }
  964. return [true, ''];
  965. },
  966. };
  967. materialSpread.bind(spreadNS.Events.EditStarting, materialSpreadObj.editStarting);
  968. materialSpread.bind(spreadNS.Events.EditEnded, materialSpreadObj.editEnded);
  969. materialSpread.bind(spreadNS.Events.ClipboardPasted, materialSpreadObj.clipboardPasted);
  970. SpreadJsObj.addDeleteBind(materialSpread, materialSpreadObj.deletePress);
  971. if (!openMaterialChecklist) {
  972. $.contextMenu({
  973. selector: '#material-spread',
  974. build: function ($trigger, e) {
  975. const target = SpreadJsObj.safeRightClickSelection($trigger, e, materialSpread);
  976. return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
  977. },
  978. items: {
  979. 'create': {
  980. name: '添加工料',
  981. icon: 'fa-sign-in',
  982. callback: function (key, opt) {
  983. // 获取已选清单
  984. changeMaterialTable();
  985. $('#addgl').modal('show');
  986. },
  987. disabled: function (key, opt) {
  988. const sheet = leafXmjSpread.getActiveSheet();
  989. const select = SpreadJsObj.getSelectObject(sheet);
  990. // const notx = findNotJoinLeafXmj(select);
  991. if (!select) {
  992. return true;
  993. }
  994. // if (!readOnly && notx === undefined) {
  995. // return false;
  996. // } else {
  997. // return true;
  998. // }
  999. return readOnly;
  1000. }
  1001. },
  1002. 'delete': {
  1003. name: '删除工料',
  1004. icon: 'fa-remove',
  1005. callback: function (key, opt) {
  1006. materialSpreadObj.del(materialSpread.getActiveSheet());
  1007. },
  1008. disabled: function (key, opt) {
  1009. const sheet = materialSpread.getActiveSheet();
  1010. const select = SpreadJsObj.getSelectObject(sheet);
  1011. if (!select) {
  1012. return true;
  1013. }
  1014. if (!readOnly && select && materialBase.isEdit(select, 'del')) {
  1015. return false;
  1016. } else {
  1017. return true;
  1018. }
  1019. }
  1020. },
  1021. }
  1022. });
  1023. }
  1024. }
  1025. // 应用调差工料至其他清单明细
  1026. $('#user_all_material').click(function () {
  1027. const ledgerSheet = ledgerSpread.getActiveSheet();
  1028. const ledgerSelect = SpreadJsObj.getSelectObject(ledgerSheet);
  1029. if (ledgerSelect.leafXmjs.length < 2) {
  1030. toastr.warning('没有需要应用调差工料的其它清单明细');
  1031. return false;
  1032. }
  1033. const xmjSheet = leafXmjSpread.getActiveSheet();
  1034. const xmjSelect = SpreadJsObj.getSelectObject(xmjSheet);
  1035. console.log(ledgerSelect.leafXmjs);
  1036. // 判断需要应用调差工料的清单明细
  1037. const needAddList = [];
  1038. for (const xmj of ledgerSelect.leafXmjs) {
  1039. const notx = findNotJoinLeafXmj(xmj);
  1040. if (notx === undefined && xmjSelect !== xmj && xmj.gather_qty && xmj.jiacha === null && xmjSelect.jiacha !== null) {
  1041. needAddList.push(xmj);
  1042. }
  1043. }
  1044. // if (needAddList.length === 0) {
  1045. // toastr.warning('没有需要应用调差工料的其它清单明细');
  1046. // return false;
  1047. // }
  1048. console.log(needAddList, materialList);
  1049. // 更新至服务器
  1050. postData(window.location.pathname + '/save', { type:'useOther', postData: { addXmj: needAddList, materialBills: materialList } }, function (result) {
  1051. materialListData = result;
  1052. toastr.success('已成功应用');
  1053. calculateJiaCha(gclGatherData);
  1054. const index = gclGatherData.indexOf(ledgerSelect);
  1055. loadLeafXmjData(index);
  1056. const xmjSheet = leafXmjSpread.getActiveSheet();
  1057. const xmjSelect = SpreadJsObj.getSelectObject(xmjSheet);
  1058. const xmjIndex = gclGatherData[index].leafXmjs.indexOf(xmjSelect);
  1059. loadMaterialData(index, xmjIndex);
  1060. SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), index);
  1061. });
  1062. });
  1063. // 切换清单行,读取所属项目节数据
  1064. ledgerSpread.getActiveSheet().bind(spreadNS.Events.SelectionChanged, function (e, info) {
  1065. if (info.oldSelections !== undefined) {
  1066. const iOldRow = info.oldSelections[0].row, iNewRow = info.newSelections[0].row;
  1067. if (iNewRow !== iOldRow) {
  1068. loadLeafXmjData(iNewRow);
  1069. SpreadJsObj.resetTopAndSelect(leafXmjSpread.getActiveSheet());
  1070. loadMaterialData(iNewRow, 0);
  1071. checkNotJoinMaterialData();
  1072. }
  1073. }
  1074. });
  1075. // 切换项目节数据清单明细行,读取已调用的清单工料数据
  1076. leafXmjSpread.getActiveSheet().bind(spreadNS.Events.SelectionChanged, function (e, info) {
  1077. if (info.oldSelections !== undefined) {
  1078. const iOldRow = info.oldSelections[0].row, iNewRow = info.newSelections[0].row;
  1079. if (iNewRow !== iOldRow) {
  1080. const sheet = ledgerSpread.getActiveSheet();
  1081. const select = SpreadJsObj.getSelectObject(sheet);
  1082. const index = gclGatherData.indexOf(select);
  1083. loadMaterialData(index, iNewRow);
  1084. SpreadJsObj.resetTopAndSelect(materialSpread.getActiveSheet());
  1085. }
  1086. }
  1087. });
  1088. // 显示有调差工料清单
  1089. $('#show_material_gcl').click(function () {
  1090. if ($(this).is(':checked')) {
  1091. const hadMaterialGclGatherData = [];
  1092. const hadGclIdList = [];
  1093. for (const ml of materialListData) {
  1094. if (hadGclIdList.indexOf(ml.gcl_id) === -1) {
  1095. hadGclIdList.push(ml.gcl_id);
  1096. }
  1097. }
  1098. for (const gcl of gclGatherData) {
  1099. for (const index in gcl.leafXmjs) {
  1100. const gcl_id = gcl.leafXmjs[index].gcl_id;
  1101. if (hadGclIdList.indexOf(gcl_id) !== -1) {
  1102. hadMaterialGclGatherData.push(gcl);
  1103. break;
  1104. }
  1105. }
  1106. }
  1107. gclGatherData = hadMaterialGclGatherData;
  1108. } else {
  1109. gclGatherModel.loadLedgerData(ledger, curLedgerData);
  1110. gclGatherModel.loadPosData(pos, curPosData);
  1111. gclGatherData = gclGatherModel.gatherGclData().filter(item => {
  1112. return item.qc_qty || item.contract_qty
  1113. });
  1114. if (openMaterialChecklist) {
  1115. // 取交集
  1116. gclGatherData = _.filter(gclGatherData, function (item) {
  1117. return _.find(materialChecklistData, { b_code: item.b_code, name: item.name, unit: item.unit, unit_price: item.unit_price });
  1118. });
  1119. }
  1120. }
  1121. calculateJiaCha(gclGatherData);
  1122. SpreadJsObj.loadSheetData(ledgerSpread.getActiveSheet(), SpreadJsObj.DataType.Data, gclGatherData);
  1123. loadLeafXmjData(0);
  1124. loadMaterialData(0, 0);
  1125. SpreadJsObj.resetTopAndSelect(ledgerSpread.getActiveSheet());
  1126. SpreadJsObj.resetTopAndSelect(leafXmjSpread.getActiveSheet());
  1127. SpreadJsObj.resetTopAndSelect(materialSpread.getActiveSheet());
  1128. checkNotJoinMaterialData();
  1129. });
  1130. $.subMenu({
  1131. menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
  1132. toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
  1133. key: 'menu.1.0.0',
  1134. miniHint: '#sub-mini-hint', hintKey: 'menu.hint.1.0.1',
  1135. callback: function (info) {
  1136. if (info.mini) {
  1137. $('.panel-title').addClass('fluid');
  1138. $('#sub-menu').removeClass('panel-sidebar');
  1139. } else {
  1140. $('.panel-title').removeClass('fluid');
  1141. $('#sub-menu').addClass('panel-sidebar');
  1142. }
  1143. autoFlashHeight();
  1144. ledgerSpread.refresh();
  1145. leafXmjSpread.refresh();
  1146. materialSpread.refresh();
  1147. }
  1148. });
  1149. $.divResizer({
  1150. select: '#right-spr',
  1151. callback: function () {
  1152. ledgerSpread.refresh();
  1153. // leafXmjSpread.refresh();
  1154. materialSpread.refresh();
  1155. const width = (($('#right-view').width()/$('#right-view').parent('div').width())*100).toFixed();
  1156. setLocalCache('material_list_' + materialID, width);
  1157. }
  1158. });
  1159. $.divResizer({
  1160. select: '#main-resize',
  1161. callback: function () {
  1162. materialSpread.refresh();
  1163. ledgerSpread.refresh();
  1164. let bcontent = $(".bcontent-wrap") ? $(".bcontent-wrap").height() : 0;
  1165. $(".sp-wrap").height(bcontent-30);
  1166. leafXmjSpread.refresh();
  1167. const height = $('.bcontent-wrap').height();
  1168. setLocalCache('material_list2_' + materialID, height);
  1169. }
  1170. });
  1171. // 展开收起月信息价并浏览器记住本期展开收起
  1172. $('a', '.right-nav').bind('click', function () {
  1173. //const main = $('#main-view'), tool = $('#tools-view');
  1174. const tab = $(this), tabPanel = $(tab.attr('content'));
  1175. if (!tab.hasClass('active')) {
  1176. $('a', '.side-menu').removeClass('active');
  1177. $('.tab-content .tab-select-show').removeClass('active');
  1178. tab.addClass('active');
  1179. tabPanel.addClass('active');
  1180. showSideTools(tab.hasClass('active'));
  1181. if (tab.attr('content') === '#material-tab') {
  1182. const width = (($('#right-view').width()/$('#right-view').parent('div').width())*100).toFixed();
  1183. setLocalCache('material_list_' + materialID, width);
  1184. }
  1185. } else {
  1186. removeLocalCache('material_list_' + materialID);
  1187. tab.removeClass('active');
  1188. tabPanel.removeClass('active');
  1189. showSideTools(tab.hasClass('active'));
  1190. }
  1191. ledgerSpread.refresh();
  1192. // leafXmjSpread.refresh();
  1193. materialSpread.refresh();
  1194. });
  1195. // 根据浏览器记录展开收起
  1196. if (getLocalCache('material_list_' + materialID)) {
  1197. const tab = $('.right-nav a[content="#material-tab"]'), tabPanel = $(tab.attr('content'));
  1198. $('a', '.side-menu').removeClass('active');
  1199. $('.tab-content .tab-select-show').removeClass('active');
  1200. tab.addClass('active');
  1201. tabPanel.addClass('active');
  1202. $('#right-view').width(getLocalCache('material_list_' + materialID) + '%');
  1203. showSideTools(tab.hasClass('active'));
  1204. ledgerSpread.refresh();
  1205. // leafXmjSpread.refresh();
  1206. materialSpread.refresh();
  1207. }
  1208. if (getLocalCache('material_list2_' + materialID)) {
  1209. $('.bcontent-wrap').height(getLocalCache('material_list2_' + materialID));
  1210. const cHeader = getObjHeight($(".c-header"));
  1211. const bcontent = $(".bcontent-wrap") ? $(".bcontent-wrap").height() : 0;
  1212. $(".sp-wrap").height(bcontent-30);
  1213. $('.sjs-height-1').height($(window).height()-cHeader-bcontent-90+53);
  1214. materialSpread.refresh();
  1215. ledgerSpread.refresh();
  1216. leafXmjSpread.refresh();
  1217. }
  1218. function getObjHeight(select) {
  1219. return select.length > 0 ? select.height() : 0;
  1220. }
  1221. });