|
|
@@ -1011,6 +1011,7 @@
|
|
|
import ProductionVersion from '@/components/ProductionVersion2/index.vue';
|
|
|
import {
|
|
|
getInventoryTotalAPI,
|
|
|
+ getWarehouseOutStockBatchAPI,
|
|
|
buildInventoryTotalQueryKey,
|
|
|
matchInventoryTotal
|
|
|
} from '@/api/wms';
|
|
|
@@ -1949,13 +1950,31 @@
|
|
|
},
|
|
|
async getSupplierObj(productList, queryName) {
|
|
|
try {
|
|
|
- let categoryIds = productList
|
|
|
- .filter((item) => item.productId)
|
|
|
- .map((item) => item.productId);
|
|
|
+ const categoryIds = [
|
|
|
+ ...new Set(
|
|
|
+ productList
|
|
|
+ .map((item) => item[queryName])
|
|
|
+ .filter((categoryId) => categoryId)
|
|
|
+ )
|
|
|
+ ];
|
|
|
if (categoryIds.length > 0) {
|
|
|
- return await contactQueryByCategoryIdsAPI({
|
|
|
+ const supplierObj = await contactQueryByCategoryIdsAPI({
|
|
|
categoryIds
|
|
|
});
|
|
|
+ Object.keys(supplierObj || {}).forEach((categoryId) => {
|
|
|
+ const supplierIds = new Set();
|
|
|
+ supplierObj[categoryId] = (supplierObj[categoryId] || []).filter(
|
|
|
+ (supplier) => {
|
|
|
+ const supplierId = String(supplier.id);
|
|
|
+ if (supplierIds.has(supplierId)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ supplierIds.add(supplierId);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ );
|
|
|
+ });
|
|
|
+ return supplierObj;
|
|
|
} else {
|
|
|
return Promise.resolve({});
|
|
|
}
|
|
|
@@ -2035,6 +2054,93 @@
|
|
|
this.getStockCount(item) - Number(item.lockQuantity || 0);
|
|
|
return Number(availableCount.toFixed(4));
|
|
|
},
|
|
|
+ getInventoryIdentity(item) {
|
|
|
+ return [
|
|
|
+ item.productCode,
|
|
|
+ item.warehouseId,
|
|
|
+ item.batchNo,
|
|
|
+ item.systemBatchNo,
|
|
|
+ item.colorKey,
|
|
|
+ item.modelType
|
|
|
+ ]
|
|
|
+ .map((value) => (value == null ? '' : String(value).trim()))
|
|
|
+ .join('|');
|
|
|
+ },
|
|
|
+ buildExactInventoryRequest(item) {
|
|
|
+ return {
|
|
|
+ code: item.productCode,
|
|
|
+ warehouseId: item.warehouseId,
|
|
|
+ batchNo: item.batchNo,
|
|
|
+ systemBatchNo: item.systemBatchNo,
|
|
|
+ colorKey: item.colorKey,
|
|
|
+ modelType: item.modelType
|
|
|
+ };
|
|
|
+ },
|
|
|
+ async refreshStockOrderInventory(validateQuantity = false) {
|
|
|
+ if (this.needProduce != 0) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ const inventoryGroups = new Map();
|
|
|
+ this.form.datasource.forEach((item, index) => {
|
|
|
+ if (!item.productCode || !item.warehouseId) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const identity = this.getInventoryIdentity(item);
|
|
|
+ const group = inventoryGroups.get(identity) || {
|
|
|
+ request: this.buildExactInventoryRequest(item),
|
|
|
+ rows: [],
|
|
|
+ requiredQuantity: 0,
|
|
|
+ productCode: item.productCode,
|
|
|
+ productName: item.productName
|
|
|
+ };
|
|
|
+ group.rows.push(index);
|
|
|
+ group.requiredQuantity += Number(item.totalCount || item.saleCount || 0);
|
|
|
+ inventoryGroups.set(identity, group);
|
|
|
+ });
|
|
|
+ const groups = Array.from(inventoryGroups.values());
|
|
|
+ if (groups.length === 0) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ const inventoryList = await getWarehouseOutStockBatchAPI(
|
|
|
+ groups.map((group) => group.request)
|
|
|
+ );
|
|
|
+ const insufficient = [];
|
|
|
+ groups.forEach((group, groupIndex) => {
|
|
|
+ const inventory = inventoryList[groupIndex] || {};
|
|
|
+ const stockCountBase = Number(inventory.stockCountBase || 0);
|
|
|
+ const availableCountBase = Number(inventory.availableCountBase || 0);
|
|
|
+ group.rows.forEach((rowIndex) => {
|
|
|
+ if (this.showStockCount) {
|
|
|
+ this.$set(
|
|
|
+ this.form.datasource[rowIndex],
|
|
|
+ 'stockCountBase',
|
|
|
+ stockCountBase
|
|
|
+ );
|
|
|
+ }
|
|
|
+ this.$set(
|
|
|
+ this.form.datasource[rowIndex],
|
|
|
+ 'availableCountBase',
|
|
|
+ availableCountBase
|
|
|
+ );
|
|
|
+ });
|
|
|
+ if (
|
|
|
+ validateQuantity &&
|
|
|
+ group.requiredQuantity > availableCountBase
|
|
|
+ ) {
|
|
|
+ insufficient.push(
|
|
|
+ `${group.productCode}-${group.productName || ''}需求${group.requiredQuantity},可用${availableCountBase}`
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if (insufficient.length > 0) {
|
|
|
+ this.$message.error(`库存不足:${insufficient.join(';')}`);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ async validateInventoryAvailability() {
|
|
|
+ return this.refreshStockOrderInventory(true);
|
|
|
+ },
|
|
|
// 返回列表数据
|
|
|
getTableValue() {
|
|
|
let comitDatasource = copyObj(this.form.datasource);
|
|
|
@@ -2367,34 +2473,38 @@
|
|
|
});
|
|
|
this.form.datasource = productList;
|
|
|
|
|
|
- let codeList = this.form.datasource
|
|
|
- .filter((item) => item.productCode)
|
|
|
- .map((item) => buildInventoryTotalQueryKey(item));
|
|
|
- //获取仓库库存
|
|
|
- let inventoryTotalList = await getInventoryTotalAPI(codeList);
|
|
|
- this.form.datasource
|
|
|
- .filter((item) => item.productCode)
|
|
|
- .forEach((item, index) => {
|
|
|
- let find =
|
|
|
- inventoryTotalList.find((key) =>
|
|
|
- matchInventoryTotal(item, key)
|
|
|
- ) || {};
|
|
|
- this.form.datasource;
|
|
|
- if (this.showStockCount) {
|
|
|
+ if (this.needProduce == 0) {
|
|
|
+ await this.refreshStockOrderInventory();
|
|
|
+ } else {
|
|
|
+ let codeList = this.form.datasource
|
|
|
+ .filter((item) => item.productCode)
|
|
|
+ .map((item) => buildInventoryTotalQueryKey(item));
|
|
|
+ // 非库存式业务保留原有物品/批次汇总库存口径。
|
|
|
+ let inventoryTotalList = await getInventoryTotalAPI(codeList);
|
|
|
+ this.form.datasource
|
|
|
+ .filter((item) => item.productCode)
|
|
|
+ .forEach((item, index) => {
|
|
|
+ let find =
|
|
|
+ inventoryTotalList.find((key) =>
|
|
|
+ matchInventoryTotal(item, key)
|
|
|
+ ) || {};
|
|
|
+ this.form.datasource;
|
|
|
+ if (this.showStockCount) {
|
|
|
+ this.$set(
|
|
|
+ this.form.datasource[index],
|
|
|
+ 'stockCountBase',
|
|
|
+ this.getStockCount(find)
|
|
|
+ );
|
|
|
+ }
|
|
|
this.$set(
|
|
|
this.form.datasource[index],
|
|
|
- 'stockCountBase',
|
|
|
- this.getStockCount(find)
|
|
|
+ 'availableCountBase',
|
|
|
+ this.showStockCount
|
|
|
+ ? this.getAvailableStockCount(find)
|
|
|
+ : find.availableCountBase
|
|
|
);
|
|
|
- }
|
|
|
- this.$set(
|
|
|
- this.form.datasource[index],
|
|
|
- 'availableCountBase',
|
|
|
- this.showStockCount
|
|
|
- ? this.getAvailableStockCount(find)
|
|
|
- : find.availableCountBase
|
|
|
- );
|
|
|
- });
|
|
|
+ });
|
|
|
+ }
|
|
|
if (this.isChangeCount) {
|
|
|
this.changeCount();
|
|
|
} else {
|