index.vue 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376
  1. <script>
  2. import {
  3. editColumns,
  4. editTabColumns,
  5. forbidden,
  6. SelectColumns,
  7. } from "./initColumn";
  8. import orderApi from "@/api/business/purchase/purchase-order";
  9. import { initDicts, initRules, initParams } from "@/utils/init/index.js";
  10. import { tax, currency } from "@/components/popover-select-v2/fetch";
  11. import VirtualScroll from "el-table-virtual-scroll";
  12. import { VirtualColumn } from "el-table-virtual-scroll";
  13. export default {
  14. name: "EditPurchaseOrderDrawer",
  15. dicts: initDicts(SelectColumns),
  16. components: {
  17. "virtual-scroll": VirtualScroll,
  18. VirtualColumn,
  19. FileUploadCenter: () => import("../components/FileUploadCenter/index.vue"),
  20. BatchImport: () => import("@/components/BatchImport/index.vue"),
  21. ButtonHide: () => import("../components/hide/index.vue"),
  22. CgxjButton: () => import("../cai-gou-xun-jia/index.vue"),
  23. },
  24. data() {
  25. return {
  26. size: "mini",
  27. visible: false,
  28. loading: false,
  29. tabLoading: false,
  30. columns: editColumns,
  31. rules: initRules(editColumns),
  32. params: {
  33. ...initParams(editColumns),
  34. puOrderItemList: [],
  35. // puOrderExecuteList: [],
  36. },
  37. tabColumns: editTabColumns,
  38. tabName: "puOrderItemList",
  39. count: 1,
  40. tableData: [], //虚拟滚动加载显示的数据
  41. };
  42. },
  43. computed: {
  44. role: {
  45. get() {
  46. let { roles } = this.$store.state.user;
  47. return (
  48. roles.find((item) => item === "syfz-purchaseorder") ||
  49. "procurementManager"
  50. );
  51. },
  52. set() {},
  53. },
  54. tabHeight: {
  55. get() {
  56. let length = this.params["puOrderItemList"].filter(
  57. (item) => item.delFlag === "0"
  58. ).length;
  59. return `${length ? (length > 8 ? 500 : length * 36 + 120) : 120}px`;
  60. },
  61. set() {},
  62. },
  63. innerColumns: {
  64. get() {
  65. let { tabName, tabColumns } = this;
  66. let obj = tabColumns.find(({ key }) => key === tabName).tableColumns;
  67. return obj;
  68. },
  69. set(value) {
  70. let { tabName, tabColumns } = this;
  71. this.tabColumns = tabColumns.map((item) => {
  72. if (item.key === tabName) {
  73. item.tableColumns = value;
  74. }
  75. return { ...item };
  76. });
  77. this.$nextTick(() => {
  78. this.$refs.puOrderItemList &&
  79. this.$refs.puOrderItemList[0].doLayout();
  80. });
  81. },
  82. },
  83. // 手动询价
  84. isManualInquiry: {
  85. get() {
  86. let { handleIsRevise, role, params } = this;
  87. if (
  88. !handleIsRevise() &&
  89. role === "procurementManager" &&
  90. params.source != "3"
  91. ) {
  92. return true;
  93. }
  94. return false;
  95. },
  96. set() {},
  97. },
  98. },
  99. watch: {
  100. "params.contractType": function (newProp) {
  101. this.tabColumns = editTabColumns.filter((element) =>
  102. newProp === "1" ? element.key !== "puOrderItemList" : element
  103. );
  104. this.tabName = this.tabColumns[0].key;
  105. },
  106. tabName: function (newProp) {
  107. const { id } = this.params;
  108. // this.fetchTable(id, newProp);
  109. },
  110. // "params.puOrderItemList": {
  111. // handler(nVal, oVal) {
  112. // this.params.source == 3 &&
  113. // this.handleSynchronousMaterial(
  114. // "puOrderItemList",
  115. // "puOrderExecuteList"
  116. // );
  117. // },
  118. // deep: true,
  119. // immediate: true,
  120. // },
  121. // "params.puOrderExecuteList": {
  122. // handler(nVal, oVal) {
  123. // this.params.source == 3 &&
  124. // this.handleSynchronousMaterial(
  125. // "puOrderExecuteList",
  126. // "puOrderItemList"
  127. // );
  128. // },
  129. // deep: true,
  130. // immediate: true,
  131. // },
  132. "params.billType": {
  133. handler(nVal, oVal) {
  134. let billList = ["21-Cxx-02", "21-Cxx-04", "21-Cxx-10", "21-Cxx-14"];
  135. if (billList.find((item) => item === nVal)) {
  136. this.rules.warehouseName = [
  137. {
  138. required: true,
  139. message: "WMS入库仓库不能为空",
  140. trigger: "change",
  141. },
  142. ];
  143. } else {
  144. this.rules.warehouseName = null;
  145. }
  146. this.count++;
  147. },
  148. },
  149. "params.isBack": {
  150. handler(nVal, oVal) {
  151. if (nVal === "Y") {
  152. this.rules.retReasonName = [
  153. { required: true, message: "退换原因不能为空", trigger: "change" },
  154. ];
  155. this.rules.processTypeName = [
  156. { required: true, message: "处理方式不能为空", trigger: "change" },
  157. ];
  158. } else {
  159. this.rules.retReasonName = null;
  160. this.rules.processTypeName = null;
  161. }
  162. this.count++;
  163. },
  164. },
  165. },
  166. methods: {
  167. setVisible(prop) {
  168. this.visible = prop;
  169. if (!this.visible) {
  170. this.$refs["orderEditForm"].clearValidate();
  171. }
  172. },
  173. // 同步子表物料
  174. handleSynchronousMaterial(tableOne, tableTwo) {
  175. let _this = this;
  176. // this.params[tableOne]-- -> this.params[tableTwo]
  177. this.params[tableOne] &&
  178. this.params[tableOne].length &&
  179. this.params[tableOne].forEach((item, index) => {
  180. for (const key in item) {
  181. if (
  182. _this.params[tableTwo][index] &&
  183. key in _this.params[tableTwo][index]
  184. ) {
  185. _this.params[tableTwo][index].material = item.material;
  186. key !== "id" && (_this.params[tableTwo][index][key] = item[key]);
  187. }
  188. }
  189. });
  190. },
  191. // 判断属性是否禁用
  192. async handleIsForbidden(status, source) {
  193. let { updateColumns, updateTabColumns } = await forbidden(
  194. status != "2",
  195. source
  196. );
  197. this.columns = updateColumns;
  198. this.tabColumns = updateTabColumns;
  199. try {
  200. const { code, rows } = await orderApi.REFER(
  201. {
  202. type: "WAREHOUSE_PARAM",
  203. // search: this.params.warehouseName,
  204. search: "",
  205. id: this.params.warehouse,
  206. isPage: true,
  207. },
  208. { pageNum: 1, pageSize: 10 }
  209. );
  210. if (code == 200) {
  211. this.judgeGoodsAllocation(rows[0].csFlag);
  212. }
  213. } catch (error) {}
  214. this.count++;
  215. },
  216. // 查询详细
  217. async fetchItem(prop) {
  218. try {
  219. this.loading = true;
  220. const { code, msg, data } = await orderApi.details(prop);
  221. if (code === 200) {
  222. this.params = { ...this.params, ...data };
  223. this.handleIsForbidden(this.params.status, this.params.source);
  224. }
  225. } catch (err) {
  226. //
  227. } finally {
  228. this.loading = false;
  229. }
  230. },
  231. // 新增行
  232. addTableRow(prop) {
  233. for (const key in this.params) {
  234. // if (key === "puOrderItemList" || key === "puOrderExecuteList") {
  235. if (key === "puOrderItemList") {
  236. const arr = this.tabColumns.find(
  237. (element) => element["key"] === key
  238. ).tableColumns;
  239. let rowData = initParams(arr, "key", "value");
  240. "rowno" in rowData &&
  241. (rowData["rowno"] = this.params[key].length
  242. ? this.params[key][this.params[key].length - 1]["rowno"] + 1
  243. : this.params[key].length + 1);
  244. // 物料
  245. if ("rowNo" in rowData) {
  246. rowData["rowNo"] = this.params[key].length
  247. ? this.params[key][this.params[key].length - 1]["rowNo"] + 1
  248. : this.params[key].length + 1;
  249. // 扣税类别
  250. rowData["taxDeductClassify"] = "1";
  251. // 折本汇率
  252. rowData["exchangeRate"] = "1";
  253. // 价格类型
  254. rowData["priceType"] = "order";
  255. // 币种
  256. rowData["currency"] = "1002Z0100000000001K1";
  257. rowData["currencyName"] = "人民币";
  258. }
  259. // 是否完成询价,新增明细行需默认明细为false
  260. // rowData['whetherCompleteInquiry'] = false;
  261. rowData["delFlag"] = "0";
  262. rowData["insertId"] = new Date().getTime();
  263. this.params[key].push(rowData);
  264. }
  265. }
  266. // const arr = this.tabColumns.find(
  267. // (element) => element.key === this.tabName
  268. // ).tableColumns;
  269. // prop.push(initParams(arr, "key", "value"));
  270. },
  271. // 删除行
  272. async delTableRow(prop, row, name) {
  273. let delNo = name === "puOrderItemList" ? "rowNo" : "rowno";
  274. if (prop.length === 1) {
  275. this.$alert("订单行不允许为空", "提示", {
  276. confirmButtonText: "确定",
  277. callback: (action) => {},
  278. });
  279. return;
  280. }
  281. // 编辑 非手工 数量为0 不允许删除
  282. const { source } = this.params;
  283. if (!this.handleIsRevise() && source != "3" && row.qty == 0) {
  284. this.$notify.warning("数量为0,不可删除当前行");
  285. return;
  286. }
  287. for (const key in this.params) {
  288. // if (key === "puOrderItemList" || key === "puOrderExecuteList") {
  289. if (key === "puOrderItemList") {
  290. this.params[key].forEach((item, index) => {
  291. let flag = key === "puOrderItemList" ? "rowNo" : "rowno";
  292. if (item[flag] && item[flag] === row[delNo]) {
  293. item.id
  294. ? (item["delFlag"] = "2")
  295. : this.params[key].splice(index, 1);
  296. }
  297. });
  298. // this.params[key][index].id ?
  299. // (this.params[key][index]['delFlag'] = '2') :
  300. // this.params[key].splice(index, 1);
  301. }
  302. }
  303. await this.handleGetPrice();
  304. },
  305. // 取消
  306. handleCancel() {
  307. this.params = {
  308. ...initParams(this.columns),
  309. puOrderItemList: [],
  310. // puOrderExecuteList: [],
  311. };
  312. this.setVisible(false);
  313. },
  314. // 判断保存条件
  315. judgeSaveCondition(cb) {
  316. const _this = this;
  317. this.$refs["orderEditForm"].validate(async (valid) => {
  318. if (valid) {
  319. // 执行结果在审批之后出现
  320. let validList = _this.params["puOrderItemList"].filter(
  321. (item) => item.delFlag === "0"
  322. );
  323. if (!validList.length) {
  324. _this.$notify.error({
  325. title: "错误",
  326. message: "请填写订单行!",
  327. });
  328. return false;
  329. }
  330. // let isPrice = _this.params.puOrderItemList.filter(item => !item.whetherCompleteInquiry);
  331. // if(isPrice.length && this.role === 'procurementManager'){
  332. // _this.$notify.error({
  333. // title: '错误',
  334. // message: '询价失败!'
  335. // });
  336. // return false
  337. // }
  338. cb();
  339. } else {
  340. _this.$notify.error({
  341. title: "错误",
  342. message: "存在必填项未填写",
  343. });
  344. console.log("error submit!!");
  345. return false;
  346. }
  347. });
  348. },
  349. // 保存
  350. handleSava() {
  351. console.log(this.params, "this.params---------");
  352. this.judgeSaveCondition(async () => {
  353. try {
  354. this.loading = true;
  355. const { code, msg } = await (this.handleIsRevise()
  356. ? orderApi.revision(this.params)
  357. : orderApi.edit(this.params));
  358. if (code === 200) {
  359. this.handleCancel();
  360. }
  361. } catch (err) {
  362. //
  363. } finally {
  364. this.loading = false;
  365. }
  366. });
  367. },
  368. beforeOpen() {},
  369. judgeGoodsAllocation(porp) {
  370. if (porp === "Y") {
  371. this.rules.goodsAllocationName = [
  372. { required: true, message: "货位不能为空", trigger: "change" },
  373. ];
  374. } else {
  375. this.rules.goodsAllocationName = null;
  376. }
  377. this.count++;
  378. },
  379. // 主表参照改变之后
  380. async handleReferChange(val, type, source) {
  381. // 供应商选择
  382. if (type === "SUPPLIER_PARAM") {
  383. let page = { pageNum: 1, pageSize: 10 };
  384. let relevanceRefer = [
  385. {
  386. // 供应商联系人
  387. key: "supplierContacts",
  388. params: {
  389. type: "SUPPLIERCONTACTS_PARAM",
  390. supplierId: val.id,
  391. },
  392. },
  393. {
  394. // 供应商业务员
  395. key: "supplierPersonal",
  396. params: {
  397. type: "PSNLICENSE_PARAM",
  398. supplierId: val.id,
  399. pkOrg: source.puOrg,
  400. },
  401. },
  402. ];
  403. try {
  404. let promiseArr = relevanceRefer.map((refer) => {
  405. return new Promise((resolve, reject) => {
  406. orderApi
  407. .REFER(
  408. {
  409. ...refer.params,
  410. search: "",
  411. isPage: true,
  412. },
  413. page
  414. )
  415. .then((res) => {
  416. let { code, rows } = res;
  417. if (code === 200) {
  418. source[refer.key] = rows[0] ? rows[0].id : "";
  419. source[`${refer.key}Name`] = rows[0] ? rows[0].name : "";
  420. resolve();
  421. }
  422. });
  423. });
  424. });
  425. Promise.all(promiseArr).then(async () => {
  426. // 需要手动询价
  427. if (this.isManualInquiry) {
  428. // 清空含税单价
  429. this.params["puOrderItemList"] = this.params[
  430. "puOrderItemList"
  431. ].map((item) => ({
  432. ...item,
  433. taxPrice: 0,
  434. money: 0,
  435. }));
  436. return;
  437. }
  438. // 明细不为空的情况下进行询价
  439. let detailList = this.params["puOrderItemList"].filter(
  440. (item) => item.material && item.material != ""
  441. );
  442. if (detailList.length) {
  443. await this.handleGetPrice();
  444. }
  445. });
  446. } catch (error) {}
  447. }
  448. // 组织
  449. if (type === "ORG_PARAM") {
  450. for (const key in this.params) {
  451. // if (key === "puOrderItemList" || key === "puOrderExecuteList") {
  452. if (key === "puOrderItemList") {
  453. this.params[key] = [];
  454. } else if (key === "sysFileRecordList") {
  455. this.params[key] = [];
  456. } else if (
  457. key != "puOrg" &&
  458. key != "puOrgName" &&
  459. // key != "buyer" &&
  460. // key != "buyerName" &&
  461. // key != "puDept" &&
  462. // key != "puDeptName" &&
  463. key != "status" &&
  464. key != "billDate" &&
  465. key != "createTime" &&
  466. key != "source"
  467. ) {
  468. this.params[key] = "";
  469. } else {
  470. }
  471. }
  472. }
  473. // WMS仓库
  474. if (type === "WAREHOUSE_PARAM") {
  475. // this.judgeGoodsAllocation(val.csFlag);
  476. // source.goodsAllocation = "";
  477. // source.goodsAllocationName = "";
  478. this.params.puOrderItemList = this.params.puOrderItemList.map(
  479. (item) => ({
  480. ...item,
  481. goodsAllocation: "",
  482. goodsAllocationName: "",
  483. })
  484. );
  485. // this.count++
  486. }
  487. },
  488. // 子表参照改变之后
  489. async handleTabReferChange(val, type, source) {
  490. // 物料触发税率
  491. if (type == "MATERIAL_PARAM") {
  492. let { rateCode } = source;
  493. try {
  494. // try
  495. this.loading = true;
  496. const { ntaxrate } = await tax(rateCode);
  497. source.tax = ntaxrate === "0E-8" ? 0 : ntaxrate;
  498. } catch (err) {
  499. // catch
  500. console.error(err);
  501. } finally {
  502. // finally
  503. this.loading = false;
  504. }
  505. if (source.qty && source.qty != "") {
  506. source["qty"] = 0;
  507. // source['whetherCompleteInquiry'] = false;
  508. source["taxPrice"] = 0;
  509. source["money"] = 0;
  510. source["taxDeductMoneya"] = 0;
  511. source["price"] = 0;
  512. source["notaxMoney"] = 0;
  513. source["tax"] = 0;
  514. this.params["qty"] = 0;
  515. this.params["originalQty"] = 0;
  516. this.params["money"] = 0;
  517. this.params["originalMoney"] = 0;
  518. this.params["notaxMoney"] = 0;
  519. source.isDrug = val.materialMedcine.isDrug == "0" ? "Y" : "N";
  520. // await this.handleGetPrice();
  521. }
  522. }
  523. },
  524. // Select改变之后
  525. handleSelectChange(val, typeName) {
  526. if (val === "billType") {
  527. this.params["billTypeName"] = this.dict.type[typeName].find(
  528. (item) => item.value == this.params[val]
  529. ).label;
  530. this.params.warehouse = "";
  531. this.params.warehouseName = "";
  532. this.params.goodsAllocation = "";
  533. this.params.goodsAllocationName = "";
  534. this.rules.goodsAllocationName = null;
  535. this.params["puOrderItemList"] = this.params["puOrderItemList"].map(
  536. (item) => ({
  537. ...item,
  538. goodsAllocation: "",
  539. goodsAllocationName: "",
  540. })
  541. );
  542. }
  543. },
  544. // 子表下拉框改变
  545. handleTabSelectChange(type, row) {
  546. if (type == "priceType") {
  547. // 需要手动询价
  548. if (this.isManualInquiry) {
  549. // 清空含税单价
  550. row["taxPrice"] = 0;
  551. row["money"] = 0;
  552. this.params.money = this.params["puOrderItemList"].reduce(
  553. (total, item) => {
  554. return (total += item.money);
  555. },
  556. 0
  557. );
  558. return;
  559. }
  560. if (row.material && row.qty != "") {
  561. // row['whetherCompleteInquiry'] = false;
  562. this.handleGetPrice();
  563. }
  564. }
  565. },
  566. // 子表inputNumber
  567. handleInputChange(row, type) {
  568. if (this.isManualInquiry) {
  569. if (type == "qty" || type === "taxPrice") {
  570. // 不进行询价
  571. row.money = Number(row.taxPrice) * Number(row.qty);
  572. // 主表价税合计
  573. this.params.money = this.params["puOrderItemList"].reduce(
  574. (total, item) => {
  575. return (total += item.money);
  576. },
  577. 0
  578. );
  579. this.params.qty = this.params["puOrderItemList"].reduce(
  580. (total, item) => {
  581. return (total += item.qty);
  582. },
  583. 0
  584. );
  585. return;
  586. }
  587. }
  588. // 物料数量变化----询价
  589. if (
  590. (type == "qty" || type == "taxPrice" || type == "taxDeductMoneya") &&
  591. row.material
  592. ) {
  593. if (this.params.status === "2") {
  594. // 修订
  595. this.handleCalculateOrderAmount();
  596. } else {
  597. // row['whetherCompleteInquiry'] = false;
  598. this.handleGetPrice();
  599. }
  600. this.$refs.puOrderItemList[0].updateFooter();
  601. // this.$refs.puOrderExecuteList[0].updateFooter();
  602. }
  603. },
  604. // 子表多选框改变
  605. handleTabCheckbox(type, row) {
  606. if (type == "isGift" && this.isManualInquiry) {
  607. if (row.isGift === "Y") {
  608. row.money = 0;
  609. } else {
  610. row.money = Number(row.taxPrice) * Number(row.qty);
  611. }
  612. // 不进行询价
  613. // 主表价税合计
  614. this.params.money = this.params["puOrderItemList"].reduce(
  615. (total, item) => {
  616. return (total += item.money);
  617. },
  618. 0
  619. );
  620. return;
  621. }
  622. // 勾选赠品,价税合计更新为0,含税单价、无税单价更新为0
  623. if (type === "isGift" && row.material && row.qty && row.qty != "") {
  624. // row['whetherCompleteInquiry'] = false;
  625. this.handleGetPrice();
  626. }
  627. },
  628. // 询价 getPrice
  629. async handleGetPrice() {
  630. // if(this.role === 'procurementManager'){
  631. try {
  632. // action:insert(新增)、revise(修订)、update(编辑)
  633. let { code, data } = await orderApi.getPrice({
  634. ...this.params,
  635. action: this.handleIsRevise() ? "revise" : "update",
  636. });
  637. if (code == 200) {
  638. this.params = data;
  639. }
  640. } catch (error) {
  641. } finally {
  642. }
  643. // }
  644. },
  645. // 修订——计算金额
  646. async handleCalculateOrderAmount() {
  647. try {
  648. let { code, data } = await orderApi.calculateOrderAmount({
  649. ...this.params,
  650. action: this.handleIsRevise() ? "revise" : "update",
  651. });
  652. code == 200 && (this.params = data);
  653. } catch (error) {
  654. } finally {
  655. }
  656. },
  657. // 判断修订还是编辑
  658. handleIsRevise() {
  659. return this.params.status == "2";
  660. },
  661. // /handleIsRevise() ? scope.row[cColumn.key] : Infinity
  662. getInputNumberMax(key, row) {
  663. if (key === "qty") {
  664. return this.handleIsRevise()
  665. ? Math.sign(row["originalQty"]) == -1
  666. ? 0
  667. : row["originalQty"]
  668. : this.params.source == "3"
  669. ? Infinity
  670. : row["originalQty"];
  671. }
  672. return Infinity;
  673. },
  674. async handelImport(fileList) {
  675. try {
  676. let formData = new FormData();
  677. formData.append("file", fileList[0].raw);
  678. let tabList = {
  679. puOrderItemList: [...this.params.puOrderItemList],
  680. warehouse: this.params.warehouse,
  681. // puOrderExecuteList: [...this.params.puOrderExecuteList],
  682. };
  683. const blob = new Blob([JSON.stringify(tabList)], {
  684. type: "application/json",
  685. });
  686. formData.append("tabList", blob);
  687. this.$modal.loading("正在上传文件,请稍候...");
  688. let {
  689. code,
  690. data: { puOrderItemList, puOrderExecuteList },
  691. } = await orderApi.orderImport(formData);
  692. if (code == 200) {
  693. // for (const key in data) {
  694. // this.params[key].push(...data[key]);
  695. // }
  696. this.params["puOrderItemList"] = [...puOrderItemList];
  697. this.params["puOrderExecuteList"] = [...puOrderExecuteList];
  698. let { setVisible } = this.$refs.batchImport;
  699. setVisible(false);
  700. // if(num > total)
  701. this.handleGetPrice();
  702. }
  703. } catch (error) {
  704. } finally {
  705. this.$modal.closeLoading();
  706. }
  707. },
  708. async handleTemDownload() {
  709. this.download(
  710. "/pu/order/downloadFailData",
  711. {},
  712. `物料信息模板${new Date().getTime()}.xlsx`
  713. );
  714. },
  715. getSummaries({ columns, data }) {
  716. const means = []; // 合计
  717. let { tabColumns, tabName } = this;
  718. columns.forEach((column, columnIndex) => {
  719. if (columnIndex === 0) {
  720. means.push("合计");
  721. } else {
  722. const values = data.map((item) => Number(item[column.property]));
  723. let sumColumn = tabColumns
  724. .find((tab) => tab.key === tabName)
  725. .tableColumns.filter((item) => item.hidden)
  726. .filter(
  727. ({ key, isSummary }) => isSummary && key === column.property
  728. );
  729. // 合计
  730. // if (!values.every(value => isNaN(value))) {
  731. if (sumColumn.length) {
  732. means[columnIndex] = values.reduce((prev, curr) => {
  733. const value = Number(curr);
  734. if (!isNaN(value)) {
  735. return prev + curr;
  736. } else {
  737. return prev;
  738. }
  739. }, 0);
  740. means[columnIndex] = means[columnIndex].toFixed(2);
  741. } else {
  742. means[columnIndex] = "";
  743. }
  744. }
  745. });
  746. // sums[index] = sums[index] && sums[index].toFixed(2); // 保留2位小数,解决小数合计列
  747. return [means];
  748. },
  749. // 子表-批量复制
  750. async tabCopyChange(prop, { column, source }) {
  751. let { key, referName, dataMapping } = column;
  752. try {
  753. this.tabLoading = true;
  754. if (key === "materialCode") {
  755. let {
  756. code,
  757. data: { puOrderItemList },
  758. } = await orderApi.materialCopy({
  759. materialCode: prop,
  760. puOrderItemList: this.params.puOrderItemList.filter(
  761. (item) => item.rowNo != source.rowNo
  762. ),
  763. // puOrderExecuteList
  764. });
  765. if (code == 200) {
  766. this.params.puOrderItemList = [...puOrderItemList];
  767. // this.params.puOrderExecuteList = [...puOrderExecuteList];
  768. }
  769. } else {
  770. let params = {
  771. searchList: prop,
  772. type: referName,
  773. };
  774. key === "goodsAllocationName" &&
  775. (params["stordocId"] = this.params.warehouse);
  776. let { code, rows } = await orderApi.REFER(params);
  777. if (code == 200) {
  778. // !rows.length &&
  779. // this.$notify.warning({
  780. // message: "粘贴数据检索为空,请检查是否符合要求!",
  781. // });
  782. if (!rows.length) {
  783. this.$notify.warning({
  784. message: "粘贴数据检索为空,请检查是否符合要求!",
  785. });
  786. for (const key in dataMapping) {
  787. source[key] = "";
  788. }
  789. }
  790. rows = rows.map((item) => {
  791. let obj = {};
  792. for (const key in dataMapping) {
  793. obj[key] = item[dataMapping[key]];
  794. }
  795. return obj;
  796. });
  797. let invariant = this.params.puOrderItemList.filter(
  798. (item) => item.rowNo < source.rowNo || item.delFlag !== "0"
  799. );
  800. let change = this.params.puOrderItemList
  801. .filter(
  802. (item) => !(item.rowNo < source.rowNo) && item.delFlag === "0"
  803. )
  804. .map((item, index) => {
  805. return {
  806. ...item,
  807. ...rows[index],
  808. };
  809. });
  810. this.params.puOrderItemList = [...invariant, ...change];
  811. }
  812. }
  813. } catch (error) {
  814. } finally {
  815. this.tabLoading = false;
  816. }
  817. },
  818. inputTabChange(prop, { column, source }) {
  819. let { key, copy } = column;
  820. // 数量-批量复制
  821. if (copy) {
  822. if (key === "qty") {
  823. let munList = prop.split(/,|,|\s+/);
  824. let invariant = this.params.puOrderItemList.filter(
  825. (item) => item.rowNo < source.rowNo || item.delFlag !== "0"
  826. );
  827. let change = this.params.puOrderItemList
  828. .filter(
  829. (item) => !(item.rowNo < source.rowNo) && item.delFlag === "0"
  830. )
  831. .map((item, index) => {
  832. return {
  833. ...item,
  834. qty: munList[index] || item.qty,
  835. money: this.isManualInquiry
  836. ? Number(item.taxPrice) * Number(item.qty)
  837. : item.money,
  838. };
  839. });
  840. this.params.puOrderItemList = [...invariant, ...change];
  841. if (this.isManualInquiry) {
  842. // 不进行询价
  843. // 主表价税合计
  844. this.params.money = this.params["puOrderItemList"].reduce(
  845. (total, item) => {
  846. return (total += Number(item.money));
  847. },
  848. 0
  849. );
  850. // 原始总数量
  851. this.params.qty = this.params["puOrderItemList"].reduce(
  852. (total, item) => {
  853. return (total += Number(item.qty));
  854. },
  855. 0
  856. );
  857. return;
  858. }
  859. if (this.params.status === "2") {
  860. // 修订
  861. this.handleCalculateOrderAmount();
  862. } else {
  863. this.handleGetPrice();
  864. }
  865. }
  866. }
  867. },
  868. onHide(prop) {
  869. this.innerColumns = prop;
  870. },
  871. },
  872. created() {},
  873. mounted() {},
  874. updated() {
  875. this.$nextTick(() => {
  876. // this.$refs.puOrderExecuteList &&
  877. // this.$refs.puOrderExecuteList[0].doLayout();
  878. this.$refs.puOrderItemList && this.$refs.puOrderItemList[0].doLayout();
  879. });
  880. },
  881. destroyed() {},
  882. };
  883. </script>
  884. <template>
  885. <el-drawer
  886. direction="btt"
  887. size="100%"
  888. :with-header="false"
  889. :visible.sync="visible"
  890. @open="beforeOpen"
  891. @close="$emit('close')"
  892. >
  893. <el-form
  894. :key="count"
  895. v-loading="loading"
  896. :size="size"
  897. ref="orderEditForm"
  898. class="orderEditForm"
  899. label-position="right"
  900. label-width="140px"
  901. :model="params"
  902. :rules="rules"
  903. >
  904. <el-card
  905. :body-style="{
  906. padding: '20px',
  907. display: 'flex',
  908. 'flex-wrap': 'wrap',
  909. }"
  910. style="margin: 10px"
  911. >
  912. <div
  913. slot="header"
  914. style="
  915. display: flex;
  916. justify-content: space-between;
  917. align-items: center;
  918. "
  919. >
  920. <h3>{{ handleIsRevise() ? "修订" : "编辑" }}</h3>
  921. <div style="text-align: right">
  922. <!-- 编辑 非自制 采购角色 -->
  923. <cgxj-button
  924. v-if="
  925. !handleIsRevise() &&
  926. role === 'procurementManager' &&
  927. params.source != '3'
  928. "
  929. v-model="params"
  930. :size="size"
  931. :source.sync="params"
  932. ></cgxj-button>
  933. <el-button :size="size" type="primary" @click="handleSava"
  934. >更 新</el-button
  935. >
  936. <el-button :size="size" @click="handleCancel">取 消</el-button>
  937. </div>
  938. </div>
  939. <el-row style="display: flex; flex-wrap: wrap">
  940. <el-col
  941. v-for="(column, index) in columns"
  942. :key="index"
  943. :span="column.span || 6"
  944. >
  945. <el-form-item
  946. :prop="column.key"
  947. :label="column.title"
  948. v-if="column.isShow"
  949. >
  950. <el-input
  951. v-if="column.inputType === 'Input'"
  952. v-model="params[column.key]"
  953. :placeholder="column.placeholder"
  954. :clearable="column.clearable"
  955. :disabled="column.disabled"
  956. style="width: 100%"
  957. ></el-input>
  958. <dr-popover-select
  959. v-if="column.inputType === 'PopoverSelect'"
  960. v-model="params[column.key]"
  961. :size="size"
  962. :value-key="column.valueKey"
  963. :source.sync="params"
  964. :title="column.title"
  965. :type="column.referName"
  966. :multiple="column.multiple"
  967. :placeholder="column.placeholder"
  968. :data-mapping="column.dataMapping"
  969. :disabled="column.disabled"
  970. :clearable="column.clearable"
  971. :query-params="column.queryParams"
  972. @change="handleReferChange"
  973. ></dr-popover-select>
  974. <el-input
  975. v-if="column.inputType === 'Textarea'"
  976. v-model="params[column.key]"
  977. type="textarea"
  978. :rows="column.rows"
  979. :placeholder="column.placeholder"
  980. :clearable="column.clearable"
  981. :disabled="column.disabled"
  982. :maxlength="column.maxlength"
  983. show-word-limit
  984. style="width: 100%"
  985. ></el-input>
  986. <el-input-number
  987. v-if="column.inputType === 'InputNumber'"
  988. v-model="params[column.key]"
  989. :precision="column.precision"
  990. :controls-position="column.controlsPosition"
  991. :placeholder="column.placeholder"
  992. :clearable="column.clearable"
  993. :disabled="column.disabled"
  994. style="width: 100%"
  995. ></el-input-number>
  996. <el-select
  997. v-if="column.inputType === 'Select'"
  998. v-model="params[column.key]"
  999. :disabled="column.disabled"
  1000. :clearable="column.clearable"
  1001. :placeholder="column.placeholder"
  1002. style="width: 100%"
  1003. @change="handleSelectChange(column.key, column.referName)"
  1004. >
  1005. <el-option
  1006. v-for="item in dict.type[column.referName]"
  1007. :key="item.value"
  1008. :label="item.label"
  1009. :value="item.value"
  1010. ></el-option>
  1011. </el-select>
  1012. <el-select
  1013. v-if="column.inputType === 'TagSelect'"
  1014. v-model="params[column.key]"
  1015. multiple
  1016. clearable
  1017. collapse-tags
  1018. :placeholder="column.placeholder"
  1019. :clearable="column.clearable"
  1020. :disabled="column.disabled"
  1021. style="width: 100%"
  1022. >
  1023. <template #prefix>
  1024. <el-icon
  1025. class="el-icon-view"
  1026. style="cursor: pointer"
  1027. @click.stop="$message.info(234)"
  1028. ></el-icon>
  1029. </template>
  1030. <el-option
  1031. v-for="item in options"
  1032. :key="item.value"
  1033. :label="item.label"
  1034. :value="item.value"
  1035. ></el-option>
  1036. </el-select>
  1037. <el-date-picker
  1038. v-if="column.inputType === 'DatePicker'"
  1039. v-model="params[column.key]"
  1040. :type="column.type"
  1041. :placeholder="column.placeholder"
  1042. :clearable="column.clearable"
  1043. :disabled="column.disabled"
  1044. :picker-options="column.pickerOptions"
  1045. style="width: 100%"
  1046. v-bind="cColumn.attr || {}"
  1047. ></el-date-picker>
  1048. <el-checkbox
  1049. v-if="column.inputType === 'Checkbox'"
  1050. v-model="params[column.key]"
  1051. :disabled="column.disabled"
  1052. true-label="Y"
  1053. false-label="N"
  1054. >
  1055. </el-checkbox>
  1056. <file-upload-center
  1057. v-if="column.inputType === 'Upload'"
  1058. v-model="params[column.key]"
  1059. :file-type="column.fileType"
  1060. :disabled="handleIsRevise()"
  1061. ></file-upload-center>
  1062. </el-form-item>
  1063. </el-col>
  1064. </el-row>
  1065. </el-card>
  1066. <el-card
  1067. :body-style="{
  1068. padding: '20px',
  1069. display: 'flex',
  1070. 'flex-wrap': 'wrap',
  1071. position: 'relative',
  1072. }"
  1073. style="margin: 10px"
  1074. >
  1075. <el-tabs v-model="tabName" style="width: 100%" v-loading="tabLoading">
  1076. <el-tab-pane
  1077. v-for="(column, index) in tabColumns"
  1078. :key="index"
  1079. :label="column.title"
  1080. :name="column.key"
  1081. >
  1082. <ux-grid
  1083. border
  1084. use-virtual
  1085. keep-source
  1086. show-summary
  1087. show-overflow
  1088. beautify-table
  1089. :ref="column.key"
  1090. :size="size"
  1091. :height="tabHeight"
  1092. style="width: 100%"
  1093. :data="params[column.key].filter((item) => item.delFlag === '0')"
  1094. :summary-method="getSummaries"
  1095. :header-row-style="{
  1096. color: '#515a6e',
  1097. }"
  1098. >
  1099. <ux-table-column
  1100. title="序号"
  1101. type="index"
  1102. width="60"
  1103. ></ux-table-column>
  1104. <ux-table-column
  1105. v-for="(cColumn, cIndex) in column.tableColumns.filter(
  1106. (item) => item.hidden
  1107. )"
  1108. :key="cColumn.key + cColumn.hidden"
  1109. :field="cColumn.key"
  1110. :title="cColumn.title"
  1111. :width="cColumn.width || 80"
  1112. resizable
  1113. >
  1114. <template slot="header" slot-scope="scope">
  1115. <span v-if="cColumn.require" style="color: #ff4949">*</span>
  1116. <span>
  1117. {{ cColumn.title }}
  1118. </span>
  1119. </template>
  1120. <template slot-scope="scope">
  1121. <el-form-item label-width="0">
  1122. <span v-if="!cColumn.inputType">
  1123. {{ scope.row[cColumn.key] }}
  1124. </span>
  1125. <el-input
  1126. v-if="cColumn.inputType === 'Input'"
  1127. v-model="scope.row[cColumn.key]"
  1128. :placeholder="cColumn.placeholder"
  1129. :clearable="cColumn.clearable"
  1130. :disabled="cColumn.disabled"
  1131. :size="size"
  1132. style="width: 100%"
  1133. @change="
  1134. (prop) =>
  1135. inputTabChange(prop, {
  1136. column: cColumn,
  1137. source: scope.row,
  1138. })
  1139. "
  1140. ></el-input>
  1141. <dr-popover-select
  1142. v-if="cColumn.inputType === 'PopoverSelect'"
  1143. v-model="scope.row[cColumn.key]"
  1144. :source.sync="scope.row"
  1145. :title="cColumn.title"
  1146. :value-key="cColumn.valueKey"
  1147. :disabled="cColumn.disabled"
  1148. :clearable="cColumn.clearable"
  1149. :copy="cColumn.copy"
  1150. :type="cColumn.referName"
  1151. :multiple="cColumn.multiple"
  1152. :placeholder="cColumn.placeholder"
  1153. :data-mapping="cColumn.dataMapping"
  1154. :query-params="
  1155. cColumn.key !== 'goodsAllocationName'
  1156. ? cColumn.queryParams
  1157. : () => ({
  1158. stordocId: params.warehouse,
  1159. pkOrg: params.puOrg,
  1160. })
  1161. "
  1162. :size="size"
  1163. @change="handleTabReferChange"
  1164. @copyChange="
  1165. (prop) =>
  1166. tabCopyChange(prop, {
  1167. column: cColumn,
  1168. source: scope.row,
  1169. })
  1170. "
  1171. ></dr-popover-select>
  1172. <el-select
  1173. v-if="cColumn.inputType === 'Select'"
  1174. v-model="scope.row[cColumn.key]"
  1175. :size="size"
  1176. :disabled="cColumn.disabled"
  1177. :clearable="cColumn.clearable"
  1178. :placeholder="cColumn.placeholder"
  1179. style="width: 100%"
  1180. @change="handleTabSelectChange(cColumn.key, scope.row)"
  1181. >
  1182. <el-option
  1183. v-for="item in dict.type[cColumn.referName]"
  1184. :key="item.value"
  1185. :label="item.label"
  1186. :value="item.value"
  1187. ></el-option>
  1188. </el-select>
  1189. <el-checkbox
  1190. v-if="cColumn.inputType === 'Checkbox'"
  1191. v-model="scope.row[cColumn.key]"
  1192. :disabled="cColumn.disabled"
  1193. true-label="Y"
  1194. false-label="N"
  1195. @change="handleTabCheckbox(cColumn.key, scope.row)"
  1196. ></el-checkbox>
  1197. <el-input-number
  1198. v-if="cColumn.inputType === 'InputNumber'"
  1199. v-model="scope.row[cColumn.key]"
  1200. :precision="cColumn.precision"
  1201. :controls-position="cColumn.controlsPosition"
  1202. :max="getInputNumberMax(cColumn.key, scope.row)"
  1203. :min="cColumn.key === 'reservedQty' ? 0 : -Infinity"
  1204. @change="handleInputChange(scope.row, cColumn.key)"
  1205. :placeholder="cColumn.placeholder"
  1206. :clearable="cColumn.clearable"
  1207. :disabled="cColumn.disabled"
  1208. :size="size"
  1209. style="width: 100%"
  1210. ></el-input-number>
  1211. <el-date-picker
  1212. v-if="cColumn.inputType === 'DatePicker'"
  1213. v-model="scope.row[cColumn.key]"
  1214. :size="size"
  1215. :type="cColumn.type"
  1216. :placeholder="cColumn.placeholder"
  1217. :clearable="cColumn.clearable"
  1218. :disabled="cColumn.disabled"
  1219. :picker-options="cColumn.pickerOptions"
  1220. style="width: 100%"
  1221. v-bind="cColumn.attr || {}"
  1222. ></el-date-picker>
  1223. </el-form-item>
  1224. </template>
  1225. </ux-table-column>
  1226. <!-- 修订:不可删除、增行
  1227. 编辑:自制:可删可增 -->
  1228. <!-- v-if="!handleIsRevise()" -->
  1229. <ux-table-column
  1230. v-if="!handleIsRevise()"
  1231. fixed="right"
  1232. label="操作"
  1233. width="120"
  1234. >
  1235. <template slot-scope="scope">
  1236. <el-button
  1237. @click.native.prevent="
  1238. delTableRow(params[tabName], scope.row, tabName)
  1239. "
  1240. type="text"
  1241. :size="size"
  1242. >
  1243. 删行
  1244. </el-button>
  1245. </template>
  1246. </ux-table-column>
  1247. </ux-grid>
  1248. <!-- </template>
  1249. </virtual-scroll> -->
  1250. </el-tab-pane>
  1251. </el-tabs>
  1252. <el-row style="position: absolute; top: 20px; right: 20px">
  1253. <el-button
  1254. v-if="params.source == '3' && !handleIsRevise()"
  1255. :size="size"
  1256. @click="addTableRow(params[tabName])"
  1257. >增行</el-button
  1258. >
  1259. <BatchImport
  1260. v-if="params.source == '3' && !handleIsRevise()"
  1261. ref="batchImport"
  1262. @import="handelImport"
  1263. @temDownload="handleTemDownload"
  1264. :fileSize="2"
  1265. ></BatchImport>
  1266. </el-row>
  1267. <el-row style="margin-top: 10px">
  1268. <el-col>
  1269. <button-hide v-model="innerColumns" @change="onHide"></button-hide>
  1270. </el-col>
  1271. </el-row>
  1272. </el-card>
  1273. </el-form>
  1274. </el-drawer>
  1275. </template>
  1276. <style scoped>
  1277. .orderEditForm >>> .el-form-item {
  1278. margin-bottom: 5px;
  1279. }
  1280. ::v-deep .singleTable .el-form-item {
  1281. margin-bottom: 0px;
  1282. }
  1283. ::v-deep.uxbeautifyTableClass
  1284. .elx-header--column
  1285. .elx-resizable.is--line:before {
  1286. height: 100%;
  1287. background-color: #dfe6ec;
  1288. }
  1289. </style>