financialAccount.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636
  1. <template>
  2. <div>
  3. <basic-container>
  4. <avue-crud ref="crud" :data="data" :option="option" :table-loading="loading" @row-update="rowUpdate"
  5. @row-del="rowDel" @saveColumn="saveColumn" @resetColumn="resetColumn">
  6. <template slot="menuLeft" slot-scope="{size}">
  7. <el-button type="primary" icon="el-icon-plus" size="small" :loading="submitButton" @click="entering"
  8. v-if="addBut">录入
  9. </el-button>
  10. </template>
  11. <template slot-scope="{row,index}" slot="menu">
  12. <el-button type="text" size="small" icon="el-icon-edit" @click="rowCell(row, index)">{{ row.$cellEdit ? '保存' :
  13. '修改'
  14. }}
  15. </el-button>
  16. <el-button type="text" icon="el-icon-delete" size="small" @click="rowDel(row, index)">删除</el-button>
  17. </template>
  18. <template slot-scope="{row,index}" slot="corpId">
  19. <span v-if="row.$cellEdit && category != 2" class="required_fields"
  20. style="float: left;line-height: 32px">*</span>
  21. <span v-if="row.$cellEdit && category != 2" style="display: flex">
  22. <el-select v-model="corpId" placeholder="请选择" size="small" style="width:60%" filterable>
  23. <el-option v-for="item in corpOption" :key="item.id" :label="item.cname" :value="item.id" />
  24. </el-select>
  25. <el-button icon="el-icon-search" size="small" @click="openDialog(row, index, 1)"></el-button>
  26. </span>
  27. <span v-else>{{ corpsName }}</span>
  28. </template>
  29. <!-- <template slot-scope="{row,index}" slot="costType">-->
  30. <!-- <breakdown-select-->
  31. <!-- v-if="row.$cellEdit"-->
  32. <!-- v-model="row.costType"-->
  33. <!-- style="width: 90%"-->
  34. <!-- :configuration="configuration"-->
  35. <!-- @selectValue="(value) => {getFeeValue(row, value)}"-->
  36. <!-- >-->
  37. <!-- </breakdown-select>-->
  38. <!-- <span v-else>{{ row.costName }}</span>-->
  39. <!-- </template>-->
  40. <template slot-scope="{row,index}" slot="billNo">
  41. <el-select placeholder="请选择" v-if="row.$cellEdit" v-model="row.billNo" size="small" filterable allow-create
  42. default-first-option clearable>
  43. <el-option v-for="item in row.billNoList" :key="item" :label="item" :value="item"></el-option>
  44. </el-select>
  45. <span v-else>{{ row.billNo }}</span>
  46. </template>
  47. <template slot-scope="{row,index}" slot="taxRate">
  48. <el-input v-model="row.taxRate" v-if="row.$cellEdit" size="small"
  49. oninput='this.value=this.value.replace(/[^(\d.)]/g,"").replace(/^(\d+)\.(\d\d\d\d\d\d).*$/, "$1.$2")'
  50. autocomplete="off">
  51. <i slot="suffix" style="margin-right: 10px;top:6px">%</i>
  52. </el-input>
  53. <span v-else>{{ row.taxRate }}</span>
  54. </template>
  55. <template slot-scope="{row,index}" slot="currency">
  56. <span v-if="row.$cellEdit" class="required_fields">*</span>
  57. <el-select v-if="row.$cellEdit" v-model="row.currency" size="small" placeholder="请选择" style="width: 90%"
  58. @change="currencyChange(row)" clearable filterable>
  59. <el-option v-for="(item, index) in currencyDic" :key="index" :label="item.dictValue"
  60. :value="item.dictValue">
  61. </el-option>
  62. </el-select>
  63. <span v-else>{{ row.currency }}</span>
  64. </template>
  65. <template slot-scope="{row,index}" slot="unit">
  66. <el-select v-if="row.$cellEdit" v-model="row.unit" size="small" style="width: 90%" placeholder="请选择" clearable
  67. filterable>
  68. <el-option v-for="(item, index) in unitDic" :key="index" :label="item.dictValue" :value="item.dictValue">
  69. </el-option>
  70. </el-select>
  71. <span v-else>{{ row.unit }}</span>
  72. </template>
  73. <template slot-scope="{row,index}" slot="price">
  74. <el-input-number v-if="row.$cellEdit" v-model="row.price" size="small" :controls="false" :precision="2"
  75. @input="amountChange(row)" style="width: 100%" />
  76. <span v-else>{{ Number(row.price).toFixed(2) }}</span>
  77. </template>
  78. <template slot-scope="{row,index}" slot="quantity">
  79. <el-input-number v-if="row.$cellEdit" v-model="row.quantity" size="small" :controls="false" :precision="0"
  80. @input="amountChange(row)" style="width: 100%" />
  81. <span v-else>{{ Number(row.quantity).toFixed(2) }}</span>
  82. </template>
  83. <template slot-scope="{row,index}" slot="amount">
  84. <el-input-number v-if="row.$cellEdit" v-model="row.amount" size="small" :controls="false" :precision="2"
  85. style="width: 100%" />
  86. <span v-else>{{ Number(row.amount).toFixed(2) }}</span>
  87. </template>
  88. </avue-crud>
  89. <div class="dialogButton">
  90. <el-button size="small" :loading="submitButton" @click="$emit('choceFun')">取消</el-button>
  91. <el-button type="primary" size="small" :loading="submitButton" @click="submit()">确定</el-button>
  92. </div>
  93. </basic-container>
  94. <containerTitle v-if="billId" title="历史账单"></containerTitle>
  95. <basic-container v-if="billId">
  96. <avue-crud :option="historyOption" :data="historyDataList" ref="historyCrud" v-model="historyForm"
  97. :page.sync="page" :table-loading="historyLoading" @on-load="onLoad">
  98. </avue-crud>
  99. </basic-container>
  100. <el-dialog title="客户、供应商" :visible.sync="corpVisible" width="80%" top="5vh" append-to-body @closed="closeCorp"
  101. class="el-dialogDeep" v-dialog-drag>
  102. <span>
  103. <el-row>
  104. <el-col :span="4">
  105. <el-scrollbar>
  106. <basic-container>
  107. <avue-tree :option="corpTreeOption" :data="treeData" @node-click="corpNodeClick" :style="treeStyle" />
  108. </basic-container>
  109. </el-scrollbar>
  110. </el-col>
  111. <el-col :span="20">
  112. <avue-crud :option="KHOption" :data="corpData" ref="crud" :page.sync="corpPage" :search.sync="corpSearch"
  113. @search-change="corpSearchChange" @search-reset="corpSearchReset" @selection-change="selectionChange"
  114. @current-change="corpCurrentChange" @size-change="corpSizeChange" @on-load="corpOnLoad"
  115. @tree-load="corpTreeLoad" @saveColumn="saveColumn" @resetColumn="resetColumn"
  116. @refresh-change="corpRefreshChange" :table-loading="dialogLoading">
  117. </avue-crud>
  118. </el-col>
  119. </el-row>
  120. </span>
  121. <span slot="footer" class="dialog-footer">
  122. <el-button @click="corpVisible = false">取 消</el-button>
  123. <el-button type="primary" @click="importCorp" :disabled="selectionList.length != 1">确 定</el-button>
  124. </span>
  125. </el-dialog>
  126. </div>
  127. </template>
  128. <script>
  129. import { applyLoan, paymentApply } from "@/api/financialManagement/paymentRequest";
  130. import { getApplyAmount } from "@/api/basicData/purchaseOrder"
  131. import option from "./config/option.json"
  132. import historyOption from "../bill/config/application.json"
  133. import { getUserInfo } from "@/api/system/user";
  134. import { getBillList } from "@/api/financialManagement/paymentRequest";
  135. import { customerList, getDeptLazyTree } from "@/api/basicData/customerInformation";
  136. import { getDeptLazyTree as getFeeLazyTree, customerList as feeList } from "@/api/basicData/basicFeesDesc";
  137. import corpOption from './config/corpOption.json'
  138. export default {
  139. name: "financialAccount",
  140. props: {
  141. debitAmount: {
  142. type: Number,
  143. default: 0,
  144. },
  145. addBut: {
  146. type: Boolean,
  147. default: true
  148. },
  149. billId: {
  150. type: String
  151. },
  152. billType: {
  153. type: String
  154. },
  155. srcType: {
  156. type: Number,
  157. default: 1,
  158. },
  159. billData: {
  160. type: Object
  161. },
  162. srcBillId: {
  163. type: Object
  164. },
  165. choceFun: {
  166. type: Function
  167. },
  168. arrList: {
  169. type: Array,
  170. default: []
  171. },
  172. checkData: {
  173. type: Object,
  174. default: {
  175. url: null,
  176. pageStatus: null,
  177. pageLabel: null,
  178. checkType: null
  179. },
  180. },
  181. belongCompany: {
  182. type: String,
  183. },
  184. tradeType: {
  185. type: String,
  186. default: null
  187. }
  188. },
  189. data() {
  190. return {
  191. data: [],
  192. corpId: '',
  193. corpsName: '',
  194. option: option,
  195. loading: false,
  196. submitButton: false,
  197. currencyDic: [],
  198. unitDic: [],
  199. configuration: {
  200. multipleChoices: false,
  201. multiple: false,
  202. disabled: true,
  203. searchShow: true,
  204. collapseTags: false,
  205. placeholder: '请点击右边按钮选择',
  206. dicData: []
  207. },
  208. category: '',
  209. historyLoading: false,
  210. historyOption: historyOption,
  211. historyDataList: [],
  212. historyForm: {},
  213. page: {
  214. pageSize: 10,
  215. pagerCount: 1,
  216. total: 0,
  217. },
  218. corpOption: [], //客户
  219. feeOption: [], // 费用
  220. rowData: null,
  221. corpVisible: false,
  222. feeVisible: false,
  223. treeStyle: 'height:' + (window.innerHeight - 315) + 'px',
  224. corpTreeOption: {
  225. nodeKey: "id",
  226. lazy: true,
  227. addBtn: false,
  228. menu: false,
  229. size: "small",
  230. props: {
  231. labelText: "标题",
  232. label: "title",
  233. value: "value",
  234. children: "children"
  235. }
  236. },
  237. treeCorpId: '',
  238. selectionList: [],
  239. corpPage: {
  240. currentPage: 1,
  241. pageSize: 10,
  242. total: 0
  243. },
  244. corpSearch: {},
  245. dialogLoading: false,
  246. KHOption: corpOption,
  247. corpData: [],
  248. }
  249. },
  250. created() {
  251. this.option.height = window.innerHeight - 240;
  252. this.historyOption.searchShow = false
  253. customerList({
  254. size: 10000,
  255. current: 1
  256. }).then(res => {
  257. // this.corpOption = res.data.data.records? res.data.data.records: [];
  258. if (res.data.data.total > 0) {
  259. this.corpOption = res.data.data.records;
  260. if (Math.ceil(res.data.data.total / 10) > 1) {
  261. for (let i = 2; i <= Math.ceil(res.data.data.total / 10); i++) {
  262. customerList({ current: i, size: 10 }).then(e => {
  263. this.corpOption = this.corpOption.concat(e.data.data.records);
  264. });
  265. }
  266. }
  267. }
  268. })
  269. this.loading = true;
  270. feeList({ size: 10000, current: 1 }).then(res => {
  271. this.feeOption = res.data.data.records ? res.data.data.records : [];
  272. this.init()
  273. }).finally(() => {
  274. this.loading = false;
  275. })
  276. getUserInfo().then(res => {
  277. this.category = res.data.data.billType
  278. if (this.category == 2) {
  279. }
  280. })
  281. //币别
  282. this.getWorkDicts("currency").then(res => {
  283. this.currencyDic = res.data.data
  284. })
  285. this.getWorkDicts("unit").then(res => {
  286. this.unitDic = res.data.data
  287. })
  288. },
  289. mounted() {
  290. // this.init()
  291. },
  292. watch: {
  293. billId(val, oldVal) {
  294. if (val != oldVal) {
  295. this.onLoad(this.page)
  296. }
  297. },
  298. },
  299. methods: {
  300. init() {
  301. if (this.arrList.length === 0) {
  302. this.corpId = this.billData.corpId
  303. this.corpsName = this.billData.corpsName[0].cname
  304. this.feeOption.forEach(item => {
  305. if (this.billData.costType == item.id) {
  306. this.$set(this.billData, 'costName', item.cname)
  307. }
  308. })
  309. this.data.push(this.billData)
  310. } else {
  311. this.billData = this.arrList[0]
  312. this.corpId = this.arrList[0].corpId
  313. this.corpsName = this.arrList[0].corpsName[0].cname
  314. this.arrList.forEach(item => {
  315. this.feeOption.forEach(e => {
  316. if (item.costType == e.id) {
  317. this.$set(item, 'costName', e.cname)
  318. }
  319. })
  320. this.data.push(item)
  321. })
  322. }
  323. this.$nextTick(() => {
  324. this.$refs.crud.doLayout()
  325. })
  326. //删除 提单号
  327. if (this.billData.optionType !== "JK") {
  328. this.option.column.forEach(item => {
  329. if (item.prop === "billNo") {
  330. item.hide = true
  331. } else {
  332. item.hide = false
  333. }
  334. })
  335. }
  336. },
  337. currencyChange(row) {
  338. this.currencyDic.forEach(item => {
  339. if (item.dictValue === row.currency) {
  340. row.exchangeRate = item.remark
  341. }
  342. })
  343. },
  344. rowCell(row, index) {
  345. // this.$refs.crud.rowCell(row, index)
  346. if (row.$cellEdit == true) {
  347. this.$set(row, '$cellEdit', false)
  348. } else {
  349. this.$set(row, '$cellEdit', true)
  350. }
  351. },
  352. rowDel(row, index) {
  353. this.$confirm("确定将选择数据删除?", {
  354. confirmButtonText: "确定",
  355. cancelButtonText: "取消",
  356. type: "warning"
  357. }).then(() => {
  358. this.data.splice(index, 1);
  359. })
  360. },
  361. rowUpdate(row, index, done, loading) {
  362. done(row);
  363. },
  364. entering() {
  365. if (this.data.length !== 0) {
  366. //取第一条数据的 合同号 以及客户
  367. let params = {
  368. ...this.billData,
  369. srcOrderno: this.data[0].srcOrderno,
  370. corpId: this.data[0].corpId
  371. }
  372. this.$refs.crud.rowCellAdd(params);
  373. } else {
  374. this.$refs.crud.rowCellAdd(this.billData);
  375. }
  376. },
  377. onLoad(page, params = {}) {
  378. this.historyLoading = true;
  379. params.srcParentId = this.billId
  380. params.flag = 1
  381. getBillList(page.currentPage, page.pageSize, params).then(res => {
  382. this.historyDataList = res.data.data.records
  383. }).finally(() => {
  384. this.historyLoading = false;
  385. })
  386. },
  387. async forData() {
  388. if (this.addBut) {
  389. let amountSum = 0
  390. for (let item in this.data) {
  391. amountSum += Number(this.data[item].amount)
  392. }
  393. let res = await getApplyAmount({ srcBillId: this.srcBillId, billType: "申请" })
  394. if ((Number(this.debitAmount) - Number(res.data.data)) < amountSum) {
  395. return '可结算金额:' + (Number(this.debitAmount) - Number(res.data.data)) + '元'
  396. }
  397. } else {
  398. for (let item in this.data) {
  399. let res = await getApplyAmount({ srcBillId: this.data[item].itemId, billType: "申请" })
  400. if ((Number(this.data[item].itemorderAmount) - Number(res.data.data)) < this.data[item].amount) {
  401. return '合同号:' + this.data[item].srcOrderno + '可结算金额:' + (Number(this.data[item].itemorderAmount) - Number(res.data.data)) + '元'
  402. }
  403. }
  404. }
  405. },
  406. async submit() {
  407. for (let i = 0; i < this.data.length; i++) {
  408. if (this.corpId === (null || "")) {
  409. return this.$message.error(`请输入第${i + 1}行的客户`);
  410. }
  411. if (this.data[i].costType === (null || "")) {
  412. return this.$message.error(`请输入第${i + 1}行的费用名称`);
  413. }
  414. if (this.data[i].accDate === (null || "")) {
  415. return this.$message.error(`请输入第${i + 1}行的合同日期`);
  416. }
  417. if (this.data[i].amount === (null || "")) {
  418. return this.$message.error(`请输入第${i + 1}行的金额`);
  419. }
  420. if (this.data[i].currency === (null || "")) {
  421. return this.$message.error(`请输入第${i + 1}行的币别`);
  422. }
  423. if (this.data[i].exchangeRate === (null || "")) {
  424. return this.$message.error(`请输入第${i + 1}行的汇率`);
  425. }
  426. if (this.data[i].taxRate === (null || "")) {
  427. return this.$message.error(`请输入第${i + 1}行的税率`);
  428. }
  429. }
  430. let forData = await this.forData()
  431. if (forData) {
  432. if (this.addBut) {
  433. return this.$message.error(forData)
  434. } else {
  435. return this.$message.error(forData)
  436. }
  437. }
  438. // if (forData) {
  439. // return this.$message.error('已付费金额大于货款')
  440. // }else{
  441. // return this.$message.error('合同号:' + forData + '已付费金额大于货款')
  442. // }
  443. this.submitButton = true
  444. const itemsList = this.data.map(item => {
  445. item.corpId = this.corpId;
  446. item.tradeType = this.billData.optionType ? this.billData.optionType : item.tradeType;
  447. item.srcType = item.srcType ? item.srcType : this.srcType;
  448. return item;
  449. })
  450. const params = {
  451. url: this.checkData.url,
  452. pageStatus: this.checkData.pageStatus,
  453. pageLabel: this.checkData.pageLabel,
  454. checkType: this.checkData.checkType,
  455. billType: this.billType,
  456. tradeType: this.tradeType,
  457. DC: this.billData.itemType === "采购" ? "C" : "D", //账单明细会根据D C区分采购 销售搜索
  458. itemsList: itemsList,
  459. belongCompany: this.belongCompany // 所属公司
  460. }
  461. // 采购申请货款 销售申请退款 都会走申请 走审核 => 付款申请
  462. if (this.billType === "申请") {
  463. applyLoan(params).then(res => {
  464. if (res.data.success) {
  465. this.$message.success("操作成功!")
  466. this.$emit("choceFun");
  467. this.$emit("submit")
  468. //跳转付款申请页面
  469. // if(this.$store.getters.pqStatus){
  470. // this.$alert("无法自动跳,因为付费申请页面已存在!", "温馨提示", {
  471. // confirmButtonText: "确定",
  472. // type: 'warning',
  473. // callback: action => {
  474. // }
  475. // });
  476. // }else{
  477. // //关闭一下存在的列表页 跳转
  478. // this.$router.$avueRouter.closeTag('/financialManagement/paymentRequest/index');
  479. // this.$router.push({
  480. // path: "/financialManagement/paymentRequest/index",
  481. // query: {params: res.data.data.id},
  482. // });
  483. // }
  484. }
  485. }).finally(() => {
  486. this.submitButton = false
  487. })
  488. }
  489. //采购退款结算 销售收款结算 不需申请请核 直接结算 => 结算
  490. if (this.billType === "收费") {
  491. paymentApply(params).then(res => {
  492. if (res.data.success) {
  493. this.$message.success("操作成功!")
  494. this.$emit("choceFun");
  495. this.$emit("submit")
  496. }
  497. }).finally(() => {
  498. this.submitButton = false
  499. })
  500. }
  501. },
  502. saveColumn() {
  503. },
  504. resetColumn() {
  505. },
  506. amountChange(row) {
  507. if (!row.quantity) {
  508. row.quantity = 0;
  509. }
  510. if (!row.price) {
  511. row.price = 0;
  512. }
  513. row.amount = Number(row.price) * Number(row.quantity)
  514. },
  515. // 客户、费用弹窗
  516. openDialog(row, index, type) {
  517. this.rowData = {
  518. ...row,
  519. index
  520. }
  521. // 1客户 2费用
  522. if (type == 1) {
  523. this.corpTreeOption.treeLoad = function (node, resolve) {
  524. const parentId = node.level === 0 ? 0 : node.data.id;
  525. getDeptLazyTree({
  526. parentId: parentId,
  527. corpType: "KG"
  528. }).then(res => {
  529. resolve(
  530. res.data.data.map(item => {
  531. return {
  532. ...item,
  533. leaf: !item.hasChildren
  534. };
  535. })
  536. );
  537. });
  538. };
  539. this.corpVisible = !this.corpVisible;
  540. } else if (type == 2) {
  541. this.feeVisible = !this.feeVisible;
  542. }
  543. },
  544. selectionChange(list) {
  545. this.selectionList = list;
  546. },
  547. closeCorp() {
  548. this.selectionList = [];
  549. this.treeCorpId = "";
  550. this.reData = null;
  551. },
  552. corpNodeClick(data) {
  553. this.treeCorpId = data.id;
  554. this.corpPage.currentPage = 1;
  555. this.corpOnLoad(this.corpPage);
  556. },
  557. //列表内展开树节点
  558. corpTreeLoad(tree, treeNode, resolve) {
  559. const parentId = tree.id;
  560. customerList({ parentId: parentId }).then(res => {
  561. resolve(res.data.data.records);
  562. });
  563. },
  564. //点击搜索按钮触发
  565. corpSearchChange(params, done) {
  566. this.corpPage.currentPage = 1;
  567. this.corpOnLoad(this.corpPage, params);
  568. done();
  569. },
  570. corpSearchReset() {
  571. this.treeCorpId = null;
  572. },
  573. corpSizeChange(val) {
  574. this.corpPage.pageSize = val;
  575. this.corpOnLoad();
  576. },
  577. corpCurrentChange(val) {
  578. this.corpPage.currentPage = val;
  579. this.corpOnLoad();
  580. },
  581. corpRefreshChange() {
  582. this.corpOnLoad(this.corpPage, this.corpSearch);
  583. },
  584. corpOnLoad(page, params = { parentId: 0 }) {
  585. let queryParams = Object.assign({}, params, {
  586. size: page.pageSize,
  587. current: page.currentPage,
  588. corpsTypeId: this.treeDeptId,
  589. corpType: 'KG'
  590. });
  591. this.dialogLoading = true;
  592. customerList(queryParams).then(res => {
  593. this.corpData = res.data.data.records;
  594. this.corpPage.total = res.data.data.total;
  595. if (this.corpPage.total) {
  596. this.KHOption.height = window.innerHeight - 350;
  597. }
  598. })
  599. .finally(() => {
  600. this.dialogLoading = false;
  601. });
  602. },
  603. importCorp() {
  604. // item.srcFeesId = item.id
  605. this.corpData.forEach((item, index) => {
  606. if (index == this.rowData.index) {
  607. item.corpId = this.selectionList[0].id;
  608. }
  609. })
  610. this.corpVisible = false;
  611. },
  612. getFeeValue(row, value) {
  613. this.$set(row, 'costName', value.cname)
  614. }
  615. }
  616. }
  617. </script>
  618. <style scoped lang="scss">
  619. .required_fields {
  620. color: #F56C6C;
  621. display: inline-block;
  622. width: 7%
  623. }
  624. </style>