mlchen пре 6 дана
родитељ
комит
f5861f7d99

+ 157 - 14
src/views/bpm/outgoingManagement/components/AssetsDialog.vue

@@ -14,6 +14,7 @@
                 style="width: 100%"
                 @change="changeDimensionHandler"
                 v-model="dimension"
+                :disabled="bizType === 10 && !hasMixedReturnSources()"
                 placeholder="请选择"
               >
                 <!-- <el-option label="物料维度" value="4"> </el-option> -->
@@ -195,14 +196,7 @@
             width="55"
             align="center"
             fixed="left"
-            :selectable="
-              (row) => {
-                return (
-                  !this.productLists.some((it) => it.id == row.id) &&
-                  this.getAvailableQuantity(row) > 0
-                );
-              }
-            "
+            :selectable="(row) => this.canSelectBatch(row)"
           >
           </el-table-column>
           <el-table-column label="序号" type="index" width="50" fixed="left">
@@ -416,7 +410,9 @@
   export default {
     components: { AssetTree },
     props: {
-      treeIds: { type: Array, default: () => [] }
+      treeIds: { type: Array, default: () => [] },
+      returnProductList: { type: Array, default: () => [] },
+      bizType: { type: Number, default: null }
     },
     data() {
       return {
@@ -498,6 +494,48 @@
           Math.round((inventoryBalance - lockQuantity) * 100) / 100
         );
       },
+      canSelectBatch(row) {
+        if (this.bizType !== 10) {
+          return (
+            !this.productLists.some((item) => item.id == row.id) &&
+            this.getAvailableQuantity(row) > 0
+          );
+        }
+        if (this.dimension == 3) {
+          return this.returnPackages().some((source) => this.matchesReturnPackage(source, row))
+            && this.getAvailableQuantity(row) > 0
+            && !this.productLists.some((item) => (item.outInDetailRecordRequestList || [])
+              .some((record) => record.packageNo === row.packageNo));
+        }
+        const source = this.returnProductList.find((item) =>
+          !(item.packageSources || []).length && this.matchesReturnProduct(item, row));
+        return !!source && this.getAvailableQuantity(row) > 0;
+      },
+      hasMixedReturnSources() {
+        return this.returnPackages().length > 0 && this.returnProductList.some(
+          (product) => !(product.packageSources || []).length
+        );
+      },
+      returnPackages() {
+        return this.returnProductList.flatMap((product) =>
+          (product.packageSources || []).map((source) => ({ ...source, product }))
+        );
+      },
+      matchesReturnPackage(source, row) {
+        return String(source.packageNo) === String(row.packageNo)
+          && String(source.product.productId) === String(row.categoryId)
+          && String(source.product.receiveProductId) === String(row.sourceReceiveProductId)
+          && String(source.product.warehouseId) === String(row.warehouseId)
+          && String(source.product.batchNo || '') === String(row.batchNo || '')
+          && String(source.product.systemBatchNo || '') === String(row.systemBatchNo || '');
+      },
+      matchesReturnProduct(product, row) {
+        return String(product.productId) === String(row.categoryId)
+          && String(product.receiveProductId) === String(row.sourceReceiveProductId)
+          && String(product.warehouseId) === String(row.warehouseId)
+          && String(product.batchNo || '') === String(row.batchNo || '')
+          && String(product.systemBatchNo || '') === String(row.systemBatchNo || '');
+      },
       formatMeasureQuantity(row) {
         return this.dimension == 2
           ? this.getAvailableQuantity(row)
@@ -591,7 +629,18 @@
           this.total = data.count;
         } else if (this.dimension == 2) {
           // 批次维度
-          const data = await storageApi.getBatchList(this.searchForm);
+          const legacyProducts = this.returnProductList.filter((item) => !(item.packageSources || []).length);
+          const receiveProductIds = legacyProducts.map((item) => item.receiveProductId).filter(Boolean);
+          if (this.bizType === 10 && receiveProductIds.length !== legacyProducts.length) {
+            this.tableData = [];
+            this.total = 0;
+            this.$message.error('退货产品缺少采购收货明细,无法查询不良库存');
+            return;
+          }
+          const params = this.bizType === 10
+            ? { ...this.searchForm, sourceReceiveProductIds: receiveProductIds.join(','), result: 2 }
+            : this.searchForm;
+          const data = await storageApi.getBatchList(params);
           for (let i = 0; i < data.list.length; i++) {
             data.list[i].outboundNum = this.getAvailableQuantity(data.list[i]);
           }
@@ -604,9 +653,18 @@
           this.total = data.count;
         } else {
           // 包装维度
-          const data = await storageApi.getPackingList(this.searchForm);
+          const packageSources = this.returnPackages();
+          const params = this.bizType === 10
+            ? { ...this.searchForm,
+                ...(packageSources.length ? {
+                  packageNos: [...new Set(packageSources.map((source) => source.packageNo))].join(','),
+                  sourceReceiveProductIds: [...new Set(packageSources.map((source) => source.product.receiveProductId))].join(',')
+                } : {}),
+                result: 2 }
+            : this.searchForm;
+          const data = await storageApi.getPackingList(params);
           for (let i = 0; i < data.list.length; i++) {
-            data.list[i].outboundNum = data.list[i].packingQuantity;
+            data.list[i].outboundNum = data.list[i].measureQuantity;
           }
           this.tableData = data.list;
           this.total = data.count;
@@ -638,6 +696,20 @@
         } else {
           for (let i = 0; i < list.length; i++) {
             const item = list[i];
+            if (this.dimension == 2 && this.bizType === 10) {
+              const returnProduct = this.returnProductList.find((product) => this.matchesReturnProduct(product, item));
+              if (returnProduct) {
+                this.$set(
+                  item,
+                  'outboundNum',
+                  Math.min(
+                    Number(returnProduct.totalCount) || 0,
+                    this.getAvailableQuantity(item)
+                  )
+                );
+                continue;
+              }
+            }
             const matchedProduct = this.productLists.find((product) => {
               const isMatch = product.id === item.id;
               return isMatch;
@@ -657,6 +729,9 @@
       },
       open(val) {
         this.productLists = val || [];
+        if (this.bizType === 10) {
+          this.dimension = this.returnPackages().length ? '3' : '2';
+        }
         this.visible = true;
         this.$nextTick(() => {
           this.$refs.treeList.getTreeData().then(async (data) => {
@@ -676,16 +751,74 @@
             return;
           }
         }
+        if (this.bizType === 10) {
+          if (!this.hasMixedReturnSources() && this.dimension != (this.returnPackages().length ? 3 : 2)) {
+            this.$message.error('采购退货库存选择维度不正确!');
+            return;
+          }
+          const invalidBatch = this.selectionList.some((item) =>
+            this.dimension == 3
+              ? !this.returnPackages().some((source) => this.matchesReturnPackage(source, item))
+              : !this.returnProductList.some((source) =>
+                  !(source.packageSources || []).length && this.matchesReturnProduct(source, item)));
+          if (invalidBatch) {
+            this.$message.error('所选批次与采购退货来源批次不一致!');
+            return;
+          }
+          const exceededReturn = this.dimension == 3
+            ? this.selectionList.some((item) => {
+                const quantity = this.returnPackages()
+                  .filter((source) => this.matchesReturnPackage(source, item))
+                  .reduce((sum, source) => sum + Number(source.measureQuantity || 0), 0);
+                return quantity <= 0 || quantity > this.getAvailableQuantity(item);
+              })
+            : this.selectionList.some((item) => {
+            const source = this.returnProductList.find((product) =>
+              !(product.packageSources || []).length && this.matchesReturnProduct(product, item));
+            return (
+              !source ||
+              Number(item.outboundNum) <= 0 ||
+              Number(item.outboundNum) > Number(source.totalCount) ||
+              Number(item.outboundNum) > this.getAvailableQuantity(item)
+            );
+          });
+          if (exceededReturn) {
+            this.$message.error('出库数量不能超过采购退货数量!');
+            return;
+          }
+        }
         console.log(this.selectionList);
         let data = null;
         if (this.dimension == 3) {
           data = await storageApi.getHierarchyList({
             ids: this.selectionList.map((item) => item.id).join(','),
-            type: this.dimension
+            type: this.dimension,
+            result: this.bizType === 10 ? 2 : null
           });
+          if (this.bizType === 10) {
+            data.forEach((detail) => {
+              detail.outInDetailRecordRequestList.forEach((record) => {
+                const sources = this.returnPackages().filter((source) =>
+                  this.matchesReturnPackage(source, { ...detail, ...record,
+                    sourceReceiveProductId: detail.sourceReceiveProductId }));
+                const quantity = sources.reduce((sum, source) => sum + Number(source.measureQuantity || 0), 0);
+                const originalQuantity = Number(record.measureQuantity);
+                record.measureQuantity = quantity;
+                record.weight = originalQuantity > 0
+                  ? Number(record.weight || 0) * quantity / originalQuantity
+                  : 0;
+              });
+              detail.measureQuantity = detail.outInDetailRecordRequestList
+                .reduce((sum, record) => sum + Number(record.measureQuantity), 0);
+              detail.weight = detail.outInDetailRecordRequestList
+                .reduce((sum, record) => sum + Number(record.weight || 0), 0);
+            });
+          }
         } else if (this.dimension == 2) {
+          const returnProducts = this.returnProductList;
           data = await storageApi.getHierarchyFifo({
             type: this.dimension,
+            result: this.bizType === 10 ? 2 : null,
             ids: this.selectionList.map((item) => item.id),
             builders: this.selectionList.map((item) => {
               return {
@@ -693,7 +826,17 @@
                 batchNo: item.batchNo,
                 // 历史数据保持空值,由后端按外部批次号兼容匹配
                 systemBatchNo: item.systemBatchNo || '',
-                num: item.outboundNum,
+                warehouseId: item.warehouseId,
+                num:
+                  this.bizType === 10
+                    ? Math.min(
+                        Number(item.outboundNum),
+                        Number(
+                          returnProducts.find((product) =>
+                            !(product.packageSources || []).length && this.matchesReturnProduct(product, item))?.totalCount || 0
+                        )
+                      )
+                    : item.outboundNum,
                 id: item.id
               };
             })

+ 6 - 1
src/views/bpm/outgoingManagement/outbound.vue

@@ -393,7 +393,8 @@
       ref="assetsDialogRef"
       :treeIds="formData.extInfo?.assetType"
       @detailData="detailData"
-      :productLists="this.productList"
+      :returnProductList="bizType == 10 ? form.productList || [] : []"
+      :bizType="bizType"
     />
   </div>
 </template>
@@ -1287,6 +1288,10 @@
             });
           return;
         }
+        //采购退货按收货明细选择不良库存,不使用普通物品先进先出预填。
+        if (this.bizType == 10) {
+          return;
+        }
         //采购委外
         if (this.form.productList?.length > 0) {
           this.getStaffList({ id: this.form.deptId }).then(() => {