goodsExchangeAdd.vue 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064
  1. <template>
  2. <div class="bg-in-stock">
  3. <el-form ref="goodsExchangeAddForm" :model="goodsExchangeAddForm" :rules="goodsExchangeAddFormRule"
  4. label-width="160px" inline class="change-form">
  5. <el-form-item prop="warehouse_id" label="出库仓库" class="change-form-item">
  6. <el-select v-model="goodsExchangeAddForm.warehouse_id" :disabled="type === 'detail' || type === 'audit'">
  7. <!-- @change="handleChangeWareHouse" -->
  8. <el-option v-for="item in warehouseList" :key="item.id" :label="item.name" :value="item.id" />
  9. </el-select>
  10. </el-form-item>
  11. <el-form-item label="类型" prop="type" class="change-form-item">
  12. <el-select v-model="goodsExchangeAddForm.type" filterable allow-create clearable default-first-option
  13. :disabled="type === 'detail' || type === 'audit'">
  14. <el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value"
  15. :disabled="item.value == 'SALE_OUT' || item.value == 'HAIL_OUT' || item.value == 'DAMAGE_OUT' || item.value == 'TRANSFER_OUT'" />
  16. </el-select>
  17. </el-form-item>
  18. <!-- <el-form-item label="订单" prop="order_sn" class="change-form-item">
  19. <el-input
  20. v-model="goodsExchangeAddForm.order_list[0].order_sn"
  21. :disabled="type === 'detail' || type === 'audit'"
  22. ref="order"
  23. >
  24. </el-input>
  25. </el-form-item> -->
  26. <el-form-item label="备注" prop="notes" class="change-form-item" style="width: 61%">
  27. <el-input style="flex: 1" v-model="goodsExchangeAddForm.notes" type="textarea"
  28. :disabled="type === 'detail' || type === 'audit'" maxlength="250" :autosize="{ minRows: 3, maxRows: 4 }"
  29. placeholder="请输入"></el-input>
  30. </el-form-item>
  31. <!-- <div class="mx">
  32. <h3>商品明细</h3>
  33. </div>
  34. <div style="width: 100%; display: block;">
  35. <el-form-item style="width: 100%;">
  36. <el-table :data="goodsExchangeAddForm.return_list" border :cell-style="{ textAlign: 'center' }"
  37. :header-cell-style="{ textAlign: 'center' }" style="width: 100%; margin-top: 20px;">
  38. <el-table-column label="入库单号">
  39. <template slot-scope="scope">
  40. {{ scope.row.stock_sn }}
  41. </template>
  42. </el-table-column>
  43. <el-table-column label="商品编号">
  44. <template slot-scope="scope">
  45. {{ scope.row.product_sn }}
  46. </template>
  47. </el-table-column>
  48. <el-table-column label="商品名称">
  49. <template slot-scope="scope">
  50. {{ scope.row.product_name }}
  51. </template>
  52. </el-table-column>
  53. <el-table-column label="规格型号">
  54. <template slot-scope="scope">
  55. {{ scope.row.specification }}
  56. </template>
  57. </el-table-column>
  58. <el-table-column label="单位">
  59. <template slot-scope="scope">
  60. {{ scope.row.unit }}
  61. </template>
  62. </el-table-column>
  63. <el-table-column label="单价">
  64. <template slot-scope="scope">
  65. ¥{{ scope.row.amount }}
  66. </template>
  67. </el-table-column>
  68. <el-table-column label="数量">
  69. <template slot-scope="scope">
  70. <el-input v-model="scope.row.num" type="number" :min="0" :maxlength="20"
  71. :disabled="type === 'detail' || type === 'audit'"></el-input>
  72. </template>
  73. </el-table-column>
  74. <el-table-column label="金额">
  75. <template slot-scope="scope">
  76. {{ scope.row.num * scope.row.amount || 0 }}
  77. </template>
  78. </el-table-column>
  79. <el-table-column label="操作" v-if="type !== 'detail' && type !== 'audit'">
  80. <template slot-scope="scope">
  81. <el-button size="mini" type="danger"
  82. @click="goodsExchangeAddForm.return_list.splice(scope.$index, 1)">删除</el-button>
  83. </template>
  84. </el-table-column>
  85. </el-table>
  86. </el-form-item>
  87. </div> -->
  88. <div class="mx">
  89. <h3>商品明细</h3>
  90. <el-button class="button" size="mini" type="primary" v-if="type !== 'detail' && type !== 'audit'"
  91. @click="scanCode">扫码出库</el-button>
  92. <el-button class="button" size="mini" type="primary" v-if="type !== 'detail' && type !== 'audit'"
  93. @click="handleSelectWarehouseEntryBatch">选择</el-button>
  94. </div>
  95. <div style="width: 100%; display: block">
  96. <el-form-item style="width: 100%">
  97. <el-table :data="goodsExchangeAddForm.product_list" border :cell-style="{ textAlign: 'center' }"
  98. :header-cell-style="{ textAlign: 'center' }" style="width: 100%; margin-top: 20px">
  99. <el-table-column label="库位号">
  100. <template slot-scope="scope">
  101. <el-popover placement="right" trigger="click">
  102. <div>
  103. <p v-for="item in scope.row.area_stock_list" :key="item.id">{{ item.warehouse_area_name }}</p>
  104. </div>
  105. <span slot="reference">{{ scope.row.area_stock_list[0].warehouse_area_name }}</span>
  106. </el-popover>
  107. </template>
  108. </el-table-column>
  109. <el-table-column label="商品编号">
  110. <template slot-scope="scope">
  111. <span v-if="id">{{ scope.row.goods_vo.sn }}</span>
  112. <span v-else>{{ scope.row.goods_vo.sn }}</span>
  113. </template>
  114. </el-table-column>
  115. <el-table-column label="商品名称">
  116. <template slot-scope="scope">
  117. <span v-if="id">{{ scope.row.goods_vo.name }}</span>
  118. <span v-else>{{ scope.row.goods_vo.name }}</span>
  119. </template>
  120. </el-table-column>
  121. <el-table-column label="sku">
  122. <template slot-scope="scope">
  123. <span v-if="id">{{ scope.row.product_vo.sku }}</span>
  124. <span v-else>{{ scope.row.product_vo.sku }}</span>
  125. </template>
  126. </el-table-column>
  127. <el-table-column label="序列号" v-if="sn_code_list">
  128. <template slot-scope="scope">
  129. <div class="sn-code-container">
  130. <span v-for="item in scope.row.sn_code_list" :key="item.id">
  131. <p>{{ item.sn_code }}</p>
  132. </span>
  133. </div>
  134. </template>
  135. </el-table-column>
  136. <el-table-column prop="product_vo.spec_name" label="规格型号" v-if="id">
  137. <!-- <template slot-scope="scope">
  138. {{ scope.row.product_vo.spec_name.join("/") }}
  139. </template> -->
  140. </el-table-column>
  141. <el-table-column prop="product_vo.spec_name" label="规格型号" v-else>
  142. <!-- <template slot-scope="scope">
  143. {{ scope.row.product_vo.spec_name.join("/") }}
  144. </template> -->
  145. </el-table-column>
  146. <el-table-column label="单位">
  147. <template slot-scope="scope">
  148. <span v-if="id">{{ scope.row.product_vo.unit }}</span>
  149. <span v-else>{{ scope.row.product_vo.unit }}</span>
  150. </template>
  151. </el-table-column>
  152. <el-table-column label="出库数量">
  153. <template slot-scope="scope">
  154. <el-input v-model="scope.row.out_num" type="number" :min="0" :maxlength="20"
  155. :disabled="type === 'detail' || type === 'audit'"></el-input>
  156. </template>
  157. </el-table-column>
  158. <el-table-column label="订单数量">
  159. <template slot-scope="scope">
  160. {{ scope.row.order_num }}
  161. </template>
  162. </el-table-column>
  163. <el-table-column label="可用库存">
  164. <template slot-scope="scope">
  165. {{ scope.row.usable_stock }}
  166. </template>
  167. </el-table-column>
  168. <el-table-column label="实际库存">
  169. <template slot-scope="scope">
  170. {{ scope.row.actual_stock }}
  171. </template>
  172. </el-table-column>
  173. <!-- <el-table-column label="剩余数量">
  174. <template slot-scope="scope">
  175. {{ scope.row.usable_stock - scope.row.out_num || 0 }}
  176. </template>
  177. </el-table-column> -->
  178. <el-table-column width="200" label="操作" v-if="type !== 'detail' && type !== 'audit'">
  179. <template slot-scope="scope">
  180. <!-- <el-button
  181. size="mini"
  182. @click="addSnCode(scope.row,scope.$index)"
  183. >添加序列号</el-button
  184. > -->
  185. <el-button size="mini" type="danger" @click="
  186. goodsExchangeAddForm.product_list.splice(scope.$index, 1)
  187. ">删除</el-button>
  188. </template>
  189. </el-table-column>
  190. </el-table>
  191. </el-form-item>
  192. </div>
  193. </el-form>
  194. <div class="footer">
  195. <!-- <el-button v-if="type === 'audit'" type="primary" @click="handlePassGoodsExchange()">审核通过
  196. </el-button>
  197. <el-button v-if="type === 'audit'" type="danger" @click="dialogVisible = true">审核驳回
  198. </el-button> -->
  199. <el-button v-if="type !== 'audit' && type !== 'detail' && checkPermission(['warehouseOut2:add'])" type="primary"
  200. @click="saveGoodsExchangeAddForm">保存
  201. </el-button>
  202. <el-button v-if="type !== 'audit' && type !== 'detail' && checkPermission(['warehouseOut:update'])" type="primary"
  203. @click="submitGoodsExchangeAddForm">出库
  204. </el-button>
  205. <el-button @click="printIng" v-if="type == 'audit'">打印</el-button>
  206. <el-button @click="toBack()">返回</el-button>
  207. </div>
  208. <el-dialog title="提示" :visible.sync="dialogVisible" width="30%">
  209. <el-form ref="goodsExchangeAddForm" :model="goodsExchangeAddForm" label-width="120px" inline style="width: 900px">
  210. <el-form-item label="驳回原因" prop="reject_reason">
  211. <el-input v-model="goodsExchangeAddForm.reject_reason" type="textarea" :minlength="0"
  212. :maxlength="100"></el-input>
  213. </el-form-item>
  214. </el-form>
  215. <span slot="footer" class="dialog-footer">
  216. <el-button @click="dialogVisible = false">取 消</el-button>
  217. <el-button type="primary" @click="handleRejectGoodsExchange()">确 定</el-button>
  218. </span>
  219. </el-dialog>
  220. <el-dialog title="扫码出库" :visible.sync="scanDialogVisible" width="30%" :close-on-click-modal="false">
  221. <el-form ref="scanGoodsForm" :model="scanGoodsForm" label-width="120px" inline>
  222. <el-form-item label="sku" prop="bar_code">
  223. <el-input v-model="scanGoodsForm.bar_code" ref="input" @keyup.enter.native="toSearch()" :minlength="0"
  224. :maxlength="100"></el-input>
  225. </el-form-item>
  226. <el-form-item label="序列号" prop="sn_code">
  227. <el-input v-model="sn_code" ref="sn_input" @keyup.enter.native="toSnCode()" :minlength="0"
  228. :maxlength="100"></el-input>
  229. </el-form-item>
  230. </el-form>
  231. <span slot="footer" class="dialog-footer">
  232. <!-- <el-button @click="dialogVisible = false">取 消</el-button>
  233. <el-button type="primary" @click="handleRejectGoodsExchange()">确 定</el-button> -->
  234. </span>
  235. </el-dialog>
  236. <!-- <el-dialog
  237. title="序列号"
  238. :visible.sync="snCodeVisible"
  239. width="30%"
  240. :close-on-press-escape="false"
  241. :close-on-click-modal="false"
  242. >
  243. <el-form
  244. ref="scanGoodsForm"
  245. :model="scanGoodsForm"
  246. label-width="120px"
  247. inline
  248. >
  249. <el-form-item label="序列号" prop="sn_code">
  250. <el-input
  251. v-model="sn_code"
  252. @keyup.enter.native="toSnCode()"
  253. :minlength="0"
  254. :maxlength="100"
  255. ></el-input>
  256. </el-form-item>
  257. </el-form>
  258. </el-dialog> -->
  259. <!-- <el-dialog
  260. title="出库商品"
  261. :visible.sync="goodsVisible"
  262. width="1000px"
  263. @close="closeGoosData"
  264. >
  265. <el-table
  266. :data="goodsData"
  267. border
  268. style="width: 100%"
  269. @selection-change="handleSelectionChange"
  270. >
  271. <el-table-column type="selection" width="55" />
  272. <el-table-column prop="sn" label="商品编号"> </el-table-column>
  273. <el-table-column prop="bar_code" label="商品条码"> </el-table-column>
  274. <el-table-column prop="sn_code" label="序列号"> </el-table-column>
  275. <el-table-column prop="name" label="商品名称"> </el-table-column>
  276. <el-table-column prop="goods_style" label="规格型号"> </el-table-column>
  277. <el-table-column prop="goods_unit" label="单位"> </el-table-column>
  278. <el-table-column prop="product_list.stock_num" label="库存数量">
  279. </el-table-column>
  280. </el-table>
  281. <span slot="footer" class="dialog-footer">
  282. <el-button @click="closeGoosData">取 消</el-button>
  283. <el-button type="primary" @click="submitGoosData()">确 定</el-button>
  284. </span>
  285. </el-dialog> -->
  286. </div>
  287. </template>
  288. <script>
  289. import { mapGetters } from "vuex";
  290. import { Foundation, RegExp } from "~/ui-utils";
  291. import * as API_GoodsExchange from "@/api/goodsExchange";
  292. import * as API_Setting from "@/api/setting";
  293. import * as API_BasicSetting from "@/api/basicSetting";
  294. import * as API_Erp from "@/api/erp";
  295. import * as API_Auth from "@/api/auth";
  296. export default {
  297. name: "goodsExchangeAdd",
  298. data() {
  299. const checkPrice = (rule, value, callback) => {
  300. if (!value && value !== 0) {
  301. return callback(new Error("换货金额不能为空"));
  302. } else if (!RegExp.money.test(value)) {
  303. callback(new Error("请输入正整数或者两位小数"));
  304. } else if (parseFloat(value) > 99999999) {
  305. callback(new Error("换货金额设置超过上限值"));
  306. } else {
  307. callback();
  308. }
  309. };
  310. return {
  311. typeList: [
  312. /* {
  313. real_name: "销售出库",
  314. id: "销售出库",
  315. },
  316. {
  317. real_name: "租赁出库",
  318. id: "租赁出库",
  319. },
  320. {
  321. real_name: "借用出库",
  322. id: "借用出库",
  323. },
  324. {
  325. real_name: "其他出库",
  326. id: "其他出库",
  327. }, */
  328. ],
  329. adminList: [],
  330. dialogVisible: false,
  331. warehouseList: [],
  332. deptList: [],
  333. deptListAll: [],
  334. orderList: [],
  335. id: "",
  336. type: "",
  337. /** 出库单表单*/
  338. goodsExchangeAddForm: {
  339. order_list: [
  340. {
  341. order_id: "1752156400898293761",
  342. order_item_list: [
  343. {
  344. batch_list: [
  345. {
  346. batch_id: 0,
  347. batch_sn: "",
  348. out_num: 0,
  349. remain_num: 0,
  350. warehouse_entry_sn: "",
  351. },
  352. ],
  353. num: 0,
  354. order_item_id: 0,
  355. product_id: 0,
  356. product_name: "string",
  357. product_sn: "string",
  358. product_specification: "string",
  359. product_unit: "string",
  360. },
  361. ],
  362. order_sn: "",
  363. },
  364. ],
  365. product_list: [],
  366. type: "",
  367. },
  368. /** 校验规则 */
  369. goodsExchangeAddFormRule: {
  370. warehouse_id: [
  371. { required: true, message: "请选择出库仓库", trigger: "change" },
  372. ],
  373. type: [
  374. { required: true, message: "请选择出库类型", trigger: "change" },
  375. ],
  376. // change_amount: [
  377. // { required: true, message: '请输入换货金额', trigger: 'blur' },
  378. // { validator: checkPrice, trigger: 'blur' }
  379. // ]
  380. },
  381. warehouseProduct: null,
  382. scanDialogVisible: false,
  383. scanGoodsForm: {},
  384. routeName: "",
  385. //出入库
  386. sttorageType: "",
  387. // 出库商品明细
  388. goodsVisible: false,
  389. goodsData: [],
  390. // 暂存已勾选商品
  391. goodsList: [],
  392. product_list: [],
  393. snCodeVisible: false,
  394. sn_code: "",
  395. sku: "",
  396. sn_code_list: [],
  397. index: "",
  398. };
  399. },
  400. mounted() {
  401. this.routeName = this.$route.name;
  402. this.sttorageType = this.$route.params.type;
  403. this.GET_WarehouseList();
  404. this.GET_DeptList();
  405. this.outType();
  406. },
  407. watch: {
  408. $route: {
  409. immediate: true,
  410. handler(newVal) {
  411. if (this.$route.name === "goodsExchangeEdit") {
  412. this.type = "edit";
  413. } else if (this.$route.name === "goodsExchangeAudit") {
  414. this.type = "audit";
  415. } else if (this.$route.name === "goodsExchangeReturn") {
  416. this.type = "return";
  417. } else if (this.$route.name === "goodsExchangeAdd") {
  418. this.type = "add";
  419. /* this.goodsExchangeAddForm = {
  420. change_amount: 0,
  421. change_list: [],
  422. return_list: [],
  423. product_list: [],
  424. handled_by_id: this.user.uid,
  425. dept_id: this.user.dept_id,
  426. }; */
  427. // this.goodsExchangeAddForm.handled_by_id = this.user.uid
  428. // this.goodsExchangeAddForm.dept_id = this.user.dept_id
  429. this.GET_WarehouseList({ dept_id: this.user.dept_id });
  430. this.$set(
  431. this.goodsExchangeAddForm,
  432. "change_time",
  433. new Date().getTime()
  434. );
  435. } else if (this.$route.name === "goodsExchangeDetail") {
  436. this.type = "detail";
  437. }
  438. if (this.$route.params.id) {
  439. this.id = this.$route.params.id;
  440. this.GET_goodsExchangeAddDetail();
  441. }
  442. this.GET_AdministratorList();
  443. },
  444. },
  445. },
  446. computed: {
  447. ...mapGetters(["user"]),
  448. },
  449. methods: {
  450. /* 返回出入明细 */
  451. toBack() {
  452. this.$router.push({
  453. name: "goodsExchange",
  454. params: { type: "first" },
  455. });
  456. },
  457. //扫序列号goodsExchangeAddForm.product_list[this.index].sn_code_list
  458. toSnCode() {
  459. if (this.sku == '') return this.$message.error('请录入正确的sku')
  460. API_GoodsExchange.getSnCode("out", this.sku, this.sn_code.replace(/\s+/g, '')).then((res) => {
  461. this.sn_code = "";
  462. // 假设res是一个对象,我们根据res的某个属性(如sn)来检查重复
  463. let exists = this.goodsExchangeAddForm.product_list[
  464. this.index
  465. ].sn_code_list.find(
  466. (item) => item.sn_code === res.sn_code && item.sku === res.sku
  467. );
  468. if (!exists) {
  469. if (this.id) {
  470. API_GoodsExchange.skuRedis({
  471. send_order_id: this.id, item_id: this.goodsExchangeAddForm.product_list[
  472. this.index
  473. ].id, sku: res
  474. }).then(response => {
  475. this.goodsExchangeAddForm.product_list[this.index].sn_code_list.push(
  476. res
  477. );
  478. })
  479. } else {
  480. this.goodsExchangeAddForm.product_list[this.index].sn_code_list.push(
  481. res
  482. );
  483. }
  484. /* this.goodsExchangeAddForm.product_list[this.index].sn_code_list.push(
  485. res
  486. ); */
  487. }
  488. this.goodsExchangeAddForm.product_list[this.index].out_num = this.goodsExchangeAddForm.product_list[this.index].sn_code_list.length
  489. this.scanGoodsForm.bar_code = "";
  490. this.$nextTick(() => {
  491. this.$refs.input.focus();
  492. });
  493. });
  494. },
  495. addSnCode(row, index) {
  496. this.sku = row.product_vo.sku;
  497. this.index = index;
  498. this.snCodeVisible = true;
  499. },
  500. //获取出库类型字典
  501. outType() {
  502. API_Setting.getPage({ dictType: "out_warehouse_type" }).then((res) => {
  503. this.typeList = res.data
  504. /* .filter((el) => {
  505. if (el.value !== "SALE_OUT" && el.value !== "HAIL_OUT") {
  506. return el;
  507. }
  508. }); */
  509. });
  510. },
  511. /*//商品对应字段
  512. handleSelectionChange(val) {
  513. this.goodsList = val.map((el) => {
  514. el.product_id = el.id;
  515. el.goods_id = el.id;
  516. el.product_name = el.name;
  517. el.product_sn = el.sn;
  518. el.product_specification = el.goods_style;
  519. el.batch_list =
  520. this.goodsExchangeAddForm.order_list[0].order_item_list[0].batch_list;
  521. return el;
  522. });
  523. },
  524. // 保存已选商品
  525. submitGoosData() {
  526. if (this.goodsList.length >= 1) {
  527. this.goodsExchangeAddForm.order_list[0].order_item_list =
  528. this.goodsList;
  529. this.product_list = this.goodsList;
  530. this.goodsVisible = false;
  531. } else {
  532. this.$message.error("请选择商品信息");
  533. }
  534. },
  535. // 关闭商品明细
  536. closeGoosData() {
  537. this.goodsVisible = false;
  538. },*/
  539. // 打印功能
  540. printIng() { },
  541. /* 出库扫码 */
  542. toSearch() {
  543. API_GoodsExchange.getProduct(
  544. this.goodsExchangeAddForm.warehouse_id,
  545. this.scanGoodsForm.bar_code.replace(/\s+/g, '')
  546. ).then((res) => {
  547. res.sn_code_list = []
  548. this.sku = res.product_vo.sku;
  549. // 查找当前商品是否已存在于列表中
  550. const indexs = this.goodsExchangeAddForm.product_list.findIndex((el) => {
  551. console.log("Comparing with:", el);
  552. return (
  553. el.goods_id === res.goods_id &&
  554. el.product_id === res.product_id &&
  555. el.product_vo.sku === res.product_vo.sku
  556. );
  557. });
  558. // 如果商品不存在,则添加到列表
  559. if (indexs === -1) {
  560. this.index = this.goodsExchangeAddForm.product_list.length
  561. this.goodsExchangeAddForm.product_list.push(res);
  562. } else {
  563. this.index = indexs
  564. }
  565. if (res.product_vo.have_sn) {
  566. this.$nextTick(() => {
  567. this.$refs.sn_input.focus();
  568. });
  569. } else {
  570. this.goodsExchangeAddForm.product_list[this.index].num += 1
  571. // this.scanDialogVisible = false;
  572. }
  573. });
  574. },
  575. // 扫码出库
  576. scanCode() {
  577. if (!this.goodsExchangeAddForm.warehouse_id) {
  578. this.$message.error("请先选择仓库!");
  579. return;
  580. }
  581. this.scanDialogVisible = true;
  582. this.$nextTick(() => {
  583. this.$refs.input.focus();
  584. });
  585. },
  586. /** 获取人员列表 */
  587. GET_AdministratorList() {
  588. API_Auth.getAdministratorList({
  589. page_no: 1,
  590. page_size: 9999,
  591. user_state: 0,
  592. }).then((response) => {
  593. this.adminList = response.data;
  594. });
  595. },
  596. /** 清除已选商品明细
  597. cleanGoodsList() {
  598. // 切换部门或仓库需要清除已选对应仓库下的商品数据 change_list
  599. this.goodsExchangeAddForm.order_list[0].order_item_list = [];
  600. this.product_list = [];
  601. },
  602. changewarehouseList(e) {
  603. this.$set(this.goodsExchangeAddForm, "warehouse_id", "");
  604. this.GET_WarehouseList({ dept_id: e });
  605. this.cleanGoodsList();
  606. },
  607. //审核-通过
  608. handlePassGoodsExchange() {
  609. if (this.goodsExchangeAddForm.check_amount_same === false) {
  610. this.$confirm(this.goodsExchangeAddForm.diff_amount_message, "提示", {
  611. type: "warning",
  612. })
  613. .then(() => {
  614. this.$confirm("确定通过吗?", "提示", { type: "warning" })
  615. .then(() => {
  616. API_GoodsExchange.auditGoodsExchange(this.id, {
  617. status: "PASS",
  618. }).then(() => {
  619. this.$message.success("已通过!");
  620. const { callback } = this.$route.params;
  621. if (typeof callback === "function") callback();
  622. this.$store.dispatch("delCurrentViews", {
  623. view: this.$route,
  624. $router: this.$router,
  625. });
  626. this.$router.push({ name: "goodsExchange" });
  627. });
  628. })
  629. .catch(() => {});
  630. })
  631. .catch(() => {});
  632. } else {
  633. this.$confirm("确定通过吗?", "提示", { type: "warning" })
  634. .then(() => {
  635. API_GoodsExchange.auditGoodsExchange(this.id, {
  636. status: "PASS",
  637. }).then(() => {
  638. this.$message.success("已通过!");
  639. const { callback } = this.$route.params;
  640. if (typeof callback === "function") callback();
  641. this.$store.dispatch("delCurrentViews", {
  642. view: this.$route,
  643. $router: this.$router,
  644. });
  645. this.$router.push({ name: "goodsExchange" });
  646. });
  647. })
  648. .catch(() => {});
  649. }
  650. },
  651. // 审核-拒绝
  652. handleRejectGoodsExchange() {
  653. this.$confirm("确定拒绝吗?", "提示", { type: "warning" })
  654. .then(() => {
  655. API_GoodsExchange.auditGoodsExchange(this.id, {
  656. status: "REJECT",
  657. reject_reason: this.goodsExchangeAddForm.reject_reason,
  658. }).then(() => {
  659. this.$message.success("已拒绝!");
  660. this.dialogVisible = false;
  661. const { callback } = this.$route.params;
  662. if (typeof callback === "function") callback();
  663. this.$store.dispatch("delCurrentViews", {
  664. view: this.$route,
  665. $router: this.$router,
  666. });
  667. this.$router.push({ name: "goodsExchange" });
  668. });
  669. })
  670. .catch(() => {});
  671. },*/
  672. /** 获取仓库 */
  673. GET_WarehouseList(e) {
  674. API_BasicSetting.getWarehouseListAll().then((response) => {
  675. this.warehouseList = response;
  676. });
  677. },
  678. //保存
  679. saveGoodsExchangeAddForm() {
  680. this.$refs["goodsExchangeAddForm"].validate((valid) => {
  681. if (valid) {
  682. const { id } = this.goodsExchangeAddForm;
  683. const params = this.MixinClone(this.goodsExchangeAddForm);
  684. //保存类型
  685. params.save_or_submit = "save";
  686. params.warehouse_consignee_id = this.deptListAll.id;
  687. params.out_time = Date.parse(new Date());
  688. params.staff_name = this.goodsExchangeAddForm.distribution_name;
  689. if (params.warehouse_id) {
  690. params.warehouse_name = this.warehouseList.find(
  691. (ware) => ware.id === params.warehouse_id
  692. ).name;
  693. }
  694. if (params.handled_by_id) {
  695. params.handled_by = this.adminList.find(
  696. (admin) => admin.id === params.handled_by_id
  697. ).real_name;
  698. }
  699. params.change_time = Math.floor(params.change_time / 1000);
  700. if (!this.goodsExchangeAddForm.product_list.length) {
  701. return;
  702. }
  703. if (params.type == 'OTHER_OUT' || params.type == 'BORROW_OUT') {
  704. const isStockSufficient = params.product_list.map((el) => {
  705. if (el.out_num < el.usable_stock) {
  706. this.$message.error("该商品库存不足!");
  707. return false
  708. }
  709. return true
  710. });
  711. if (!isStockSufficient) {
  712. return;
  713. }
  714. }
  715. if (this.$route.name === "goodsExchangeEdit") {
  716. API_GoodsExchange.editWarehouseOut(id, params).then((response) => {
  717. this.$message.success("修改成功!");
  718. const { callback } = this.$route.params;
  719. if (typeof callback === "function") callback();
  720. this.$store.dispatch("delCurrentViews", {
  721. view: this.$route,
  722. $router: this.$router,
  723. });
  724. this.$router.push({ name: "goodsExchange" });
  725. });
  726. } else if (this.$route.name === "goodsExchangeAdd") {
  727. // 新增入库
  728. params.product_list.map(el => {
  729. el.product_stock_id = el.id
  730. el.id = ''
  731. })
  732. API_GoodsExchange.warehouseOut(params).then(() => {
  733. this.$message.success("添加成功!");
  734. const { callback } = this.$route.params;
  735. if (typeof callback === "function") callback();
  736. this.$store.dispatch("delCurrentViews", {
  737. view: this.$route,
  738. $router: this.$router,
  739. });
  740. this.$router.push({ name: "goodsExchange" });
  741. });
  742. }
  743. }
  744. });
  745. },
  746. //出库
  747. submitGoodsExchangeAddForm() {
  748. this.$refs["goodsExchangeAddForm"].validate((valid) => {
  749. if (valid) {
  750. const { id } = this.goodsExchangeAddForm;
  751. const params = this.MixinClone(this.goodsExchangeAddForm);
  752. //保存类型
  753. params.save_or_submit = "submit";
  754. params.warehouse_consignee_id = this.deptListAll.id;
  755. params.out_time = Date.parse(new Date());
  756. params.staff_name = this.goodsExchangeAddForm.distribution_name;
  757. if (params.warehouse_id) {
  758. params.warehouse_name = this.warehouseList.find(
  759. (ware) => ware.id === params.warehouse_id
  760. ).name;
  761. }
  762. if (params.handled_by_id) {
  763. params.handled_by = this.adminList.find(
  764. (admin) => admin.id === params.handled_by_id
  765. ).real_name;
  766. }
  767. params.change_time = Math.floor(params.change_time / 1000);
  768. if (!this.goodsExchangeAddForm.product_list.length) {
  769. this.$message.error("请选择商品!");
  770. return;
  771. }
  772. if (params.type == 'OTHER_OUT' || params.type == 'BORROW_OUT') {
  773. const isStockSufficient = params.product_list.map((el) => {
  774. if (el.out_num < el.usable_stock) {
  775. this.$message.error("该商品库存不足!");
  776. return false
  777. }
  778. return true
  779. });
  780. if (!isStockSufficient) {
  781. return;
  782. }
  783. }
  784. if (this.$route.name === "goodsExchangeEdit") {
  785. API_GoodsExchange.editWarehouseOut(id, params).then((response) => {
  786. this.$message.success("修改成功!");
  787. const { callback } = this.$route.params;
  788. if (typeof callback === "function") callback();
  789. this.$store.dispatch("delCurrentViews", {
  790. view: this.$route,
  791. $router: this.$router,
  792. });
  793. this.$router.push({ name: "goodsExchange" });
  794. });
  795. } else if (this.$route.name === "goodsExchangeAdd") {
  796. params.product_list.map(el => {
  797. el.product_stock_id = el.id
  798. el.id = ''
  799. })
  800. // 新增入库
  801. API_GoodsExchange.warehouseOut(params).then(() => {
  802. this.$message.success("添加成功!");
  803. const { callback } = this.$route.params;
  804. if (typeof callback === "function") callback();
  805. this.$store.dispatch("delCurrentViews", {
  806. view: this.$route,
  807. $router: this.$router,
  808. });
  809. this.$router.push({ name: "goodsExchange" });
  810. });
  811. }
  812. }
  813. });
  814. },
  815. // 选择出库单
  816. async handleSelectWarehouseEntryBatch() {
  817. /* API_GoodsExchange.getProductStock().then((res) => {
  818. this.goodsData = res.data;
  819. this.goodsVisible = true;
  820. });*/
  821. if (!this.goodsExchangeAddForm.warehouse_id) {
  822. this.$message.error("请先选择仓库!");
  823. return;
  824. }
  825. const goodsData = await this.$EnwarehouseEntryBatch({
  826. goodsApi: `/admin/erp/warehouseOut/getGoodByWarehouse/${this.goodsExchangeAddForm.warehouse_id}`,
  827. warehouseList: this.warehouseList,
  828. //change_list
  829. selectedIds: this.id
  830. ? this.goodsExchangeAddForm.product_list &&
  831. this.goodsExchangeAddForm.product_list.map((item) => item.id)
  832. : this.goodsExchangeAddForm.product_list.map((item) => item.id),
  833. purchasePlanApiParams: {
  834. warehouse_id: this.goodsExchangeAddForm.warehouse_id,
  835. },
  836. });
  837. goodsData.purchasePlans.map(el => { el.sn_code_list = [] })
  838. this.goodsExchangeAddForm.warehouse_id = goodsData.warehouse_id;
  839. this.goodsExchangeAddForm.product_list = goodsData.purchasePlans;
  840. console.log(this.goodsExchangeAddForm.product_list);/*.map(
  841. (item) => {
  842. //
  843. item.amount = item.entry_price;
  844. item.product_sn = item.product_sn;
  845. item.product_name = item.product_name;
  846. item.specification = item.product_specification;
  847. item.product_id = item.product_id;
  848. item.unit = item.product_unit;
  849. item.stock_sn = item.warehouse_entry_sn;
  850. item.stock_id = item.warehouse_entry_id;
  851. item.stock_batch_sn = item.sn;
  852. item.stock_batch_id = item.id;
  853. item.cost_price = item.product_cost_price;
  854. item.goods_id=item.id
  855. return item;
  856. }
  857. );*/
  858. this.goodsExchangeAddForm.change_amount =
  859. this.goodsExchangeAddForm.product_list.reduce(
  860. (sum, obj) => sum + obj.entry_price,
  861. 0
  862. );
  863. },
  864. /** 选择订单编号 */
  865. async handleSelectOrderSn() {
  866. const orders = await this.$EnPickerOrder({
  867. orderApi: "admin/erp/order",
  868. selectedIds: [this.goodsExchangeAddForm.order_sn],
  869. limit: 1,
  870. });
  871. this.$set(
  872. this.goodsExchangeAddForm,
  873. "distribution_name",
  874. orders[0].distribution_name
  875. );
  876. const orderIds = orders.map((v) => v.sn);
  877. this.$set(this.goodsExchangeAddForm, "order_sn", orderIds.join(","));
  878. this.GET_WarehouseOutProduct();
  879. },
  880. /** 获取出库单商品明细 */
  881. async GET_WarehouseOutProduct() {
  882. const res = await API_Erp.getWarehouseOutProduct({
  883. order_sn: this.goodsExchangeAddForm.order_sn,
  884. });
  885. this.goodsExchangeAddForm.return_list = res.data.map((item) => {
  886. item.amount = item.product_price;
  887. item.product_sn = item.product_sn;
  888. item.product_name = item.product_name;
  889. item.specification = item.product_specification;
  890. item.product_id = item.product_id;
  891. item.unit = item.product_unit;
  892. item.out_num = item.return_num;
  893. item.stock_sn = item.warehouse_entry_sn;
  894. item.cost_price = item.product_cost_price;
  895. return item;
  896. });
  897. },
  898. /** 获取仓库 */
  899. GET_DeptList() {
  900. API_GoodsExchange.getInfo().then((response) => {
  901. this.deptListAll = response;
  902. this.deptListAll.password = "";
  903. });
  904. },
  905. /** 切换仓库 */
  906. handleChangeWareHouse(val) {
  907. //this.goodsExchangeAddForm.product_list = []change_list
  908. },
  909. /** 获取详情页面数据 */
  910. GET_goodsExchangeAddDetail() {
  911. this.$nextTick(() => {
  912. API_GoodsExchange.getGoodsWarehouseOut(this.id).then((response) => {
  913. this.goodsExchangeAddForm = response;
  914. this.GET_WarehouseList({ dept_id: response.warehouse_id });
  915. this.goodsExchangeAddForm.change_time = Math.floor(
  916. this.goodsExchangeAddForm.change_time * 1000
  917. );
  918. /* 获取缓存数据 */
  919. API_GoodsExchange.skuRedis({ send_order_id: this.id, type: 'enter' }).then(response => {
  920. response.product_list.map(el => {
  921. el.order_num = el.out_num
  922. el.out_num = 0
  923. Object.keys(response).map(item => {
  924. if (el.id == item) {
  925. el.sn_code_list = response[item]
  926. el.num = el.sn_code_list.length
  927. }
  928. })
  929. if (!el.sn_code_list) {
  930. el.sn_code_list = []
  931. }
  932. })
  933. })
  934. this.goodsExchangeAddForm.distribution_name = response.staff_name;
  935. this.goodsExchangeAddForm.product_list =
  936. response.product_list; /*.map((item) => {
  937. item.name=item.goods_vo.name
  938. item.sn=item.goods_vo.sn
  939. item.sn_code=item.goods_vo.sn_code
  940. item.bar_code=item.goods_vo.bar_code
  941. item.entry_price = item.amount;
  942. item.product_specification = item.specification;
  943. item.product_unit = item.unit;
  944. item.warehouse_entry_sn = item.stock_sn;
  945. item.usable_stock=item.goods_vo.usable_stock
  946. return item;
  947. });
  948. this.goodsExchangeAddForm.return_list = response.return_list.map(
  949. (item) => {
  950. item.product_price = item.amount;
  951. item.product_specification = item.specification;
  952. item.product_unit = item.unit;
  953. item.return_num = item.out_num;
  954. item.warehouse_entry_sn = item.stock_sn;
  955. return item;
  956. }
  957. ); */
  958. // this.GET_WarehouseOutProduct()
  959. });
  960. });
  961. },
  962. },
  963. };
  964. </script>
  965. <style type="text/scss" lang="scss" scoped>
  966. /** 底部步骤 */
  967. .footer {
  968. width: 100%;
  969. padding: 10px;
  970. bottom: 0px;
  971. text-align: center;
  972. z-index: 999;
  973. }
  974. .mx {
  975. display: flex;
  976. align-items: center;
  977. width: 100%;
  978. .button {
  979. margin-left: 10px;
  980. }
  981. }
  982. .change-form {
  983. display: flex;
  984. justify-content: flex-start;
  985. align-items: flex-start;
  986. flex-wrap: wrap;
  987. min-width: 900px;
  988. .change-form-item {
  989. width: 30%;
  990. margin: 0 10px 20px 0;
  991. display: flex;
  992. flex-direction: row;
  993. flex-wrap: nowrap;
  994. }
  995. /deep/ {
  996. .el-form-item__content {
  997. flex: 1;
  998. width: 100%;
  999. }
  1000. .el-date-editor,
  1001. .el-cascader,
  1002. .el-select {
  1003. width: 100%;
  1004. }
  1005. }
  1006. }
  1007. .bg-in-stock {
  1008. background-color: #fff;
  1009. margin: 10px;
  1010. padding: 25px;
  1011. }
  1012. .goods-info {
  1013. display: flex;
  1014. .goods-name-box {
  1015. text-align: left;
  1016. .goods-name {
  1017. text-overflow: ellipsis;
  1018. display: -webkit-box;
  1019. -webkit-line-clamp: 2;
  1020. -webkit-box-orient: vertical;
  1021. overflow: hidden;
  1022. line-height: 16px;
  1023. }
  1024. .specs {
  1025. color: #999999;
  1026. }
  1027. }
  1028. }
  1029. .sn-code-container {
  1030. max-height: 100px;
  1031. /* 设置最大高度,超过这个高度将显示滚动条 */
  1032. overflow-y: auto;
  1033. /* 垂直方向上溢出时显示滚动条 */
  1034. }
  1035. /deep/ {
  1036. .el-input--suffix .el-input__inner {
  1037. padding-right: 10px;
  1038. }
  1039. .error-input {
  1040. .el-input__inner {
  1041. border: 1px solid red;
  1042. }
  1043. }
  1044. }
  1045. </style>