|
@@ -14,6 +14,7 @@
|
|
|
style="width: 100%"
|
|
style="width: 100%"
|
|
|
@change="changeDimensionHandler"
|
|
@change="changeDimensionHandler"
|
|
|
v-model="dimension"
|
|
v-model="dimension"
|
|
|
|
|
+ :disabled="bizType === 10 && !hasMixedReturnSources()"
|
|
|
placeholder="请选择"
|
|
placeholder="请选择"
|
|
|
>
|
|
>
|
|
|
<!-- <el-option label="物料维度" value="4"> </el-option> -->
|
|
<!-- <el-option label="物料维度" value="4"> </el-option> -->
|
|
@@ -195,14 +196,7 @@
|
|
|
width="55"
|
|
width="55"
|
|
|
align="center"
|
|
align="center"
|
|
|
fixed="left"
|
|
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>
|
|
|
<el-table-column label="序号" type="index" width="50" fixed="left">
|
|
<el-table-column label="序号" type="index" width="50" fixed="left">
|
|
@@ -416,7 +410,9 @@
|
|
|
export default {
|
|
export default {
|
|
|
components: { AssetTree },
|
|
components: { AssetTree },
|
|
|
props: {
|
|
props: {
|
|
|
- treeIds: { type: Array, default: () => [] }
|
|
|
|
|
|
|
+ treeIds: { type: Array, default: () => [] },
|
|
|
|
|
+ returnProductList: { type: Array, default: () => [] },
|
|
|
|
|
+ bizType: { type: Number, default: null }
|
|
|
},
|
|
},
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
@@ -498,6 +494,48 @@
|
|
|
Math.round((inventoryBalance - lockQuantity) * 100) / 100
|
|
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) {
|
|
formatMeasureQuantity(row) {
|
|
|
return this.dimension == 2
|
|
return this.dimension == 2
|
|
|
? this.getAvailableQuantity(row)
|
|
? this.getAvailableQuantity(row)
|
|
@@ -591,7 +629,18 @@
|
|
|
this.total = data.count;
|
|
this.total = data.count;
|
|
|
} else if (this.dimension == 2) {
|
|
} 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++) {
|
|
for (let i = 0; i < data.list.length; i++) {
|
|
|
data.list[i].outboundNum = this.getAvailableQuantity(data.list[i]);
|
|
data.list[i].outboundNum = this.getAvailableQuantity(data.list[i]);
|
|
|
}
|
|
}
|
|
@@ -604,9 +653,18 @@
|
|
|
this.total = data.count;
|
|
this.total = data.count;
|
|
|
} else {
|
|
} 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++) {
|
|
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.tableData = data.list;
|
|
|
this.total = data.count;
|
|
this.total = data.count;
|
|
@@ -638,6 +696,20 @@
|
|
|
} else {
|
|
} else {
|
|
|
for (let i = 0; i < list.length; i++) {
|
|
for (let i = 0; i < list.length; i++) {
|
|
|
const item = list[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 matchedProduct = this.productLists.find((product) => {
|
|
|
const isMatch = product.id === item.id;
|
|
const isMatch = product.id === item.id;
|
|
|
return isMatch;
|
|
return isMatch;
|
|
@@ -657,6 +729,9 @@
|
|
|
},
|
|
},
|
|
|
open(val) {
|
|
open(val) {
|
|
|
this.productLists = val || [];
|
|
this.productLists = val || [];
|
|
|
|
|
+ if (this.bizType === 10) {
|
|
|
|
|
+ this.dimension = this.returnPackages().length ? '3' : '2';
|
|
|
|
|
+ }
|
|
|
this.visible = true;
|
|
this.visible = true;
|
|
|
this.$nextTick(() => {
|
|
this.$nextTick(() => {
|
|
|
this.$refs.treeList.getTreeData().then(async (data) => {
|
|
this.$refs.treeList.getTreeData().then(async (data) => {
|
|
@@ -676,16 +751,74 @@
|
|
|
return;
|
|
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);
|
|
console.log(this.selectionList);
|
|
|
let data = null;
|
|
let data = null;
|
|
|
if (this.dimension == 3) {
|
|
if (this.dimension == 3) {
|
|
|
data = await storageApi.getHierarchyList({
|
|
data = await storageApi.getHierarchyList({
|
|
|
ids: this.selectionList.map((item) => item.id).join(','),
|
|
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) {
|
|
} else if (this.dimension == 2) {
|
|
|
|
|
+ const returnProducts = this.returnProductList;
|
|
|
data = await storageApi.getHierarchyFifo({
|
|
data = await storageApi.getHierarchyFifo({
|
|
|
type: this.dimension,
|
|
type: this.dimension,
|
|
|
|
|
+ result: this.bizType === 10 ? 2 : null,
|
|
|
ids: this.selectionList.map((item) => item.id),
|
|
ids: this.selectionList.map((item) => item.id),
|
|
|
builders: this.selectionList.map((item) => {
|
|
builders: this.selectionList.map((item) => {
|
|
|
return {
|
|
return {
|
|
@@ -693,7 +826,17 @@
|
|
|
batchNo: item.batchNo,
|
|
batchNo: item.batchNo,
|
|
|
// 历史数据保持空值,由后端按外部批次号兼容匹配
|
|
// 历史数据保持空值,由后端按外部批次号兼容匹配
|
|
|
systemBatchNo: item.systemBatchNo || '',
|
|
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
|
|
id: item.id
|
|
|
};
|
|
};
|
|
|
})
|
|
})
|