PurchaseApplyArea.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. <template>
  2. <el-form
  3. ref="dataForm"
  4. v-loading="loading"
  5. class="form"
  6. :model="dataForm"
  7. :rules="dataFormRules"
  8. label-position="left"
  9. label-width="80px"
  10. >
  11. <el-form-item v-if="formDisabled" label="单据编号" prop="sheetId">
  12. <el-input disabled :value="dataForm.sheetId" />
  13. </el-form-item>
  14. <el-row :gutter="20">
  15. <el-col :span="8">
  16. <el-form-item label="网点" prop="shopId">
  17. <el-select v-model="dataForm.shopId" :disabled="formDisabled" placeholder="请选择网点" style="width: 100%">
  18. <el-option
  19. v-for="(item, index) in getAuthShop(null, dataForm)"
  20. :key="index"
  21. :label="shopLabelStrHandle(item)"
  22. :value="item.shopId"
  23. />
  24. </el-select>
  25. </el-form-item>
  26. </el-col>
  27. <el-col :span="8">
  28. <el-form-item label="供应商" prop="venderId">
  29. <el-select
  30. v-model="dataForm.venderId"
  31. filterable
  32. :disabled="formDisabled"
  33. placeholder="请选择供应商"
  34. style="width: 100%"
  35. @change="getVenderGoodsList"
  36. >
  37. <el-option
  38. v-for="(item, index) in venderList"
  39. :key="index"
  40. :label="vendorLabelStrHandle(item)"
  41. :value="item.venderId"
  42. />
  43. </el-select>
  44. </el-form-item>
  45. </el-col>
  46. <el-col :span="8">
  47. <el-form-item label="状态" prop="flag">
  48. <el-input disabled :value="sheetFlagStr('label', dataForm.flag)" />
  49. </el-form-item>
  50. </el-col>
  51. </el-row>
  52. <el-form-item label="备注" prop="notes3">
  53. <el-input
  54. v-model="dataForm.notes3"
  55. autocomplete="off"
  56. placeholder="备注"
  57. :disabled="inputParam.openType === 'view'"
  58. />
  59. </el-form-item>
  60. <el-row>
  61. <el-col>
  62. <el-divider>采购明细</el-divider>
  63. </el-col>
  64. <el-col>
  65. <el-button
  66. size="small"
  67. :disabled="inputParam.openType === 'view' || goodsList.length === 0"
  68. @click="innerVisible = true"
  69. >添加商品</el-button
  70. >
  71. <el-table
  72. ref="goodsTable"
  73. :data="dataForm.items"
  74. max-height="500"
  75. size="mini"
  76. border
  77. header-cell-class-name="headerRowColor"
  78. class="detail-table"
  79. show-summary
  80. :summary-method="getSummaries"
  81. >
  82. <el-table-column prop="goodsId" label="辅材编号" />
  83. <el-table-column prop="goodsName" label="辅材名称" width="230" />
  84. <el-table-column prop="estimateCost" label="预估进价" header-align="left" align="center">
  85. <template slot-scope="{ $index, row }">
  86. <label v-if="inputParam.openType === 'view'">{{ row.estimateCost + ' 元/' + row.measureUnit }}</label>
  87. <el-form-item
  88. v-else
  89. style="margin: 18px 0"
  90. label-width="0"
  91. size="mini"
  92. :prop="'items.' + $index + '.estimateCost'"
  93. :rules="dataFormRules.estimateCost"
  94. >
  95. <el-input v-model="row.estimateCost" size="mini" @change="changeCostValue($index, row)">
  96. <template slot="suffix">{{ ' 元/' + row.measureUnit }}</template>
  97. </el-input>
  98. </el-form-item>
  99. </template>
  100. </el-table-column>
  101. <el-table-column prop="purchaseQty" label="订货数量" header-align="left" align="center" width="120">
  102. <template slot-scope="{ $index, row }">
  103. <label v-if="inputParam.openType === 'view'">{{ row.purchaseQty + ' /' + row.measureUnit }}</label>
  104. <el-form-item
  105. v-else
  106. style="margin: 18px 0"
  107. label-width="0"
  108. size="mini"
  109. :prop="'items.' + $index + '.purchaseQty'"
  110. :rules="dataFormRules.purchaseQty"
  111. >
  112. <el-input v-model="row.purchaseQty" size="mini" @change="changeCostValue($index, row)">
  113. <template slot="suffix">{{ ' /' + row.measureUnit }}</template>
  114. </el-input>
  115. </el-form-item>
  116. </template>
  117. </el-table-column>
  118. <el-table-column prop="estimateCostValue" label="预估金额" header-align="left" align="center">
  119. <template slot-scope="{ $index, row }">
  120. <label>{{ row.estimateCostValue + ' 元' }}</label>
  121. </template>
  122. </el-table-column>
  123. <el-table-column prop="measureUnit" label="采购单位" />
  124. <el-table-column prop="unitQty" label="转换系数" />
  125. <el-table-column prop="salesUnit" label="售卖单位" />
  126. <el-table-column prop="productModel" label="商品型号" min-width="100" />
  127. <el-table-column prop="specification" label="规格" min-width="80" />
  128. <el-table-column v-if="inputParam.openType !== 'view'" fixed="right" align="center" label="">
  129. <template slot-scope="scope">
  130. <el-button type="text" @click="delItem(scope.$index)">删除</el-button>
  131. </template>
  132. </el-table-column>
  133. </el-table>
  134. <el-row style="margin-top: 15px">
  135. <el-col :span="24"
  136. ><div>共 {{ goodsTotalCount }} 条记录</div></el-col
  137. >
  138. </el-row>
  139. </el-col>
  140. </el-row>
  141. <div style="text-align: right">
  142. <el-button @click="cancelForm">取 消</el-button>
  143. <el-button v-if="checkBtn('add')" type="primary" :disabled="saveBtn" @click="submitForm('add')">保 存</el-button>
  144. <el-button v-if="checkBtn('edit')" type="primary" :disabled="saveBtn" @click="submitForm('edit')"
  145. >保 存</el-button
  146. >
  147. <el-button v-if="checkBtn('submit')" type="success" @click="submitSheet(dataForm.sheetId)">提 交</el-button>
  148. </div>
  149. <el-dialog
  150. width="70%"
  151. title="商品列表"
  152. :visible.sync="innerVisible"
  153. :close-on-click-modal="false"
  154. @close="$refs.goodsTable.clearSelection()"
  155. >
  156. <el-input
  157. v-model="searchGoods"
  158. size="small"
  159. placeholder="输入 辅材名称 或 规格 模糊搜索"
  160. style="margin-bottom: 5px"
  161. :clearable="true"
  162. />
  163. <el-table
  164. ref="goodsTable"
  165. :data="
  166. goodsList.filter(
  167. data =>
  168. !searchGoods ||
  169. data.goodsName.toLowerCase().includes(searchGoods.toLowerCase()) ||
  170. data.specification.toLowerCase().includes(searchGoods.toLowerCase())
  171. )
  172. "
  173. :row-key="getRowKeys"
  174. height="400"
  175. size="mini"
  176. border
  177. header-cell-class-name="headerRowColor"
  178. style="width: 100%"
  179. >
  180. <el-table-column type="selection" width="55" :reserve-selection="true" />
  181. <el-table-column prop="goodsId" label="辅材编号" />
  182. <el-table-column prop="goodsCode" label="辅材代码" />
  183. <el-table-column prop="goodsName" label="辅材名称" />
  184. <el-table-column prop="categoryName" label="小类名称" />
  185. <el-table-column prop="productModel" label="商品型号" />
  186. <el-table-column prop="specification" label="规格" />
  187. <el-table-column prop="qty" label="库存数量" />
  188. </el-table>
  189. <div slot="footer" class="dialog-footer">
  190. <el-button type="primary" @click="selGoods">确 定</el-button>
  191. </div>
  192. </el-dialog>
  193. </el-form>
  194. </template>
  195. <script>
  196. import {
  197. addPurchaseApplySheet,
  198. submitPurchaseApplySheet,
  199. editPurchaseApplySheet,
  200. getPurchaseApplySheet
  201. } from '@/api/material-system/shop/purchase-apply-sheet'
  202. import { getVenderGoodsList, getVenderList } from '@/api/material-system/vender'
  203. import { computeVal } from '@/api/material-system/common'
  204. export default {
  205. name: 'PurchaseApplyArea',
  206. props: {
  207. inputParam: {
  208. type: Object,
  209. default: function () {
  210. return {
  211. openType: 'add',
  212. sheetId: ''
  213. }
  214. }
  215. }
  216. },
  217. data() {
  218. const validatePurchaseQty = (rule, value, callback) => {
  219. this.saveBtn = true
  220. if (Number.isNaN(parseFloat(value))) {
  221. return callback(new Error('请输入数字值'))
  222. }
  223. if (parseFloat(value) <= 0) {
  224. return callback(new Error('必须大于0'))
  225. }
  226. this.saveBtn = false
  227. callback()
  228. }
  229. return {
  230. loading: true,
  231. dataForm: {
  232. sheetId: '', // 单据ID
  233. shopId: '', // 网点ID
  234. shopName: '', // 网点名称
  235. venderId: '', // 供应商ID
  236. venderName: '', // 供应商名称
  237. notes3: '', // 备注
  238. flag: '',
  239. items: [] // 关系辅材列表
  240. },
  241. dataFormRules: {
  242. shopId: [{ required: true, message: '请选择网点', trigger: 'change' }],
  243. purchaseQty: [{ validator: validatePurchaseQty, trigger: 'blur' }]
  244. },
  245. goodsList: [], // 商品列表
  246. venderList: [], // 供应商列表
  247. innerVisible: false,
  248. searchGoods: '',
  249. saveBtn: false // 保存按钮状态
  250. }
  251. },
  252. computed: {
  253. formDisabled() {
  254. return this.inputParam.openType === 'view' || this.dataForm.sheetId !== ''
  255. },
  256. goodsTotalCount: function () {
  257. return this.dataForm && this.dataForm.items ? this.dataForm.items.length : 0
  258. }
  259. },
  260. watch: {
  261. // 网点变动重新执行辅材获取资料
  262. 'shopPurchaseForm.shopId': function () {
  263. this.getVenderGoodsList(this.dataForm.venderId)
  264. },
  265. searchGoods: function () {
  266. this.$refs.goodsTable.clearSelection()
  267. }
  268. },
  269. mounted() {
  270. this.getVenderList()
  271. this.getDetail()
  272. },
  273. methods: {
  274. getDetail(id) {
  275. this.loading = true
  276. const openType = this.inputParam.openType
  277. const sheetId = id || this.inputParam.sheetId
  278. if (openType !== 'add') {
  279. getPurchaseApplySheet({ sheetId }).then(res => {
  280. this.setDataForm(res.data)
  281. if (openType !== 'view') {
  282. this.getVenderGoodsList(res.data.venderId, false)
  283. }
  284. this.loading = false
  285. })
  286. } else {
  287. this.loading = false
  288. }
  289. },
  290. cancelForm() {
  291. this.$parent.getList()
  292. this.$emit('update:isOpen', false)
  293. },
  294. submitForm(type) {
  295. if (this.dataForm.items && this.dataForm.items.length === 0) {
  296. this.$errorMsg('请添加商品后再保存!')
  297. return
  298. }
  299. this.$refs.dataForm.validate(valid => {
  300. if (valid) {
  301. if (type === 'edit') {
  302. editPurchaseApplySheet(this.dataForm).then(() => {
  303. this.$successMsg('保存成功')
  304. })
  305. } else {
  306. this.dataForm.shopName = this.getArraysName(this.authShop, this.dataForm, 'shopId', 'shopName')
  307. this.dataForm.venderName = this.getArraysName(this.venderList, this.dataForm, 'venderId', 'venderName')
  308. addPurchaseApplySheet(this.dataForm).then(res => {
  309. this.inputParam.openType = 'edit'
  310. this.setDataForm(res.data)
  311. this.$successMsg('保存成功')
  312. })
  313. }
  314. }
  315. })
  316. },
  317. setDataForm(data) {
  318. this.dataForm = {
  319. sheetId: data.sheetId, // 单据编号
  320. shopId: data.shopId, // 网点ID
  321. venderId: data.venderId, // 供应商Id
  322. flag: data.flag,
  323. notes: data.notes, // 备注
  324. items: data.items // 关系商品列表
  325. }
  326. },
  327. checkBtn(type) {
  328. const typeMap = {
  329. add: this.inputParam.openType === type,
  330. edit: this.dataForm.flag === 0 && this.inputParam.openType === type,
  331. revoke: this.dataForm.flag === 1,
  332. submit: this.dataForm.flag === 0 && this.dataForm.sheetId !== ''
  333. }
  334. // 检查按钮权限
  335. return this.checkBtnRole(type) && typeMap[type]
  336. },
  337. // 获取供应商列表
  338. getVenderList() {
  339. getVenderList({ pageNum: 1, pageSize: -1, flag: 1 }).then(res => {
  340. this.venderList = res.data.records
  341. })
  342. },
  343. // 获取供应商关系辅材列表
  344. getVenderGoodsList(val, clear = true) {
  345. if (clear) {
  346. this.dataForm.items = []
  347. }
  348. getVenderGoodsList({
  349. pageNum: 1,
  350. pageSize: -1,
  351. venderId: val,
  352. flag: 1,
  353. status: 1,
  354. shopId: this.dataForm.shopId
  355. }).then(res => {
  356. this.goodsList = res.data.records
  357. })
  358. },
  359. // 选中辅材添加到表单中
  360. selGoods() {
  361. this.searchGoods = ''
  362. this.$refs.goodsTable.selection.forEach(value => {
  363. const index = this.dataForm.items.findIndex(item => {
  364. return item.goodsId === value.goodsId
  365. })
  366. // 添加不在列表的商品
  367. if (index < 0) {
  368. this.dataForm.items.push({
  369. goodsId: value.goodsId,
  370. goodsName: value.goodsName,
  371. ndays: value.ndays,
  372. purchaseQty: 0,
  373. estimateCost: 0,
  374. estimateCostValue: 0,
  375. measureUnit: value.measureUnit,
  376. unitQty: value.unitQty,
  377. salesUnit: value.salesUnit,
  378. productModel: value.productModel,
  379. specification: value.specification
  380. })
  381. }
  382. })
  383. this.$refs.goodsTable.clearSelection()
  384. this.innerVisible = false
  385. },
  386. // 删除明细
  387. delItem(index) {
  388. this.dataForm.items.splice(index, 1)
  389. },
  390. getRowKeys(row) {
  391. return row.goodsId
  392. },
  393. // 提交 采购申请单
  394. submitSheet(sheetId) {
  395. this.$confirm(
  396. `此操作将提交 ${sheetId} 单据,<span style="color: #ff0000;">当前内容如果已修改将忽略保存</span>,是否继续?`,
  397. '提示',
  398. {
  399. confirmButtonText: '确定',
  400. cancelButtonText: '取消',
  401. type: 'warning',
  402. dangerouslyUseHTMLString: true
  403. }
  404. )
  405. .then(() => {
  406. this.loading = true
  407. submitPurchaseApplySheet({ sheetId: sheetId }).then(
  408. () => {
  409. setTimeout(() => {
  410. this.inputParam.openType = 'view'
  411. this.getDetail(sheetId)
  412. this.$successMsg('提交成功')
  413. this.loading = false
  414. }, 2000)
  415. },
  416. () => {
  417. this.loading = false
  418. }
  419. )
  420. })
  421. .catch(() => console.log('取消'))
  422. },
  423. // 预估进价或申请数量变动
  424. changeCostValue(index, row) {
  425. computeVal({
  426. frontVal: row.purchaseQty,
  427. afterVal: row.estimateCost,
  428. operator: '*',
  429. scale: 4
  430. }).then(res => {
  431. this.dataForm.items[index].estimateCostValue = res.data
  432. })
  433. },
  434. getSummaries(param) {
  435. const { columns, data } = param
  436. const sums = []
  437. columns.forEach((column, index) => {
  438. if (index === 0) {
  439. sums[index] = '合计'
  440. return
  441. }
  442. const values = data.map(item => Number(item[column.property]))
  443. if (column.property === 'estimateCostValue') {
  444. let count = 0
  445. sums[index] = values.reduce((prev, curr) => {
  446. const suffix = (curr + '').split('.')
  447. if (suffix.length > 1) {
  448. count = suffix[1].length > count ? suffix[1].length : count
  449. }
  450. const value = Number(curr)
  451. if (!isNaN(value)) {
  452. return prev + curr
  453. } else {
  454. return prev
  455. }
  456. }, 0)
  457. sums[index] = parseFloat(sums[index]).toFixed(count)
  458. }
  459. })
  460. return sums
  461. }
  462. }
  463. }
  464. </script>
  465. <style lang="scss" scoped>
  466. .detail-table {
  467. width: 100%;
  468. margin: 15px 0;
  469. ::v-deep .el-input__suffix-inner {
  470. color: red;
  471. }
  472. }
  473. .form {
  474. padding: 0 20px;
  475. }
  476. </style>