fix:订单配备货相关链路功能调整
parent
7597a444b9
commit
71e8eb1e37
|
|
@ -243,6 +243,15 @@
|
|||
<div class="stocking-product-meta">
|
||||
<span class="stocking-product-meta__label">产品型号:</span>
|
||||
<span class="stocking-product-meta__value stocking-product-meta__value--strong">{{ item.model || '-' }}</span>
|
||||
<el-button
|
||||
v-if="item.vendorName && item.vendorName.startsWith('新华三')"
|
||||
type="primary"
|
||||
plain
|
||||
icon="el-icon-plus"
|
||||
size="mini"
|
||||
style="margin-left: 12px;"
|
||||
@click="handleGenerateVirtualPurchase(item)"
|
||||
>生成虚拟采购单</el-button>
|
||||
</div>
|
||||
<div class="stocking-product-summary">
|
||||
<div class="stocking-product-summary__item">
|
||||
|
|
@ -250,32 +259,38 @@
|
|||
<span class="stocking-product-summary__value">{{ item.orderNum !== undefined && item.orderNum !== null ? item.orderNum : '-' }}</span>
|
||||
</div>
|
||||
<div class="stocking-product-summary__item">
|
||||
<span class="stocking-product-summary__label">已配货:</span>
|
||||
<span class="stocking-product-summary__value stocking-product-summary__value--green">{{ item.phNum !== undefined && item.phNum !== null ? item.phNum : '-' }}</span>
|
||||
<span v-if="(item.orderNum !== undefined && item.orderNum !== null ? item.orderNum-(item.phNum||0) : 0) > 0" class="stocking-product-summary__value stocking-product-summary__value--red-bg" style="margin-left: 8px; font-size: 12px; font-weight: normal; padding: 2px 6px;">缺货: {{ item.orderNum !== undefined && item.orderNum !== null ? item.orderNum-(item.phNum||0): '-'}}</span>
|
||||
<span class="stocking-product-summary__label">已配额:</span>
|
||||
<span class="stocking-product-summary__value stocking-product-summary__value--green">{{ calculateCurrentTotalPhNum(item) }}</span>
|
||||
<span v-if="(item.orderNum !== undefined && item.orderNum !== null ? item.orderNum-calculateCurrentTotalPhNum(item) : 0) > 0" class="stocking-product-summary__value stocking-product-summary__value--red-bg" style="margin-left: 8px; font-size: 12px; font-weight: normal; padding: 2px 6px;">缺货: {{ item.orderNum !== undefined && item.orderNum !== null ? item.orderNum-calculateCurrentTotalPhNum(item): '-'}}</span>
|
||||
</div>
|
||||
<div class="stocking-product-summary__item">
|
||||
<span class="stocking-product-summary__label">已备货:</span>
|
||||
<span class="stocking-product-summary__value stocking-product-summary__value--green">{{ item.bhNum !== undefined && item.bhNum !== null ? item.bhNum : '-' }}</span>
|
||||
<span v-if="(item.orderNum !== undefined && item.orderNum !== null ? item.orderNum-(item.bhNum||0) : 0) > 0" class="stocking-product-summary__value stocking-product-summary__value--red-bg" style="margin-left: 8px; font-size: 12px; font-weight: normal; padding: 2px 6px;">缺货: {{ item.orderNum !== undefined && item.orderNum !== null ? item.orderNum-(item.bhNum||0): '-'}}</span>
|
||||
<span v-if="item.bhNum !== undefined && item.bhNum !== null && item.orderNum !== undefined && item.orderNum !== null && item.bhNum === item.orderNum" class="stocking-product-summary__value" style="margin-left: 8px; font-size: 12px; font-weight: normal; padding: 2px 6px; background: #67c23a; color: #fff; border-radius: 3px;">备货完成</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="item.bindList || []" class="stocking-product-table">
|
||||
<el-table-column label="采购单号" align="center" prop="purchaseNo" width="200" />
|
||||
<el-table-column label="制造者" align="center" prop="vendorAddress" width="200" />
|
||||
<el-table-column label="批次数量" align="center" prop="cgNum" />
|
||||
<el-table-column label="可用" align="center" prop="kyNum">
|
||||
<el-table-column label="采购单号" align="center" prop="purchaseNo" width="250" />
|
||||
<el-table-column label="入库状态" align="center" prop="status" >
|
||||
<template slot-scope="scope">
|
||||
<span>{{ String(scope.row.status) === '0' ? '-' : scope.row.kyNum }}</span>
|
||||
<dict-tag :options="dict.type.purchase_status" :value="String(scope.row.status)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="配额量" align="center" prop="phNum" width="140">
|
||||
<el-table-column label="制造者" align="center" prop="vendorAddress" />
|
||||
<el-table-column label="单价" align="center" prop="price" width="130">
|
||||
<template slot-scope="scope">
|
||||
<span style="color: #f05a00;">¥ {{ formatCurrency(scope.row.price) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="批次数量" align="center" prop="cgNum" />
|
||||
<el-table-column label="可用" align="center" prop="kyNum" />
|
||||
<el-table-column label="配额" align="center" prop="phNum" >
|
||||
<template slot-scope="scope">
|
||||
<el-input
|
||||
v-model="scope.row.phNum"
|
||||
type="number"
|
||||
:disabled="String(scope.row.status) === '0'"
|
||||
:min="scope.row.bhNum || 0"
|
||||
:max="calculateMaxPhNum(scope.row, item)"
|
||||
size="small"
|
||||
|
|
@ -285,19 +300,14 @@
|
|||
></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="入库状态" align="center" prop="status" width="120">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.purchase_status" :value="String(scope.row.status)"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="200">
|
||||
<el-table-column label="已出库" align="center" prop="bhNum" />
|
||||
<el-table-column label="操作" align="center" width="130" >
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
v-if="['1', '2'].includes(String(scope.row.status))"
|
||||
type="text"
|
||||
icon="el-icon-edit-outline"
|
||||
@click="handleAssignOuterSnCode(scope.row, item)"
|
||||
>分配出库SN码</el-button>
|
||||
>查看出库SN码</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -321,7 +331,7 @@
|
|||
</div>
|
||||
<div>
|
||||
<el-button @click="stockingDetailVisible = false">关 闭</el-button>
|
||||
<!-- <el-button type="primary" :loading="stockingDetailSaving" @click="handleSaveStockingBind">保存修改</el-button>-->
|
||||
<el-button type="primary" :loading="stockingDetailSaving" @click="handleSaveStockingBind">保存修改</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
|
@ -337,8 +347,8 @@
|
|||
<div class="stocking-save-confirm__title">本次将保存 {{ stockingSaveChangedList.length }} 条配额量变更,是否继续?</div>
|
||||
<el-table :data="stockingSaveChangedList" max-height="300" size="mini">
|
||||
<el-table-column label="采购单号" align="center" prop="purchaseNo" min-width="160" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="原配额量" align="center" prop="originalBindNum" width="100" />
|
||||
<el-table-column label="新配额量" align="center" prop="bindNum" width="100" />
|
||||
<el-table-column label="原配额" align="center" prop="originalBindNum" width="100" />
|
||||
<el-table-column label="新配额" align="center" prop="bindNum" width="100" />
|
||||
</el-table>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
|
|
@ -356,7 +366,7 @@
|
|||
>
|
||||
<div slot="title" class="outer-sn-dialog-title">
|
||||
<i class="el-icon-box"></i>
|
||||
<span>分配出库 SN 码</span>
|
||||
<span>已出库 SN 码</span>
|
||||
</div>
|
||||
<div v-loading="outerSnLoading" class="outer-sn-dialog-body">
|
||||
<div class="outer-sn-header">
|
||||
|
|
@ -406,22 +416,17 @@
|
|||
|
||||
<div class="outer-sn-grid-container">
|
||||
<div class="outer-sn-grid-header">
|
||||
<el-checkbox
|
||||
v-model="outerSnSelectAll"
|
||||
:indeterminate="outerSnSelectIndeterminate"
|
||||
@change="handleOuterSnSelectAll"
|
||||
>
|
||||
全选
|
||||
</el-checkbox>
|
||||
<span class="outer-sn-current-count">当前仓库SN码总数:{{ getWarehouseSnCount(outerSnActiveWarehouse) }}</span>
|
||||
<el-button
|
||||
type="text"
|
||||
size="small"
|
||||
style="color: #f56c6c;"
|
||||
@click="handleOuterSnClearSelected"
|
||||
>
|
||||
清空已选
|
||||
</el-button>
|
||||
<pagination
|
||||
small
|
||||
layout="total, sizes, prev, pager, next"
|
||||
:total="outerSnPagination.total"
|
||||
:page.sync="outerSnPagination.pageNum"
|
||||
:limit.sync="outerSnPagination.pageSize"
|
||||
:page-sizes="[100, 200, 500]"
|
||||
@pagination="handleOuterSnPageChange"
|
||||
style="display: inline-block;"
|
||||
/>
|
||||
</div>
|
||||
<div class="outer-sn-grid">
|
||||
<div
|
||||
|
|
@ -432,27 +437,29 @@
|
|||
'outer-sn-card--selected': isSnSelected(sn.productSn),
|
||||
'outer-sn-card--disabled': isSnDisabled(sn)
|
||||
}"
|
||||
@click="handleSnCardClick(sn)"
|
||||
>
|
||||
<el-checkbox
|
||||
:value="isSnSelected(sn.productSn)"
|
||||
:disabled="isSnDisabled(sn)"
|
||||
@click.native.stop
|
||||
@change="handleSnCheckboxChange(sn, $event)"
|
||||
/>
|
||||
<span class="outer-sn-card-text">{{ sn.productSn }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="outerSnDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleConfirmSnSelection">
|
||||
确认分配 {{ outerSnSelectedCount }}
|
||||
</el-button>
|
||||
<el-button @click="outerSnDialogVisible = false">关闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 新增采购单弹窗 -->
|
||||
<el-dialog :title="purchaseTitle" :close-on-click-modal="false" :visible.sync="purchaseOpen" width="80vw" append-to-body>
|
||||
<purchase-order-detail ref="purchaseOrderDetail" :order-data="currentPurchaseOrderData"
|
||||
@close="purchaseOpen = false"
|
||||
@success="handlePurchaseSuccess">
|
||||
</purchase-order-detail>
|
||||
<template slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitPurchaseForm">确 定</el-button>
|
||||
<el-button @click="cancelPurchase">取 消</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
@ -464,13 +471,15 @@ import { getToken } from "@/utils/auth";
|
|||
import OrderDetailDrawer from '../../project/order/OrderDetailDrawer.vue';
|
||||
import ProjectDetailDrawer from '../../project/info/ProjectDetailDrawer.vue';
|
||||
import Edit from './edit.vue';
|
||||
import PurchaseOrderDetail from '../../purchaseorder/components/PurchaseOrderDetail.vue';
|
||||
|
||||
export default {
|
||||
name: "Execution",
|
||||
components: {
|
||||
ProjectDetailDrawer,
|
||||
OrderDetailDrawer,
|
||||
Edit // Register the Edit component
|
||||
Edit,
|
||||
PurchaseOrderDetail
|
||||
},
|
||||
dicts: ['execution_outer_status', 'execution_delivery_status', 'execution_sign_status', 'purchase_status'],
|
||||
data() {
|
||||
|
|
@ -518,6 +527,16 @@ export default {
|
|||
outerSnSelectedList: [],
|
||||
outerSnSelectAll: false,
|
||||
outerSnSelectIndeterminate: false,
|
||||
outerSnPagination: {
|
||||
pageNum: 1,
|
||||
pageSize: 100,
|
||||
total: 0
|
||||
},
|
||||
// --- 采购单弹窗 ---
|
||||
purchaseOpen: false,
|
||||
purchaseTitle: '',
|
||||
currentPurchaseOrderData: null,
|
||||
virtualPurchaseProductInfo: null,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
|
|
@ -550,6 +569,23 @@ export default {
|
|||
created() {
|
||||
this.getList();
|
||||
},
|
||||
watch: {
|
||||
purchaseOpen(val) {
|
||||
if (!val) {
|
||||
this.currentPurchaseOrderData = null;
|
||||
this.virtualPurchaseProductInfo = null;
|
||||
this.$refs.purchaseOrderDetail?.resetForm();
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
if (this.virtualPurchaseProductInfo) {
|
||||
this.$refs.purchaseOrderDetail?.initVirtualPurchase(this.virtualPurchaseProductInfo);
|
||||
} else {
|
||||
this.$refs.purchaseOrderDetail?.resetForm();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
outerSnSelectedCount() {
|
||||
return this.outerSnSelectedList.length;
|
||||
|
|
@ -559,7 +595,24 @@ export default {
|
|||
return Number.isNaN(quotaQuantity) ? 0 : quotaQuantity;
|
||||
},
|
||||
stockingTotalCost() {
|
||||
return (this.stockingDetailList || []).reduce((total, item) => total + (Number(item.sumCost) || 0), 0);
|
||||
return (this.stockingDetailList || []).reduce((total, item) => {
|
||||
const baseCost = Number(item.sumCost) || 0;
|
||||
|
||||
let additionalCost = 0;
|
||||
if (item.allBindList) {
|
||||
item.allBindList.forEach(bindItem => {
|
||||
const originalPhNum = bindItem.originalPhNum === '' || bindItem.originalPhNum === null || bindItem.originalPhNum === undefined ? 0 : Number(bindItem.originalPhNum);
|
||||
const currentPhNum = this.stockingBindDraftMap[bindItem.purchaseId] !== undefined
|
||||
? Number(this.stockingBindDraftMap[bindItem.purchaseId])
|
||||
: (bindItem.phNum === '' || bindItem.phNum === null || bindItem.phNum === undefined ? 0 : Number(bindItem.phNum));
|
||||
const price = Number(bindItem.price) || 0;
|
||||
const diff = currentPhNum - originalPhNum;
|
||||
additionalCost += diff * price;
|
||||
});
|
||||
}
|
||||
|
||||
return total + baseCost + additionalCost;
|
||||
}, 0);
|
||||
},
|
||||
filteredSnList() {
|
||||
let list = this.outerSnDetail.snList || [];
|
||||
|
|
@ -570,7 +623,10 @@ export default {
|
|||
const keyword = this.outerSnSearchKeyword.toLowerCase();
|
||||
list = list.filter(sn => (sn.productSn || '').toLowerCase().includes(keyword));
|
||||
}
|
||||
return list;
|
||||
this.outerSnPagination.total = list.length;
|
||||
const start = (this.outerSnPagination.pageNum - 1) * this.outerSnPagination.pageSize;
|
||||
const end = start + this.outerSnPagination.pageSize;
|
||||
return list.slice(start, end);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -689,13 +745,22 @@ export default {
|
|||
this.stockingDetailLoading = true;
|
||||
productMatchList(row.orderCode).then(response => {
|
||||
const list = response.data || [];
|
||||
return Promise.all(list.map(item => this.loadBindPageData(row.orderCode, {
|
||||
...item,
|
||||
originalTotalPhNum: item.phNum,
|
||||
bindList: [],
|
||||
bindTotal: 0,
|
||||
bindPageNum: 1,
|
||||
bindPageSize: this.stockingBindPageSize
|
||||
return Promise.all(list.map(item => this.loadAllBindData(row.orderCode, item).then(allBindList => {
|
||||
const bindPageNum = 1;
|
||||
const bindPageSize = this.stockingBindPageSize;
|
||||
const startIndex = (bindPageNum - 1) * bindPageSize;
|
||||
const endIndex = startIndex + bindPageSize;
|
||||
const bindList = allBindList.slice(startIndex, endIndex);
|
||||
|
||||
return {
|
||||
...item,
|
||||
originalTotalPhNum: item.phNum,
|
||||
allBindList: allBindList,
|
||||
bindList: bindList,
|
||||
bindTotal: allBindList.length,
|
||||
bindPageNum: bindPageNum,
|
||||
bindPageSize: bindPageSize
|
||||
};
|
||||
})));
|
||||
}).then(list => {
|
||||
this.stockingDetailList = list;
|
||||
|
|
@ -720,6 +785,7 @@ export default {
|
|||
|
||||
row.phNum = validValue;
|
||||
this.$set(this.stockingBindDraftMap, row.purchaseId, validValue);
|
||||
this.updateItemTotalPhNum(item);
|
||||
},
|
||||
calculateMaxPhNum(row, item) {
|
||||
const originalPhNum = row.originalPhNum === '' || row.originalPhNum === null || row.originalPhNum === undefined ? 0 : Number(row.originalPhNum);
|
||||
|
|
@ -728,58 +794,45 @@ export default {
|
|||
|
||||
const maxPhysical = originalPhNum + originalKyNum;
|
||||
|
||||
let otherRowsPhNumSum = 0;
|
||||
if (item && item.bindList) {
|
||||
item.bindList.forEach(b => {
|
||||
if (b.purchaseId !== row.purchaseId) {
|
||||
const p = Number(b.phNum) || 0;
|
||||
otherRowsPhNumSum += p;
|
||||
}
|
||||
});
|
||||
}
|
||||
const currentTotalPhNum = this.calculateCurrentTotalPhNum(item);
|
||||
const currentRowPhNum = this.stockingBindDraftMap[row.purchaseId] !== undefined
|
||||
? Number(this.stockingBindDraftMap[row.purchaseId])
|
||||
: (row.phNum === '' || row.phNum === null || row.phNum === undefined ? 0 : Number(row.phNum));
|
||||
|
||||
const maxAllowedByOrder = orderNum - otherRowsPhNumSum;
|
||||
const maxAllowedByOrder = orderNum - currentTotalPhNum + currentRowPhNum;
|
||||
|
||||
return Math.min(maxPhysical, maxAllowedByOrder);
|
||||
},
|
||||
loadBindPageData(orderCode, item) {
|
||||
loadAllBindData(orderCode, item) {
|
||||
return productMatchBindList(orderCode, item.productCode, {
|
||||
pageNum: item.bindPageNum,
|
||||
pageSize: item.bindPageSize,
|
||||
pageNum: 1,
|
||||
pageSize: 9999,
|
||||
orderByColumn: 't6.createTime',
|
||||
isAsc: 'desc'
|
||||
}).then(bindResponse => {
|
||||
const bindList = (bindResponse.rows || []).map(bindItem => ({
|
||||
return (bindResponse.rows || []).map(bindItem => ({
|
||||
...bindItem,
|
||||
phNum: this.getDraftBindNum(bindItem.purchaseId, bindItem.phNum),
|
||||
originalPhNum: bindItem.originalPhNum !== undefined ? bindItem.originalPhNum : bindItem.phNum,
|
||||
originalKyNum: bindItem.originalKyNum !== undefined ? bindItem.originalKyNum : bindItem.kyNum
|
||||
}));
|
||||
return {
|
||||
...item,
|
||||
originalTotalPhNum: item.originalTotalPhNum !== undefined ? item.originalTotalPhNum : item.phNum,
|
||||
bindList,
|
||||
bindTotal: bindResponse.total || 0
|
||||
};
|
||||
}).catch(() => {
|
||||
return {
|
||||
...item,
|
||||
bindList: [],
|
||||
bindTotal: 0
|
||||
};
|
||||
return [];
|
||||
});
|
||||
},
|
||||
handleBindPageChange(item) {
|
||||
this.stockingDetailLoading = true;
|
||||
this.loadBindPageData(this.stockingDetailRow.orderCode, item).then(updatedItem => {
|
||||
this.stockingDetailList = this.stockingDetailList.map(currentItem => {
|
||||
if (currentItem.productCode === updatedItem.productCode) {
|
||||
return updatedItem;
|
||||
}
|
||||
return currentItem;
|
||||
});
|
||||
}).finally(() => {
|
||||
this.stockingDetailLoading = false;
|
||||
const startIndex = (item.bindPageNum - 1) * item.bindPageSize;
|
||||
const endIndex = startIndex + item.bindPageSize;
|
||||
const bindList = (item.allBindList || []).slice(startIndex, endIndex);
|
||||
|
||||
this.stockingDetailList = this.stockingDetailList.map(currentItem => {
|
||||
if (currentItem.productCode === item.productCode) {
|
||||
return {
|
||||
...currentItem,
|
||||
bindList: bindList
|
||||
};
|
||||
}
|
||||
return currentItem;
|
||||
});
|
||||
},
|
||||
handleBindNumChange(row, item) {
|
||||
|
|
@ -797,24 +850,56 @@ export default {
|
|||
row.kyNum = originalKyNum - diff;
|
||||
|
||||
this.$set(this.stockingBindDraftMap, row.purchaseId, nextValue);
|
||||
|
||||
this.updateItemTotalPhNum(item);
|
||||
},
|
||||
calculateCurrentTotalPhNum(item) {
|
||||
if (!item || !item.productCode || !item.allBindList) return 0;
|
||||
|
||||
let total = 0;
|
||||
item.allBindList.forEach(bindItem => {
|
||||
const purchaseId = bindItem.purchaseId;
|
||||
if (this.stockingBindDraftMap && this.stockingBindDraftMap[purchaseId] !== undefined) {
|
||||
total += Number(this.stockingBindDraftMap[purchaseId]);
|
||||
} else {
|
||||
const phNum = bindItem.phNum === '' || bindItem.phNum === null || bindItem.phNum === undefined ? 0 : Number(bindItem.phNum);
|
||||
total += phNum;
|
||||
}
|
||||
});
|
||||
|
||||
return total;
|
||||
},
|
||||
findBindItemByPurchaseId(productCode, purchaseId) {
|
||||
const product = this.stockingDetailList.find(item => item.productCode === productCode);
|
||||
if (!product) return null;
|
||||
|
||||
return product.allBindList?.find(b => String(b.purchaseId) === String(purchaseId));
|
||||
},
|
||||
updateItemTotalPhNum(item) {
|
||||
if (item) {
|
||||
this.$set(item, 'phNum', this.calculateCurrentTotalPhNum(item));
|
||||
}
|
||||
},
|
||||
handleSaveStockingBind() {
|
||||
const changedList = [];
|
||||
this.stockingDetailList.forEach(item => {
|
||||
(item.bindList || []).forEach(bindItem => {
|
||||
this.handleBindNumChange(bindItem, item);
|
||||
const currentPhNum = bindItem.phNum === '' || bindItem.phNum === null || bindItem.phNum === undefined ? 0 : Number(bindItem.phNum);
|
||||
const originalPhNum = bindItem.originalPhNum === '' || bindItem.originalPhNum === null || bindItem.originalPhNum === undefined ? 0 : Number(bindItem.originalPhNum);
|
||||
if (currentPhNum !== originalPhNum) {
|
||||
changedList.push({
|
||||
orderId: this.stockingDetailRow.id,
|
||||
purchaseId: bindItem.purchaseId,
|
||||
purchaseNo: bindItem.purchaseNo,
|
||||
originalBindNum: originalPhNum,
|
||||
bindNum: currentPhNum
|
||||
});
|
||||
}
|
||||
});
|
||||
if (item.allBindList) {
|
||||
item.allBindList.forEach(bindItem => {
|
||||
const currentPhNum = this.stockingBindDraftMap[bindItem.purchaseId] !== undefined
|
||||
? Number(this.stockingBindDraftMap[bindItem.purchaseId])
|
||||
: (bindItem.phNum === '' || bindItem.phNum === null || bindItem.phNum === undefined ? 0 : Number(bindItem.phNum));
|
||||
const originalPhNum = bindItem.originalPhNum === '' || bindItem.originalPhNum === null || bindItem.originalPhNum === undefined ? 0 : Number(bindItem.originalPhNum);
|
||||
if (currentPhNum !== originalPhNum) {
|
||||
changedList.push({
|
||||
orderId: this.stockingDetailRow.id,
|
||||
purchaseId: bindItem.purchaseId,
|
||||
purchaseNo: bindItem.purchaseNo,
|
||||
originalBindNum: originalPhNum,
|
||||
bindNum: currentPhNum
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (!changedList.length) {
|
||||
this.$message.warning('暂无变更数据');
|
||||
|
|
@ -832,13 +917,33 @@ export default {
|
|||
}))).then(() => {
|
||||
this.$message.success('保存成功');
|
||||
this.stockingDetailList.forEach(item => {
|
||||
item.originalTotalPhNum = item.phNum;
|
||||
(item.bindList || []).forEach(bindItem => {
|
||||
bindItem.originalPhNum = bindItem.phNum;
|
||||
bindItem.originalKyNum = bindItem.kyNum;
|
||||
this.$delete(this.stockingBindDraftMap, bindItem.purchaseId);
|
||||
});
|
||||
item.originalTotalPhNum = this.calculateCurrentTotalPhNum(item);
|
||||
if (item.allBindList) {
|
||||
item.allBindList.forEach(bindItem => {
|
||||
if (this.stockingBindDraftMap[bindItem.purchaseId] !== undefined) {
|
||||
bindItem.phNum = this.stockingBindDraftMap[bindItem.purchaseId];
|
||||
bindItem.originalPhNum = bindItem.phNum;
|
||||
const originalKyNum = bindItem.originalKyNum === '' || bindItem.originalKyNum === null || bindItem.originalKyNum === undefined ? 0 : Number(bindItem.originalKyNum);
|
||||
const diff = bindItem.phNum - (bindItem.originalPhNum || 0);
|
||||
bindItem.kyNum = originalKyNum - diff;
|
||||
bindItem.originalKyNum = bindItem.kyNum;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (item.bindList) {
|
||||
item.bindList.forEach(bindItem => {
|
||||
if (this.stockingBindDraftMap[bindItem.purchaseId] !== undefined) {
|
||||
bindItem.phNum = this.stockingBindDraftMap[bindItem.purchaseId];
|
||||
bindItem.originalPhNum = bindItem.phNum;
|
||||
const originalKyNum = bindItem.originalKyNum === '' || bindItem.originalKyNum === null || bindItem.originalKyNum === undefined ? 0 : Number(bindItem.originalKyNum);
|
||||
const diff = bindItem.phNum - (bindItem.originalPhNum || 0);
|
||||
bindItem.kyNum = originalKyNum - diff;
|
||||
bindItem.originalKyNum = bindItem.kyNum;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
this.stockingBindDraftMap = {};
|
||||
this.stockingSaveConfirmVisible = false;
|
||||
this.stockingDetailVisible = false;
|
||||
this.stockingSaveChangedList = [];
|
||||
|
|
@ -861,6 +966,7 @@ export default {
|
|||
this.outerSnSelectedList = [];
|
||||
this.outerSnSelectAll = false;
|
||||
this.outerSnSelectIndeterminate = false;
|
||||
this.outerSnPagination = { pageNum: 1, pageSize: 100, total: 0 };
|
||||
if (!row || !row.purchaseNo) {
|
||||
this.$message.warning('采购单号为空,无法查询SN码');
|
||||
return;
|
||||
|
|
@ -882,18 +988,8 @@ export default {
|
|||
const alreadyBoundSns = this.outerSnDetail.snList
|
||||
.filter(sn => sn.orderCode && sn.orderCode === this.stockingDetailRow.orderCode)
|
||||
.map(sn => sn.productSn);
|
||||
const availableSns = this.outerSnDetail.snList
|
||||
.filter(sn => !this.isSnDisabled(sn))
|
||||
.map(sn => sn.productSn);
|
||||
|
||||
let initialSelected = [...alreadyBoundSns];
|
||||
if (initialSelected.length < this.outerSnQuotaQuantity) {
|
||||
const needCount = this.outerSnQuotaQuantity - initialSelected.length;
|
||||
const remainingToSelect = availableSns.filter(sn => !initialSelected.includes(sn)).slice(0, needCount);
|
||||
initialSelected = initialSelected.concat(remainingToSelect);
|
||||
}
|
||||
|
||||
this.outerSnSelectedList = initialSelected.slice(0, this.outerSnQuotaQuantity);
|
||||
this.outerSnSelectedList = alreadyBoundSns;
|
||||
this.updateSelectAllState();
|
||||
}).finally(() => {
|
||||
this.outerSnLoading = false;
|
||||
|
|
@ -907,6 +1003,9 @@ export default {
|
|||
return this.outerSnSelectedList.includes(productSn);
|
||||
},
|
||||
isSnDisabled(sn) {
|
||||
if (sn.orderCode && sn.orderCode === (this.stockingDetailRow && this.stockingDetailRow.orderCode)) {
|
||||
return false;
|
||||
}
|
||||
return !!(sn.outerCode || (sn.orderCode && sn.orderCode !== (this.stockingDetailRow && this.stockingDetailRow.orderCode)));
|
||||
},
|
||||
handleSnCardClick(sn) {
|
||||
|
|
@ -934,36 +1033,6 @@ export default {
|
|||
}
|
||||
this.updateSelectAllState();
|
||||
},
|
||||
handleOuterSnSelectAll(checked) {
|
||||
const quotaQuantity = this.outerSnQuotaQuantity;
|
||||
const availableSns = this.filteredSnList.filter(sn => !this.isSnDisabled(sn)).map(sn => sn.productSn);
|
||||
if (checked) {
|
||||
if (quotaQuantity <= 0) {
|
||||
this.$message.warning('当前配额数量为0,不能选择SN码');
|
||||
this.outerSnSelectAll = false;
|
||||
this.outerSnSelectIndeterminate = false;
|
||||
return;
|
||||
}
|
||||
const normalizedSelectedList = this.outerSnSelectedList.slice(0, quotaQuantity);
|
||||
const unselectedSns = availableSns.filter(sn => !normalizedSelectedList.includes(sn));
|
||||
const remainCount = quotaQuantity - normalizedSelectedList.length;
|
||||
this.outerSnSelectedList = normalizedSelectedList.concat(unselectedSns.slice(0, Math.max(remainCount, 0)));
|
||||
if (availableSns.length > this.outerSnSelectedList.filter(sn => availableSns.includes(sn)).length) {
|
||||
this.$message.warning(`最多只能选择 ${quotaQuantity} 个SN码`);
|
||||
}
|
||||
} else {
|
||||
this.outerSnSelectedList = this.outerSnSelectedList.filter(sn => !availableSns.includes(sn)).slice(0, quotaQuantity);
|
||||
}
|
||||
this.updateSelectAllState();
|
||||
},
|
||||
handleOuterSnClearSelected() {
|
||||
const quotaQuantity = this.outerSnQuotaQuantity;
|
||||
if (this.outerSnSelectedList.length > quotaQuantity) {
|
||||
this.$message.warning(`已选SN码数量超过配额 ${quotaQuantity},已清空选择`);
|
||||
}
|
||||
this.outerSnSelectedList = [];
|
||||
this.updateSelectAllState();
|
||||
},
|
||||
canSelectMoreSn(showMessage = true) {
|
||||
if (this.outerSnSelectedList.length < this.outerSnQuotaQuantity) {
|
||||
return true;
|
||||
|
|
@ -984,72 +1053,6 @@ export default {
|
|||
this.outerSnSelectAll = selectedInCurrent === availableSns.length;
|
||||
this.outerSnSelectIndeterminate = selectedInCurrent > 0 && selectedInCurrent < availableSns.length;
|
||||
},
|
||||
handleConfirmSnSelection() {
|
||||
if (this.outerSnSelectedList.length > this.outerSnQuotaQuantity) {
|
||||
this.$message.warning(`最多只能选择 ${this.outerSnQuotaQuantity} 个SN码`);
|
||||
return;
|
||||
}
|
||||
this.$confirm(`确认将选中的 ${this.outerSnSelectedList.length} 个SN码分配给当前订单?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: '正在处理中...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
|
||||
// 收集所有变更的配额信息
|
||||
const changedList = [];
|
||||
this.stockingDetailList.forEach(item => {
|
||||
(item.bindList || []).forEach(bindItem => {
|
||||
const currentPhNum = bindItem.phNum === '' || bindItem.phNum === null || bindItem.phNum === undefined ? 0 : Number(bindItem.phNum);
|
||||
const originalPhNum = bindItem.originalPhNum === '' || bindItem.originalPhNum === null || bindItem.originalPhNum === undefined ? 0 : Number(bindItem.originalPhNum);
|
||||
if (currentPhNum !== originalPhNum) {
|
||||
changedList.push({
|
||||
orderId: this.stockingDetailRow.id,
|
||||
purchaseId: bindItem.purchaseId,
|
||||
purchaseNo: bindItem.purchaseNo,
|
||||
originalBindNum: originalPhNum,
|
||||
bindNum: currentPhNum,
|
||||
bindItem: bindItem
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let saveQuotaPromise = Promise.resolve();
|
||||
if (changedList.length > 0) {
|
||||
saveQuotaPromise = Promise.all(changedList.map(item => savePurchaseOrderMap({
|
||||
orderId: item.orderId,
|
||||
purchaseId: item.purchaseId,
|
||||
bindNum: item.bindNum
|
||||
})));
|
||||
}
|
||||
|
||||
saveQuotaPromise.then(() => {
|
||||
return bindOrderSnCodes(this.stockingDetailRow.orderCode, this.outerSnProductRow.productCode, this.outerSnBindRow.purchaseNo, this.stockingDetailRow.id, this.outerSnBindRow.purchaseId, this.outerSnSelectedList);
|
||||
}).then(response => {
|
||||
loading.close();
|
||||
this.$message.success(`成功分配 ${this.outerSnSelectedList.length} 个SN码` + (changedList.length > 0 ? ',并同步保存了配额修改' : ''));
|
||||
this.outerSnDialogVisible = false;
|
||||
|
||||
if (changedList.length > 0) {
|
||||
changedList.forEach(item => {
|
||||
item.bindItem.originalPhNum = item.bindNum;
|
||||
this.$delete(this.stockingBindDraftMap, item.purchaseId);
|
||||
});
|
||||
}
|
||||
|
||||
this.handleShowStockingDetail(this.stockingDetailRow);
|
||||
this.getList();
|
||||
}).catch(() => {
|
||||
loading.close();
|
||||
});
|
||||
}).catch(() => {});
|
||||
},
|
||||
/** 格式化备货状态 */
|
||||
formatOrderStockingStatus(value) {
|
||||
const statusMap = {
|
||||
|
|
@ -1069,6 +1072,64 @@ export default {
|
|||
BHWC: 'stocking-status--green'
|
||||
};
|
||||
return classMap[value] || 'stocking-status--yellow';
|
||||
},
|
||||
handleGenerateVirtualPurchase(item) {
|
||||
this.currentPurchaseOrderData = null;
|
||||
this.virtualPurchaseProductInfo = {
|
||||
productCode: item.productCode,
|
||||
model: item.model,
|
||||
productType: item.productType,
|
||||
vendorName: item.vendorName,
|
||||
vendorCode: item.vendorCode,
|
||||
orderNum: item.orderNum,
|
||||
orderCode: this.stockingDetailRow.orderCode,
|
||||
projectName: this.stockingDetailRow.projectName,
|
||||
projectCode: this.stockingDetailRow.projectCode
|
||||
};
|
||||
this.purchaseOpen = true;
|
||||
this.purchaseTitle = `生成虚拟采购单 - ${item.model || item.productCode}`;
|
||||
},
|
||||
submitPurchaseForm() {
|
||||
this.$refs.purchaseOrderDetail.submitForm();
|
||||
},
|
||||
cancelPurchase() {
|
||||
this.purchaseOpen = false;
|
||||
},
|
||||
handleOuterSnPageChange() {
|
||||
},
|
||||
handlePurchaseSuccess() {
|
||||
this.purchaseOpen = false;
|
||||
this.$message.success('采购单创建成功');
|
||||
this.getList();
|
||||
if (this.virtualPurchaseProductInfo && this.stockingDetailVisible) {
|
||||
this.refreshCurrentProductBindList(this.virtualPurchaseProductInfo.productCode);
|
||||
}
|
||||
},
|
||||
refreshCurrentProductBindList(productCode) {
|
||||
const targetItem = this.stockingDetailList.find(item => item.productCode === productCode);
|
||||
if (!targetItem) {
|
||||
return;
|
||||
}
|
||||
this.loadAllBindData(this.stockingDetailRow.orderCode, targetItem).then(allBindList => {
|
||||
const bindPageNum = targetItem.bindPageNum || 1;
|
||||
const bindPageSize = targetItem.bindPageSize || this.stockingBindPageSize;
|
||||
const startIndex = (bindPageNum - 1) * bindPageSize;
|
||||
const endIndex = startIndex + bindPageSize;
|
||||
const bindList = allBindList.slice(startIndex, endIndex);
|
||||
this.stockingDetailList = this.stockingDetailList.map(item => {
|
||||
if (item.productCode === productCode) {
|
||||
return {
|
||||
...item,
|
||||
allBindList: allBindList,
|
||||
bindList: bindList,
|
||||
bindTotal: allBindList.length
|
||||
};
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}).catch(() => {
|
||||
this.$message.error('刷新采购列表失败');
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1374,6 +1435,12 @@ export default {
|
|||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.outer-sn-grid-header .pagination-container {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.outer-sn-current-count {
|
||||
flex: 1;
|
||||
margin-left: 16px;
|
||||
|
|
|
|||
|
|
@ -548,10 +548,10 @@ export default {
|
|||
this.$modal.msgWarning("请至少添加一条产品信息");
|
||||
return;
|
||||
}
|
||||
if (this.form.quantity!==this.form.inventoryInfoList.length && !this.isServiceIn){
|
||||
this.$modal.msgWarning("采购数量与入库数量不一致");
|
||||
return;
|
||||
}
|
||||
// if (this.form.quantity!==this.form.inventoryInfoList.length && !this.isServiceIn){
|
||||
// this.$modal.msgWarning("采购数量与入库数量不一致");
|
||||
// return;
|
||||
// }
|
||||
if (this.form.id != null) {
|
||||
updateInner(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
|
|
|
|||
|
|
@ -227,12 +227,11 @@ export default {
|
|||
});
|
||||
},
|
||||
handleSelectPurchaseBeforeImport() {
|
||||
if (((this.productData.orderType || '1') === '1' ) && !this.outerData.vendorName.startsWith('新华三') ) {
|
||||
// if (((this.productData.orderType || '1') === '1' ) && !this.outerData.vendorName.startsWith('新华三') ) {
|
||||
this.purchaseOrderSelectVisible = true;
|
||||
}else{
|
||||
this.handleImport()
|
||||
}
|
||||
|
||||
// }else{
|
||||
// this.handleImport()
|
||||
// }
|
||||
},
|
||||
handlePurchaseOrderSelect(order) {
|
||||
this.warehouseId = order.warehouseId;
|
||||
|
|
@ -304,6 +303,7 @@ export default {
|
|||
outerCode: this.outerData.outerCode,
|
||||
detailId: this.productData.id,
|
||||
productSnDataList: this.isImported ? this.snList : [],
|
||||
orderCode: this.queryParams.orderCode,
|
||||
};
|
||||
|
||||
addDelivery(data).then(() => {
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ import SelectProduct from "@/views/system/product/selectProduct";
|
|||
import FileUpload from "@/components/FileUpload";
|
||||
import { getDicts } from "@/api/system/dict/data";
|
||||
import TaxRateInput from "@/components/TaxRateInput/TaxInput.vue";
|
||||
import { listProduct } from "@/api/project/product";
|
||||
import request from '@/utils/request'
|
||||
|
||||
|
||||
|
|
@ -260,6 +261,7 @@ export default {
|
|||
approveStatus: 0,
|
||||
approveNode: null,
|
||||
confirmStatus: null,
|
||||
isVirtual: false,
|
||||
omsPurchaseOrderItemList: [
|
||||
{
|
||||
productType: null,
|
||||
|
|
@ -488,6 +490,65 @@ export default {
|
|||
}
|
||||
});
|
||||
},
|
||||
initVirtualPurchase(item) {
|
||||
this.resetForm();
|
||||
this.form.isVirtual = true;
|
||||
|
||||
const applyDefaults = () => {
|
||||
if (item.vendorCode && this.vendorOptions.length > 0) {
|
||||
const vendor = this.vendorOptions.find(v => v.vendorCode === item.vendorCode);
|
||||
if (vendor) {
|
||||
this.form.vendorId = vendor.vendorId;
|
||||
this.$nextTick(() => {
|
||||
this.handleVendorChange(vendor.vendorId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (item.productType && this.form.omsPurchaseOrderItemList.length > 0) {
|
||||
this.$set(this.form.omsPurchaseOrderItemList[0], 'productType', item.productType);
|
||||
|
||||
if (item.productCode && item.vendorCode) {
|
||||
listProduct({
|
||||
productCode: item.productCode,
|
||||
vendorCode: item.vendorCode,
|
||||
type: item.productType,
|
||||
pageNum: 1,
|
||||
pageSize: 1
|
||||
}).then(response => {
|
||||
if (response.rows && response.rows.length > 0) {
|
||||
const product = response.rows[0];
|
||||
const firstItem = this.form.omsPurchaseOrderItemList[0];
|
||||
this.$set(firstItem, 'productCode', product.productCode);
|
||||
this.$set(firstItem, 'productModel', product.model);
|
||||
this.$set(firstItem, 'productDescription', product.description);
|
||||
this.$set(firstItem, 'quantity', item.orderNum || 1);
|
||||
this.calculateRowTotal(firstItem);
|
||||
}
|
||||
}).catch(() => {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (item.projectCode && item.projectName) {
|
||||
this.form.remark = `${item.projectCode} ${item.projectName}`;
|
||||
}
|
||||
};
|
||||
|
||||
const vendorReady = this.vendorOptions.length > 0
|
||||
? Promise.resolve()
|
||||
: this.getVendorList();
|
||||
|
||||
const productTypeReady = this.productTypeOptions.length > 0
|
||||
? Promise.resolve()
|
||||
: getDicts('product_type').then(response => {
|
||||
this.productTypeOptions = response.data;
|
||||
});
|
||||
|
||||
Promise.all([vendorReady, productTypeReady]).then(() => {
|
||||
this.$nextTick(applyDefaults);
|
||||
});
|
||||
},
|
||||
resetForm() {
|
||||
this.form = {
|
||||
id: null,
|
||||
|
|
@ -511,6 +572,7 @@ export default {
|
|||
approveStatus: 0,
|
||||
approveNode: null,
|
||||
confirmStatus: null,
|
||||
isVirtual: false,
|
||||
omsPurchaseOrderItemList: [
|
||||
{
|
||||
productType: null,
|
||||
|
|
|
|||
|
|
@ -155,10 +155,10 @@ export default {
|
|||
this.handleQuery();
|
||||
},
|
||||
handleSelect(row) {
|
||||
if (this.quantity && this.quantity!==row.quantity){
|
||||
this.$message.error("请选择数量为"+this.quantity+"的采购单");
|
||||
return
|
||||
}
|
||||
// if (this.quantity && this.quantity!==row.quantity){
|
||||
// this.$message.error("请选择数量为"+this.quantity+"的采购单");
|
||||
// return
|
||||
// }
|
||||
this.$emit("select", row);
|
||||
this.handleClose();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@
|
|||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.approveStatus === '0' || scope.row.approveStatus === '3'"
|
||||
v-if="(scope.row.approveStatus === '0' || scope.row.approveStatus === '3') && !scope.row.isVirtual"
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-s-promotion"
|
||||
|
|
|
|||
|
|
@ -128,6 +128,9 @@ public class OmsPurchaseOrder extends BaseEntity
|
|||
@Excel(name = "备注", wrapText = true)
|
||||
private String remark;
|
||||
|
||||
/** 是否虚拟采购单 */
|
||||
private Boolean isVirtual;
|
||||
|
||||
/** 删除标志(0正常 1删除) */
|
||||
private Integer delFlag;
|
||||
|
||||
|
|
@ -164,14 +167,12 @@ public class OmsPurchaseOrder extends BaseEntity
|
|||
this.code = code;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Getter
|
||||
public enum FlowTypeEnum {
|
||||
ONLINE("online", "线上"),
|
||||
OFFLINE("offline", "线下"),
|
||||
|
||||
|
||||
;
|
||||
|
||||
private final String value;
|
||||
|
|
@ -181,25 +182,22 @@ public class OmsPurchaseOrder extends BaseEntity
|
|||
this.code = code;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@Getter
|
||||
|
||||
@Getter
|
||||
public enum StatusEnum {
|
||||
WAIT_COMPLETED(0, "待入库"),
|
||||
PART_COMPLETED(1, "部分入库"),
|
||||
COMPLETED(2, "已完成"),
|
||||
|
||||
|
||||
;
|
||||
|
||||
private final String value;
|
||||
private final Integer code;
|
||||
|
||||
StatusEnum(Integer code, String value) {
|
||||
StatusEnum(Integer code, String value) {
|
||||
this.code = code;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ public class OmsPurchaseOrderHistory extends BaseEntity
|
|||
/** 确认状态(0待确认 1已确认) */
|
||||
private String confirmStatus;
|
||||
|
||||
private Boolean isVirtual;
|
||||
|
||||
/** 删除标志(0正常 1删除) */
|
||||
private Integer delFlag;
|
||||
private String flowType;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import lombok.AllArgsConstructor;
|
|||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
|
|
@ -24,6 +26,9 @@ public class OrderProductMatchBindDto {
|
|||
/** 制造商 */
|
||||
private String vendorAddress;
|
||||
|
||||
/** 单价 */
|
||||
private Double price;
|
||||
|
||||
/** 采购数量 */
|
||||
private Integer cgNum;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,15 @@ public class OrderProductMatchDto {
|
|||
/** 产品型号 */
|
||||
private String model;
|
||||
|
||||
/** 产品类型 */
|
||||
private String productType;
|
||||
|
||||
/** 制造商编码 */
|
||||
private String vendorCode;
|
||||
|
||||
/** 制造商名称 */
|
||||
private String vendorName;
|
||||
|
||||
/** 订单数量 */
|
||||
private Integer orderNum;
|
||||
|
||||
|
|
|
|||
|
|
@ -89,4 +89,6 @@ public interface InventoryInfoMapper
|
|||
int updateOrderCodeByProductSnList(@Param("productSnList") List<String> productSnList, @Param("orderCode") String orderCode);
|
||||
|
||||
int countByOrderCodeAndPurchaseNo(@Param("orderCode") String orderCode, @Param("purchaseNo") String purchaseNo);
|
||||
|
||||
void clearOrderCodeByIds(@Param("idList") List<Long> idList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,5 +101,7 @@ public interface IOmsPurchaseOrderService
|
|||
|
||||
OmsPurchaseOrder selectOmsPurchaseOrderByNo(String purchaseNo);
|
||||
|
||||
List<OmsPurchaseOrderItem> listByItemId(Long itemId);
|
||||
|
||||
AddToNexRes addToNex(AddToNexReq addToNexReq);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,4 +122,6 @@ public interface IProjectOrderInfoService
|
|||
|
||||
int bindOrderSnCodes(BindOrderSnCodesDto params);
|
||||
|
||||
void refreshOrderStockingStatus(String orderCode);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ public class ExecutionTrackServiceImpl implements IExecutionTrackService {
|
|||
private IProjectOrderInfoRecallService projectOrderInfoRecallService;
|
||||
@Autowired
|
||||
private OmsPurchaseOrderMapMapper omsPurchaseOrderMapMapper;
|
||||
@Autowired
|
||||
private IInventoryOuterDetailService inventoryOuterDetailService;
|
||||
@Override
|
||||
public ExecutionOrderVo selectInfo(Long id) {
|
||||
ExecutionOrderVo vo = new ExecutionOrderVo();
|
||||
|
|
@ -310,6 +312,10 @@ public class ExecutionTrackServiceImpl implements IExecutionTrackService {
|
|||
inventoryOuter.setOrderCode(projectOrderInfo.getOrderCode());
|
||||
List<InventoryOuter> inventoryOuters = outerService.selectInventoryOuterList(inventoryOuter);
|
||||
if (CollUtil.isNotEmpty(inventoryOuters)) {
|
||||
List<String> outerCodeList = inventoryOuters.stream()
|
||||
.map(InventoryOuter::getOuterCode)
|
||||
.collect(Collectors.toList());
|
||||
inventoryOuterDetailService.deleteByOuterCode(outerCodeList);
|
||||
outerService.deleteInventoryOuterByIds(inventoryOuters.stream().map(item -> item.getId().toString()).collect(Collectors.joining(",")));
|
||||
}
|
||||
Map<String, Long> outerSumMap = inventoryOuters.stream().collect(Collectors.toMap(InventoryOuter::getProductCode, InventoryOuter::getQuantity, Long::sum));
|
||||
|
|
|
|||
|
|
@ -14,8 +14,10 @@ import com.ruoyi.common.utils.StringUtils;
|
|||
import com.ruoyi.sip.domain.*;
|
||||
import com.ruoyi.sip.dto.ApiDataQueryDto;
|
||||
import com.ruoyi.sip.dto.inventory.InventoryDeliveryDetailExcelDto;
|
||||
import com.ruoyi.sip.mapper.InventoryInfoMapper;
|
||||
import com.ruoyi.sip.mapper.InventoryOuterDetailMapper;
|
||||
import com.ruoyi.sip.mapper.InventoryOuterMapper;
|
||||
import com.ruoyi.sip.mapper.OmsPurchaseOrderMapMapper;
|
||||
import com.ruoyi.sip.service.*;
|
||||
import com.ruoyi.sip.vo.DeliveryApproveVo;
|
||||
import com.ruoyi.sip.vo.DeliveryInfoVo;
|
||||
|
|
@ -69,6 +71,12 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
|
|||
private IOmsPayableBillService payableBillService;
|
||||
@Autowired
|
||||
private IOmsReceivableBillService billService;
|
||||
@Autowired
|
||||
private IOmsPurchaseOrderService omsPurchaseOrderService;
|
||||
@Resource
|
||||
private OmsPurchaseOrderMapMapper omsPurchaseOrderMapMapper;
|
||||
@Resource
|
||||
private InventoryInfoMapper inventoryInfoMapper;
|
||||
|
||||
@Value("${oms.inventory.innerTax:0.13}")
|
||||
private String defaultTax;
|
||||
|
|
@ -104,6 +112,81 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
|
|||
@Override
|
||||
public int insertInventoryDelivery(InventoryDelivery inventoryDelivery) {
|
||||
|
||||
List<String> productSnList = inventoryDelivery.getProductSnList();
|
||||
List<InventoryInfo> productSnDataList = inventoryDelivery.getProductSnDataList();
|
||||
if (CollUtil.isEmpty(productSnList) && CollUtil.isEmpty(productSnDataList)) {
|
||||
throw new ServiceException("发货清单为空,保存失败");
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(inventoryDelivery.getOrderCode())) {
|
||||
ProjectOrderInfo orderInfo = projectOrderInfoService.selectProjectOrderInfoByOrderCode(inventoryDelivery.getOrderCode());
|
||||
if (orderInfo == null) {
|
||||
throw new ServiceException("订单信息不存在");
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(inventoryDelivery.getPurchaseNo())) {
|
||||
int newSnCount = CollUtil.isEmpty(productSnList) ? productSnDataList.size() : productSnList.size();
|
||||
OmsPurchaseOrder purchaseOrder = omsPurchaseOrderService.selectOmsPurchaseOrderByNo(inventoryDelivery.getPurchaseNo());
|
||||
if (purchaseOrder == null) {
|
||||
throw new ServiceException("采购单信息不存在");
|
||||
}
|
||||
OmsPurchaseOrderMap purchaseOrderMap = omsPurchaseOrderMapMapper.selectByOrderIdAndPurchaseId(orderInfo.getId(), purchaseOrder.getId());
|
||||
if (purchaseOrderMap == null || purchaseOrderMap.getBindNum() == null || purchaseOrderMap.getBindNum() <= 0) {
|
||||
throw new ServiceException("当前订单与采购单未建立绑定关系或绑定数量为0");
|
||||
}
|
||||
int totalBindNum = purchaseOrderMap.getBindNum();
|
||||
int alreadyBindNum = inventoryInfoMapper.countByOrderCodeAndPurchaseNo(inventoryDelivery.getOrderCode(), inventoryDelivery.getPurchaseNo());
|
||||
int remainingNum = totalBindNum - alreadyBindNum;
|
||||
if (newSnCount > remainingNum) {
|
||||
throw new ServiceException(String.format("新增SN码数量(%d)超过剩余可新增数量(%d),总绑定数(%d),已绑定数(%d)", newSnCount, remainingNum, totalBindNum, alreadyBindNum));
|
||||
}
|
||||
} else if (CollUtil.isNotEmpty(productSnList)) {
|
||||
List<InventoryInfo> inventoryInfoList = inventoryInfoMapper.listByProductSnList(productSnList);
|
||||
if (CollUtil.isEmpty(inventoryInfoList)) {
|
||||
throw new ServiceException("未找到SN码对应的库存信息");
|
||||
}
|
||||
Map<String, List<InventoryInfo>> innerCodeMap = inventoryInfoList.stream()
|
||||
.filter(info -> StringUtils.isNotEmpty(info.getInnerCode()))
|
||||
.collect(Collectors.groupingBy(InventoryInfo::getInnerCode));
|
||||
|
||||
Map<String, Long> purchaseNoCountMap = new HashMap<>();
|
||||
for (Map.Entry<String, List<InventoryInfo>> entry : innerCodeMap.entrySet()) {
|
||||
String innerCode = entry.getKey();
|
||||
OmsInventoryInner queryInner = new OmsInventoryInner();
|
||||
queryInner.setInnerCode(innerCode);
|
||||
List<OmsInventoryInner> innerList = omsInventoryInnerService.selectOmsInventoryInnerList(queryInner);
|
||||
if (CollUtil.isNotEmpty(innerList) && StringUtils.isNotEmpty(innerList.get(0).getPurchaseNo())) {
|
||||
String purchaseNo = innerList.get(0).getPurchaseNo();
|
||||
purchaseNoCountMap.put(purchaseNo, purchaseNoCountMap.getOrDefault(purchaseNo, 0L) + entry.getValue().size());
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Long> entry : purchaseNoCountMap.entrySet()) {
|
||||
String purchaseNo = entry.getKey();
|
||||
long newSnCount = entry.getValue();
|
||||
|
||||
OmsPurchaseOrder purchaseOrder = omsPurchaseOrderService.selectOmsPurchaseOrderByNo(purchaseNo);
|
||||
if (purchaseOrder == null) {
|
||||
throw new ServiceException(String.format("采购单[%s]信息不存在", purchaseNo));
|
||||
}
|
||||
|
||||
OmsPurchaseOrderMap purchaseOrderMap = omsPurchaseOrderMapMapper.selectByOrderIdAndPurchaseId(orderInfo.getId(), purchaseOrder.getId());
|
||||
if (purchaseOrderMap == null || purchaseOrderMap.getBindNum() == null || purchaseOrderMap.getBindNum() <= 0) {
|
||||
throw new ServiceException(String.format("订单与采购单[%s]未建立绑定关系或绑定数量为0", purchaseNo));
|
||||
}
|
||||
|
||||
int totalBindNum = purchaseOrderMap.getBindNum();
|
||||
int alreadyBindNum = inventoryInfoMapper.countByOrderCodeAndPurchaseNo(inventoryDelivery.getOrderCode(), purchaseNo);
|
||||
int remainingNum = totalBindNum - alreadyBindNum;
|
||||
|
||||
if (newSnCount > remainingNum) {
|
||||
throw new ServiceException(String.format("采购单[%s]新增SN码数量(%d)超过剩余可新增数量(%d),总绑定数(%d),已绑定数(%d)",
|
||||
purchaseNo, newSnCount, remainingNum, totalBindNum, alreadyBindNum));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Date nowDate = DateUtils.getNowDate();
|
||||
inventoryDelivery.setCreateTime(nowDate);
|
||||
String currentUserId = ShiroUtils.getUserId().toString();
|
||||
|
|
@ -112,12 +195,6 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
|
|||
inventoryDelivery.setUpdateBy(currentUserId);
|
||||
inventoryDelivery.setUpdateTime(nowDate);
|
||||
inventoryDelivery.setDeliveryStatus(InventoryDelivery.DeliveryStatusEnum.WAIT_DELIVERY.getCode());
|
||||
//处理库存
|
||||
List<String> productSnList = inventoryDelivery.getProductSnList();
|
||||
List<InventoryInfo> productSnDataList = inventoryDelivery.getProductSnDataList();
|
||||
if (CollUtil.isEmpty(productSnList) && CollUtil.isEmpty(productSnDataList)) {
|
||||
throw new ServiceException("发货清单为空,保存失败");
|
||||
}
|
||||
//修改数据的时候同步修改出库价
|
||||
BigDecimal bigDecimal = inventoryOuterMapper.selectOutPriceByCode(inventoryDelivery.getOuterCode());
|
||||
|
||||
|
|
@ -131,6 +208,7 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
|
|||
info.setUpdateBy(currentUserId);
|
||||
info.setUpdateTime(nowDate);
|
||||
info.setOuterPrice(bigDecimal);
|
||||
info.setOrderCode(inventoryDelivery.getOrderCode());
|
||||
OmsInventoryDeliveryDetail detail = new OmsInventoryDeliveryDetail();
|
||||
detail.setProductSn(item);
|
||||
detailList.add(detail);
|
||||
|
|
@ -149,6 +227,7 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
|
|||
inventoryInfo.setUpdateBy(currentUserId);
|
||||
inventoryInfo.setUpdateTime(nowDate);
|
||||
inventoryInfo.setOuterPrice(bigDecimal);
|
||||
inventoryInfo.setOrderCode(inventoryDelivery.getOrderCode());
|
||||
OmsInventoryDeliveryDetail detail = new OmsInventoryDeliveryDetail();
|
||||
detail.setProductSn(inventoryInfo.getProductSn());
|
||||
detailList.add(detail);
|
||||
|
|
@ -168,6 +247,7 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
|
|||
}
|
||||
deliveryDetailService.saveBatch(detailList);
|
||||
}
|
||||
projectOrderInfoService.refreshOrderStockingStatus(inventoryDelivery.getOrderCode());
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
@ -417,7 +497,12 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
|
|||
if (realDelete) {
|
||||
// 原逻辑,删除库存表以及sn码的关联
|
||||
deliveryDetailService.deleteOmsInventoryDeliveryDetailByDeliveryId(id);
|
||||
return inventoryDeliveryMapper.deleteInventoryDeliveryById(id);
|
||||
if (CollUtil.isNotEmpty(inventoryInfos)) {
|
||||
inventoryInfoMapper.clearOrderCodeByIds(inventoryInfos.stream().map(InventoryInfo::getId).collect(Collectors.toList()));
|
||||
}
|
||||
int result = inventoryDeliveryMapper.deleteInventoryDeliveryById(id);
|
||||
projectOrderInfoService.refreshOrderStockingStatus(inventoryDelivery.getOrderCode());
|
||||
return result;
|
||||
} else {
|
||||
// 2026-03-19:新逻辑,仅修改发货单状态为撤回,不删除库存表
|
||||
InventoryDelivery updateDelivery = new InventoryDelivery();
|
||||
|
|
@ -425,6 +510,10 @@ public class InventoryDeliveryServiceImpl implements IInventoryDeliveryService {
|
|||
updateDelivery.setDeliveryStatus(InventoryDelivery.DeliveryStatusEnum.RECALL_DELIVERY.getCode());
|
||||
updateDelivery.setUpdateTime(DateUtils.getNowDate());
|
||||
int rows = inventoryDeliveryMapper.updateInventoryDelivery(updateDelivery);
|
||||
if (CollUtil.isNotEmpty(inventoryInfos)) {
|
||||
inventoryInfoMapper.clearOrderCodeByIds(inventoryInfos.stream().map(InventoryInfo::getId).collect(Collectors.toList()));
|
||||
}
|
||||
projectOrderInfoService.refreshOrderStockingStatus(inventoryDelivery.getOrderCode());
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,6 +144,36 @@ public class OmsInventoryInnerServiceImpl implements IOmsInventoryInnerService {
|
|||
}
|
||||
omsInventoryInner.setWarehouseId(warehouseIdList.get(0));
|
||||
|
||||
if (omsInventoryInner.getItemId() != null) {
|
||||
List<OmsPurchaseOrderItem> purchaseOrderItems = purchaseOrderService.listByItemId(omsInventoryInner.getItemId());
|
||||
if (CollUtil.isNotEmpty(purchaseOrderItems)) {
|
||||
OmsPurchaseOrderItem purchaseOrderItem = purchaseOrderItems.stream()
|
||||
.filter(item -> item.getId().equals(omsInventoryInner.getItemId()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (purchaseOrderItem != null) {
|
||||
int purchaseQuantity = purchaseOrderItem.getQuantity() != null ? purchaseOrderItem.getQuantity().intValue() : 0;
|
||||
int alreadyInnerQuantity = purchaseOrderItem.getInnerQuantity() != null ? purchaseOrderItem.getInnerQuantity().intValue() : 0;
|
||||
int remainingQuantity = purchaseQuantity - alreadyInnerQuantity;
|
||||
|
||||
int currentInnerQuantity = omsInventoryInner.getQuantity() != null ? omsInventoryInner.getQuantity().intValue() : inventoryInfoList.size();
|
||||
if (currentInnerQuantity > remainingQuantity) {
|
||||
throw new ServiceException(StrUtil.format("入库数量[{}]超过采购单剩余可入库数量[{}]", currentInnerQuantity, remainingQuantity));
|
||||
}
|
||||
|
||||
BigDecimal purchasePrice = purchaseOrderItem.getPrice();
|
||||
if (purchasePrice != null) {
|
||||
for (InventoryInfo inventoryInfo : inventoryInfoList) {
|
||||
if (inventoryInfo.getInnerPrice() != null && inventoryInfo.getInnerPrice().compareTo(purchasePrice) != 0) {
|
||||
throw new ServiceException(StrUtil.format("入库价[{}]必须等于采购单单价[{}]", inventoryInfo.getInnerPrice(), purchasePrice));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OmsPayableBill payableBill = new OmsPayableBill();
|
||||
VendorInfo vendorInfo = vendorInfoService.selectVendorInfoByVendorCode(vendorCode);
|
||||
if ((vendorInfo != null && VendorInfo.PayTypeEnum.INNER_PAY.getCode().equals(vendorInfo.getPayType())) || !Arrays.asList("1", "2").contains(omsInventoryInner.getProductType())) {
|
||||
|
|
|
|||
|
|
@ -160,7 +160,13 @@ public class OmsPurchaseOrderServiceImpl implements IOmsPurchaseOrderService, To
|
|||
omsPurchaseOrder.setOwnerName(ShiroUtils.getSysUser().getUserName());
|
||||
}
|
||||
omsPurchaseOrder.setCreateTime(DateUtils.getNowDate());
|
||||
omsPurchaseOrder.setPurchaseNo(generatePurchaseNo(omsPurchaseOrder.getVendorId()));
|
||||
String purchaseNo = generatePurchaseNo(omsPurchaseOrder.getVendorId(), Boolean.TRUE.equals(omsPurchaseOrder.getIsVirtual()));
|
||||
if (Boolean.TRUE.equals(omsPurchaseOrder.getIsVirtual())) {
|
||||
omsPurchaseOrder.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
|
||||
omsPurchaseOrder.setConfirmStatus(OmsPurchaseOrder.ConfirmStatusEnum.CONFIRM.getCode());
|
||||
omsPurchaseOrder.setFlowType(OmsPurchaseOrder.FlowTypeEnum.ONLINE.getCode());
|
||||
}
|
||||
omsPurchaseOrder.setPurchaseNo(purchaseNo);
|
||||
// 设置初始版本号为 1
|
||||
omsPurchaseOrder.setVersion(1);
|
||||
int rows = omsPurchaseOrderMapper.insertOmsPurchaseOrder(omsPurchaseOrder);
|
||||
|
|
@ -172,10 +178,11 @@ public class OmsPurchaseOrderServiceImpl implements IOmsPurchaseOrderService, To
|
|||
* 生成订单编号
|
||||
*
|
||||
* @param vendorId 制造商ID
|
||||
* @param isVirtual 是否为虚拟采购单
|
||||
* @return 订单编号
|
||||
*/
|
||||
|
||||
private String generatePurchaseNo(Long vendorId) {
|
||||
private String generatePurchaseNo(Long vendorId, boolean isVirtual) {
|
||||
VendorInfo vendorInfo = vendorInfoService.selectVendorInfoByVendorId(vendorId);
|
||||
if (vendorInfo==null || StringUtils.isEmpty(vendorInfo.getProvince())) {
|
||||
throw new ServiceException("制造商所属省为空,无法生成订单编号");
|
||||
|
|
@ -191,6 +198,9 @@ public class OmsPurchaseOrderServiceImpl implements IOmsPurchaseOrderService, To
|
|||
}
|
||||
String shortCode = cnareas.get(0).getShortCode();
|
||||
StringBuilder result = new StringBuilder();
|
||||
if (isVirtual) {
|
||||
result.append("XN-");
|
||||
}
|
||||
result.append("ZGCV-").append(currentDate).append(shortCode);
|
||||
// 查询当天已有的订单数量,用于生成顺序编码
|
||||
int count = omsPurchaseOrderMapper.selectMaxOrderCode(result.toString());
|
||||
|
|
@ -222,6 +232,11 @@ public class OmsPurchaseOrderServiceImpl implements IOmsPurchaseOrderService, To
|
|||
omsPurchaseOrder.setUpdateTime(DateUtils.getNowDate());
|
||||
// 版本号 +1
|
||||
omsPurchaseOrder.setVersion(oldOrder.getVersion() + 1);
|
||||
if (Boolean.TRUE.equals(omsPurchaseOrder.getIsVirtual())) {
|
||||
omsPurchaseOrder.setApproveStatus(ApproveStatusEnum.APPROVE_COMPLETE.getCode());
|
||||
omsPurchaseOrder.setConfirmStatus(OmsPurchaseOrder.ConfirmStatusEnum.CONFIRM.getCode());
|
||||
omsPurchaseOrder.setFlowType(OmsPurchaseOrder.FlowTypeEnum.ONLINE.getCode());
|
||||
}
|
||||
omsPurchaseOrderMapper.deleteOmsPurchaseOrderItemByPurchaseId(omsPurchaseOrder.getId());
|
||||
insertOmsPurchaseOrderItem(omsPurchaseOrder);
|
||||
return omsPurchaseOrderMapper.updateOmsPurchaseOrder(omsPurchaseOrder);
|
||||
|
|
@ -419,6 +434,11 @@ public class OmsPurchaseOrderServiceImpl implements IOmsPurchaseOrderService, To
|
|||
return omsPurchaseOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OmsPurchaseOrderItem> listByItemId(Long itemId) {
|
||||
return omsPurchaseOrderMapper.listByItemId(itemId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 新增采购单明细表信息
|
||||
|
|
@ -497,17 +517,27 @@ public class OmsPurchaseOrderServiceImpl implements IOmsPurchaseOrderService, To
|
|||
if (omsPurchaseOrder == null) {
|
||||
throw new ServiceException("采购订单不存在");
|
||||
}
|
||||
// 只有审批状态为“已通过”(2) 且 供应商确认状态为空或 null 时才能撤回
|
||||
if (ApproveStatusEnum.APPROVE_COMPLETE.getCode().equals(omsPurchaseOrder.getApproveStatus()) &&
|
||||
(StringUtils.isEmpty(omsPurchaseOrder.getConfirmStatus()) || "".equals(omsPurchaseOrder.getConfirmStatus())|| OmsPurchaseOrder.ConfirmStatusEnum.REJECT.getCode().equals(omsPurchaseOrder.getConfirmStatus()))) {
|
||||
// 只有审批状态为"已通过"(2) 时才能撤回,虚拟采购单不校验供应商确认状态
|
||||
boolean isVirtual = Boolean.TRUE.equals(omsPurchaseOrder.getIsVirtual());
|
||||
boolean canRecall = false;
|
||||
if (ApproveStatusEnum.APPROVE_COMPLETE.getCode().equals(omsPurchaseOrder.getApproveStatus())) {
|
||||
if (isVirtual) {
|
||||
canRecall = true;
|
||||
} else {
|
||||
canRecall = StringUtils.isEmpty(omsPurchaseOrder.getConfirmStatus()) ||
|
||||
"".equals(omsPurchaseOrder.getConfirmStatus()) ||
|
||||
OmsPurchaseOrder.ConfirmStatusEnum.REJECT.getCode().equals(omsPurchaseOrder.getConfirmStatus());
|
||||
}
|
||||
}
|
||||
if (canRecall) {
|
||||
// 保存历史记录
|
||||
saveOrderHistory(omsPurchaseOrder);
|
||||
|
||||
omsPurchaseOrder.setApproveStatus(ApproveStatusEnum.WAIT_COMMIT.getCode()); // 设置为待审批(草稿)
|
||||
omsPurchaseOrder.setApproveTime(null); // 清空审批时间
|
||||
omsPurchaseOrder.setConfirmStatus(null); // 清空审批时间
|
||||
omsPurchaseOrder.setApproveStatus(ApproveStatusEnum.WAIT_COMMIT.getCode());
|
||||
omsPurchaseOrder.setApproveTime(null);
|
||||
omsPurchaseOrder.setConfirmStatus(null);
|
||||
omsPurchaseOrder.setUpdateTime(DateUtils.getNowDate());
|
||||
omsPurchaseOrder.setVersion(omsPurchaseOrder.getVersion() + 1); // 版本号 +1
|
||||
omsPurchaseOrder.setVersion(omsPurchaseOrder.getVersion() + 1);
|
||||
return omsPurchaseOrderMapper.recallPurchaseOrder(omsPurchaseOrder);
|
||||
} else {
|
||||
throw new ServiceException("当前订单状态不允许撤回");
|
||||
|
|
|
|||
|
|
@ -2879,17 +2879,7 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
|
|||
|
||||
@Override
|
||||
public List<OrderProductMatchDto> selectProductMatchList(String orderCode) {
|
||||
List<OrderProductMatchDto> orderProductMatchDtos = projectOrderInfoMapper.selectProductMatchList(orderCode);
|
||||
List<OrderProductMatchBindDto> orderProductMatchBindDtos = projectOrderInfoMapper.selectProductMatchBindList(orderCode, null);
|
||||
Map<String, Integer> kyNumMap = orderProductMatchBindDtos.stream().filter(
|
||||
item -> !item.getStatus().equals("0"))
|
||||
.collect(Collectors.toMap(OrderProductMatchBindDto::getProductCode, item -> item.getKyNum() != null ? item.getKyNum() : 0, Integer::sum));
|
||||
|
||||
for (OrderProductMatchDto orderProductMatchDto : orderProductMatchDtos) {
|
||||
orderProductMatchDto.setPhNum(orderProductMatchDto.getPhNum()+
|
||||
(kyNumMap.get(orderProductMatchDto.getProductCode())==null?0:kyNumMap.get(orderProductMatchDto.getProductCode())));
|
||||
}
|
||||
return orderProductMatchDtos;
|
||||
return projectOrderInfoMapper.selectProductMatchList(orderCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2944,21 +2934,6 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
|
|||
if (CollUtil.isNotEmpty(params.getProductSnList())) {
|
||||
result = inventoryInfoMapper.updateOrderCodeByProductSnList(params.getProductSnList(), params.getOrderCode());
|
||||
}
|
||||
//根据实际绑定的sn码修改订单与采购单的绑定数
|
||||
if (params.getOrderId() != null && params.getPurchaseId() != null && StringUtils.isNotEmpty(params.getPurchaseNo())) {
|
||||
int actualBindNum = inventoryInfoMapper.countByOrderCodeAndPurchaseNo(params.getOrderCode(), params.getPurchaseNo());
|
||||
OmsPurchaseOrderMap map = omsPurchaseOrderMapMapper.selectByOrderIdAndPurchaseId(params.getOrderId(), params.getPurchaseId());
|
||||
if (map == null) {
|
||||
map = new OmsPurchaseOrderMap();
|
||||
map.setOrderId(params.getOrderId());
|
||||
map.setPurchaseId(params.getPurchaseId());
|
||||
map.setBindNum(actualBindNum);
|
||||
omsPurchaseOrderMapMapper.insertOmsPurchaseOrderMap(map);
|
||||
} else {
|
||||
map.setBindNum(actualBindNum);
|
||||
omsPurchaseOrderMapMapper.updateOmsPurchaseOrderMap(map);
|
||||
}
|
||||
}
|
||||
//更新订单的备货状态
|
||||
this.refreshOrderStockingStatus(params.getOrderCode());
|
||||
return result;
|
||||
|
|
@ -2969,7 +2944,8 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
|
|||
*
|
||||
* @param orderCode
|
||||
*/
|
||||
private void refreshOrderStockingStatus(String orderCode) {
|
||||
@Override
|
||||
public void refreshOrderStockingStatus(String orderCode) {
|
||||
if (StringUtils.isEmpty(orderCode)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</sql>
|
||||
|
||||
<select id="selectInventoryInfoList" parameterType="InventoryInfo" resultMap="InventoryInfoResult">
|
||||
<include refid="selectInventoryInfoVo"/>
|
||||
select t1.id, t1.product_code, t1.product_sn, t1.license_key, t1.inventory_status, t1.inner_code, t1.outer_code, t1.order_code, t1.warehouse_id, t1.inner_price,t1.tax_rate,
|
||||
t1.outer_price, t1.create_by, t1.create_time, t1.update_by, t1.update_time ,
|
||||
t2.warehouse_name,t3.description as 'product_desc',t3.model,t3.type as product_type
|
||||
from oms_inventory_info t1
|
||||
left join oms_warehouse_info t2 on t1.warehouse_id = t2.id
|
||||
left join product_info t3 on t1.product_code = t3.product_code
|
||||
<if test="orderCode != null and orderCode != ''">
|
||||
left join oms_inventory_inner t4 on t1.inner_code = t4.inner_code
|
||||
left join oms_purchase_order t5 on t4.purchase_no = t5.purchase_no
|
||||
left join oms_purchase_order_map t6 on t5.id = t6.purchase_id
|
||||
left join project_order_info t7 on t6.order_id = t7.id and t7.order_code = #{orderCode}
|
||||
</if>
|
||||
<where>
|
||||
<if test="productCode != null and productCode != ''">and t1.product_code = #{productCode}</if>
|
||||
<if test="productCodeList != null and productCodeList != ''">and t1.product_code in
|
||||
|
|
@ -51,7 +62,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</if>
|
||||
<if test="innerCode != null and innerCode != ''">and t1.inner_code = #{innerCode}</if>
|
||||
<if test="outerCode != null and outerCode != ''">and t1.outer_code = #{outerCode}</if>
|
||||
<if test="orderCode != null and orderCode != ''">and t1.order_code = #{orderCode}</if>
|
||||
<if test="orderCode != null and orderCode != ''">
|
||||
and t6.bind_num > 0
|
||||
</if>
|
||||
<if test="warehouseId != null ">and t1.warehouse_id = #{warehouseId}</if>
|
||||
<if test="innerPrice != null ">and t1.inner_price = #{innerPrice}</if>
|
||||
<if test="outerPrice != null ">and t1.outer_price = #{outerPrice}</if>
|
||||
|
|
@ -166,10 +179,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
</insert>
|
||||
<insert id="saveBatch">
|
||||
insert into oms_inventory_info (product_code, product_sn, license_key, inventory_status, inner_code, outer_code
|
||||
, warehouse_id, inner_price, outer_price, create_by, create_time, update_by, update_time,payable_bill_code,tax_rate) values
|
||||
, warehouse_id, inner_price, outer_price, create_by, create_time, update_by, update_time,payable_bill_code,tax_rate,order_code) values
|
||||
<foreach item="item" index="index" collection="list" separator=",">
|
||||
(#{item.productCode}, #{item.productSn}, #{item.licenseKey}, #{item.inventoryStatus}, #{item.innerCode}, #{item.outerCode}
|
||||
, #{item.warehouseId}, #{item.innerPrice}, #{item.outerPrice}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime},#{item.payableBillCode},#{item.taxRate})
|
||||
, #{item.warehouseId}, #{item.innerPrice}, #{item.outerPrice}, #{item.createBy}, #{item.createTime}, #{item.updateBy}, #{item.updateTime},#{item.payableBillCode},#{item.taxRate},#{item.orderCode})
|
||||
</foreach>
|
||||
ON DUPLICATE KEY UPDATE
|
||||
license_key = VALUES(license_key),
|
||||
|
|
@ -177,7 +190,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
outer_code = VALUES(outer_code),
|
||||
outer_price = VALUES(outer_price),
|
||||
update_by = VALUES(update_by),
|
||||
update_time = now()
|
||||
update_time = now(),
|
||||
order_code = VALUES(order_code)
|
||||
</insert>
|
||||
|
||||
<update id="updateInventoryInfo" parameterType="InventoryInfo">
|
||||
|
|
@ -241,6 +255,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
and t2.purchase_no = #{purchaseNo}
|
||||
</select>
|
||||
|
||||
<update id="clearOrderCodeByIds">
|
||||
update oms_inventory_info
|
||||
set order_code = null,
|
||||
update_time = now()
|
||||
where id in
|
||||
<foreach item="id" collection="idList" separator="," open="(" close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<delete id="deleteInventoryInfoById" parameterType="Long">
|
||||
delete from oms_inventory_info where id = #{id}
|
||||
</delete>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<result property="approveTime" column="approve_time" />
|
||||
<result property="approveNode" column="approve_node" />
|
||||
<result property="confirmStatus" column="confirm_status" />
|
||||
<result property="isVirtual" column="is_virtual" />
|
||||
<result property="delFlag" column="del_flag" />
|
||||
<result property="version" column="version" />
|
||||
<result property="createBy" column="create_by" />
|
||||
|
|
@ -69,6 +70,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="approveTime != null">approve_time,</if>
|
||||
<if test="approveNode != null">approve_node,</if>
|
||||
<if test="confirmStatus != null">confirm_status,</if>
|
||||
<if test="isVirtual != null">is_virtual,</if>
|
||||
<if test="delFlag != null">del_flag,</if>
|
||||
<if test="version != null">version,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
|
|
@ -103,6 +105,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="approveTime != null">#{approveTime},</if>
|
||||
<if test="approveNode != null">#{approveNode},</if>
|
||||
<if test="confirmStatus != null">#{confirmStatus},</if>
|
||||
<if test="isVirtual != null">#{isVirtual},</if>
|
||||
<if test="delFlag != null">#{delFlag},</if>
|
||||
<if test="version != null">#{version},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<sql id="selectOmsPurchaseOrderVo">
|
||||
select t1.id, t1.purchase_no, t1.buyer_name, t1.buyer_address, t1.vendor_id, t1.currency, t1.purchaser_id, t1.purchaser_name
|
||||
, t1.purchaser_mobile, t1.purchaser_email, t1.warehouse_id, t1.pay_method, t1.owner_id, t1.owner_name, t1.remark, t1.total_amount
|
||||
, t1.status, t1.approve_status, t1.approve_time, t1.approve_node, t1.confirm_status, t1.purchase_date, t1.create_time, t1.update_time, t1.del_flag,t1.version,t1.flow_type
|
||||
, t1.status, t1.approve_status, t1.approve_time, t1.approve_node, t1.confirm_status, t1.is_virtual, t1.purchase_date, t1.create_time, t1.update_time, t1.del_flag,t1.version,t1.flow_type
|
||||
, t1.file_id
|
||||
from oms_purchase_order t1
|
||||
</sql>
|
||||
|
|
@ -71,7 +71,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<sql id="selectOmsPurchaseOrderRelationVo">
|
||||
select t1.id, t1.purchase_no, t1.buyer_name, t1.buyer_address, t1.vendor_id, t1.currency, t1.purchaser_id, t1.purchaser_name
|
||||
, t1.purchaser_mobile, t1.purchaser_email, t1.warehouse_id, t1.pay_method, t1.owner_id, t1.owner_name, t1.remark, t1.total_amount,t1.flow_type
|
||||
, t1.status, t1.approve_status, t1.approve_time, t1.approve_node, t1.confirm_status, t1.purchase_date, t1.create_time, t1.update_time, t1.del_flag,t1.version
|
||||
, t1.status, t1.approve_status, t1.approve_time, t1.approve_node, t1.confirm_status, t1.is_virtual, t1.purchase_date, t1.create_time, t1.update_time, t1.del_flag,t1.version
|
||||
, t1.file_id
|
||||
,t2.vendor_address,t2.vendor_name,t2.vendor_user,t2.vendor_code,t2.vendor_phone,t2.vendor_email,t3.warehouse_name,t1.remark,
|
||||
(select max(tax_rate) from oms_purchase_order_item as it where it.purchase_id = t1.id) as tax_rate
|
||||
|
|
@ -301,6 +301,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="approveTime != null">approve_time,</if>
|
||||
<if test="approveNode != null">approve_node,</if>
|
||||
<if test="confirmStatus != null">confirm_status,</if>
|
||||
<if test="isVirtual != null">is_virtual,</if>
|
||||
<if test="purchaseDate != null">purchase_date,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
|
|
@ -330,6 +331,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="approveTime != null">#{approveTime},</if>
|
||||
<if test="approveNode != null">#{approveNode},</if>
|
||||
<if test="confirmStatus != null">#{confirmStatus},</if>
|
||||
<if test="isVirtual != null">#{isVirtual},</if>
|
||||
<if test="purchaseDate != null">#{purchaseDate},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
|
|
@ -363,6 +365,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
<if test="approveTime != null">approve_time = #{approveTime},</if>
|
||||
<if test="approveNode != null">approve_node = #{approveNode},</if>
|
||||
<if test="confirmStatus != null">confirm_status = #{confirmStatus},</if>
|
||||
<if test="isVirtual != null">is_virtual = #{isVirtual},</if>
|
||||
<if test="purchaseDate != null">purchase_date = #{purchaseDate},</if>
|
||||
<if test="createTime != null">create_time = #{createTime},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
|
|
|
|||
|
|
@ -931,25 +931,29 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
select
|
||||
t3.product_code as product_code,
|
||||
t3.model,
|
||||
t3.type as product_type,
|
||||
t7.vendor_code,
|
||||
t7.vendor_name,
|
||||
t1.quantity as order_num,
|
||||
sum(ifnull(t5.bind_num, 0)) as ph_num,
|
||||
ifnull(t6.bh_num,0) as bh_num,ifnull(t6.sum_cost,0) as sum_cost
|
||||
ifnull(t6.bh_num,0) as bh_num,
|
||||
sum(ifnull(t5.bind_num, 0) * t4.price) as sum_cost
|
||||
from project_product_info as t1
|
||||
inner join project_order_info as t2
|
||||
on t1.project_id = t2.project_id
|
||||
inner join product_info as t3
|
||||
on t1.product_bom_code = t3.product_code
|
||||
left join oms_purchase_order_item as t4
|
||||
on t3.product_code = t4.product_code
|
||||
left join oms_purchase_order_map as t5
|
||||
on t2.id = t5.order_id and t4.purchase_id = t5.purchase_id
|
||||
left join (select count(1) bh_num, sum(inner_price) sum_cost, product_code
|
||||
from oms_inventory_info
|
||||
where order_code = #{orderCode}
|
||||
group by product_code) t6 on t3.product_code = t6.product_code
|
||||
inner join project_order_info as t2 on t1.project_id = t2.project_id
|
||||
inner join product_info as t3 on t1.product_bom_code = t3.product_code
|
||||
left join oms_purchase_order_item as t4 on t3.product_code = t4.product_code
|
||||
left join oms_purchase_order_map as t5 on t2.id = t5.order_id and t4.purchase_id = t5.purchase_id
|
||||
left join (
|
||||
select count(1) bh_num, product_code
|
||||
from oms_inventory_info
|
||||
where order_code = #{orderCode}
|
||||
group by product_code
|
||||
) t6 on t3.product_code = t6.product_code
|
||||
left join oms_vendor_info as t7 on t3.vendor_code = t7.vendor_code
|
||||
where t2.order_code = #{orderCode}
|
||||
and t3.type in (1, 2)
|
||||
group by t3.product_code, t3.model, t1.quantity
|
||||
group by t3.product_code, t3.model
|
||||
order by t3.type, t3.product_code
|
||||
</select>
|
||||
|
||||
<select id="selectProductMatchBindList" resultType="com.ruoyi.sip.dto.OrderProductMatchBindDto">
|
||||
|
|
@ -959,6 +963,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
t6.id as purchase_id,
|
||||
t6.purchase_no,
|
||||
(select vendor_address from oms_vendor_info as tt where tt.vendor_id = t6.vendor_id) as vendor_address,
|
||||
max(t4.price) as price,
|
||||
t4.quantity as cg_num,
|
||||
t4.quantity - ifnull((select sum(bind_num) from oms_purchase_order_map as tt where tt.purchase_id = t4.purchase_id), 0) as ky_num,
|
||||
t5.bind_num as ph_num,
|
||||
|
|
@ -1024,7 +1029,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||
on t1.inner_code = t2.inner_code
|
||||
left join oms_warehouse_info as t3
|
||||
on t2.warehouse_id = t3.id
|
||||
where t2.purchase_no = #{purchaseNo} and t1.inventory_status=0
|
||||
where t2.purchase_no = #{purchaseNo}
|
||||
order by t1.product_sn
|
||||
</select>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue