瀏覽代碼

创建补货单

lilei 2 年之前
父節點
當前提交
7fbda3a705

+ 1 - 1
public/version.json

@@ -1,5 +1,5 @@
 {
   "message": "发现有新版本发布,确定更新系统?",
   "vendorJsVersion": "",
-  "version": 1667801610481
+  "version": 1667980444347
 }

+ 16 - 0
src/api/shelf.js

@@ -19,6 +19,22 @@ export const shelfDetail = (params) => {
     method: 'post'
   })
 }
+//待补货产品列表
+export const queryListForReplenish = (params) => {
+  return axios({
+    url: `/shelf/queryListForReplenish`,
+    data: params,
+    method: 'post'
+  })
+}
+// 补货产品明细
+export const queryProductListForReplenish = (params) => {
+  return axios({
+    url: `/shelf/queryProductListForReplenish `,
+    data: params,
+    method: 'post'
+  })
+}
 //  货架  保存
 export const shelfSave = (params) => {
   return axios({

+ 23 - 0
src/api/shelfReplenish.js

@@ -34,6 +34,14 @@ export const shelfReplenishDetailList = (params) => {
     method: 'post'
   })
 }
+// 保存补货单和明细
+export const saveMainAndDetail = (params) => {
+  return axios({
+    url: '/shelfReplenish/saveMainAndDetail',
+    data: params,
+    method: 'post'
+  })
+}
 // 出库单详情列表
 export const queryListForOutStock = (params) => {
   return axios({
@@ -42,6 +50,21 @@ export const queryListForOutStock = (params) => {
     method: 'post'
   })
 }
+// 查询关联的销售单
+export const queryRelationSalesBill = (params) => {
+  return axios({
+    url: `/shelfReplenish/queryRelationSalesBill/${params.replenishBillSn}`,
+    method: 'get'
+  })
+}
+// 生成销售单
+export const createSalesBill = (params) => {
+  return axios({
+    url: `/shelfReplenish/createSalesBill/${params.replenishBillSn}`,
+    data: params,
+    method: 'post'
+  })
+}
 //  补货单 取消补货单
 export const shelfReplenishCancel = (params) => {
   return axios({

+ 5 - 2
src/views/common/commonModal.vue

@@ -13,7 +13,7 @@
       <div class="common-main" v-html="modalHtml"></div>
       <slot></slot>
       <div class="btn-box">
-        <a-button type="primary" class="button-warning" @click="handleCommonCancel" v-if="isCancel">{{ cancelText }}</a-button>
+        <a-button type="default" class="button-warning" @click="handleCommonCancel" v-if="isCancel">{{ cancelText }}</a-button>
         <a-button type="primary" class="button-info" @click="handleCommonOk">{{ okText }}</a-button>
       </div>
     </a-spin>
@@ -107,7 +107,10 @@ export default {
     }
     .btn-box{
       text-align: center;
-      margin-top: 20px;
+      margin-top: 40px;
+      button{
+        margin: 0 10px;
+      }
     }
   }
 </style>

+ 105 - 37
src/views/numsGoodsShelves/replenishmentManagement/creatReplenishmentOrder.vue

@@ -23,7 +23,7 @@
                 <a-input id="chooseShelf-code" ref="searchProductCode" v-model.trim="queryParam.productCode" allowClear placeholder="请输入产品编码"/>
               </a-form-model-item>
             </a-col>
-            <a-col :md="8" :sm="24">
+            <a-col :md="6" :sm="24">
               <a-form-model-item label="产品名称">
                 <a-input id="chooseShelf-name" v-model.trim="queryParam.productName" allowClear placeholder="请输入产品名称"/>
               </a-form-model-item>
@@ -43,11 +43,11 @@
       <div>
         <div class="table-operator">
           <div>
-            <a-button type="primary" class="button-error" @click="handleSave">创建补货单</a-button>
-            <span v-if="selectTotal">已选{{ selectTotal }}款产品,共15件</span>
+            <a-button type="primary" @click="handleSave">创建补货单</a-button>
+            <span style="margin-left:20px;">已选{{ totalCategory }}款产品,共{{ totalQty }}件</span>
           </div>
           <div style="margin-left:20px;">
-            <a-checkbox>
+            <a-checkbox @change="changeShowChecked">
               仅显示已选产品
             </a-checkbox>
           </div>
@@ -63,9 +63,17 @@
           :columns="columns"
           :data="loadData"
           :scroll="{ y: 450 }"
-          :defaultLoadData="false"
           :showPagination="false"
           bordered>
+          <template slot="action" slot-scope="text, record">
+            <a-input-number
+              size="small"
+              v-model="record.replenishQty"
+              :precision="0"
+              :min="1"
+              placeholder="请输入"
+              style="width: 100%" />
+          </template>
         </s-table>
       </div>
     </a-spin>
@@ -75,9 +83,10 @@
 <script>
 import { commonMixin } from '@/utils/mixin'
 import { STable, VSelect } from '@/components'
-import { shelfReplenishList, shelfTaskInsertBill } from '@/api/shelfReplenish'
+import { queryProductListForReplenish } from '@/api/shelf'
+import { saveMainAndDetail } from '@/api/shelfReplenish'
 export default {
-  name: 'ConfirmModal',
+  name: 'CreatReplenishmentOrder',
   components: { STable, VSelect },
   mixins: [commonMixin],
   props: {
@@ -94,25 +103,35 @@ export default {
   },
   computed: {
     modalTit () {
-      const hjName = this.nowData && this.nowData.shelfInfo.shelfName ? this.nowData.shelfInfo.shelfName : ''
+      const hjName = this.nowData ? this.nowData.shelfName : ''
       return '待补货产品 —— ' + hjName
     },
     columns () {
       const arr = [
         { title: '序号', dataIndex: 'no', width: '4%', align: 'center' },
-        { title: '库存批次', dataIndex: 'stockBatchNo', width: '20%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '入库类型', dataIndex: 'putBizTypeDictValue', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '仓库', dataIndex: 'warehouseName', width: '15%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
-        { title: '仓位', dataIndex: 'warehouseLocationName', width: '15%', align: 'center', customRender: function (text) { return text || '--' }, ellipsis: true },
-        // { title: '成本价', dataIndex: 'putCost', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '本次出库数量', dataIndex: 'outQty', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
-        // { title: '成本小计', dataIndex: 'totalCost', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } }
+        { title: '货位号', dataIndex: 'shelfPlaceCode', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品编码', dataIndex: 'productCode', width: '12%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '产品名称', dataIndex: 'productName', width: '18%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
+        { title: '最大库容', dataIndex: 'maxQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '货架库存', dataIndex: 'qty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '补货在途', dataIndex: 'replenishBillQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '调回在途', dataIndex: 'recallBillQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '待补货数量', dataIndex: 'replenishBillWaitQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '门店库存数量', dataIndex: 'qplsStockQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '单位', dataIndex: 'productUnit', width: '10%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '本次补货数量', scopedSlots: { customRender: 'action' }, width: '10%', align: 'center' }
       ]
-      if (this.$hasPermissions('M_ShowAllCost')) {
-        arr.splice(5, 0, { title: '成本价', dataIndex: 'putCost', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } })
-        arr.splice(7, 0, { title: '成本小计', dataIndex: 'totalCost', width: '10%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } })
-      }
       return arr
+    },
+    totalCategory () {
+      return this.rowSelectionInfo && this.rowSelectionInfo.selectedRows.length
+    },
+    totalQty () {
+      let ret = 0
+      this.rowSelectionInfo && this.rowSelectionInfo.selectedRows.map(item => {
+        ret = ret + item.replenishQty
+      })
+      return ret
     }
   },
   data () {
@@ -120,51 +139,96 @@ export default {
       spinning: false,
       isShow: this.openModal, //  是否打开弹框
       options: [
-        { label: '库存充足', value: '1' },
-        { label: '部分缺货', value: '2' },
-        { label: '全部缺货', value: '3' }
+        { label: '库存充足', value: 'stockEnough' },
+        { label: '部分缺货', value: 'portionStockout' },
+        { label: '全部缺货', value: 'allStockout' }
       ],
       queryParam: {
         productCode: '', //  产品编码
-        productName: '' //  产品名称
+        productName: '', //  产品名称
+        stockStateList: []
       },
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
         this.spinning = true
-        return shelfReplenishList(Object.assign(parameter, this.queryParam)).then(res => {
+        this.disabled = true
+        this.queryParam.shelfSn = this.nowData.shelfSn
+        return queryProductListForReplenish(this.queryParam).then(res => {
           let data
           if (res.status == 200) {
-            data = res.data.list
-            const no = 0
+            data = res.data
+            if (this.showChecked) {
+              data = this.rowSelectionInfo && this.rowSelectionInfo.selectedRows || []
+            }
             for (var i = 0; i < data.length; i++) {
-              data[i].no = no + i + 1
+              data[i].no = i + 1
+              data[i].replenishQty = data[i].replenishBillWaitQty || 1
             }
+            this.disabled = false
           }
           this.spinning = false
           return data
         })
       },
-      rowSelectionInfo: null
+      rowSelectionInfo: null,
+      showChecked: false
     }
   },
   methods: {
     onStockChange (val) {
-      console.log(val)
+      this.queryParam.stockStateList = val
+    },
+    // 显示已选产品
+    changeShowChecked (e) {
+      this.showChecked = e.target.checked
+      this.$refs.table.refresh(true)
     },
     // 表格选中项
     rowSelectionFun (obj) {
       this.rowSelectionInfo = obj || null
     },
+    // 重置
+    resetSearchForm () {
+      this.queryParam = {
+        productCode: '', //  产品编码
+        productName: '', //  产品名称
+        stockStateList: []
+      }
+      this.showChecked = false
+      this.$refs.table.clearSelected()
+      this.$refs.table.refresh(true)
+    },
     //  确认补货
     handleSave () {
-      this.spinning = true
-      shelfTaskInsertBill(this.targetKeys).then(res => {
-        if (res.status == 200) {
-          this.$message.success(res.message)
-          this.$emit('ok')
-        }
-        this.spinning = false
-      })
+      if (this.totalCategory) {
+        const data = this.rowSelectionInfo && this.rowSelectionInfo.selectedRows || []
+        const dataList = []
+        data.map(item => {
+          dataList.push({
+            shelfPlaceSn: item.shelfPlaceSn,
+            shelfPlaceCode: item.shelfPlaceCode,
+            productSn: item.productSn,
+            productCode: item.productCode,
+            qty: item.replenishQty
+          })
+        })
+        // 开始提交
+        this.spinning = true
+        saveMainAndDetail({
+          shelfSn: this.nowData.shelfSn,
+          dealerSn: this.nowData.dealerSn,
+          detailList: dataList
+        }).then(res => {
+          if (res.status == 200) {
+            this.$message.success(res.message)
+            this.$emit('ok')
+            this.$emit('close')
+          }
+          this.spinning = false
+        })
+      } else {
+        this.$message.info('请选择产品')
+      }
     }
   },
   watch: {
@@ -176,6 +240,10 @@ export default {
     isShow (newValue, oldValue) {
       if (!newValue) {
         this.$emit('close')
+      } else {
+        this.$nextTick(() => {
+          this.resetSearchForm()
+        })
       }
     }
   }

+ 45 - 5
src/views/numsGoodsShelves/replenishmentManagement/detailModal.vue

@@ -20,8 +20,8 @@
             <a-descriptions-item label="签收时间">{{ detailData&&detailData.putStockTime || '--' }}</a-descriptions-item>
             <a-descriptions-item label="出库备注">{{ detailData&&detailData.remarks || '--' }}</a-descriptions-item>
             <a-descriptions-item label="关联销售单" :span="3" v-if="detailData.billState=='WAIT_CHECK' || detailData.billState=='WAIT_OUT_STOCK' || detailData.billState=='FINISH'">
-              <a-button type="link" class="button-info">XS234234234;</a-button>
-              <a-button type="primary" class="button-info">生成销售单</a-button>
+              <a-button type="link" class="button-info" v-for="item in salesOrderList" :key="item.id">{{ item.orderNo }};</a-button>
+              <a-button type="primary" class="button-info" @click="showPlModal=true">生成销售单</a-button>
             </a-descriptions-item>
           </a-descriptions>
         </div>
@@ -44,16 +44,37 @@
     <div class="btn-cont">
       <a-button @click="isShow = false">关闭</a-button>
     </div>
+    <!-- 生成销售单 -->
+    <commonModal modalTit="" :openModal="showPlModal" @close="showPlModal=false" @ok="createSales">
+      <div style="display: flex;justify-content: center;margin-bottom: 15px;">
+        <div style="padding:5px 20px;">产品款数:<span style="color:red;">9</span></div>
+        <div style="padding:5px 20px;">产品总件数:<span style="color:red;">12</span></div>
+      </div>
+      <div style="text-align: center;" v-if="salesOrderList.length">
+        <div style="margin-bottom: 5px;font-size: 14px;">此补货单已经存在对应的销售单</div>
+        <div style="margin-bottom: 15px;font-size: 14px;"><strong>确认再次生成销售单吗?</strong></div>
+        <div style="line-height: 24px;">
+          <div style="padding:5px;border-bottom: 1px solid #eee;color:#00aaff;display: flex;justify-content: space-between;align-items: center;" v-for="item in salesOrderList" :key="item.id">
+            <div class="flex-grow:1;padding:0 5px;">{{ item.orderNo }};</div>
+            <div class="padding:0 5px;"><a-icon type="right" style="color:#00aaff;" /></div>
+          </div>
+        </div>
+      </div>
+      <div style="text-align: center;" v-else>
+        <div style="margin-bottom: 15px;font-size: 14px;"><strong>确认生成销售单吗?</strong></div>
+      </div>
+    </commonModal>
   </a-modal>
 </template>
 
 <script>
 import { commonMixin } from '@/utils/mixin'
 import { STable, VSelect } from '@/components'
-import { shelfReplenishDetailList, shelfReplenishDetail } from '@/api/shelfReplenish'
+import commonModal from '@/views/common/commonModal.vue'
+import { shelfReplenishDetailList, shelfReplenishDetail, queryRelationSalesBill, createSalesBill } from '@/api/shelfReplenish'
 export default {
   name: 'DetailModal',
-  components: { STable, VSelect },
+  components: { STable, VSelect, commonModal },
   mixins: [commonMixin],
   props: {
     openModal: { //  弹框显示状态
@@ -72,6 +93,7 @@ export default {
       isShow: this.openModal, //  是否打开弹框
       spinning: false,
       disabled: false,
+      showPlModal: false,
       // 表头
       columns: [
         { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
@@ -100,7 +122,8 @@ export default {
         })
       },
       localDataSource: [],
-      detailData: null //  详情数据
+      detailData: null, //  详情数据
+      salesOrderList: []
     }
   },
   computed: {
@@ -120,11 +143,28 @@ export default {
         }
       })
     },
+    // 查询关联销售单
+    getSalesOrder () {
+      queryRelationSalesBill({ replenishBillSn: this.nowData.replenishBillSn }).then(res => {
+        if (res.status == 200) {
+          this.salesOrderList = res.data
+        } else {
+          this.salesOrderList = []
+        }
+      })
+    },
+    // 生成销售单
+    createSales () {
+      createSalesBill().then(res => {
+
+      })
+    },
     pageInit () {
       const vm = this
       vm.$nextTick(() => {
         vm.spinning = false
         vm.disabled = false
+        vm.getSalesOrder()
         vm.getDetail()
       })
     }

+ 3 - 3
src/views/numsGoodsShelves/replenishmentManagement/list.vue

@@ -162,9 +162,9 @@ export default {
         { title: '补货单号', dataIndex: 'replenishBillNo', scopedSlots: { customRender: 'replenishBillNo' }, width: '15%', align: 'center' },
         { title: '货架名称', dataIndex: 'shelfInfo.shelfName', width: '25%', align: 'left', customRender: function (text) { return text || '--' }, ellipsis: true },
         { title: '状态', dataIndex: 'billStateDictValue', width: '8%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '补货总量', dataIndex: 'totalConfirmQty', width: '7%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '签收总量', dataIndex: 'totalPutQty', width: '7%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '操作', scopedSlots: { customRender: 'action' }, width: '17%', align: 'left' }
+        { title: '补货总量', dataIndex: 'totalConfirmQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '签收总量', dataIndex: 'totalPutQty', width: '8%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
+        { title: '操作', scopedSlots: { customRender: 'action' }, width: '16%', align: 'left' }
       ],
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {

+ 26 - 13
src/views/numsGoodsShelves/replenishmentManagement/slodOutModal.vue

@@ -37,7 +37,11 @@
             :columns="columns"
             :data="loadData"
             :scroll="{ y: 400 }"
+            :showPagination="false"
             bordered>
+            <template slot="shelfName" slot-scope="text, record">
+              {{ text }}<span style="color:#ff5500;margin-left:5px;" v-if="record.state!=='ENABLE'">(状态为“已暂停”)</span>
+            </template>
             <template slot="action" slot-scope="text, record">
               <span class="table-td-link" @click.stop="handleDetail(record)">产品明细</span>
             </template>
@@ -54,7 +58,7 @@
 import { commonMixin } from '@/utils/mixin'
 import { STable, VSelect } from '@/components'
 import shelfSList from '@/views/common/shelfList'
-import { shelfReplenishList } from '@/api/shelfReplenish'
+import { queryListForReplenish } from '@/api/shelf'
 import creatReplenishmentOrder from './creatReplenishmentOrder.vue'
 export default {
   name: 'SlodOutModal',
@@ -77,26 +81,31 @@ export default {
       },
       // 表头
       columns: [
-        { title: '序号', dataIndex: 'no', width: '5%', align: 'center' },
-        { title: '货架名称', dataIndex: 'shelfInfo.shelfName', width: '35%', align: 'center', customRender: function (text) { return text || '--' } },
-        { title: '待补产品款数', dataIndex: 'totalConfirmQty', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '待补产品数量', dataIndex: 'totalPutQty', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') } },
-        { title: '最近一次补货时间', dataIndex: 'createDate', width: '15%', align: 'center', customRender: function (text) { return text || '--' } },
+        { title: '序号', dataIndex: 'no', width: '5%', align: 'center', customRender: function (text) { return text } },
+        { title: '货架名称', dataIndex: 'shelfName', scopedSlots: { customRender: 'shelfName' }, width: '35%', align: 'left' },
+        { title: '待补产品款数', dataIndex: 'productCategory', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') }, sorter: true },
+        { title: '待补产品数量', dataIndex: 'productQty', width: '15%', align: 'center', customRender: function (text) { return ((text || text == 0) ? text : '--') }, sorter: true },
+        { title: '最近一次补货时间', dataIndex: 'lastDate', width: '15%', align: 'center', customRender: function (text) { return text || '--' }, sorter: true },
         { title: '操作', scopedSlots: { customRender: 'action' }, width: '15%', align: 'center' }
       ],
       // 加载数据方法 必须为 Promise 对象
       loadData: parameter => {
         this.disabled = true
         this.spinning = true
-        return shelfReplenishList(Object.assign(parameter, this.queryParam)).then(res => {
+        if (parameter.sortOrder) {
+          this.queryParam.queryWord = parameter.sortField
+          this.queryParam.orderBy = parameter.sortOrder == 'ascend' ? 'ASC' : 'DESC'
+        } else {
+          this.queryParam.queryWord = undefined
+          this.queryParam.orderBy = undefined
+        }
+        return queryListForReplenish(this.queryParam).then(res => {
           let data
           if (res.status == 200) {
             data = res.data
-            const no = (data.pageNo - 1) * data.pageSize
-            for (var i = 0; i < data.list.length; i++) {
-              data.list[i].no = no + i + 1
+            for (var i = 0; i < data.length; i++) {
+              data[i].no = i + 1
             }
-            this.listData = data.list || []
             this.disabled = false
           }
           this.spinning = false
@@ -115,8 +124,12 @@ export default {
       this.$refs.table.refresh(true)
     },
     handleDetail (row) {
-      this.nowData = row
-      this.openCreatRoModal = true
+      if (row.productCategory) {
+        this.nowData = row
+        this.openCreatRoModal = true
+      } else {
+        this.$message.info('此货架没有待补货产品')
+      }
     },
     pageInit () {
       const vm = this

+ 2 - 2
vue.config.js

@@ -211,8 +211,8 @@ const vueConfig = {
     // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
     proxy: {
       '/api': {
-        // target: 'http://192.168.0.103:8503/qpls-md',
-        target: 'http://p.iscm.360arrow.com/qpls-md',
+        target: 'http://192.168.0.182:8503/qpls-md',
+        // target: 'http://p.iscm.360arrow.com/qpls-md',
         // ws: false,
         ws: true,
         changeOrigin: true,