From 8639f19c82f6e263654db44286256bb8d028d2c2 Mon Sep 17 00:00:00 2001
From: 647556386 <647556386@qq.com>
Date: 星期日, 30 十一月 2025 10:10:40 +0800
Subject: [PATCH] 1
---
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Allocate/AllocateOrderController.cs | 20
项目代码/WIDESEA_WMSClient/src/views/stock/stockInfo.vue | 5
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_DTO/Allocate/AllocateDto.cs | 2
项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/SelectedStock.vue | 19
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs | 20
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue | 1985 +++++-----
项目代码/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js | 19
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs | 9
项目代码/WIDESEA_WMSClient/src/router/viewGird.js | 16
项目代码/WIDESEA_WMSClient/src/views/inbound/Dt_AllocateOrder.vue | 2
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/WIDESEA_BasicService.csproj | 1
项目代码/WMS无仓储版/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-shm | 0
项目代码/WIDESEA_WMSClient/src/views/inbound/allocateinboundOrder.vue | 16
项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/printView.vue | 2
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs | 65
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InboundOrderMenu.cs | 8
项目代码/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue | 19
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/ESSController.cs | 28
项目代码/WIDESEA_WMSClient/src/views/outbound/outboundOrder.vue | 2
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockStatusEmun.cs | 8
项目代码/WIDESEA_WMSClient/src/views/record/locationStatusChangeRecord.vue | 6
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundBatchPickingService.cs | 29
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs | 2
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Jobs/InventoryLockJob.cs | 22
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Outbound.cs | 260 +
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs | 1343 ++++++-
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Inbound.cs | 6
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WIDESEA_TaskInfoService.csproj | 1
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderGetDTO.cs | 45
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/SelectedStock.vue | 13
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs | 6
项目代码/WMS无仓储版/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-shm | 0
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs | 51
项目代码/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js | 14
项目代码/WIDESEA_WMSClient/src/extension/check/extend/StockSelect.vue | 347 ++
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs | 149
项目代码/WIDESEA_WMSClient/src/views/check/checkOrder.vue | 176
项目代码/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js | 7
项目代码/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue | 1278 +++++++
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Common/CommonEnum/PalletTypeEnum.cs | 14
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_PickingRecord.cs | 31
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs | 29
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/allocateOrderDetail.vue | 4
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_AllocateService/AllocateService.cs | 136
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundOrderDetailService.cs | 2
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutboundOrderEnum.cs | 8
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs | 304 +
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundBatch.cs | 68
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutStockLockInfoService.cs | 7
项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue | 209 +
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/BatchOutBoundDto.cs | 169
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundLockInfo.cs | 7
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/MaterialUnitService.cs | 12
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_DTO/Stock/StockSelectViewDTO.cs | 10
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundBatchPickingService.cs | 1441 ++++++++
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/DailySequenceService.cs | 52
项目代码/WIDESEA_WMSClient/src/views/outbound/allocateoutboundOrder.vue | 2
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Core/Helper/SqlSugarHelper.cs | 29
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutStockLockInfoService.cs | 2
项目代码/WIDESEA_WMSClient/src/views/check/ReCheckOrder.vue | 115
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs | 371 +
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/WIDESEA_OutboundService.csproj | 2
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrder.cs | 2
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundBatchPickingController.cs | 219 +
项目代码/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue | 19
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs | 11
项目代码/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue | 179
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/OutLockStockStatusEnum.cs | 20
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrderDetail.cs | 10
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs | 3
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IBasicService/IMaterialUnitService.cs | 2
项目代码/WIDESEA_WMSClient/src/extension/check/recheckOrder.js | 84
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderDetailService.cs | 632 +++
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Check/ReCheckOrderController.cs | 19
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/StockSelect.vue | 43
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_DTO/Task/WMSTaskDTO.cs | 11
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs | 2
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderAddDTO.cs | 5
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Allocate/Dt_AllocateOrderDetail.cs | 2
79 files changed, 8,461 insertions(+), 1,827 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/check/extend/StockSelect.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/check/extend/StockSelect.vue"
new file mode 100644
index 0000000..ae450b1
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/check/extend/StockSelect.vue"
@@ -0,0 +1,347 @@
+<template>
+ <div>
+ <vol-box
+ v-model="showDetialBox"
+ :lazy="true"
+ width="60%"
+ :padding="15"
+ title="鎸囧畾搴撳瓨"
+ >
+ <div class="box-head">
+ <el-alert :closable="false" style="width: 100%">
+ <el-row>
+ <el-col :span="16">
+ <span class="less-style">鐗╂枡鍚嶇О锛� {{ row.materielName }} </span>
+ <el-divider direction="vertical"></el-divider>
+ <span class="less-style">鐗╂枡缂栧彿锛� {{ row.materielCode }} </span>
+ <el-divider direction="vertical"></el-divider>
+ <span class="less-style">闇�姹傛暟閲忥細 {{ row.qty }} </span>
+ <el-divider direction="vertical"></el-divider>
+ <span :class="selectionClass">宸查�夋暟閲忥細 {{ selectionSum }} </span>
+ </el-col>
+ <el-col :span="8">
+ <el-link
+ type="primary"
+ size="small"
+ style="float: right; height: 20px; margin-right: 10px"
+ @click="getData"
+ >鍒锋柊</el-link
+ >
+ <el-link
+ type="primary"
+ size="small"
+ style="float: right; height: 20px; margin-right: 10px"
+ @click="openOutboundDialog"
+ >鐩存帴鍑哄簱</el-link
+ >
+ </el-col>
+ </el-row>
+ </el-alert>
+ </div>
+ <div class="box-table" style="margin-top: 1%">
+ <el-table
+ ref="singleTable"
+ :data="tableData"
+ style="width: 100%; height: 100%"
+ highlight-current-row
+ @row-click="handleRowClick"
+ height="500px"
+ @selection-change="handleSelectionChange"
+ >
+ <el-table-column type="selection" width="55"> </el-table-column>
+ <el-table-column
+ label="搴忓彿"
+ type="index"
+ fixed="left"
+ width="55"
+ align="center"
+ ></el-table-column>
+ <el-table-column
+ v-for="(item, index) in tableColumns.filter((x) => !x.hidden)"
+ :key="index"
+ :prop="item.prop"
+ :label="item.title"
+ :width="item.width"
+ align="center"
+ >
+ <template #default="scoped" v-if="item.type == 'icon'">
+ <el-tooltip
+ class="item"
+ effect="dark"
+ :content="item.title"
+ placement="bottom"
+ ><el-button
+ type="text"
+ @click="tableButtonClick(scoped.row, item)"
+ ><i :class="item.icon" style="font-size: 22px"></i></el-button
+ ></el-tooltip>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ <template #footer>
+ <el-button type="danger" size="small" @click="showDetialBox = false"
+ >鍏抽棴</el-button
+ >
+ </template>
+ </vol-box>
+
+ <!-- 鍑哄簱绔欏彴閫夋嫨寮圭獥锛堥潤鎬佹ā鏉垮疄鐜帮級 -->
+ <el-dialog
+ v-model="showOutboundDialog"
+ title="鍑哄簱鎿嶄綔 - 閫夋嫨鍑哄簱绔欏彴"
+ width="500px"
+ :append-to-body="true"
+ >
+ <el-form
+ :model="outboundForm"
+ :rules="outboundRules"
+ ref="outboundFormRef"
+ label-width="100px"
+ style="padding: 0 20px"
+ >
+ <el-form-item label="鍑哄簱绔欏彴" prop="selectedPlatform" style="margin-bottom: 24px">
+ <el-select
+ v-model="outboundForm.selectedPlatform"
+ placeholder="璇烽�夋嫨鍑哄簱绔欏彴锛�3-12锛�"
+ style="width: 100%; height: 40px"
+ >
+ <el-option
+ v-for="platform in platformOptions"
+ :key="platform.value"
+ :label="platform.label"
+ :value="platform.value"
+ ></el-option>
+ </el-select>
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <el-button @click="showOutboundDialog = false" style="margin-right: 8px">鍙栨秷</el-button>
+ <el-button type="primary" @click="confirmOutbound">纭畾鍑哄簱</el-button>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script>
+import VolBox from "@/components/basic/VolBox.vue";
+import { ElMessage } from "element-plus";
+
+export default {
+ components: { VolBox },
+ data() {
+ return {
+ row: null,
+ showDetialBox: false,
+ tableData: [],
+ tableColumns: [
+ { prop: "materielCode", title: "鐗╂枡缂栧彿", type: "string", width: 150 },
+ { prop: "barcode", title: "鐗╂枡鏉$爜", type: "string", width: 150 },
+ { prop: "palletCode", title: "鎵樼洏缂栧彿", type: "string", width: 150 },
+ { prop: "locationCode", title: "璐т綅缂栧彿", type: "string", width: 180 },
+ { prop: "useableQuantity", title: "鍙敤鏁伴噺", type: "string" },
+ ],
+ selection: [],
+ selectionSum: 0,
+ selectionClass: "less-style",
+ originalQuantity: 0,
+
+ // 鍑哄簱寮圭獥鐩稿叧鏁版嵁
+ showOutboundDialog: false,
+ outboundForm: { selectedPlatform: "" }, // 琛ㄥ崟缁戝畾鏁版嵁
+ outboundRules: {
+ selectedPlatform: [
+ { required: true, message: "璇烽�夋嫨鍑哄簱绔欏彴", trigger: "change" },
+ ],
+ },
+ platformOptions: [
+ { label: "绔欏彴2", value: "2-1" },
+ { label: "绔欏彴3", value: "3-1" },
+ ],
+ };
+ },
+ methods: {
+ open(row) {
+ this.row = row;
+ this.showDetialBox = true;
+ this.getData();
+ console.log(row.id)
+ this.updateSelectionClass(); // 鍒濆鍖栧凡閫夋暟閲忔牱寮�
+ },
+
+ lockStock() {
+ this.http
+ .post(
+ "api/OutboundOrderDetail/LockOutboundStock?id=" + this.row.id,
+ this.selection,
+ "鏁版嵁澶勭悊涓�"
+ )
+ .then((x) => {
+ if (!x.status) return ElMessage.error(x.message);
+ ElMessage.success("鎿嶄綔鎴愬姛");
+ this.showDetialBox = false;
+ this.$emit("parentCall", ($vue) => {
+ $vue.getData();
+ });
+ });
+ },
+
+ // 鎵撳紑鍑哄簱寮圭獥
+ openOutboundDialog() {
+ if (this.selection.length === 0) {
+ return ElMessage.error("璇烽�夋嫨鍗曟嵁鏄庣粏");
+ }
+ // 閲嶇疆琛ㄥ崟閬垮厤娈嬬暀鍊�
+ this.outboundForm.selectedPlatform = "";
+ this.showOutboundDialog = true;
+ },
+
+ // 纭鍑哄簱鎿嶄綔
+ confirmOutbound() {
+ this.$refs.outboundFormRef.validate((valid) => {
+ if (!valid) return;
+
+
+ if (this.selection.length <= 0) {
+ return this.$message.error("璇峰嬀閫�");
+ }
+ let url = this.pkcx
+ ? "api/Task/GenerateOutboundTask?orderDetailId="
+ : "api/Task/GenerateOutboundTask?orderDetailId=";
+ this.http
+ .post(url + this.row.id, this.selection, "鏁版嵁澶勭悊涓�")
+ .then((x) => {
+ if (!x.status) return this.$message.error(x.message);
+ this.$message.success("鎿嶄綔鎴愬姛");
+ this.showDetialBox = false;
+ this.$emit("parentCall", ($vue) => {
+ $vue.getData();
+ });
+ });
+
+ });
+ },
+
+ // 鍥哄畾鏌ヨ绔嬪簱搴撳瓨
+ getData() {
+ const url = "api/StockInfo/GetStockSelectViews?materielCode=";
+ this.http
+ .post(
+ url + this.row.materielCode + "&orderId=" + this.row.id,
+ null,
+ "鏌ヨ涓�"
+ )
+ .then((x) => {
+ this.tableData = x;
+ // 鍒锋柊鍚庢竻绌轰箣鍓嶇殑閫夋嫨鍜岃鏁�
+ this.clearSelection();
+ this.selectionSum = 0;
+ this.originalQuantity = 0;
+ this.updateSelectionClass();
+ });
+ },
+
+ revokeAssign() {
+ this.http
+ .post(
+ "api/OutboundOrderDetail/RevokeLockOutboundStock?id=" + this.row.id,
+ null,
+ "鏁版嵁澶勭悊涓�"
+ )
+ .then((x) => {
+ if (!x.status) return ElMessage.error(x.message);
+ ElMessage.success("鎿嶄綔鎴愬姛");
+ this.showDetialBox = false;
+ this.$emit("parentCall", ($vue) => {
+ $vue.getData();
+ });
+ });
+ },
+
+ handleSelectionChange(val) {
+ this.selection = val;
+ // 璁$畻宸查�夋暟閲忥紙杞暟瀛楅伩鍏嶅瓧绗︿覆鎷兼帴锛�
+ this.selectionSum = val.reduce(
+ (acc, curr) => acc + Number(curr.useableQuantity || 0),
+ 0
+ ) + this.originalQuantity;
+ this.updateSelectionClass();
+ },
+
+ // 鏇存柊宸查�夋暟閲忔牱寮�
+ updateSelectionClass() {
+ if (!this.row) return;
+ if (this.selectionSum === this.row.orderQuantity) {
+ this.selectionClass = "equle-style";
+ } else if (this.selectionSum < this.row.orderQuantity) {
+ this.selectionClass = "less-style";
+ } else {
+ this.selectionClass = "more-style";
+ }
+ },
+
+ toggleSelection(rows) {
+ rows ? rows.forEach((row) => this.$refs.singleTable.toggleRowSelection(row)) : this.clearSelection();
+ },
+
+ clearSelection() {
+ if (this.$refs.singleTable) {
+ this.$refs.singleTable.clearSelection();
+ }
+ },
+
+ handleRowClick(row) {
+ this.$refs.singleTable.toggleRowSelection(row);
+ },
+
+ // 鍥炬爣鎸夐挳鐐瑰嚮鍗犱綅鏂规硶锛堝彲鏍规嵁闇�姹傛墿灞曪級
+ tableButtonClick(row, item) {
+ console.log("鍥炬爣鎸夐挳鐐瑰嚮锛�", item.title, row);
+ },
+ },
+};
+</script>
+
+<style scoped>
+.less-style {
+ color: black;
+}
+
+.equle-style {
+ color: green;
+}
+
+.more-style {
+ color: red;
+}
+</style>
+
+<style>
+.text-button:hover {
+ background-color: #f0f9eb !important;
+}
+
+.el-table .warning-row {
+ background: oldlace;
+}
+
+.box-table .el-table tbody tr:hover > td {
+ background-color: #d8e0d4 !important;
+}
+
+.box-table .el-table tbody tr.current-row > td {
+ background-color: #f0f9eb !important;
+}
+
+.el-table .success-row {
+ background: #f0f9eb;
+}
+
+.box-table .el-table {
+ border: 1px solid #ebeef5;
+}
+
+.box-head .el-alert__content {
+ width: 100%;
+}
+</style>
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/check/recheckOrder.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/check/recheckOrder.js"
new file mode 100644
index 0000000..5637829
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/check/recheckOrder.js"
@@ -0,0 +1,84 @@
+/*****************************************************************************************
+** Author:jxx 2022
+** QQ:283591387
+**瀹屾暣鏂囨。瑙侊細http://v2.volcore.xyz/document/api 銆愪唬鐮佺敓鎴愰〉闈iewGrid銆�
+**甯哥敤绀轰緥瑙侊細http://v2.volcore.xyz/document/vueDev
+**鍚庡彴鎿嶄綔瑙侊細http://v2.volcore.xyz/document/netCoreDev
+*****************************************************************************************/
+//姝s鏂囦欢鏄敤鏉ヨ嚜瀹氫箟鎵╁睍涓氬姟浠g爜锛屽彲浠ユ墿灞曚竴浜涜嚜瀹氫箟椤甸潰鎴栬�呴噸鏂伴厤缃敓鎴愮殑浠g爜
+import gridBody from './extend/StockSelect.vue'
+
+let extension = {
+ components: {
+ //鏌ヨ鐣岄潰鎵╁睍缁勪欢
+ gridHeader: '',
+ gridBody: gridBody,
+ gridFooter: '',
+ //鏂板缓銆佺紪杈戝脊鍑烘鎵╁睍缁勪欢
+ modelHeader: '',
+ modelBody: '',
+ modelFooter: ''
+ },
+ tableAction: '', //鎸囧畾鏌愬紶琛ㄧ殑鏉冮檺(杩欓噷濉啓琛ㄥ悕,榛樿涓嶇敤濉啓)
+ buttons: { view: [], box: [], detail: [] }, //鎵╁睍鐨勬寜閽�
+ methods: {
+ //涓嬮潰杩欎簺鏂规硶鍙互淇濈暀涔熷彲浠ュ垹闄�
+ onInit() { //妗嗘灦鍒濆鍖栭厤缃墠锛�
+ this.columns.push({
+ field: '鎿嶄綔',
+ title: '鎿嶄綔',
+ width: 90,
+ fixed: 'right',
+ align: 'center',
+ formatter: (row) => {
+ return (
+ '<i style="cursor: pointer;color: #2d8cf0;"class="el-icon-view">鎸囧畾搴撳瓨</i>'
+ );
+ },
+ click: (row) => {
+ const table = this.$refs.table.$refs.table;
+ if (table) {
+ table.clearSelection();
+ table.toggleRowSelection(row, true);
+ }
+ this.$refs.gridBody.open(row);
+ }
+ });
+ },
+ onInited() {
+ //妗嗘灦鍒濆鍖栭厤缃悗
+ //濡傛灉瑕侀厤缃槑缁嗚〃,鍦ㄦ鏂规硶鎿嶄綔
+ //this.detailOptions.columns.forEach(column=>{ });
+ },
+ searchBefore(param) {
+ //鐣岄潰鏌ヨ鍓�,鍙互缁檖aram.wheres娣诲姞鏌ヨ鍙傛暟
+ //杩斿洖false锛屽垯涓嶄細鎵ц鏌ヨ
+ return true;
+ },
+ searchAfter(result) {
+ //鏌ヨ鍚庯紝result杩斿洖鐨勬煡璇㈡暟鎹�,鍙互鍦ㄦ樉绀哄埌琛ㄦ牸鍓嶅鐞嗚〃鏍肩殑鍊�
+ return true;
+ },
+ addBefore(formData) {
+ //鏂板缓淇濆瓨鍓峟ormData涓哄璞★紝鍖呮嫭鏄庣粏琛紝鍙互缁欑粰琛ㄥ崟璁剧疆鍊硷紝鑷繁杈撳嚭鐪媐ormData鐨勫��
+ return true;
+ },
+ updateBefore(formData) {
+ //缂栬緫淇濆瓨鍓峟ormData涓哄璞★紝鍖呮嫭鏄庣粏琛ㄣ�佸垹闄よ鐨処d
+ return true;
+ },
+ rowClick({ row, column, event }) {
+ //鏌ヨ鐣岄潰鐐瑰嚮琛屼簨浠�
+ // this.$refs.table.$refs.table.toggleRowSelection(row); //鍗曞嚮琛屾椂閫変腑褰撳墠琛�;
+ },
+ modelOpenAfter(row) {
+ //鐐瑰嚮缂栬緫銆佹柊寤烘寜閽脊鍑烘鍚庯紝鍙互鍦ㄦ澶勫啓閫昏緫锛屽锛屼粠鍚庡彴鑾峰彇鏁版嵁
+ //(1)鍒ゆ柇鏄紪杈戣繕鏄柊寤烘搷浣滐細 this.currentAction=='Add';
+ //(2)缁欏脊鍑烘璁剧疆榛樿鍊�
+ //(3)this.editFormFields.瀛楁='xxx';
+ //濡傛灉闇�瑕佺粰涓嬫媺妗嗚缃粯璁ゅ�硷紝璇烽亶鍘唗his.editFormOptions鎵惧埌瀛楁閰嶇疆瀵瑰簲data灞炴�х殑key鍊�
+ //鐪嬩笉鎳傚氨鎶婅緭鍑虹湅锛歝onsole.log(this.editFormOptions)
+ }
+ }
+};
+export default extension;
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js"
index 0ec3d7d..76c131e 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/allocateinboundOrder.js"
@@ -40,7 +40,7 @@
const targetRow = selectedRows[0];
- this.$emit('openPalletDialog', targetRow.inboundOrderNo);
+ this.$emit('openPalletDialog', targetRow.orderNo);
}
},
{
@@ -71,9 +71,8 @@
// 鍙戣捣鎾ら攢缁勭洏璇锋眰
try {
//console.log('鍙戣捣鎾ら攢缁勭洏璇锋眰锛屾墭鐩樺彿锛�', formData.palletCode.trim());
- const response = await http.post('/api/InboundOrder/CancelPalletGroup', {
- palletCode: formData.palletCode.trim()
- });
+ const response = await http.post('/api/InboundOrder/UndoPalletGroup?palletCode='+formData.palletCode.trim());
+
const { status, message, data } = response;
if (status) {
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue"
index b976153..db36e69 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/Pallet.vue"
@@ -1,37 +1,16 @@
<template>
- <vol-box
- v-model="groupPalletVisible"
- :title="'缁勭洏鎿嶄綔 - 鍗曟嵁鍙凤細' + currentDocNo"
- :height="1000"
- :width="1100"
- :padding="20"
- :modal="true"
-
- @open="handleDialogOpen"
- @close="handleDialogClose"
- >
- <div class="barcode-scanner-container">
-
+ <vol-box v-model="groupPalletVisible" :title="'缁勭洏鎿嶄綔 - 鍗曟嵁鍙凤細' + currentDocNo" :height="1000" :width="1100" :padding="20"
+ :modal="true" @open="handleDialogOpen" @close="handleDialogClose">
+ <div class="barcode-scanner-container">
+
<!-- 浠撳簱閫夋嫨 - 绱у噾甯冨眬 -->
<div class="location-section compact">
<el-form :model="form" :rules="rules" ref="locationForm" class="compact-form">
<el-form-item label="浠撳簱" prop="warehouseType" class="location-select compact-item">
- <el-select
- v-model="form.warehouseType"
- placeholder="璇烽�夋嫨浠撳簱"
- clearable
- filterable
- @change="handleWarehouseChange"
- style="width: 100%"
- :loading="warehouseLoading"
- size="medium"
- >
- <el-option
- v-for="item in warehouseTypes"
- :key="item.warehouseType"
- :label="item.warehouseTypeDesc"
- :value="item.warehouseType"
- />
+ <el-select v-model="form.warehouseType" placeholder="璇烽�夋嫨浠撳簱" clearable filterable
+ @change="handleWarehouseChange" style="width: 100%" :loading="warehouseLoading" size="medium">
+ <el-option v-for="item in warehouseTypes" :key="item.warehouseType" :label="item.warehouseTypeDesc"
+ :value="item.warehouseType" />
</el-select>
</el-form-item>
</el-form>
@@ -41,38 +20,26 @@
<div class="location-section compact">
<el-form :model="form" :rules="rules" ref="locationForm" class="compact-form">
<el-form-item label="浠撳簱鍖哄煙" prop="locationType" class="location-select compact-item">
- <el-select
- v-model="form.locationType"
- placeholder="璇峰厛閫夋嫨浠撳簱"
- clearable
- filterable
- @change="handleLocationChange"
- style="width: 100%"
- :loading="locationLoading"
- size="medium"
- >
- <el-option
- v-for="item in locationTypes"
- :key="item.locationType"
- :label="item.locationTypeDesc"
- :value="item.locationType"
- />
+ <el-select v-model="form.locationType" placeholder="璇峰厛閫夋嫨浠撳簱" clearable filterable
+ @change="handleLocationChange" style="width: 100%" :loading="locationLoading" size="medium">
+ <el-option v-for="item in locationTypes" :key="item.locationType" :label="item.locationTypeDesc"
+ :value="item.locationType" />
</el-select>
</el-form-item>
</el-form>
</div>
-
+
<!-- 鎵樼洏淇℃伅鏄剧ず - 绱у噾甯冨眬 -->
<div class="tray-info compact" v-if="trayBarcode">
<i class="el-icon-s-management"></i> 褰撳墠鏂欑: {{ trayBarcode }}
<span class="location-info" v-if="form.warehouseType">
- | 浠撳簱: {{ currentWarehouseName }}
+ | 浠撳簱: {{ currentWarehouseName }}
</span>
<span class="location-info" v-if="form.locationType">
| 浠撳簱鍖哄煙: {{ currentLocationDesc }}
</span>
</div>
-
+
<!-- 鎵爜鍖哄煙 - 绱у噾甯冨眬 -->
<div class="input-section compact">
<el-card shadow="hover" class="compact-card">
@@ -83,73 +50,45 @@
{{ form.locationType && form.warehouseType ? '鎵爜灏辩华' : '璇峰厛閫夋嫨浠撳簱鍜屼粨搴撳尯鍩�' }}
</span>
</div>
-
+
<!-- 鎵樼洏鏉$爜杈撳叆 -->
<div class="input-wrapper custom-input-group compact-input">
<div class="input-label">鏂欑鐮�</div>
- <el-input
- ref="trayInput"
- v-model="trayBarcode"
- placeholder="璇锋壂鎻忔垨杈撳叆鏂欑鐮佸悗鎸夊洖杞﹂敭"
- clearable
- :disabled="!form.locationType || !form.warehouseType"
- @keyup.enter.native="handleTraySubmit"
- @clear="handleTrayClear"
- @input="handleTrayInput"
- class="custom-input"
- size="medium"
- >
+ <el-input ref="trayInput" v-model="trayBarcode" placeholder="璇锋壂鎻忔垨杈撳叆鏂欑鐮佸悗鎸夊洖杞﹂敭" clearable
+ :disabled="!form.locationType || !form.warehouseType" @keyup.enter.native="handleTraySubmit"
+ @clear="handleTrayClear" @input="handleTrayInput" class="custom-input" size="medium">
<template slot="append">
- <el-button
- @click="handleTraySubmit"
- type="primary"
- icon="el-icon-position"
- :disabled="!form.locationType || !trayBarcode || !form.warehouseType"
- size="medium"
- >
+ <el-button @click="handleTraySubmit" type="primary" icon="el-icon-position"
+ :disabled="!form.locationType || !trayBarcode || !form.warehouseType" size="medium">
纭
</el-button>
</template>
</el-input>
</div>
-
+
<!-- 鐗╂枡鏉$爜杈撳叆 -->
<div class="input-wrapper custom-input-group compact-input">
<div class="input-label">鐗╂枡鏉$爜</div>
- <el-input
- ref="barcodeInput"
- v-model="barcode"
- placeholder="璇锋壂鎻忔垨杈撳叆鐗╂枡鏉$爜鍚庢寜鍥炶溅閿�"
- clearable
+ <el-input ref="barcodeInput" v-model="barcode" placeholder="璇锋壂鎻忔垨杈撳叆鐗╂枡鏉$爜鍚庢寜鍥炶溅閿�" clearable
:disabled="!form.locationType || !trayBarcode || !form.warehouseType"
- @keyup.enter.native="handleBarcodeSubmit"
- @clear="handleClear"
- @input="handleBarcodeInput"
- class="custom-input"
- size="medium"
- >
+ @keyup.enter.native="handleBarcodeSubmit" @clear="handleClear" @input="handleBarcodeInput"
+ class="custom-input" size="medium">
<template slot="append">
- <el-button
- :loading="loading"
- @click="handleBarcodeSubmit"
- type="primary"
- icon="el-icon-search"
- :disabled="!form.locationType || !trayBarcode || !barcode || !from.warehouseType"
- size="medium"
- >
+ <el-button :loading="loading" @click="handleBarcodeSubmit" type="primary" icon="el-icon-search"
+ :disabled="!form.locationType || !trayBarcode || !barcode || !from.warehouseType" size="medium">
{{ loading ? '鏌ヨ涓�...' : '鏌ヨ' }}
</el-button>
</template>
</el-input>
</div>
-
+
<div class="input-tips compact-tips">
<p>鎻愮ず锛氳鍏堥�夋嫨浠撳簱 鈫� 閫夋嫨浠撳簱鍖哄煙 鈫� 杈撳叆鏂欑鐮� 鈫� 杈撳叆鐗╂枡鏉$爜</p>
<p v-if="!form.warehouseType" class="warning-text">鈿狅笍 璇峰厛閫夋嫨浠撳簱</p>
<p v-if="!form.locationType && !form.warehouseType" class="warning-text">鈿狅笍 璇峰厛閫夋嫨浠撳簱鍖哄煙</p>
<p v-if="form.warehouseType && form.locationType && !trayBarcode" class="warning-text">鈿狅笍 璇峰厛杈撳叆鏂欑鐮�</p>
</div>
-
+
</el-card>
</div>
@@ -161,13 +100,7 @@
<!-- 閿欒鎻愮ず -->
<div v-if="error" class="error-message compact">
- <el-alert
- :title="error"
- type="error"
- show-icon
- closable
- @close="error = ''"
- />
+ <el-alert :title="error" type="error" show-icon closable @close="error = ''" />
</div>
<!-- 鐗╂枡鍒楄〃 - 鍥哄畾楂樺害甯︽粴鍔ㄦ潯 -->
@@ -184,7 +117,7 @@
<el-tag v-if="form.locationType" type="info" size="small">鍖哄煙: {{ currentLocationDesc }}</el-tag>
</span>
</div>
-
+
<div v-if="materials.length === 0" class="empty-state compact">
<i class="el-icon-document"></i>
<p v-if="!form.warehouseType">璇峰厛閫夋嫨浠撳簱</p>
@@ -192,15 +125,9 @@
<p v-else-if="!trayBarcode">璇峰厛杈撳叆鏂欑鏉$爜</p>
<p v-else>鏆傛棤鐗╂枡鏁版嵁锛岃鎵弿鎴栬緭鍏ョ墿鏂欐潯鐮�</p>
</div>
-
+
<div class="table-container" v-else>
- <el-table
- :data="materials"
- stripe
- style="width: 100%"
- height="100%"
- size="small"
- >
+ <el-table :data="materials" stripe style="width: 100%" height="100%" size="small">
<el-table-column type="index" label="搴忓彿" width="60" align="center"></el-table-column>
<el-table-column prop="barcode" label="鏉$爜" min-width="140" show-overflow-tooltip></el-table-column>
<el-table-column prop="materielCode" label="鐗╂枡缂栫爜" min-width="150" show-overflow-tooltip></el-table-column>
@@ -214,19 +141,19 @@
</el-card>
</div>
</div>
-
- <!-- <div slot="footer" class="dialog-footer">
+
+ <!-- <div slot="footer" class="dialog-footer">
<el-button @click="handleCancel">鍙栨秷</el-button>
<el-button type="primary" @click="handleConfirm">纭</el-button>
</div> -->
- </vol-box>
+ </vol-box>
</template>
<script>
import http from '@/api/http.js';
import VolBox from '@/components/basic/VolBox.vue';
import VolForm from '@/components/basic/VolForm.vue';
import VolTable from '@/components/basic/VolTable.vue';
-import { ElLoading, ElMessage,ElMessageBox } from 'element-plus';
+import { ElLoading, ElMessage, ElMessageBox } from 'element-plus';
import { ref, onMounted, onUnmounted } from 'vue'
import InboundOrder from '../../../views/inbound/inboundOrder.vue';
import { th } from 'element-plus/es/locales.mjs';
@@ -241,50 +168,50 @@
data() {
return {
- palletVisible: this.visible,
- trayBarcode: '',
- barcode: '',
- materials: [],
- loading: false,
- error: '',
- debugMode: false,
- currentFocus: 'warehouse',
-
- // 鎵爜鏋浉鍏冲彉閲�
- scanCode: '',
- lastKeyTime: null,
- isManualInput: false,
- isScanning: false,
- scanTimer: null,
- manualInputTimer: null,
- scanTarget: 'tray', // 褰撳墠鎵爜鐩爣: tray 鎴� material
+ palletVisible: this.visible,
+ trayBarcode: '',
+ barcode: '',
+ materials: [],
+ loading: false,
+ error: '',
+ debugMode: false,
+ currentFocus: 'warehouse',
- // 搴撳瓨缁熻鐩稿叧鍙橀噺
- totalStockSum: 0,
- totalStockCount: 0,
- uniqueUnit: '',
- sumLoading: false,
- sumError: '',
- // 浠撳簱鐩稿叧鍙橀噺
- warehouseTypes: [],
- warehouseLoading: false,
- // 浠撳簱鍖哄煙鐩稿叧鍙橀噺
- locationTypes: [],
- locationLoading: false,
- form: {
- warehouseType: null,
- locationType: null
- },
- rules: {
- locationType: [
- {
- validator: this.validateLocationType,
- trigger: 'change'
- }
- ],
- warehouseType: [
- {
- massage:'璇烽�夋嫨浠撳簱',
+ // 鎵爜鏋浉鍏冲彉閲�
+ scanCode: '',
+ lastKeyTime: null,
+ isManualInput: false,
+ isScanning: false,
+ scanTimer: null,
+ manualInputTimer: null,
+ scanTarget: 'tray', // 褰撳墠鎵爜鐩爣: tray 鎴� material
+
+ // 搴撳瓨缁熻鐩稿叧鍙橀噺
+ totalStockSum: 0,
+ totalStockCount: 0,
+ uniqueUnit: '',
+ sumLoading: false,
+ sumError: '',
+ // 浠撳簱鐩稿叧鍙橀噺
+ warehouseTypes: [],
+ warehouseLoading: false,
+ // 浠撳簱鍖哄煙鐩稿叧鍙橀噺
+ locationTypes: [],
+ locationLoading: false,
+ form: {
+ warehouseType: null,
+ locationType: null
+ },
+ rules: {
+ locationType: [
+ {
+ validator: this.validateLocationType,
+ trigger: 'change'
+ }
+ ],
+ warehouseType: [
+ {
+ massage: '璇烽�夋嫨浠撳簱',
trigger: 'change'
}
]
@@ -297,44 +224,44 @@
set(newVal) { this.$emit('update:visible', newVal); }
},
currentDocNo() { return this.docNo; },
- // 褰撳墠閫夋嫨鐨勪粨搴撳悕绉�
+ // 褰撳墠閫夋嫨鐨勪粨搴撳悕绉�
currentWarehouseName() {
const warehouse = this.warehouseTypes.find(item => item.warehouseType === this.form.warehouseType);
return warehouse ? warehouse.warehouseTypeDesc : '';
},
- // 褰撳墠閫夋嫨鐨勪粨搴撳尯鍩熸弿杩�
+ // 褰撳墠閫夋嫨鐨勪粨搴撳尯鍩熸弿杩�
currentLocationDesc() {
- const location = this.locationTypes.find(item => item.locationType === this.form.locationType)
- return location ? location.locationTypeDesc : ''
+ const location = this.locationTypes.find(item => item.locationType === this.form.locationType)
+ return location ? location.locationTypeDesc : ''
}
},
watch: {
visible(newVal, oldVal) {
- this.palletVisible = newVal;
-
- // 褰撲粠 false 鍙樹负 true 鏃讹紝琛ㄧず寮规鎵撳紑
- if (newVal === true && oldVal === false) {
- console.log('寮规鎵撳紑锛岄噸缃暟鎹�');
- this.resetData();
- this.$nextTick(() => {
- setTimeout(() => {
- // this.focusTrayInput();
- this.initwarehouseTypes(); // 鍒濆鍖栦粨搴�
- this.initLocationTypes(); // 鍒濆鍖栦粨搴撳尯鍩�
- this.fetchStockStatistics(); // 鍔犺浇缁熻鏁版嵁
- }, 300);
- });
- }
-
- // 褰撲粠 true 鍙樹负 false 鏃讹紝琛ㄧず寮规鍏抽棴
- if (newVal === false && oldVal === true) {
- console.log('寮规鍏抽棴锛岄噸缃暟鎹�');
- this.resetData();
- }
- },
- palletVisible(newVal) {
- this.$emit('update:visible', newVal);
- },
+ this.palletVisible = newVal;
+
+ // 褰撲粠 false 鍙樹负 true 鏃讹紝琛ㄧず寮规鎵撳紑
+ if (newVal === true && oldVal === false) {
+ console.log('寮规鎵撳紑锛岄噸缃暟鎹�');
+ this.resetData();
+ this.$nextTick(() => {
+ setTimeout(() => {
+ // this.focusTrayInput();
+ this.initwarehouseTypes(); // 鍒濆鍖栦粨搴�
+ this.initLocationTypes(); // 鍒濆鍖栦粨搴撳尯鍩�
+ this.fetchStockStatistics(); // 鍔犺浇缁熻鏁版嵁
+ }, 300);
+ });
+ }
+
+ // 褰撲粠 true 鍙樹负 false 鏃讹紝琛ㄧず寮规鍏抽棴
+ if (newVal === false && oldVal === true) {
+ console.log('寮规鍏抽棴锛岄噸缃暟鎹�');
+ this.resetData();
+ }
+ },
+ palletVisible(newVal) {
+ this.$emit('update:visible', newVal);
+ },
docNo(newVal) {
if (newVal) {
this.palletForm = { palletCode: '', barcode: '' };
@@ -345,160 +272,160 @@
}
},
'form.warehouseType'(newVal) {
- if (newVal) {
- this.form.locationType = null;
+ if (newVal) {
+ this.form.locationType = null;
+ } else {
+ this.locationTypes = [];
+ }
+ },
+
+ mounted() {
+
+ // 娣诲姞鍏ㄥ眬閿洏鐩戝惉
+ document.addEventListener('keypress', this.handleKeyPress);
+
+ // 浣跨敤setTimeout纭繚DOM瀹屽叏娓叉煋鍚庡啀鑱氱劍
+ setTimeout(() => {
+ // this.focusTrayInput();
+ this.focusLocationSelect();
+ }, 300);
+ },
+ beforeDestroy() {
+ // 娓呯悊浜嬩欢鐩戝惉
+ document.removeEventListener('keypress', this.handleKeyPress);
+ this.clearAllTimers();
+ },
+ methods: {
+ /**
+* 鑷畾涔変粨搴撳尯鍩熼獙璇�
+* 鍏佽鍊间负0锛屽洜涓�0鏄悎娉曠殑locationType
+*/
+ validateLocationType(rule, value, callback) {
+ // 妫�鏌ュ�兼槸鍚︿负null銆乽ndefined鎴栫┖瀛楃涓诧紝浣嗗厑璁告暟瀛�0
+ if (!this.form.warehouseType) {
+ callback(new Error('璇峰厛閫夋嫨浠撳簱'));
+ } else if (value === null || value === undefined || value === '') {
+ callback(new Error('璇烽�夋嫨浠撳簱鍖哄煙'));
} else {
- this.locationTypes = [];
+ callback();
+ }
+ },
+ /**
+ * 鍒濆鍖栦粨搴撳尯鍩熸暟鎹�
+ */
+ async initLocationTypes() {
+ this.locationLoading = true;
+ this.error = '';
+
+ try {
+ const response = await http.post('/api/LocationInfo/GetLocationTypes');
+
+ if (response.status && Array.isArray(response.data)) {
+ this.locationTypes = response.data;
+ if (this.locationTypes.length === 0) {
+ this.error = '鏈幏鍙栧埌浠撳簱鍖哄煙鏁版嵁';
+ } else {
+ // 濡傛灉鏈夐粯璁ゅ尯鍩燂紝鍙互鍦ㄨ繖閲岃缃�
+ // this.form.locationType = this.locationTypes[0].locationType;
+ }
+ } else {
+ this.error = '鑾峰彇浠撳簱鍖哄煙鏁版嵁澶辫触';
+ }
+ } catch (error) {
+ console.error('鑾峰彇浠撳簱鍖哄煙澶辫触:', error);
+ this.error = `鑾峰彇浠撳簱鍖哄煙澶辫触: ${error.message || '缃戠粶閿欒'}`;
+ } finally {
+ this.locationLoading = false;
}
},
- mounted() {
-
- // 娣诲姞鍏ㄥ眬閿洏鐩戝惉
- document.addEventListener('keypress', this.handleKeyPress);
-
- // 浣跨敤setTimeout纭繚DOM瀹屽叏娓叉煋鍚庡啀鑱氱劍
- setTimeout(() => {
- // this.focusTrayInput();
- this.focusLocationSelect();
- }, 300);
- },
- beforeDestroy() {
- // 娓呯悊浜嬩欢鐩戝惉
- document.removeEventListener('keypress', this.handleKeyPress);
- this.clearAllTimers();
- },
- methods: {
- /**
- * 鑷畾涔変粨搴撳尯鍩熼獙璇�
- * 鍏佽鍊间负0锛屽洜涓�0鏄悎娉曠殑locationType
- */
- validateLocationType(rule, value, callback) {
- // 妫�鏌ュ�兼槸鍚︿负null銆乽ndefined鎴栫┖瀛楃涓诧紝浣嗗厑璁告暟瀛�0
- if (!this.form.warehouseType) {
- callback(new Error('璇峰厛閫夋嫨浠撳簱'));
- } else if (value === null || value === undefined || value === '') {
- callback(new Error('璇烽�夋嫨浠撳簱鍖哄煙'));
- } else {
- callback();
- }
- },
- /**
- * 鍒濆鍖栦粨搴撳尯鍩熸暟鎹�
- */
- async initLocationTypes() {
- this.locationLoading = true;
- this.error = '';
-
- try {
- const response = await http.post('/api/LocationInfo/GetLocationTypes');
-
- if (response.status && Array.isArray(response.data)) {
- this.locationTypes = response.data;
- if (this.locationTypes.length === 0) {
- this.error = '鏈幏鍙栧埌浠撳簱鍖哄煙鏁版嵁';
- } else {
- // 濡傛灉鏈夐粯璁ゅ尯鍩燂紝鍙互鍦ㄨ繖閲岃缃�
- // this.form.locationType = this.locationTypes[0].locationType;
- }
- } else {
- this.error = '鑾峰彇浠撳簱鍖哄煙鏁版嵁澶辫触';
- }
- } catch (error) {
- console.error('鑾峰彇浠撳簱鍖哄煙澶辫触:', error);
- this.error = `鑾峰彇浠撳簱鍖哄煙澶辫触: ${error.message || '缃戠粶閿欒'}`;
- } finally {
- this.locationLoading = false;
- }
- },
+ /**
+ * 鍒濆鍖栦粨搴撴暟鎹�
+ */
+ async initwarehouseTypes() {
+ this.warehouseLoading = true;
+ this.error = '';
- /**
- * 鍒濆鍖栦粨搴撴暟鎹�
- */
- async initwarehouseTypes() {
- this.warehouseLoading = true;
- this.error = '';
-
- try {
- const response = await http.post('/api/Warehouse/GetwarehouseTypes');
-
- if (response.status && Array.isArray(response.data)) {
- this.warehouseTypes = response.data;
- if (this.warehouseTypes.length === 0) {
- this.error = '鏈幏鍙栧埌浠撳簱鏁版嵁';
- } else {
- // 濡傛灉鏈夐粯璁ゅ尯鍩燂紝鍙互鍦ㄨ繖閲岃缃�
- // this.form.locationType = this.locationTypes[0].locationType;
- }
- } else {
- this.error = '鑾峰彇浠撳簱鏁版嵁澶辫触';
- }
- } catch (error) {
- console.error('鑾峰彇浠撳簱澶辫触:', error);
- this.error = `鑾峰彇浠撳簱澶辫触: ${error.message || '缃戠粶閿欒'}`;
- } finally {
- this.warehouseLoading = false;
- }
- },
+ try {
+ const response = await http.post('/api/Warehouse/GetwarehouseTypes');
+
+ if (response.status && Array.isArray(response.data)) {
+ this.warehouseTypes = response.data;
+ if (this.warehouseTypes.length === 0) {
+ this.error = '鏈幏鍙栧埌浠撳簱鏁版嵁';
+ } else {
+ // 濡傛灉鏈夐粯璁ゅ尯鍩燂紝鍙互鍦ㄨ繖閲岃缃�
+ // this.form.locationType = this.locationTypes[0].locationType;
+ }
+ } else {
+ this.error = '鑾峰彇浠撳簱鏁版嵁澶辫触';
+ }
+ } catch (error) {
+ console.error('鑾峰彇浠撳簱澶辫触:', error);
+ this.error = `鑾峰彇浠撳簱澶辫触: ${error.message || '缃戠粶閿欒'}`;
+ } finally {
+ this.warehouseLoading = false;
+ }
+ },
- /**
- * 浠撳簱鍖哄煙鍙樻洿澶勭悊
- */
-handleLocationChange(value) {
- console.log('閫夋嫨浠撳簱鍖哄煙:', value, '绫诲瀷:', typeof value, this.currentLocationDesc);
-
- // 绔嬪嵆娓呴櫎閿欒淇℃伅
- this.error = '';
-
- // 鎵嬪姩瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
- this.$nextTick(() => {
- if (this.$refs.locationForm) {
- // 娓呴櫎璇ュ瓧娈电殑楠岃瘉鐘舵�侊紝鐒跺悗閲嶆柊楠岃瘉
- this.$refs.locationForm.clearValidate('locationType');
-
- // 鐭殏寤惰繜鍚庨噸鏂伴獙璇侊紝纭繚DOM宸叉洿鏂�
- setTimeout(() => {
- this.$refs.locationForm.validateField('locationType', (errorMsg) => {
- if (!errorMsg && (value === 0 || value)) {
- console.log('浠撳簱鍖哄煙楠岃瘉閫氳繃:', value);
- // 鍖哄煙閫夋嫨鍚庯紝鑷姩鑱氱劍鍒版墭鐩樿緭鍏ユ
- this.focusLocationSelect();
- }
- });
- }, 100);
- }
- });
-},
+ /**
+ * 浠撳簱鍖哄煙鍙樻洿澶勭悊
+ */
+ handleLocationChange(value) {
+ console.log('閫夋嫨浠撳簱鍖哄煙:', value, '绫诲瀷:', typeof value, this.currentLocationDesc);
-/**
- * 浠撳簱鍙樻洿澶勭悊
- */
-handleWarehouseChange(value) {
- console.log('閫夋嫨浠撳簱:', value, '绫诲瀷:', typeof value, this.currentWarehouseName);
-
- // 绔嬪嵆娓呴櫎閿欒淇℃伅
- this.error = '';
-
- // 鎵嬪姩瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
- this.$nextTick(() => {
- if (this.$refs.locationForm) {
- // 娓呴櫎璇ュ瓧娈电殑楠岃瘉鐘舵�侊紝鐒跺悗閲嶆柊楠岃瘉
- this.$refs.locationForm.clearValidate('warehouseType');
-
- // 鐭殏寤惰繜鍚庨噸鏂伴獙璇侊紝纭繚DOM宸叉洿鏂�
- setTimeout(() => {
- this.$refs.locationForm.validateField('warehouseType', (errorMsg) => {
- if (!errorMsg && (value === 0 || value)) {
- console.log('浠撳簱楠岃瘉閫氳繃:', value);
- this.focusLocationSelect();
- }
- });
- }, 100);
- }
- });
-},
-
+ // 绔嬪嵆娓呴櫎閿欒淇℃伅
+ this.error = '';
+
+ // 鎵嬪姩瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+ this.$nextTick(() => {
+ if (this.$refs.locationForm) {
+ // 娓呴櫎璇ュ瓧娈电殑楠岃瘉鐘舵�侊紝鐒跺悗閲嶆柊楠岃瘉
+ this.$refs.locationForm.clearValidate('locationType');
+
+ // 鐭殏寤惰繜鍚庨噸鏂伴獙璇侊紝纭繚DOM宸叉洿鏂�
+ setTimeout(() => {
+ this.$refs.locationForm.validateField('locationType', (errorMsg) => {
+ if (!errorMsg && (value === 0 || value)) {
+ console.log('浠撳簱鍖哄煙楠岃瘉閫氳繃:', value);
+ // 鍖哄煙閫夋嫨鍚庯紝鑷姩鑱氱劍鍒版墭鐩樿緭鍏ユ
+ this.focusLocationSelect();
+ }
+ });
+ }, 100);
+ }
+ });
+ },
+
+ /**
+ * 浠撳簱鍙樻洿澶勭悊
+ */
+ handleWarehouseChange(value) {
+ console.log('閫夋嫨浠撳簱:', value, '绫诲瀷:', typeof value, this.currentWarehouseName);
+
+ // 绔嬪嵆娓呴櫎閿欒淇℃伅
+ this.error = '';
+
+ // 鎵嬪姩瑙﹀彂琛ㄥ崟楠岃瘉鏇存柊
+ this.$nextTick(() => {
+ if (this.$refs.locationForm) {
+ // 娓呴櫎璇ュ瓧娈电殑楠岃瘉鐘舵�侊紝鐒跺悗閲嶆柊楠岃瘉
+ this.$refs.locationForm.clearValidate('warehouseType');
+
+ // 鐭殏寤惰繜鍚庨噸鏂伴獙璇侊紝纭繚DOM宸叉洿鏂�
+ setTimeout(() => {
+ this.$refs.locationForm.validateField('warehouseType', (errorMsg) => {
+ if (!errorMsg && (value === 0 || value)) {
+ console.log('浠撳簱楠岃瘉閫氳繃:', value);
+ this.focusLocationSelect();
+ }
+ });
+ }, 100);
+ }
+ });
+ },
+
async fetchStockStatistics() {
// 鍗曟嵁鍙蜂负绌烘椂涓嶆煡璇�
if (!this.docNo) {
@@ -510,8 +437,8 @@
this.sumError = '';
try {
// 璋冪敤鍚庣缁熻鎺ュ彛锛堟浛鎹负浣犵殑瀹為檯鎺ュ彛璺緞锛�
- const response = await http.post('/api/InboundOrder/UnPalletQuantity?orderNo='+this.docNo, {
-
+ const response = await http.post('/api/InboundOrder/UnPalletQuantity?orderNo=' + this.docNo, {
+
});
// 缁戝畾鏁版嵁锛堝尮閰� PalletSumQuantityDTO 缁撴瀯锛�
@@ -529,82 +456,91 @@
this.sumLoading = false;
}
},
-/**
- * 琛ㄥ崟楠岃瘉
- */
-async validateForm() {
- return new Promise((resolve) => {
- if (!this.$refs.locationForm) {
- this.error = '琛ㄥ崟鏈垵濮嬪寲';
- this.$message.warning('璇峰厛閫夋嫨浠撳簱鍖哄煙');
- resolve(false);
- return;
- }
+ /**
+ * 琛ㄥ崟楠岃瘉
+ */
+ async validateForm() {
+ return new Promise((resolve) => {
+ if (!this.$refs.locationForm) {
+ this.error = '琛ㄥ崟鏈垵濮嬪寲';
+ this.$message.warning('璇峰厛閫夋嫨浠撳簱鍖哄煙');
+ resolve(false);
+ return;
+ }
- this.$refs.locationForm.validate((valid) => {
- if (valid) {
- this.error = '';
- resolve(true);
- } else {
- // 鎵嬪姩妫�鏌ocationType锛屾纭鐞嗗�间负0鐨勬儏鍐�
- if(!this.from.warehouseType){
- this.error='璇峰厛閫夋嫨浠撳簱';
+ this.$refs.locationForm.validate((valid) => {
+ if (valid) {
+ this.error = '';
+ resolve(true);
+ } else {
+ // 鎵嬪姩妫�鏌ocationType锛屾纭鐞嗗�间负0鐨勬儏鍐�
+ if (!this.from.warehouseType) {
+ this.error = '璇峰厛閫夋嫨浠撳簱';
+ }
+ else if (this.form.locationType === null || this.form.locationType === undefined || this.form.locationType === '') {
+ this.error = '璇峰厛閫夋嫨浠撳簱鍖哄煙';
+ //this.$message.warning('璇峰厛閫夋嫨浠撳簱鍖哄煙');
+ } else {
+ // 濡傛灉鍊煎瓨鍦紙鍖呮嫭0锛夛紝浣嗛獙璇佷笉閫氳繃锛屽彲鑳芥槸鍏朵粬楠岃瘉閿欒
+ this.error = '璇锋鏌ヨ〃鍗曞~鍐欐槸鍚︽纭�';
+ }
+ resolve(false);
+ }
+ });
+ });
+ },
+ focusWarehouseSelect() {
+ if (this.$refs.locationForm) {
+ const selectEl = this.$el.querySelector('.location-select:first-child .el-input__inner');
+ if (selectEl) {
+ selectEl.focus();
+ this.currentFocus = 'warehouse';
}
- else if(this.form.locationType === null || this.form.locationType === undefined || this.form.locationType === '') {
- this.error = '璇峰厛閫夋嫨浠撳簱鍖哄煙';
- //this.$message.warning('璇峰厛閫夋嫨浠撳簱鍖哄煙');
- } else {
- // 濡傛灉鍊煎瓨鍦紙鍖呮嫭0锛夛紝浣嗛獙璇佷笉閫氳繃锛屽彲鑳芥槸鍏朵粬楠岃瘉閿欒
- this.error = '璇锋鏌ヨ〃鍗曞~鍐欐槸鍚︽纭�';
- }
- resolve(false);
}
- });
- });
-},
- focusWarehouseSelect() {
- if (this.$refs.locationForm) {
- const selectEl = this.$el.querySelector('.location-select:first-child .el-input__inner');
- if (selectEl) {
- selectEl.focus();
- this.currentFocus = 'warehouse';
- }
- }
- },
- // 鑱氱劍鍒颁粨搴撳尯鍩熼�夋嫨
- focusLocationSelect() {
- if (this.$refs.locationForm) {
- const selectEl = this.$el.querySelector('.location-select:nth-child(2) .el-input__inner');
- if (selectEl) {
- selectEl.focus();
- this.currentFocus = 'location';
- }
- }
- },
- // 鑱氱劍鍒版墭鐩樿緭鍏ユ
- focusTrayInput() {
- if (this.$refs.trayInput && this.$refs.trayInput.$el) {
- const inputEl = this.$refs.trayInput.$el.querySelector('input');
- if (inputEl) {
- inputEl.focus();
- this.currentFocus = 'tray';
- this.scanTarget = 'tray';
- }
- }
- },
-
- // 鑱氱劍鍒扮墿鏂欒緭鍏ユ
- focusBarcodeInput() {
- if (this.$refs.barcodeInput && this.$refs.barcodeInput.$el) {
- const inputEl = this.$refs.barcodeInput.$el.querySelector('input');
- if (inputEl) {
- inputEl.focus();
- this.currentFocus = 'material';
- this.scanTarget = 'material';
- }
- }
- },
- // 閲嶇疆鎵�鏈夋暟鎹�
+ },
+ // 鑱氱劍鍒颁粨搴撳尯鍩熼�夋嫨
+ focusLocationSelect() {
+ if (this.$refs.locationForm) {
+ const selectEl = this.$el.querySelector('.location-select:nth-child(2) .el-input__inner');
+ if (selectEl) {
+ selectEl.focus();
+ this.currentFocus = 'location';
+ }
+ }
+ },
+ // 鑱氱劍鍒版墭鐩樿緭鍏ユ
+ focusTrayInput() {
+ if (this.$refs.trayInput && this.$refs.trayInput.$el) {
+ const inputEl = this.$refs.trayInput.$el.querySelector('input');
+ if (inputEl) {
+ inputEl.focus();
+ this.currentFocus = 'tray';
+ this.scanTarget = 'tray';
+ }
+ }
+ },
+
+ // 鑱氱劍鍒扮墿鏂欒緭鍏ユ
+ focusBarcodeInput() {
+ if (this.$refs.barcodeInput && this.$refs.barcodeInput.$el) {
+ const inputEl = this.$refs.barcodeInput.$el.querySelector('input');
+ if (inputEl) {
+ inputEl.focus();
+ this.currentFocus = 'material';
+ this.scanTarget = 'material';
+
+
+ inputEl.select();
+ console.log('鐗╂枡杈撳叆妗嗗唴瀹瑰凡閫変腑');
+
+ }
+ }
+ },
+
+
+
+
+ // 閲嶇疆鎵�鏈夋暟鎹�
resetData() {
console.log('閲嶇疆寮规鏁版嵁');
this.trayBarcode = '';
@@ -623,20 +559,20 @@
this.totalStockCount = 0;
this.sumLoading = false;
this.sumError = '';
- this.form={
- warehouseType:null,
- locationType:null
+ this.form = {
+ warehouseType: null,
+ locationType: null
+ }
+ this.warehouseTypes = [];
+ this.locationTypes = [];
+ // 娓呴櫎琛ㄥ崟楠岃瘉鐘舵��
+ this.$nextTick(() => {
+ if (this.$refs.locationForm) {
+ this.$refs.locationForm.clearValidate();
}
- this.warehouseTypes=[];
- this.locationTypes=[];
- // 娓呴櫎琛ㄥ崟楠岃瘉鐘舵��
- this.$nextTick(() => {
- if (this.$refs.locationForm) {
- this.$refs.locationForm.clearValidate();
- }
- });
+ });
},
-
+
// 娓呴櫎鎵�鏈夎鏃跺櫒
clearAllTimers() {
if (this.manualInputTimer) {
@@ -648,7 +584,7 @@
this.scanTimer = null;
}
},
-
+
// 寮规鎵撳紑鏃堕噸缃暟鎹�
handleDialogOpen() {
console.log('寮规鎵撳紑锛岄噸缃暟鎹�');
@@ -656,676 +592,691 @@
// 浣跨敤setTimeout纭繚DOM瀹屽叏娓叉煋鍚庡啀鑱氱劍
this.$nextTick(() => {
setTimeout(() => {
- this.initwarehouseTypes();
- this.initLocationTypes(); // 鍒濆鍖栦粨搴撳尯鍩�
- // 纭繚琛ㄥ崟寮曠敤瀛樺湪鍚庡啀鑱氱劍
- if (this.$refs.locationForm) {
- this.focusWarehouseSelect();
- } else {
- // 濡傛灉琛ㄥ崟寮曠敤杩樹笉瀛樺湪锛岀◢鍚庨噸璇�
- setTimeout(() => {
- this.focusWarehouseSelect();
- }, 500);
- }
+ this.initwarehouseTypes();
+ this.initLocationTypes(); // 鍒濆鍖栦粨搴撳尯鍩�
+ // 纭繚琛ㄥ崟寮曠敤瀛樺湪鍚庡啀鑱氱劍
+ if (this.$refs.locationForm) {
+ this.focusWarehouseSelect();
+ } else {
+ // 濡傛灉琛ㄥ崟寮曠敤杩樹笉瀛樺湪锛岀◢鍚庨噸璇�
+ setTimeout(() => {
+ this.focusWarehouseSelect();
+ }, 500);
+ }
}, 300);
});
},
-
+
// 寮规鍏抽棴鏃堕噸缃暟鎹�
handleDialogClose() {
console.log('寮规鍏抽棴锛岄噸缃暟鎹�');
this.resetData();
},
-
+
// 鍙栨秷鎸夐挳
handleCancel() {
this.palletVisible = false;
},
-
+
// 纭鎸夐挳
- async handleConfirm() {
- if (!await this.validateForm()) return;
+ async handleConfirm() {
+ if (!await this.validateForm()) return;
if (this.materials.length === 0) {
this.$message.warning('璇疯嚦灏戞坊鍔犱竴涓墿鏂�');
return;
}
-
+
if (!this.trayBarcode) {
this.$message.warning('璇疯緭鍏ユ墭鐩樻潯鐮�');
return;
}
-
+
const result = {
- warehouseType:this.form.warehouseType,
- warehouseName:this.currentWarehouseName,
+ warehouseType: this.form.warehouseType,
+ warehouseName: this.currentWarehouseName,
locationType: this.form.locationType,
locationDesc: this.currentLocationDesc,
trayBarcode: this.trayBarcode,
materials: this.materials,
docNo: this.docNo
};
-
+
// 瑙﹀彂鐖剁粍浠剁殑 back-success 浜嬩欢
this.$emit('back-success', result);
this.palletVisible = false;
},
// 澶勭悊鎵樼洏杈撳叆
- handleTrayInput() {
- // 鏍囪涓烘墜鍔ㄨ緭鍏ユā寮�
- this.isManualInput = true;
- this.isScanning = false;
-
- // 娓呴櫎涔嬪墠鐨勮鏃跺櫒
- if (this.manualInputTimer) {
- clearTimeout(this.manualInputTimer);
- }
-
- // 璁剧疆璁℃椂鍣紝濡傛灉涓�娈垫椂闂村唴娌℃湁杈撳叆锛屽垯閲嶇疆涓烘壂鐮佹ā寮�
- this.manualInputTimer = setTimeout(() => {
- this.isManualInput = false;
- }, 1000);
- },
-
- // 澶勭悊鐗╂枡杈撳叆
- handleBarcodeInput() {
- // 鏍囪涓烘墜鍔ㄨ緭鍏ユā寮�
- this.isManualInput = true;
- this.isScanning = false;
-
- // 娓呴櫎涔嬪墠鐨勮鏃跺櫒
- if (this.manualInputTimer) {
- clearTimeout(this.manualInputTimer);
- }
-
- // 璁剧疆璁℃椂鍣紝濡傛灉涓�娈垫椂闂村唴娌℃湁杈撳叆锛屽垯閲嶇疆涓烘壂鐮佹ā寮�
- this.manualInputTimer = setTimeout(() => {
- this.isManualInput = false;
- }, 1000);
- },
-
- // 澶勭悊鎵樼洏鏉$爜鎻愪氦
-async handleTraySubmit() {
- // 鍏堢洿鎺ユ鏌ocationType锛岄伩鍏嶈〃鍗曢獙璇佺殑寮傛闂
- if (!this.form.warehouseType) {
- this.error = '璇峰厛閫夋嫨浠撳簱';
- return;
- }
- if (!this.form.locationType) {
- this.error = '璇峰厛閫夋嫨浠撳簱鍖哄煙';
- //this.$message.warning('璇峰厛閫夋嫨浠撳簱鍖哄煙');
- return;
- }
-
- // 鐒跺悗鍐嶈繘琛屽畬鏁寸殑琛ㄥ崟楠岃瘉
- if (!await this.validateForm()) return;
-
- const currentTrayBarcode = this.trayBarcode.trim();
-
- if (!currentTrayBarcode) {
- this.error = '璇疯緭鍏ユ垨鎵弿鎵樼洏鏉$爜';
- return;
- }
+ handleTrayInput() {
+ // 鏍囪涓烘墜鍔ㄨ緭鍏ユā寮�
+ this.isManualInput = true;
+ this.isScanning = false;
- this.error = '';
-
- // 璁剧疆鎵樼洏鏉$爜鍚庯紝鑷姩鑱氱劍鍒扮墿鏂欒緭鍏ユ
- this.focusBarcodeInput();
-
- this.$message({
- message: `鎵樼洏鏉$爜宸茶缃�: ${currentTrayBarcode}`,
- type: 'success',
- duration: 2000
- });
-},
-
- // 娓呴櫎鎵樼洏
- clearTray() {
- this.trayBarcode = '';
- this.materials = [];
- this.focusTrayInput();
+ // 娓呴櫎涔嬪墠鐨勮鏃跺櫒
+ if (this.manualInputTimer) {
+ clearTimeout(this.manualInputTimer);
+ }
+
+ // 璁剧疆璁℃椂鍣紝濡傛灉涓�娈垫椂闂村唴娌℃湁杈撳叆锛屽垯閲嶇疆涓烘壂鐮佹ā寮�
+ this.manualInputTimer = setTimeout(() => {
+ this.isManualInput = false;
+ }, 1000);
+ },
+
+ // 澶勭悊鐗╂枡杈撳叆
+ handleBarcodeInput() {
+ // 鏍囪涓烘墜鍔ㄨ緭鍏ユā寮�
+ this.isManualInput = true;
+ this.isScanning = false;
+
+ // 娓呴櫎涔嬪墠鐨勮鏃跺櫒
+ if (this.manualInputTimer) {
+ clearTimeout(this.manualInputTimer);
+ }
+
+ // 璁剧疆璁℃椂鍣紝濡傛灉涓�娈垫椂闂村唴娌℃湁杈撳叆锛屽垯閲嶇疆涓烘壂鐮佹ā寮�
+ this.manualInputTimer = setTimeout(() => {
+ this.isManualInput = false;
+ }, 1000);
+ },
+
+ // 澶勭悊鎵樼洏鏉$爜鎻愪氦
+ async handleTraySubmit() {
+ // 鍏堢洿鎺ユ鏌ocationType锛岄伩鍏嶈〃鍗曢獙璇佺殑寮傛闂
+ if (!this.form.warehouseType) {
+ this.error = '璇峰厛閫夋嫨浠撳簱';
+ return;
+ }
+ if (!this.form.locationType) {
+ this.error = '璇峰厛閫夋嫨浠撳簱鍖哄煙';
+ //this.$message.warning('璇峰厛閫夋嫨浠撳簱鍖哄煙');
+ return;
+ }
+
+ // 鐒跺悗鍐嶈繘琛屽畬鏁寸殑琛ㄥ崟楠岃瘉
+ if (!await this.validateForm()) return;
+
+ const currentTrayBarcode = this.trayBarcode.trim();
+
+ if (!currentTrayBarcode) {
+ this.error = '璇疯緭鍏ユ垨鎵弿鎵樼洏鏉$爜';
+ return;
+ }
+
+ this.error = '';
+
+ // 璁剧疆鎵樼洏鏉$爜鍚庯紝鑷姩鑱氱劍鍒扮墿鏂欒緭鍏ユ
+ this.focusBarcodeInput();
+
+ this.$message({
+ message: `鎵樼洏鏉$爜宸茶缃�: ${currentTrayBarcode}`,
+ type: 'success',
+ duration: 2000
+ });
+ },
+
+ // 娓呴櫎鎵樼洏
+ clearTray() {
+ this.trayBarcode = '';
+ this.materials = [];
+ this.focusTrayInput();
+ this.$message({
+ message: '鎵樼洏鏉$爜宸叉竻闄�',
+ type: 'info',
+ duration: 2000
+ });
+ },
+
+ // 娓呯┖鎵樼洏杈撳叆
+ handleTrayClear() {
+ this.error = '';
+ },
+
+ // 娓呯┖杈撳叆
+ handleClear() {
+ this.error = '';
+ this.scanCode = '';
+ this.isManualInput = false;
+ this.isScanning = false;
+ },
+
+
+ // 澶勭悊鐗╂枡鏉$爜鎻愪氦
+ async handleBarcodeSubmit() {
+ if (!await this.validateForm()) return;
+ const currentBarcode = this.barcode.trim();
+
+ if (!this.trayBarcode) {
+ this.error = '璇峰厛杈撳叆鎵樼洏鏉$爜';
+ this.focusTrayInput();
+ return;
+ }
+
+ if (!currentBarcode) {
+ this.error = '璇疯緭鍏ユ垨鎵弿鐗╂枡鏉$爜';
+ return;
+ }
+
+ this.focusBarcodeInput();
+ this.error = '';
+ this.loading = true;
+
+ try {
+ // 璋冪敤API鏌ヨ鐗╂枡淇℃伅
+ const materialData = await this.fetchMaterialData(currentBarcode);
+ if (!materialData || materialData.length === 0) {
+
+
+ return;
+ }
+ // 妫�鏌ユ槸鍚﹀凡瀛樺湪鐩稿悓鐗╂枡缂栫爜鐨勮褰�
+ const exists = this.materials.some(item =>
+ item.barcode === this.trayBarcode
+ );
+ console.log('API:', materialData)
+ if (exists) {
this.$message({
- message: '鎵樼洏鏉$爜宸叉竻闄�',
- type: 'info',
+ message: '璇ユ潯鐮佸凡瀛樺湪褰撳墠鎵樼洏鐨勫垪琛ㄤ腑',
+ type: 'warning',
duration: 2000
});
- },
-
- // 娓呯┖鎵樼洏杈撳叆
- handleTrayClear() {
- this.error = '';
- },
-
- // 娓呯┖杈撳叆
- handleClear() {
- this.error = '';
- this.scanCode = '';
- this.isManualInput = false;
- this.isScanning = false;
- },
-
- // 澶勭悊鐗╂枡鏉$爜鎻愪氦
- async handleBarcodeSubmit() {
- if (!await this.validateForm()) return;
- const currentBarcode = this.barcode.trim();
- if (!this.trayBarcode) {
- this.error = '璇峰厛杈撳叆鎵樼洏鏉$爜';
- this.focusTrayInput();
- return;
- }
-
- if (!currentBarcode) {
- this.error = '璇疯緭鍏ユ垨鎵弿鐗╂枡鏉$爜';
- return;
- }
+ } else {
- this.error = '';
- this.loading = true;
+ materialData.forEach(item => {
- try {
- // 璋冪敤API鏌ヨ鐗╂枡淇℃伅
- const materialData = await this.fetchMaterialData(currentBarcode);
- if (!materialData || materialData.length === 0) {
-
-
- return;
- }
- // 妫�鏌ユ槸鍚﹀凡瀛樺湪鐩稿悓鐗╂枡缂栫爜鐨勮褰�
- const exists = this.materials.some(item =>
- item.barcode === this.trayBarcode
- );
- console.log('API:',materialData)
- if (exists) {
- this.$message({
- message: '璇ユ潯鐮佸凡瀛樺湪褰撳墠鎵樼洏鐨勫垪琛ㄤ腑',
- type: 'warning',
- duration: 2000
- });
- } else {
-
- materialData.forEach(item => {
-
- // 濡傛灉涓嶅瓨鍦紝娣诲姞鏂扮墿鏂�
- this.materials.push({
- ...item,
- trayCode: this.trayBarcode,
- locationType: this.form.locationType,
- locationDesc: this.currentLocationDesc,
- scanTime: this.formatTime(new Date())
+ // 濡傛灉涓嶅瓨鍦紝娣诲姞鏂扮墿鏂�
+ this.materials.push({
+ ...item,
+ trayCode: this.trayBarcode,
+ locationType: this.form.locationType,
+ locationDesc: this.currentLocationDesc,
+ scanTime: this.formatTime(new Date())
+ });
});
- });
-
-
-
-
- this.$message({
- message: `鎴愬姛娣诲姞鏉$爜: ${currentBarcode}`,
- type: 'success',
- duration: 2000
- });
-
- this.fetchStockStatistics();
- // 娓呯┖鐗╂枡杈撳叆妗嗗苟淇濇寔鑱氱劍
- this.barcode = '';
- this.scanCode = ''; // 娓呯┖鎵爜缂撳瓨
- this.isScanning = false;
-
- setTimeout(() => {
- this.focusBarcodeInput();
- }, 100);
- }
- } catch (err) {
- this.error = err.message || '鏌ヨ鏉$爜淇℃伅澶辫触锛岃閲嶈瘯';
- } finally {
- this.loading = false;
- }
- },
-
- // API璇锋眰 - 鏇挎崲涓哄疄闄呯殑API璋冪敤
- async fetchMaterialData(barcode) {
- try {
- const response = await http.post('/api/InboundOrder/BarcodeMaterielGroup',
- {
+
+ this.$message({
+ message: `鎴愬姛娣诲姞鏉$爜: ${currentBarcode}`,
+ type: 'success',
+ duration: 2000
+ });
+
+ this.fetchStockStatistics();
+ // 娓呯┖鐗╂枡杈撳叆妗嗗苟淇濇寔鑱氱劍
+ this.barcode = '';
+ this.scanCode = ''; // 娓呯┖鎵爜缂撳瓨
+ this.isScanning = false;
+
+ setTimeout(() => {
+ this.focusBarcodeInput();
+ }, 100);
+ }
+ } catch (err) {
+ this.error = err.message || '鏌ヨ鏉$爜淇℃伅澶辫触锛岃閲嶈瘯';
+ this.focusBarcodeInput();
+ setTimeout(() => {
+ // 閫変腑杈撳叆妗嗗唴鐨勯敊璇唴瀹癸紙纭繚focus瀹屾垚鍚庢墽琛岋級
+ const inputEl = this.$refs.barcodeInput?.$el?.querySelector('input');
+ if (inputEl) inputEl.select();
+ }, 100);
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ // API璇锋眰 - 鏇挎崲涓哄疄闄呯殑API璋冪敤
+ async fetchMaterialData(barcode) {
+ try {
+ const response = await http.post('/api/InboundOrder/BarcodeMaterielGroup',
+ {
palletCode: this.trayBarcode,
orderNo: this.docNo,
barcodes: barcode,
- locationTypeDesc: this.currentLocationDesc,
+ locationTypeDesc: this.currentLocationDesc,
locationType: this.form.locationType, // 娣诲姞浠撳簱鍖哄煙淇℃伅
- warehouseType:this.form.warehouseType
- }
+ warehouseType: this.form.warehouseType
+ }
);
-
-
+
+
let materialData;
-
+
if (typeof response.data === 'string') {
-
+
try {
materialData = JSON.parse(response.data);
} catch (e) {
-
+
}
} else {
// 濡傛灉杩斿洖鐨勬槸JSON瀵硅薄锛岀洿鎺ヤ娇鐢�
materialData = response.data;
}
- if(!response.status){
- this.error = response.message || '鏌ヨ鏉$爜淇℃伅澶辫触锛岃閲嶈瘯';
- }
+ if (!response.status) {
+ this.error = response.message || '鏌ヨ鏉$爜淇℃伅澶辫触锛岃閲嶈瘯';
+ }
- return materialData;
-
+ return materialData;
+
} catch (error) {
console.error('API璋冪敤澶辫触:', error);
-
-
- }
- },
-
- // 澶勭悊鎵爜鏋緭鍏�
- handleKeyPress(event) {
- // 濡傛灉鏄墜鍔ㄨ緭鍏ユā寮忥紝涓嶅鐞嗘壂鐮佹灙閫昏緫
- if (this.isManualInput) {
- return;
- }
-
- const key = event.key;
- const currentTime = new Date().getTime();
-
- // 蹇界暐鐩存帴鎸変笅鐨勫洖杞﹂敭锛堢敱handleBarcodeSubmit澶勭悊锛�
- if (key === 'Enter') {
- if (this.scanCode.length > 0) {
- // 闃绘榛樿鍥炶溅琛屼负锛岄伩鍏嶈〃鍗曟彁浜�
- event.preventDefault();
-
- // 鎵爜瀹屾垚锛岃嚜鍔ㄨЕ鍙戞煡璇�
- this.isScanning = false;
-
- // 鏍规嵁褰撳墠鎵爜鐩爣璁剧疆鐩稿簲鐨勮緭鍏ユ鍊�
- if (this.scanTarget === 'tray') {
- this.trayBarcode = this.scanCode;
- this.handleTraySubmit();
- } else if (this.scanTarget === 'material') {
- this.barcode = this.scanCode;
- this.handleBarcodeSubmit();
- }
- }
- this.scanCode = '';
- this.lastKeyTime = null;
- return;
- }
-
- // 鏋勫缓鎵爜鍐呭锛堝揩閫熻繛缁緭鍏ヨ涓烘壂鐮侊級
- if (this.lastKeyTime && currentTime - this.lastKeyTime < 50) {
- this.scanCode += key;
- this.isScanning = true;
- } else {
- this.scanCode = key;
- this.isScanning = true;
- }
-
- // 璁剧疆璁℃椂鍣紝濡傛灉涓�娈垫椂闂村唴娌℃湁杈撳叆锛屽垯閲嶇疆鎵弿鐘舵��
- if (this.scanTimer) {
- clearTimeout(this.scanTimer);
- }
- this.scanTimer = setTimeout(() => {
- this.isScanning = false;
- }, 100);
-
- this.lastKeyTime = currentTime;
- },
-
- // 鍒犻櫎鐗╂枡
- removeMaterial(index) {
- this.$confirm('纭畾瑕佸垹闄よ繖鏉$墿鏂欒褰曞悧?', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- this.materials.splice(index, 1);
- this.$message({
- type: 'success',
- message: '鍒犻櫎鎴愬姛!'
- });
- this.fetchStockStatistics();
- }).catch(() => {
- // 鍙栨秷鍒犻櫎
- });
- },
-
- // 娓呯┖鎵�鏈夌墿鏂�
- clearAllMaterials() {
- if (this.materials.length === 0) return;
-
- this.$confirm('纭畾瑕佹竻绌烘墍鏈夌墿鏂欒褰曞悧?', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- }).then(() => {
- this.materials = [];
- this.$message({
- type: 'success',
- message: '宸叉竻绌烘墍鏈夎褰�!'
- });
- }).catch(() => {
- // 鍙栨秷娓呯┖
- });
- },
-
- // 鏍煎紡鍖栨椂闂�
- formatTime(date) {
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- const hours = String(date.getHours()).padStart(2, '0');
- const minutes = String(date.getMinutes()).padStart(2, '0');
- const seconds = String(date.getSeconds()).padStart(2, '0');
-
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
- }
+
}
+ },
+
+ // 澶勭悊鎵爜鏋緭鍏�
+ handleKeyPress(event) {
+ // 濡傛灉鏄墜鍔ㄨ緭鍏ユā寮忥紝涓嶅鐞嗘壂鐮佹灙閫昏緫
+ if (this.isManualInput) {
+ return;
+ }
+
+ const key = event.key;
+ const currentTime = new Date().getTime();
+
+ // 蹇界暐鐩存帴鎸変笅鐨勫洖杞﹂敭锛堢敱handleBarcodeSubmit澶勭悊锛�
+ if (key === 'Enter') {
+ if (this.scanCode.length > 0) {
+ // 闃绘榛樿鍥炶溅琛屼负锛岄伩鍏嶈〃鍗曟彁浜�
+ event.preventDefault();
+
+ // 鎵爜瀹屾垚锛岃嚜鍔ㄨЕ鍙戞煡璇�
+ this.isScanning = false;
+
+ // 鏍规嵁褰撳墠鎵爜鐩爣璁剧疆鐩稿簲鐨勮緭鍏ユ鍊�
+ if (this.scanTarget === 'tray') {
+ this.trayBarcode = this.scanCode;
+ this.handleTraySubmit();
+ } else if (this.scanTarget === 'material') {
+ this.barcode = this.scanCode;
+ this.handleBarcodeSubmit();
+ }
+ }
+ this.scanCode = '';
+ this.lastKeyTime = null;
+ return;
+ }
+
+ // 鏋勫缓鎵爜鍐呭锛堝揩閫熻繛缁緭鍏ヨ涓烘壂鐮侊級
+ if (this.lastKeyTime && currentTime - this.lastKeyTime < 50) {
+ this.scanCode += key;
+ this.isScanning = true;
+ } else {
+ this.scanCode = key;
+ this.isScanning = true;
+ }
+
+ // 璁剧疆璁℃椂鍣紝濡傛灉涓�娈垫椂闂村唴娌℃湁杈撳叆锛屽垯閲嶇疆鎵弿鐘舵��
+ if (this.scanTimer) {
+ clearTimeout(this.scanTimer);
+ }
+ this.scanTimer = setTimeout(() => {
+ this.isScanning = false;
+ }, 100);
+
+ this.lastKeyTime = currentTime;
+ },
+
+ // 鍒犻櫎鐗╂枡
+ removeMaterial(index) {
+ this.$confirm('纭畾瑕佸垹闄よ繖鏉$墿鏂欒褰曞悧?', '鎻愮ず', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ }).then(() => {
+ this.materials.splice(index, 1);
+ this.$message({
+ type: 'success',
+ message: '鍒犻櫎鎴愬姛!'
+ });
+ this.fetchStockStatistics();
+
+ }).catch(() => {
+ // 鍙栨秷鍒犻櫎
+ });
+ },
+
+ // 娓呯┖鎵�鏈夌墿鏂�
+ clearAllMaterials() {
+ if (this.materials.length === 0) return;
+
+ this.$confirm('纭畾瑕佹竻绌烘墍鏈夌墿鏂欒褰曞悧?', '鎻愮ず', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ }).then(() => {
+ this.materials = [];
+ this.$message({
+ type: 'success',
+ message: '宸叉竻绌烘墍鏈夎褰�!'
+ });
+ }).catch(() => {
+ // 鍙栨秷娓呯┖
+ });
+ },
+
+ // 鏍煎紡鍖栨椂闂�
+ formatTime(date) {
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, '0');
+ const day = String(date.getDate()).padStart(2, '0');
+ const hours = String(date.getHours()).padStart(2, '0');
+ const minutes = String(date.getMinutes()).padStart(2, '0');
+ const seconds = String(date.getSeconds()).padStart(2, '0');
+
+ return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+ }
+ }
}
</script>
<style scoped>
- .barcode-scanner-container {
- max-width: 1200px;
- margin: 0 auto;
- padding: 10px;
- display: flex;
- flex-direction: column;
- height: 100%;
- gap: 8px;
- }
-
- /* 绱у噾甯冨眬鏍峰紡 */
- .compact {
- margin-bottom: 0;
- }
-
- .compact-form {
- margin-bottom: 0;
- }
-
- .compact-item {
- margin-bottom: 0;
- }
-
- .compact-card {
- margin-bottom: 0;
- }
-
- .compact-card >>> .el-card__body {
- padding: 12px;
- }
-
- .compact-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 0 !important;
- }
-
- .compact-header >>> .el-card__header {
- padding: 8px 12px;
- }
-
- .compact-input {
- margin: 8px 0;
- }
-
- .compact-tips {
- margin-top: 8px;
- font-size: 11px;
- }
-
- /* 浠撳簱鍖哄煙閫夋嫨 - 绱у噾 */
- .location-section.compact {
- margin-bottom: 8px;
- }
-
- .location-section.compact >>> .el-form-item {
- margin-bottom: 0;
- }
-
- /* 鎵樼洏淇℃伅 - 绱у噾 */
- .tray-info.compact {
- padding: 6px 10px;
- margin-bottom: 8px;
- font-size: 13px;
- }
-
- /* 鎵爜鍖哄煙 - 绱у噾 */
- .input-section.compact {
- margin-bottom: 8px;
- flex-shrink: 0;
- }
-
- /* 鐗╂枡鍒楄〃 - 鍥哄畾楂樺害甯︽粴鍔� */
- .material-list.compact {
- flex: 1;
- min-height: 0; /* 閲嶈锛氬厑璁竑lex瀛愰」鏀剁缉 */
- display: flex;
- flex-direction: column;
- }
-
- .material-list.compact >>> .el-card {
- display: flex;
- flex-direction: column;
- height: 100%;
- }
-
- .material-list.compact >>> .el-card__body {
- flex: 1;
- display: flex;
- flex-direction: column;
- padding: 0;
- min-height: 0;
- }
-
- .table-container {
- flex: 1;
- min-height: 0;
- overflow: hidden;
- }
-
- .material-list.compact >>> .el-table {
- flex: 1;
- }
-
- .material-list.compact >>> .el-table__body-wrapper {
- overflow-y: auto;
- }
-
- /* 绱у噾鐨勭┖鐘舵�� */
- .empty-state.compact {
- padding: 20px 0;
- flex: 1;
- display: flex;
- flex-direction: column;
- justify-content: center;
- align-items: center;
- }
-
- .empty-state.compact i {
- font-size: 36px;
- margin-bottom: 8px;
- }
-
- .empty-state.compact p {
- font-size: 13px;
- }
-
- /* 鍏朵粬鍘熸湁鏍峰紡璋冩暣 */
- .page-title {
- text-align: center;
- margin-bottom: 15px;
- }
-
- .scan-status {
- font-size: 12px;
- color: #67C23A;
- }
-
- .scan-indicator {
- display: inline-block;
- width: 8px;
- height: 8px;
- border-radius: 50%;
- background-color: #67C23A;
- margin-right: 5px;
- animation: pulse 1.5s infinite;
- }
-
- @keyframes pulse {
- 0% { opacity: 1; }
- 50% { opacity: 0.4; }
- 100% { opacity: 1; }
- }
-
- .input-wrapper {
- position: relative;
- }
-
- .input-tips {
- margin-top: 6px;
- color: #909399;
- }
-
- .warning-text {
- color: #E6A23C;
- font-weight: bold;
- }
-
- .loading.compact {
- text-align: center;
- margin: 10px 0;
- padding: 5px;
- }
-
- .loading.compact p {
- margin-top: 5px;
- color: #409EFF;
- font-size: 12px;
- }
-
- .error-message.compact {
- margin: 5px 0;
- }
-
- .error-message.compact >>> .el-alert {
- padding: 6px 12px;
- }
-
- .list-actions {
- display: flex;
- align-items: center;
- gap: 4px;
- }
-
- .list-actions >>> .el-tag {
- height: 24px;
- line-height: 22px;
- padding: 0 6px;
- }
-
- .clear-all-btn {
- margin-left: 8px;
- }
-
- .material-code {
- font-family: 'Courier New', monospace;
- font-weight: bold;
- color: #409EFF;
- }
-
- .location-info {
- color: #606266;
- font-weight: normal;
- }
-
- .debug-info {
- background: #f5f7fa;
- padding: 8px;
- border-radius: 4px;
- margin-top: 8px;
- font-size: 11px;
- color: #909399;
- }
-
- .small-button {
- padding: 6px 8px;
- font-size: 11px;
- }
+.barcode-scanner-container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ gap: 8px;
+}
- /* 杈撳叆妗嗙粍鏍峰紡璋冩暣 */
- .custom-input-group {
- display: flex;
- align-items: center;
- width: 100%;
- margin: 8px 0;
- border: 1px solid #DCDFE6;
- border-radius: 4px;
- overflow: hidden;
- background: #fff;
- }
+/* 绱у噾甯冨眬鏍峰紡 */
+.compact {
+ margin-bottom: 0;
+}
- .input-label {
- padding: 0 12px;
- background: #F5F7FA;
- border-right: 1px solid #DCDFE6;
- color: #606266;
- font-size: 13px;
- white-space: nowrap;
- height: 36px;
- line-height: 36px;
- flex-shrink: 0;
- min-width: 70px;
- text-align: center;
- }
+.compact-form {
+ margin-bottom: 0;
+}
- .input-container {
- display: flex;
- flex: 1;
- align-items: center;
- }
+.compact-item {
+ margin-bottom: 0;
+}
- .custom-input {
- flex: 1;
- }
+.compact-card {
+ margin-bottom: 0;
+}
- .custom-input >>> .el-input__inner {
- border: none;
- border-radius: 0;
- height: 36px;
- line-height: 36px;
- font-size: 13px;
- }
-
- /* 鍝嶅簲寮忚皟鏁� */
- @media (max-width: 768px) {
- .barcode-scanner-container {
- padding: 5px;
- }
-
- .custom-input-group {
- flex-direction: column;
- border: none;
- }
-
- .input-label {
- width: 100%;
- border-right: none;
- border-bottom: 1px solid #DCDFE6;
- margin-bottom: 5px;
- }
-
- .input-container {
- width: 100%;
- border: 1px solid #DCDFE6;
- border-radius: 4px;
- }
- }
+.compact-card>>>.el-card__body {
+ padding: 12px;
+}
+
+.compact-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 !important;
+}
+
+.compact-header>>>.el-card__header {
+ padding: 8px 12px;
+}
+
+.compact-input {
+ margin: 8px 0;
+}
+
+.compact-tips {
+ margin-top: 8px;
+ font-size: 11px;
+}
+
+/* 浠撳簱鍖哄煙閫夋嫨 - 绱у噾 */
+.location-section.compact {
+ margin-bottom: 8px;
+}
+
+.location-section.compact>>>.el-form-item {
+ margin-bottom: 0;
+}
+
+/* 鎵樼洏淇℃伅 - 绱у噾 */
+.tray-info.compact {
+ padding: 6px 10px;
+ margin-bottom: 8px;
+ font-size: 13px;
+}
+
+/* 鎵爜鍖哄煙 - 绱у噾 */
+.input-section.compact {
+ margin-bottom: 8px;
+ flex-shrink: 0;
+}
+
+/* 鐗╂枡鍒楄〃 - 鍥哄畾楂樺害甯︽粴鍔� */
+.material-list.compact {
+ flex: 1;
+ min-height: 0;
+ /* 閲嶈锛氬厑璁竑lex瀛愰」鏀剁缉 */
+ display: flex;
+ flex-direction: column;
+}
+
+.material-list.compact>>>.el-card {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+}
+
+.material-list.compact>>>.el-card__body {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ padding: 0;
+ min-height: 0;
+}
+
+.table-container {
+ flex: 1;
+ min-height: 0;
+ overflow: hidden;
+}
+
+.material-list.compact>>>.el-table {
+ flex: 1;
+}
+
+.material-list.compact>>>.el-table__body-wrapper {
+ overflow-y: auto;
+}
+
+/* 绱у噾鐨勭┖鐘舵�� */
+.empty-state.compact {
+ padding: 20px 0;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.empty-state.compact i {
+ font-size: 36px;
+ margin-bottom: 8px;
+}
+
+.empty-state.compact p {
+ font-size: 13px;
+}
+
+/* 鍏朵粬鍘熸湁鏍峰紡璋冩暣 */
+.page-title {
+ text-align: center;
+ margin-bottom: 15px;
+}
+
+.scan-status {
+ font-size: 12px;
+ color: #67C23A;
+}
+
+.scan-indicator {
+ display: inline-block;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background-color: #67C23A;
+ margin-right: 5px;
+ animation: pulse 1.5s infinite;
+}
+
+@keyframes pulse {
+ 0% {
+ opacity: 1;
+ }
+
+ 50% {
+ opacity: 0.4;
+ }
+
+ 100% {
+ opacity: 1;
+ }
+}
+
+.input-wrapper {
+ position: relative;
+}
+
+.input-tips {
+ margin-top: 6px;
+ color: #909399;
+}
+
+.warning-text {
+ color: #E6A23C;
+ font-weight: bold;
+}
+
+.loading.compact {
+ text-align: center;
+ margin: 10px 0;
+ padding: 5px;
+}
+
+.loading.compact p {
+ margin-top: 5px;
+ color: #409EFF;
+ font-size: 12px;
+}
+
+.error-message.compact {
+ margin: 5px 0;
+}
+
+.error-message.compact>>>.el-alert {
+ padding: 6px 12px;
+}
+
+.list-actions {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.list-actions>>>.el-tag {
+ height: 24px;
+ line-height: 22px;
+ padding: 0 6px;
+}
+
+.clear-all-btn {
+ margin-left: 8px;
+}
+
+.material-code {
+ font-family: 'Courier New', monospace;
+ font-weight: bold;
+ color: #409EFF;
+}
+
+.location-info {
+ color: #606266;
+ font-weight: normal;
+}
+
+.debug-info {
+ background: #f5f7fa;
+ padding: 8px;
+ border-radius: 4px;
+ margin-top: 8px;
+ font-size: 11px;
+ color: #909399;
+}
+
+.small-button {
+ padding: 6px 8px;
+ font-size: 11px;
+}
+
+/* 杈撳叆妗嗙粍鏍峰紡璋冩暣 */
+.custom-input-group {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ margin: 8px 0;
+ border: 1px solid #DCDFE6;
+ border-radius: 4px;
+ overflow: hidden;
+ background: #fff;
+}
+
+.input-label {
+ padding: 0 12px;
+ background: #F5F7FA;
+ border-right: 1px solid #DCDFE6;
+ color: #606266;
+ font-size: 13px;
+ white-space: nowrap;
+ height: 36px;
+ line-height: 36px;
+ flex-shrink: 0;
+ min-width: 70px;
+ text-align: center;
+}
+
+.input-container {
+ display: flex;
+ flex: 1;
+ align-items: center;
+}
+
+.custom-input {
+ flex: 1;
+}
+
+.custom-input>>>.el-input__inner {
+ border: none;
+ border-radius: 0;
+ height: 36px;
+ line-height: 36px;
+ font-size: 13px;
+}
+
+/* 鍝嶅簲寮忚皟鏁� */
+@media (max-width: 768px) {
+ .barcode-scanner-container {
+ padding: 5px;
+ }
+
+ .custom-input-group {
+ flex-direction: column;
+ border: none;
+ }
+
+ .input-label {
+ width: 100%;
+ border-right: none;
+ border-bottom: 1px solid #DCDFE6;
+ margin-bottom: 5px;
+ }
+
+ .input-container {
+ width: 100%;
+ border: 1px solid #DCDFE6;
+ border-radius: 4px;
+ }
+}
</style>
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/SelectedStock.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/SelectedStock.vue"
index acfbc12..2050161 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/SelectedStock.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/SelectedStock.vue"
@@ -5,7 +5,7 @@
:lazy="true"
width="75%"
:padding="15"
- title="鍑哄簱璇︽儏"
+ title="璋冩嫧鍑哄簱璇︽儏"
>
<div class="box-head">
<el-alert :closable="false" style="width: 100%">
@@ -182,14 +182,19 @@
"鏌ヨ涓�"
)
.then((x) => {
-
var label=[
{ label: '宸插垎閰�', value: 0 },
{ label: '鍑哄簱涓�', value: 1 },
- { label: '鍑哄簱瀹屾垚', value: 2 },
- { label: '鎷i�夊畬鎴�', value: 3 },
+ { label: '閮ㄥ垎鎷i��', value: 2 },
+ { label: '宸叉嫞閫�', value: 3 },
+ { label: '宸插嚭搴�', value: 4 },
+ { label: '鍑哄簱瀹屾垚', value: 5 },
+ { label: '鎷i�夊畬鎴�', value: 6 },
+ { label: '鍥炲簱涓�', value: 7 },
+ { label: '宸插洖搴�', value: 8 },
{ label: '鎾ら攢', value: 99 }
]
+
this.tableData=x.map((i) => ({
...i,
status:label.find((j) => j.value === i.status).label
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/StockSelect.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/StockSelect.vue"
index 1b7e249..b525dbb 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/StockSelect.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/StockSelect.vue"
@@ -132,11 +132,11 @@
data() {
return {
row: null,
- showDetialBox: false,
+ showDetialBox: false,
tableData: [],
tableColumns: [
{ prop: "materielCode", title: "鐗╂枡缂栧彿", type: "string", width: 150 },
- { prop: "materielName", title: "鐗╂枡鍚嶇О", type: "string", width: 150 },
+ { prop: "barcode", title: "鐗╂枡鏉$爜", type: "string", width: 150 },
{ prop: "palletCode", title: "鎵樼洏缂栧彿", type: "string", width: 150 },
{ prop: "locationCode", title: "璐т綅缂栧彿", type: "string", width: 180 },
{ prop: "useableQuantity", title: "鍙敤鏁伴噺", type: "string" },
@@ -201,30 +201,23 @@
if (!valid) return;
- // 鏋勯�犺姹傚弬鏁�
- const keys = this.selection.map((item) => item.id);
- const requestParams = {
- taskIds: keys,
- outboundPlatform: this.outboundForm.selectedPlatform,
- };
- console.log(this.selection)
- // 璋冪敤鍑哄簱鎺ュ彛
- this.http
- .post("api/Task/GenerateOutboundTasks", requestParams, "鏁版嵁澶勭悊涓�")
- .then((x) => {
- if (!x.status) return ElMessage.error(x.message);
-
- ElMessage.success("鎿嶄綔鎴愬姛");
- this.showOutboundDialog = false;
- this.showDetialBox = false;
- this.$emit("parentCall", ($vue) => {
- $vue.getData();
- });
- })
- .catch((error) => {
- console.error("鍑哄簱璇锋眰澶辫触:", error);
- ElMessage.error("璇锋眰澶辫触锛岃绋嶅悗閲嶈瘯");
+ if (this.selection.length <= 0) {
+ return this.$message.error("璇峰嬀閫�");
+ }
+ let url = this.pkcx
+ ? "api/Task/GenerateOutboundTask?orderDetailId="
+ : "api/Task/GenerateOutboundTask?orderDetailId=";
+ this.http
+ .post(url + this.row.id, this.selection, "鏁版嵁澶勭悊涓�")
+ .then((x) => {
+ if (!x.status) return this.$message.error(x.message);
+ this.$message.success("鎿嶄綔鎴愬姛");
+ this.showDetialBox = false;
+ this.$emit("parentCall", ($vue) => {
+ $vue.getData();
});
+ });
+
});
},
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/allocateOrderDetail.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/allocateOrderDetail.vue"
index 87f3dbc..f685705 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/allocateOrderDetail.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/extend/allocateOrderDetail.vue"
@@ -28,13 +28,13 @@
@click="handleOpenPicking"
>鎷i��</el-link>
- <el-link
+ <!-- <el-link
type="primary"
size="small"
style="float: right; height: 20px; margin-right: 10px"
@click="outbound"
>鐩存帴鍑哄簱</el-link
- >
+ > -->
<el-link
type="primary"
size="small"
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js"
index c6578d5..b3b0c40 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/inbound/inboundOrder.js"
@@ -71,9 +71,8 @@
// 鍙戣捣鎾ら攢缁勭洏璇锋眰
try {
//console.log('鍙戣捣鎾ら攢缁勭洏璇锋眰锛屾墭鐩樺彿锛�', formData.palletCode.trim());
- const response = await http.post('/api/InboundOrder/CancelPalletGroup', {
- palletCode: formData.palletCode.trim()
- });
+ const response = await http.post('/api/InboundOrder/UndoPalletGroup?palletCode='+formData.palletCode.trim());
+
const { status, message, data } = response;
if (status) {
@@ -416,7 +415,14 @@
searchBefore(param) {
//鐣岄潰鏌ヨ鍓�,鍙互缁檖aram.wheres娣诲姞鏌ヨ鍙傛暟
//杩斿洖false锛屽垯涓嶄細鎵ц鏌ヨ
- this.searchFormFields.orderType=[0]
+ // this.searchFormFields.orderType=[0]
+ let wheres = [{
+ 'name': 'orderType',
+ 'value': '0',
+ 'displayType': 'text'}];
+
+
+ param.wheres.push(...wheres);
return true;
},
searchAfter(result) {
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/SelectedStock.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/SelectedStock.vue"
index acfbc12..0b599d2 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/SelectedStock.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/SelectedStock.vue"
@@ -111,6 +111,12 @@
width: 90,
},
{
+ prop: "currentBarcode",
+ title: "鏉$爜",
+ type: "string",
+ width: 90,
+ },
+ {
prop: "batchNo",
title: "鎵规鍙�",
type: "string",
@@ -184,12 +190,17 @@
.then((x) => {
var label=[
- { label: '宸插垎閰�', value: 0 },
+ { label: '宸插垎閰�', value: 0 },
{ label: '鍑哄簱涓�', value: 1 },
- { label: '鍑哄簱瀹屾垚', value: 2 },
- { label: '鎷i�夊畬鎴�', value: 3 },
+ { label: '閮ㄥ垎鎷i��', value: 2 },
+ { label: '宸叉嫞閫�', value: 3 },
+ { label: '宸插嚭搴�', value: 4 },
+ { label: '鍑哄簱瀹屾垚', value: 5 },
+ { label: '鎷i�夊畬鎴�', value: 6 },
+ { label: '鍥炲簱涓�', value: 7 },
+ { label: '宸插洖搴�', value: 8 },
{ label: '鎾ら攢', value: 99 }
- ]
+ ];
this.tableData=x.map((i) => ({
...i,
status:label.find((j) => j.value === i.status).label
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue"
index 07275a9..ab7d308 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue"
@@ -27,13 +27,25 @@
style="float: right; height: 20px"
@click="handleOpenPicking"
>鎷i��</el-link>
-
+ <el-link
+ type="primary"
+ size="small"
+ style="float: right; height: 20px; margin-right: 10px"
+ @click="handleOpenBatchPicking"
+ >鍒嗘壒鎷i��</el-link>
<el-link
type="primary"
size="small"
style="float: right; height: 20px; margin-right: 10px"
@click="outbound"
>鐩存帴鍑哄簱</el-link
+ >
+ <el-link
+ type="primary"
+ size="small"
+ style="float: right; height: 20px; margin-right: 10px"
+ @click="outboundbatch"
+ >鍒嗘壒鍑哄簱</el-link
>
<el-link
type="primary"
@@ -113,8 +125,9 @@
import SelectedStock from "./SelectedStock.vue";
import NoStockOut from "./NoStockOut.vue";
import { h,createVNode, render,reactive } from 'vue';
-import { ElDialog , ElForm, ElFormItem, ElSelect,ElOption, ElButton, ElMessage } from 'element-plus';
+import { ElDialog , ElForm, ElFormItem, ElSelect,ElOption, ElButton, ElInput, ElMessage } from 'element-plus';
import { th } from 'element-plus/es/locale';
+
export default {
components: { VolBox, VolForm, StockSelect, SelectedStock,NoStockOut},
data() {
@@ -200,6 +213,7 @@
title: "鎸囧畾搴撳瓨",
type: "icon",
width: 90,
+ hidden:true,
icon: "el-icon-s-grid",
},
{
@@ -336,6 +350,11 @@
path: '/outbound/picking',
query: { orderId: this.row.id ,orderNo:this.row.orderNo}
})
+ },
+ handleOpenBatchPicking() {
+ this.$router.push({
+ path: '/outbound/batchpicking',
+ query: { orderId: this.row.id ,orderNo:this.row.orderNo}})
},
outbound() {
if (this.selection.length === 0) {
@@ -474,6 +493,192 @@
vnode.appContext = this.$.appContext;
render(vnode, mountNode);
},
+ outboundbatch() {
+ if (this.selection.length === 0) {
+ return this.$message.error("璇烽�夋嫨鍗曟嵁鏄庣粏");
+ }
+ if (this.selection.length>1) {
+ return this.$message.error("鍙兘閫夋嫨涓�鏉″崟鎹槑缁嗚繘琛屽垎鎵瑰嚭搴�");
+ }
+ const platformOptions = [{label:'绔欏彴2',value:'2-1'},{label:'绔欏彴3',value:'3-1'}];
+ const mountNode = document.createElement('div');
+ document.body.appendChild(mountNode);
+
+ // 2. 琛ㄥ崟鏁版嵁锛堥粯璁ら�変腑绔欏彴3锛屾柊澧炲皬鏁板瓧娈碉級
+ const formData = reactive({
+ selectedPlatform: platformOptions[0].value, // 榛樿缁戝畾銆岀珯鍙�3銆嶇殑value
+ outboundDecimal: '' // 鏂板锛氬皬鏁拌緭鍏ユ瀛楁
+ });
+
+ // 3. 鍔ㄦ�佸垱寤哄脊绐楃粍浠�
+ const vnode = createVNode(ElDialog, {
+ title: '鍑哄簱鎿嶄綔 - 閫夋嫨鍑哄簱绔欏彴',
+ width: '500px',
+ modelValue: true,
+ appendToBody: true,
+ 'onUpdate:modelValue': (isVisible) => {
+ if (!isVisible) {
+ render(null, mountNode);
+ document.body.removeChild(mountNode);
+ }
+ },
+ style: {
+ padding: '20px 0',
+ borderRadius: '8px'
+ }
+ }, {
+ default: () => h(ElForm, {
+ model: formData,
+ rules: {
+ selectedPlatform: [
+ { required: true, message: '璇烽�夋嫨鍑哄簱绔欏彴', trigger: 'change' }
+ ],
+ // 鏂板锛氬皬鏁板瓧娈甸獙璇佽鍒欙紙蹇呭~ + 鏈夋晥灏忔暟鏍煎紡锛�
+ outboundDecimal: [
+ { required: true, message: '璇疯緭鍏ュ皬鏁版暟鍊�', trigger: 'blur' },
+ {
+ validator: (rule, value, callback) => {
+ // 楠岃瘉瑙勫垯锛氭鏁般�佹敮鎸佸皬鏁扮偣鍚庢渶澶�2浣嶏紙鍙牴鎹渶姹傝皟鏁村皬鏁颁綅鏁帮級
+ const decimalReg = /^(([1-9]\d*)|0)(\.\d{1,2})?$/;
+ if (value && !decimalReg.test(value)) {
+ callback(new Error('璇疯緭鍏ユ湁鏁堢殑灏忔暟锛堟鏁帮紝鏈�澶�2浣嶅皬鏁帮級'));
+ } else {
+ callback();
+ }
+ },
+ trigger: 'blur'
+ }
+ ]
+ },
+ ref: 'outboundForm',
+ labelWidth: '100px',
+ style: {
+ padding: '0 30px'
+ }
+ }, [
+ // 鍑哄簱绔欏彴閫夋嫨椤癸紙鏍稿績琛ㄥ崟椤癸級
+ h(ElFormItem, {
+ label: '鍑哄簱绔欏彴',
+ prop: 'selectedPlatform',
+ style: {
+ marginBottom: '24px'
+ }
+ }, [
+ h(ElSelect, {
+ placeholder: '璇烽�夋嫨鍑哄簱绔欏彴锛�3-12锛�',
+ modelValue: formData.selectedPlatform,
+ 'onUpdate:modelValue': (val) => {
+ formData.selectedPlatform = val;
+ },
+ style: {
+ width: '100%',
+ height: '40px',
+ borderRadius: '4px',
+ borderColor: '#dcdfe6'
+ }
+ }, platformOptions.map(platform =>
+ h(ElOption, { label: platform.label, value: platform.value })
+ ))
+ ]),
+ // 鏂板锛氬皬鏁拌緭鍏ユ琛ㄥ崟椤�
+ h(ElFormItem, {
+ label: '鍑哄簱鏁�', // 鍙牴鎹笟鍔¢渶姹備慨鏀规爣绛惧悕锛堝鈥滃嚭搴撴暟閲忊�濃�滈噸閲忊�濈瓑锛�
+ prop: 'outboundDecimal',
+ style: {
+ marginBottom: '24px'
+ }
+ }, [
+ h(ElInput, {
+ type: 'number', // 鏁板瓧绫诲瀷锛屽師鐢熸敮鎸佸皬鏁拌緭鍏�
+ placeholder: '璇疯緭鍏ュ皬鏁版暟鍊硷紙鏈�澶�2浣嶅皬鏁帮級',
+ modelValue: formData.outboundDecimal,
+ 'onUpdate:modelValue': (val) => {
+ formData.outboundDecimal = val;
+ },
+ style: {
+ width: '100%',
+ height: '40px',
+ borderRadius: '4px',
+ borderColor: '#dcdfe6'
+ },
+ step: '0.01', // 姝ラ暱0.01锛岀偣鍑讳笂涓嬬澶存椂鎸�0.01澧炲噺
+ precision: 2, // 闄愬埗鏈�澶氳緭鍏�2浣嶅皬鏁帮紙Element Plus灞炴�э級
+ min: 0.01, // 鍙�夛細闄愬埗鏈�灏忓�间负0.01锛岄伩鍏嶈緭鍏�0鎴栬礋鏁�
+ })
+ ]),
+ // 搴曢儴鎸夐挳鍖�
+ h('div', {
+ style: {
+ textAlign: 'right',
+ marginTop: '8px',
+ paddingRight: '4px'
+ }
+ }, [
+ h(ElButton, {
+ type: 'text',
+ onClick: () => {
+ render(null, mountNode);
+ document.body.removeChild(mountNode);
+ ElMessage.info('鍙栨秷鍒嗘壒鍑哄簱鎿嶄綔');
+ },
+ style: {
+ marginRight: '8px',
+ color: '#606266'
+ }
+ }, '鍙栨秷'),
+ h(ElButton, {
+ type: 'primary',
+ onClick: async () => {
+ const formRef = vnode.component.refs.outboundForm;
+ try {
+ // 琛ㄥ崟鏍¢獙锛堜細鍚屾椂鏍¢獙鍑哄簱绔欏彴鍜屽皬鏁板瓧娈碉級
+ await formRef.validate();
+ } catch (err) {
+ return;
+ }
+console.log(this.selection);
+ // 4. 鏋勯�犺姹傚弬鏁帮紙鏂板灏忔暟瀛楁锛�
+ const keys = this.selection.map((item) => item.id);
+ const requestParams = {
+ orderDetailId: keys[0], // 鍒嗘壒鍑哄簱浠呮敮鎸佸崟鏉℃槑缁�
+ outboundPlatform: formData.selectedPlatform, // 鍑哄簱绔欏彴
+ batchQuantity: formData.outboundDecimal // 鏂板锛氬皬鏁板瓧娈典紶缁欏悗绔�
+ };
+
+ // 5. 璋冪敤鍑哄簱鎺ュ彛
+ this.http
+ .post("api/Task/GenerateOutboundBatchTasks", requestParams, "鏁版嵁澶勭悊涓�")
+ .then((x) => {
+ if (!x.status) return ElMessage.error(x.message);
+
+ ElMessage.success("鎿嶄綔鎴愬姛");
+ this.showDetialBox = false; // 鍏抽棴璇︽儏妗�
+ this.$emit("parentCall", ($vue) => {
+ $vue.getData(); // 閫氱煡鐖剁粍浠跺埛鏂�
+ });
+ // 鍏抽棴寮圭獥
+ render(null, mountNode);
+ document.body.removeChild(mountNode);
+ })
+ .catch(() => {
+ ElMessage.error('璇锋眰澶辫触锛岃绋嶅悗閲嶈瘯');
+ });
+ },
+ style: {
+ borderRadius: '4px',
+ padding: '8px 20px'
+ }
+ }, '纭畾鍒嗘壒鍑哄簱')
+ ])
+ ])
+ });
+
+ // 缁戝畾app涓婁笅鏂囷紝纭繚El缁勪欢姝e父宸ヤ綔
+ vnode.appContext = this.$.appContext;
+ render(vnode, mountNode);
+},
+
+
setCurrent(row) {
this.$refs.singleTable.setCurrentRow(row);
},
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/printView.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/printView.vue"
index 055e360..a7156f3 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/printView.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/extend/printView.vue"
@@ -172,7 +172,7 @@
},
methods: {
generateQr(item) {
- return `${item.materialCode}_${item.supplierCode}_${item.purchaseOrderNo}_${item.materialName}_${item.batch}_${item.batchNumber}_${item.factory}_${item.date}`;
+ return `${item.batchNumber}`;
},
open(rows) {
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js"
index 23c4f2b..7e12e0e 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/extension/outbound/outboundOrder.js"
@@ -327,15 +327,6 @@
this.$refs.gridBody.open(row);
}
});
-
- let TaskHandCompletedBtn = this.buttons.find(x => x.value == 'NoStockOut');
- if (TaskHandCompletedBtn) {
- TaskHandCompletedBtn.onClick = function () {
- this.$refs.gridHeader.open();
- }
- }
-
-
},
onInited() {
//妗嗘灦鍒濆鍖栭厤缃悗
@@ -345,6 +336,16 @@
searchBefore(param) {
//鐣岄潰鏌ヨ鍓�,鍙互缁檖aram.wheres娣诲姞鏌ヨ鍙傛暟
//杩斿洖false锛屽垯涓嶄細鎵ц鏌ヨ
+
+ let wheres = [{
+ 'name': 'orderType',
+ 'value': '0',
+ 'displayType': 'text'}];
+
+
+ param.wheres.push(...wheres);
+ return true;
+
return true;
},
searchAfter(result) {
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
index 5ee8694..3896357 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
@@ -79,7 +79,14 @@
name: 'PickingConfirm',
component: () => import('@/views/outbound/PickingConfirm.vue'),
meta: { title: '鎷i�夌‘璁�', keepAlive: false }
-},{
+},
+ {
+ path: '/outbound/batchpicking',
+ name: 'BatchPickingConfirm',
+ component: () => import('@/views/outbound/BatchPickingConfirm.vue'),
+ meta: { title: '鎷i�夌‘璁�', keepAlive: false }
+},
+{
path: '/stockInfo',
name: 'stockInfo',
component: () => import('@/views/stock/stockInfo.vue')
@@ -197,7 +204,7 @@
component: () => import('@/views/inbound/allocateinboundOrder.vue')
},{
- path:'allocateoutboundOrder',
+ path:'/allocateoutboundOrder',
name: 'allocateoutboundOrder',
component: () => import('@/views/outbound/allocateoutboundOrder.vue')
},
@@ -205,6 +212,11 @@
path: '/allocateOrder',
name: 'Dt_AllocateOrder',
component: () => import('@/views/inbound/Dt_AllocateOrder.vue')
+ },
+ {
+ path: '/reCheckOrder',
+ name: 'Dt_ReCheckOrder',
+ component: () => import('@/views/check/ReCheckOrder.vue')
}
]
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/check/ReCheckOrder.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/check/ReCheckOrder.vue"
new file mode 100644
index 0000000..62a8a5c
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/check/ReCheckOrder.vue"
@@ -0,0 +1,115 @@
+<!--
+*Author锛歫xx
+ *Contact锛�283591387@qq.com
+ *浠g爜鐢辨鏋剁敓鎴�,浠讳綍鏇存敼閮藉彲鑳藉鑷磋浠g爜鐢熸垚鍣ㄨ鐩�
+ *涓氬姟璇峰湪@/extension/widesea_wcs/order/Dt_CheckOrder.js姝ゅ缂栧啓
+ -->
+<template>
+ <view-grid ref="grid" :columns="columns" :editFormFields="editFormFields"
+ :editFormOptions="editFormOptions" :searchFormFields="searchFormFields" :searchFormOptions="searchFormOptions"
+ :table="table" :extend="extend">
+ </view-grid>
+</template>
+<script>
+import extend from "@/extension/check/recheckOrder.js";
+import { ref, defineComponent } from "vue";
+export default defineComponent({
+ setup() {
+ const table = ref({
+ key: 'id',
+ footer: "Foots",
+ cnName: '閲嶆鍗�',
+ name: 'Dt_ReCheckOrder',
+ url: "/ReCheckOrder/",
+ sortName: "id"
+ });
+
+
+ const editFormFields = ref({
+ OrderNo: "",
+ MaterielCode: "",
+ BatchNo: "",
+ WarehouseCode: "",
+ Unit: "",
+ FactoryArea: "",
+ Result: 0,
+ InspectionNumber: 0,
+ Qty: 0,
+ SignSeq: 0
+ });
+
+
+ const editFormOptions = ref([
+ [
+ { title: "澶嶆鍗曞彿", field: "OrderNo", type: "input", require: true },
+ { title: "鐗╂枡缂栧彿", field: "MaterielCode", type: "input", require: true },
+ { title: "鎵规鍙�", field: "BatchNo", type: "input", require: true },
+ { title: "浠撳簱缂栫爜", field: "WarehouseCode", type: "input", require: true }
+ ],
+ [
+ { title: "鍗曚綅", field: "Unit", type: "input", require: true },
+ { title: "鍘傚尯", field: "FactoryArea", type: "input", require: true },
+ { title: "妫�楠岀粨鏋�", field: "Result", type: "select", require: true,dataKey: "inOrderType",data: []},
+ { title: "妫�楠屾鏁�", field: "InspectionNumber", type: "number", require: true, min: 1 }
+ ],
+ [
+ { title: "鏁伴噺", field: "Qty", type: "number", require: true, min: 0 },
+ { title: "绛惧瓧椤哄簭", field: "SignSeq", type: "number", require: true, min: 1 }
+ ]
+ ]);
+
+
+ const searchFormFields = ref({
+ OrderNo: "",
+ MaterielCode: "",
+ BatchNo: "",
+ WarehouseCode: "",
+ FactoryArea: "",
+ Result: ""
+ });
+
+
+ const searchFormOptions = ref([
+ [
+ { title: "澶嶆鍗曞彿", field: "OrderNo", type: "like" },
+ { title: "鐗╂枡缂栧彿", field: "MaterielCode", type: "like" },
+ { title: "鎵规鍙�", field: "BatchNo", type: "like" },
+ { title: "浠撳簱缂栫爜", field: "WarehouseCode", type: "like" }
+ ],
+ [
+ { title: "鍘傚尯", field: "FactoryArea", type: "like" },
+ { title: "妫�楠岀粨鏋�", field: "Result", type: "select",dataKey: "inOrderType", data: []}
+ ]
+ ]);
+
+
+ const columns = ref([
+ { field: 'id', title: '涓婚敭', type: 'int', width: 150, hidden: true, readonly: true, require: true, align: 'left' },
+ { field: 'orderNo', title: '澶嶆鍗曞彿', type: 'string', width: 160, require: true, align: 'left', sort: true },
+ { field: 'materielCode', title: '鐗╂枡缂栧彿', type: 'string', width: 160, require: true, align: 'left' },
+ { field: 'batchNo', title: '鎵规鍙�', type: 'string', width: 160, require: true, align: 'left' },
+ { field: 'warehouseCode', title: '浠撳簱缂栫爜', type: 'string', width: 160, require: true, align: 'left' },
+ { field: 'unit', title: '鍗曚綅', type: 'string', width: 100, require: true, align: 'left' },
+ { field: 'factoryArea', title: '鍘傚尯', type: 'string', width: 120, require: true, align: 'left' },
+ { field: 'result', title: '妫�楠岀粨鏋�', type: 'int', width: 110, require: true, align: 'left',bind: { key: "inOrderType", data: [] },},
+ { field: 'inspectionNumber', title: '妫�楠屾鏁�', type: 'int', width: 110, require: true, align: 'left' },
+ { field: 'qty', title: '鏁伴噺', type: 'float', width: 110, require: true, align: 'left' },
+ { field: 'signSeq', title: '绛惧瓧椤哄簭', type: 'int', width: 110, require: true, align: 'left' },
+ { field: 'creater', title: '鍒涘缓鑰�', type: 'string', width: 110, require: true, align: 'left' },
+ { field: 'createDate', title: '鍒涘缓鏃堕棿', type: 'datetime', width: 150, require: true, align: 'left', sort: true },
+ { field: 'modifier', title: '淇敼浜�', type: 'string', width: 100, align: 'left' },
+ { field: 'modifyDate', title: '淇敼鏃ユ湡', type: 'datetime', width: 150, align: 'left', sort: true },
+ ]);
+
+ return {
+ table,
+ extend,
+ editFormFields,
+ editFormOptions,
+ searchFormFields,
+ searchFormOptions,
+ columns
+ };
+ },
+});
+</script>
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/check/checkOrder.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/check/checkOrder.vue"
index 41ee0fc..d84f1b9 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/check/checkOrder.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/check/checkOrder.vue"
@@ -5,98 +5,92 @@
*涓氬姟璇峰湪@/extension/widesea_wcs/order/Dt_CheckOrder.js姝ゅ缂栧啓
-->
<template>
- <view-grid ref="grid"
- :columns="columns"
- :detail="detail"
- :editFormFields="editFormFields"
- :editFormOptions="editFormOptions"
- :searchFormFields="searchFormFields"
- :searchFormOptions="searchFormOptions"
- :table="table"
- :extend="extend">
+ <view-grid ref="grid" :columns="columns" :detail="detail" :editFormFields="editFormFields"
+ :editFormOptions="editFormOptions" :searchFormFields="searchFormFields" :searchFormOptions="searchFormOptions"
+ :table="table" :extend="extend">
</view-grid>
</template>
<script>
- import extend from "@/extension/check/checkOrder.js";
- import { ref, defineComponent } from "vue";
- export default defineComponent({
- setup() {
- const table = ref({
- key: 'checkOrderId',
- footer: "Foots",
- cnName: '妫�楠屽崟',
- name: 'checkOrder',
- url: "/CheckOrder/",
- sortName: "checkOrderId"
- });
- const editFormFields = ref({});
- const editFormOptions = ref([]);
- const searchFormFields = ref({
- checkOrderNo:"",
- receiveOrderNo:"",
- checkOrderStatus:"",
- auditStatus:""
- });
- const searchFormOptions = ref([
- [
- {title:"妫�楠屽崟鍙�", field:"checkOrderNo",type:"like"},
- {title:"鏀惰揣鍗曞彿", field:"receiveOrderNo",type:"like"},
- {title:"璐ㄦ鍗曠姸鎬�", field:"checkOrderStatus",type:"select",dataKey:"",data:[]},
- {title:"瀹℃壒鐘舵��", field:"auditStatus",type:"select",dataKey:"",data:[]},
- ],
- [
- {title:"鏀惰揣鍗曟槑缁嗚鍙�", field:"receiveDetailRowNo",type:"like"},
- {title:"鐗╂枡缂栧彿", field:"materielCode",type:"like"},
- {title:"妫�楠岀粨鏋�", field:"result",type:"like"},
- ]
- ]);
- const columns = ref([{field:'checkOrderId',title:'涓婚敭',type:'int',width:150,hidden:true,readonly:true,require:true,align:'left'},
- {field:'checkOrderNo',title:'妫�楠屽崟鍙�',type:'string',width:160,require:true,align:'left',sort:true},
- {field:'receiveOrderNo',title:'鏀惰揣鍗曞彿',type:'string',width:160,require:true,align:'left'},
- {field:'checkOrderStatus',title:'璐ㄦ鍗曠姸鎬�',type:'int',width:110,require:true,align:'left'},
- {field:'auditStatus',title:'瀹℃壒鐘舵��',type:'int',width:110,require:true,align:'left'},
- {field:'receiveDetailRowNo',title:'鏀惰揣鍗曟槑缁嗚鍙�',type:'int',width:110,require:true,align:'left'},
- {field:'materielCode',title:'鐗╂枡缂栧彿',type:'string',width:110,require:true,align:'left'},
- {field:'qualifiedQuantity',title:'鍚堟牸鏁伴噺',type:'float',width:110,align:'left'},
- {field:'defectedQuantity',title:'鐗归噰鏁伴噺',type:'float',width:110,align:'left'},
- {field:'returnQuantity',title:'閫�璐ф暟閲�',type:'float',width:110,align:'left'},
- {field:'scrappedQuantity',title:'鎶ュ簾鏁伴噺',type:'float',width:110,align:'left'},
- {field:'receivedQuantity',title:'妫�楠屾�绘暟',type:'float',width:110,require:true,align:'left'},
- {field:'result',title:'妫�楠岀粨鏋�',type:'string',width:110,align:'left'},
- {field:'defectedNote',title:'鐗归噰璇存槑',type:'string',width:110,align:'left'},
- {field:'checkUserName',title:'妫�楠屼汉',type:'string',width:110,align:'left'},
- {field:'creater',title:'鍒涘缓鑰�',type:'string',width:110,require:true,align:'left'},
- {field:'createDate',title:'鍒涘缓鏃堕棿',type:'datetime',width:150,require:true,align:'left',sort:true},
- {field:'modifier',title:'淇敼浜�',type:'string',width:100,align:'left'},
- {field:'modifyDate',title:'淇敼鏃ユ湡',type:'datetime',width:150,align:'left',sort:true}]);
- const detail = ref({
- cnName: "妫�楠岀粨鏋�",
- table: "CheckOrderResult",
- columns: [
- {field:'id',title:'涓婚敭',type:'int',width:110,hidden:true,readonly:true,require:true,align:'left'},
- {field:'checkOrderId',title:'妫�楠屽崟涓婚敭',type:'int',width:110,require:true,align:'left',sort:true},
- {field:'defectCode',title:'缂洪櫡浠g爜',type:'string',width:110,require:true,align:'left'},
- {field:'result',title:'妫�楠岀粨鏋�',type:'string',width:110,require:true,align:'left'},
- {field:'quantity',title:'鏁伴噺',type:'float',width:110,require:true,align:'left'},
- {field:'note',title:'澶囨敞',type:'string',width:220,align:'left'},
- {field:'creater',title:'鍒涘缓鑰�',type:'string',width:110,require:true,align:'left'},
- {field:'createDate',title:'鍒涘缓鏃堕棿',type:'datetime',width:150,require:true,align:'left',sort:true},
- {field:'modifier',title:'淇敼浜�',type:'string',width:100,align:'left'},
- {field:'modifyDate',title:'淇敼鏃ユ湡',type:'datetime',width:150,align:'left',sort:true}
- ],
- sortName: "id",
- key: "id"
- });
- return {
- table,
- extend,
- editFormFields,
- editFormOptions,
- searchFormFields,
- searchFormOptions,
- columns,
- detail,
- };
- },
- });
+import extend from "@/extension/check/checkOrder.js";
+import { ref, defineComponent } from "vue";
+export default defineComponent({
+ setup() {
+ const table = ref({
+ key: 'checkOrderId',
+ footer: "Foots",
+ cnName: '妫�楠屽崟',
+ name: 'checkOrder',
+ url: "/CheckOrder/",
+ sortName: "checkOrderId"
+ });
+ const editFormFields = ref({});
+ const editFormOptions = ref([]);
+ const searchFormFields = ref({
+ checkOrderNo: "",
+ receiveOrderNo: "",
+ checkOrderStatus: "",
+ auditStatus: ""
+ });
+ const searchFormOptions = ref([
+ [
+ { title: "妫�楠屽崟鍙�", field: "checkOrderNo", type: "like" },
+ { title: "鏀惰揣鍗曞彿", field: "receiveOrderNo", type: "like" },
+ { title: "璐ㄦ鍗曠姸鎬�", field: "checkOrderStatus", type: "select", dataKey: "", data: [] },
+ { title: "瀹℃壒鐘舵��", field: "auditStatus", type: "select", dataKey: "", data: [] },
+ ],
+ [
+ { title: "鏀惰揣鍗曟槑缁嗚鍙�", field: "receiveDetailRowNo", type: "like" },
+ { title: "鐗╂枡缂栧彿", field: "materielCode", type: "like" },
+ { title: "妫�楠岀粨鏋�", field: "result", type: "like" },
+ ]
+ ]);
+ const columns = ref([{ field: 'checkOrderId', title: '涓婚敭', type: 'int', width: 150, hidden: true, readonly: true, require: true, align: 'left' },
+ { field: 'checkOrderNo', title: '妫�楠屽崟鍙�', type: 'string', width: 160, require: true, align: 'left', sort: true },
+ { field: 'receiveOrderNo', title: '鏀惰揣鍗曞彿', type: 'string', width: 160, require: true, align: 'left' },
+ { field: 'checkOrderStatus', title: '璐ㄦ鍗曠姸鎬�', type: 'int', width: 110, require: true, align: 'left' },
+ { field: 'auditStatus', title: '瀹℃壒鐘舵��', type: 'int', width: 110, require: true, align: 'left' },
+ { field: 'receiveDetailRowNo', title: '鏀惰揣鍗曟槑缁嗚鍙�', type: 'int', width: 110, require: true, align: 'left' },
+ { field: 'materielCode', title: '鐗╂枡缂栧彿', type: 'string', width: 110, require: true, align: 'left' },
+ { field: 'qualifiedQuantity', title: '鍚堟牸鏁伴噺', type: 'float', width: 110, align: 'left' },
+ { field: 'defectedQuantity', title: '鐗归噰鏁伴噺', type: 'float', width: 110, align: 'left' },
+ { field: 'returnQuantity', title: '閫�璐ф暟閲�', type: 'float', width: 110, align: 'left' },
+ { field: 'scrappedQuantity', title: '鎶ュ簾鏁伴噺', type: 'float', width: 110, align: 'left' },
+ { field: 'receivedQuantity', title: '妫�楠屾�绘暟', type: 'float', width: 110, require: true, align: 'left' },
+ { field: 'result', title: '妫�楠岀粨鏋�', type: 'string', width: 110, align: 'left' },
+ { field: 'defectedNote', title: '鐗归噰璇存槑', type: 'string', width: 110, align: 'left' },
+ { field: 'checkUserName', title: '妫�楠屼汉', type: 'string', width: 110, align: 'left' },
+ { field: 'creater', title: '鍒涘缓鑰�', type: 'string', width: 110, require: true, align: 'left' },
+ { field: 'createDate', title: '鍒涘缓鏃堕棿', type: 'datetime', width: 150, require: true, align: 'left', sort: true },
+ { field: 'modifier', title: '淇敼浜�', type: 'string', width: 100, align: 'left' },
+ { field: 'modifyDate', title: '淇敼鏃ユ湡', type: 'datetime', width: 150, align: 'left', sort: true }]);
+ const detail = ref({
+ cnName: "妫�楠岀粨鏋�",
+ table: "CheckOrderResult",
+ columns: [
+ { field: 'id', title: '涓婚敭', type: 'int', width: 110, hidden: true, readonly: true, require: true, align: 'left' },
+ { field: 'checkOrderId', title: '妫�楠屽崟涓婚敭', type: 'int', width: 110, require: true, align: 'left', sort: true },
+ { field: 'defectCode', title: '缂洪櫡浠g爜', type: 'string', width: 110, require: true, align: 'left' },
+ { field: 'result', title: '妫�楠岀粨鏋�', type: 'string', width: 110, require: true, align: 'left' },
+ { field: 'quantity', title: '鏁伴噺', type: 'float', width: 110, require: true, align: 'left' },
+ { field: 'note', title: '澶囨敞', type: 'string', width: 220, align: 'left' },
+ { field: 'creater', title: '鍒涘缓鑰�', type: 'string', width: 110, require: true, align: 'left' },
+ { field: 'createDate', title: '鍒涘缓鏃堕棿', type: 'datetime', width: 150, require: true, align: 'left', sort: true },
+ { field: 'modifier', title: '淇敼浜�', type: 'string', width: 100, align: 'left' },
+ { field: 'modifyDate', title: '淇敼鏃ユ湡', type: 'datetime', width: 150, align: 'left', sort: true }
+ ],
+ sortName: "id",
+ key: "id"
+ });
+ return {
+ table,
+ extend,
+ editFormFields,
+ editFormOptions,
+ searchFormFields,
+ searchFormOptions,
+ columns,
+ detail,
+ };
+ },
+});
</script>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/Dt_AllocateOrder.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/Dt_AllocateOrder.vue"
index fc0542e..74bdf7a 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/Dt_AllocateOrder.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/Dt_AllocateOrder.vue"
@@ -37,7 +37,7 @@
key: "id",
footer: "Foots",
cnName: "璋冩嫧鍗�",
- name: "Dt_AllocateOrder",
+ name: "AllocateOrder",
url: "/AllocateOrder/",
sortName: "id",
});
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/allocateinboundOrder.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/allocateinboundOrder.vue"
index 8fbef36..33c7454 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/allocateinboundOrder.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/allocateinboundOrder.vue"
@@ -37,14 +37,14 @@
const table = ref({
key: "id",
footer: "Foots",
- cnName: "璋冩嫧鍗�(鏅轰粨璋冨閮ㄤ粨搴�)",
- name: "inboundOrder",
- url: "/InboundOrder/",
+ cnName: "璋冩嫧鍗�(澶栭儴浠撹皟鍏ユ櫤浠�)",
+ name: "AllocateOrder",
+ url: "/AllocateOrder/",
sortName: "id",
});
const editFormFields = ref({
orderType: "",
- inboundOrderNo: "",
+ orderNo: "",
upperOrderNo: "",
remark: "",
});
@@ -59,7 +59,7 @@
data: [],
},
{
- field: "inboundOrderNo",
+ field: "orderNo",
title: "鍗曟嵁缂栧彿",
type: "string",
},
@@ -76,7 +76,7 @@
],
]);
const searchFormFields = ref({
- inboundOrderNo: "",
+ orderNo: "",
upperOrderNo: "",
orderType: "115",
orderStatus: "",
@@ -86,7 +86,7 @@
});
const searchFormOptions = ref([
[
- { title: "鍗曟嵁缂栧彿", field: "inboundOrderNo", type: "like" },
+ { title: "鍗曟嵁缂栧彿", field: "orderNo", type: "like" },
{ title: "涓婃父鍗曟嵁缂栧彿", field: "upperOrderNo", type: "like" },
{
title: "鍗曟嵁绫诲瀷",
@@ -127,7 +127,7 @@
align: "left",
},
{
- field: "inboundOrderNo",
+ field: "orderNo",
title: "鍗曟嵁缂栧彿",
type: "string",
width: 120,
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue"
index e4defc7..0fafa8b 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue"
@@ -57,6 +57,7 @@
type: "select",
dataKey: "inOrderType",
data: [],
+ hidden:true
},
{
field: "inboundOrderNo",
@@ -94,6 +95,7 @@
type: "select",
dataKey: "inOrderType",
data: [0],
+ hidden:true
},
{
title: "鍗曟嵁鐘舵��",
@@ -148,6 +150,7 @@
width: 150,
align: "left",
bind: { key: "inOrderType", data: [] },
+ hidden:true
},
{
field: "businessType",
@@ -242,7 +245,7 @@
field: "materielCode",
title: "鐗╂枡缂栧彿",
type: "select",
- width: 150,
+ width: 120,
align: "left",
edit: { type: "" },
required: true,
@@ -251,7 +254,7 @@
field: "materielCode",
title: "鐗╂枡鍚嶇О",
type: "string",
- width: 100,
+ width: 120,
align: "left",
bind: { key: "MaterielNames", data: [] },
},
@@ -259,7 +262,7 @@
field: "batchNo",
title: "鎵规鍙�",
type: "decimal",
- width: 90,
+ width: 150,
align: "left",
edit: { type: "" },
required: true,
@@ -268,7 +271,7 @@
field: "supplyCode",
title: "渚涘簲鍟嗙紪鍙�",
type: "decimal",
- width: 90,
+ width: 100,
align: "left",
edit: { type: "" },
required: true,
@@ -285,7 +288,7 @@
field: "barcode",
title: "鏉$爜",
type: "decimal",
- width: 90,
+ width: 180,
align: "left",
edit: { type: "" },
required: true,
@@ -303,21 +306,21 @@
field: "receiptQuantity",
title: "缁勭洏鏁伴噺",
type: "int",
- width: 120,
+ width: 90,
align: "left",
},
{
field: "overInQuantity",
title: "涓婃灦鏁伴噺",
type: "string",
- width: 200,
+ width: 90,
align: "left",
},
{
field: "orderDetailStatus",
title: "璁㈠崟鏄庣粏鐘舵��",
type: "string",
- width: 180,
+ width: 100,
align: "left",
bind: { key: "orderDetailStatusEnum", data: [] },
},
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue"
new file mode 100644
index 0000000..4487276
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/BatchPickingConfirm.vue"
@@ -0,0 +1,1278 @@
+<template>
+ <div class="OutboundPicking-container">
+ <div class="page-header">
+ <el-page-header @back="goBack">
+ <template #content>
+ <span class="title">鍑哄簱鎷i�夌‘璁� - {{ this.$route.query.orderNo }}</span>
+ </template>
+ </el-page-header>
+ </div>
+
+ <!-- 鎵爜鍖哄煙 -->
+ <div class="scanner-area">
+ <el-card>
+ <div class="scanner-form">
+ <el-input
+ ref="palletInput"
+ v-model="scanData.palletCode"
+ placeholder="鎵弿鎵樼洏鐮�"
+ @change="onPalletScan"
+ @keyup.enter.native="onPalletScan">
+ </el-input>
+ <el-input
+ ref="barcodeInput"
+ v-model="scanData.barcode"
+ placeholder="鎵弿鐗╂枡鏉$爜"
+ @change="onBarcodeScan"
+ @keyup.enter.native="onBarcodeScan">
+ </el-input>
+ <el-button type="success" @click="confirmPicking">纭鎷i��</el-button>
+ <el-button type="warning" @click="openSplitDialog">鎷嗗寘</el-button>
+ <el-button type="info" @click="openRevertSplitDialog">鎾ら攢鎷嗗寘</el-button>
+ <el-button type="info" @click="handleEmptyPallet">鍙栫┖绠�</el-button>
+ <el-button type="primary" @click="openBatchReturnDialog">鍥炲簱</el-button>
+ </div>
+ </el-card>
+ </div>
+
+ <!-- 姹囨�讳俊鎭� -->
+ <div class="summary-area">
+ <el-card>
+ <div class="summary-info">
+ <el-tag type="warning">鏈嫞閫夋潯鏁�: {{summary.unpickedCount}}</el-tag>
+ <el-tag type="danger">鏈嫞閫夋暟閲�: {{summary.unpickedQuantity}}</el-tag>
+ <el-tag type="info">鎵樼洏鐘舵��: {{palletStatus}}</el-tag>
+ </div>
+ </el-card>
+ </div>
+
+ <!-- 鏁版嵁鍒楄〃 -->
+ <div class="content-area">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-card header="鏈嫞閫夊垪琛�">
+ <el-table :data="unpickedList" border height="440">
+ <el-table-column prop="materielCode" label="鐗╂枡缂栫爜" width="120"></el-table-column>
+ <el-table-column prop="assignQuantity" label="鍒嗛厤鏁伴噺" width="100"></el-table-column>
+ <el-table-column prop="pickedQty" label="宸叉嫞鏁伴噺" width="100"></el-table-column>
+ <el-table-column prop="remainQuantity" label="鍓╀綑鏁伴噺" width="100"></el-table-column>
+ <el-table-column prop="locationCode" label="璐т綅" width="100"></el-table-column>
+ <el-table-column prop="currentBarcode" label="鏉$爜"></el-table-column>
+ </el-table>
+ </el-card>
+ </el-col>
+
+ <el-col :span="12">
+ <el-card header="宸叉嫞閫夊垪琛�">
+ <div class="table-actions">
+ <el-button
+ size="mini"
+ type="danger"
+ :disabled="selectedPickedRows.length === 0"
+ @click="batchCancelSelected">
+ 鍙栨秷鎷i��
+ </el-button>
+ <span class="selection-count">宸查�夋嫨 {{selectedPickedRows.length}} 椤�</span>
+ </div>
+ <el-table
+ :data="pickedList"
+ border
+ height="400"
+ style="width: 100%"
+ @selection-change="handlePickedSelectionChange">
+ <el-table-column type="selection" width="55"></el-table-column>
+ <el-table-column prop="materielCode" label="鐗╂枡缂栫爜" width="120"></el-table-column>
+ <el-table-column prop="pickedQty" label="宸叉嫞鏁伴噺" width="100"></el-table-column>
+ <el-table-column prop="locationCode" label="璐т綅" width="100"></el-table-column>
+ <el-table-column prop="currentBarcode" label="鏉$爜"></el-table-column>
+ </el-table>
+ </el-card>
+ </el-col>
+ </el-row>
+ </div>
+
+ <!-- 鎷嗗寘寮圭獥 -->
+ <div v-if="showCustomSplitDialog" class="custom-dialog-overlay">
+ <div class="custom-dialog-wrapper">
+ <div class="custom-dialog">
+ <div class="custom-dialog-header">
+ <h3>鎷嗗寘鎿嶄綔</h3>
+ <el-button type="text" @click="closeCustomSplitDialog" class="close-button">X</el-button>
+ </div>
+ <div class="custom-dialog-body">
+ <el-form :model="splitForm" :rules="splitFormRules" ref="splitFormRef" label-width="100px">
+ <el-form-item label="璁㈠崟缂栧彿">
+ <el-input v-model="splitForm.orderNo" disabled></el-input>
+ </el-form-item>
+ <el-form-item label="鎵樼洏缂栧彿">
+ <el-input v-model="splitForm.palletCode" disabled></el-input>
+ </el-form-item>
+ <el-form-item label="鍘熸潯鐮�" prop="originalBarcode">
+ <div style="display: flex; align-items: center; gap: 10px;">
+ <el-input
+ v-model="splitForm.originalBarcode"
+ placeholder="鎵弿鍘熸潯鐮�"
+ @keyup.enter.native="onSplitBarcodeScan"
+ @change="onSplitBarcodeScan"
+ clearable
+ style="flex: 1;">
+ </el-input>
+ <!-- 鏂板锛氭煡鐪嬫媶鍖呴摼鎸夐挳 -->
+ <el-button
+ type="primary"
+ @click="viewSplitChainFromSplit(splitForm.originalBarcode)"
+ :disabled="!splitForm.originalBarcode"
+ :loading="splitChainLoading">
+ 鏌ョ湅鎷嗗寘閾�
+</el-button>
+ </div>
+ </el-form-item>
+ <el-form-item label="鐗╂枡缂栫爜">
+ <el-input v-model="splitForm.materielCode" disabled></el-input>
+ </el-form-item>
+ <el-form-item label="鍓╀綑鏁伴噺">
+ <el-input v-model="splitForm.maxQuantity" disabled></el-input>
+ </el-form-item>
+ <el-form-item label="鎷嗗寘鏁伴噺" prop="splitQuantity">
+ <el-input-number
+ v-model="splitForm.splitQuantity"
+ :min="1"
+ :max="splitForm.maxQuantity"
+ :precision="2"
+ :step="1"
+ style="width: 100%">
+ </el-input-number>
+ </el-form-item>
+ </el-form>
+ </div>
+ <div class="custom-dialog-footer">
+ <el-button @click="closeCustomSplitDialog">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleSplitPackage" :loading="splitLoading">纭鎷嗗寘</el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- 鎾ら攢鎷嗗寘寮圭獥 -->
+ <div v-if="showRevertSplitDialog" class="custom-dialog-overlay">
+ <div class="custom-dialog-wrapper">
+ <div class="custom-dialog">
+ <div class="custom-dialog-header">
+ <h3>鎾ら攢鎷嗗寘</h3>
+ <el-button type="text" @click="closeRevertSplitDialog" class="close-button">脳</el-button>
+ </div>
+ <div class="custom-dialog-body">
+ <el-form :model="revertSplitForm" :rules="revertSplitFormRules" ref="revertSplitFormRef" label-width="100px">
+ <el-form-item label="鏂版潯鐮�" prop="newBarcode">
+ <div style="display: flex; align-items: center; gap: 10px;">
+ <el-input
+ v-model="revertSplitForm.newBarcode"
+ placeholder="鎵弿鏂版潯鐮�"
+ @keyup.enter.native="onRevertSplitBarcodeScan"
+ @change="onRevertSplitBarcodeScan"
+ clearable
+ style="flex: 1;">
+ </el-input>
+ <!-- 鏂板锛氭煡鐪嬫媶鍖呴摼鎸夐挳 -->
+ <el-button
+ type="primary"
+ @click="viewSplitChain(revertSplitForm.newBarcode)"
+ :disabled="!revertSplitForm.newBarcode">
+ 鏌ョ湅鎷嗗寘閾�
+ </el-button>
+ </div>
+ </el-form-item>
+ </el-form>
+
+ <!-- 鏂板锛氭媶鍖呴摼绠�瑕佷俊鎭樉绀� -->
+ <div v-if="splitChainInfo.splitChain && splitChainInfo.splitChain.length > 0"
+ style="margin-top: 15px; padding: 10px; background: #f0f9ff; border-radius: 4px;">
+ <div style="font-size: 14px; color: #606266;">
+ <div>鎷嗗寘閾句俊鎭�: 鍏� {{ splitChainInfo.totalSplitTimes }} 娆℃媶鍖�</div>
+ <div style="margin-top: 5px;">
+ <el-tag
+ v-for="item in splitChainInfo.splitChain.slice(0, 3)"
+ :key="item.newBarcode"
+ :type="item.isReverted ? 'success' : 'primary'"
+ size="small"
+ style="margin-right: 5px;">
+ {{ item.newBarcode }} ({{ item.splitQuantity }})
+ </el-tag>
+ <span v-if="splitChainInfo.splitChain.length > 3" style="color: #909399;">
+ 绛� {{ splitChainInfo.splitChain.length }} 涓潯鐮�
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="custom-dialog-footer">
+ <el-button @click="closeRevertSplitDialog">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleRevertSplit" :loading="revertSplitLoading">纭鎾ら攢</el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- 鎷嗗寘閾句俊鎭脊绐� -->
+<div v-if="showSplitChainDialog" class="custom-dialog-overlay">
+ <div class="custom-dialog-wrapper">
+ <div class="custom-dialog" style="width: 750px;">
+ <div class="custom-dialog-header">
+ <h3>鎷嗗寘閾句俊鎭�</h3>
+ <el-button type="text" @click="closeSplitChainDialog" class="close-button">脳</el-button>
+ </div>
+ <div class="custom-dialog-body">
+ <!-- 鏂板锛氭媶鍖呴摼璇存槑 -->
+ <div style="margin-bottom: 15px; padding: 10px; background: #f0f9ff; border-radius: 4px;">
+ <div style="display: flex; justify-content: space-between; align-items: center;">
+ <div>
+ <div style="font-weight: bold; color: #303133;">鎷嗗寘閾捐鏄�</div>
+ <div style="font-size: 12px; color: #606266; margin-top: 5px;">
+ 褰撳墠鏄剧ず鐨勬槸浠� <el-tag type="primary" size="small">{{ splitChainInfo.originalBarcode }}</el-tag> 寮�濮嬬殑鎷嗗寘閾�
+ <br>鍏� {{ splitChainInfo.totalSplitTimes }} 娆℃媶鍖呮搷浣滐紝娑夊強 {{ splitChainInfo.splitChain.length }} 涓潯鐮�
+ </div>
+ </div>
+ <el-button
+ type="primary"
+ size="small"
+ @click="findRootChain(splitChainInfo.originalBarcode)"
+ v-if="splitChainInfo.chainType !== 'root'">
+ 鏌ユ壘瀹屾暣鎷嗗寘閾�
+ </el-button>
+ </div>
+ </div>
+
+ <div style="margin-bottom: 15px;">
+ <el-tag type="info">鎬绘媶鍖呮鏁�: {{ splitChainInfo.totalSplitTimes }}</el-tag>
+ <el-tag type="warning" style="margin-left: 10px;">
+ 鍘熷鏉$爜: {{ splitChainInfo.originalBarcode }}
+ </el-tag>
+ <el-tag :type="splitChainInfo.chainType === 'root' ? 'success' : 'warning'" style="margin-left: 10px;">
+ {{ splitChainInfo.chainType === 'root' ? '瀹屾暣閾�' : '鍒嗘敮閾�' }}
+ </el-tag>
+ </div>
+
+ <el-table :data="splitChainInfo.splitChain" border height="300">
+ <el-table-column type="index" label="搴忓彿" width="60" align="center"></el-table-column>
+ <el-table-column prop="splitTime" label="鎷嗗寘鏃堕棿" width="160">
+ <template #default="scope">
+ {{ formatDateTime(scope.row.splitTime) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="originalBarcode" label="鍘熸潯鐮�" width="140">
+ <template #default="scope">
+ <el-tag
+ :type="scope.row.originalBarcode === splitChainInfo.rootBarcode ? 'success' : 'primary'"
+ size="small">
+ {{ scope.row.originalBarcode }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="newBarcode" label="鏂版潯鐮�" width="140">
+ <template #default="scope">
+ <el-tag
+ :type="scope.row.isReverted ? 'info' : 'warning'"
+ size="small">
+ {{ scope.row.newBarcode }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="splitQuantity" label="鎷嗗寘鏁伴噺" width="100" align="right">
+ <template #default="scope">
+ {{ scope.row.splitQuantity.toFixed(2) }}
+ </template>
+ </el-table-column>
+ <el-table-column prop="operator" label="鎿嶄綔鍛�" width="100"></el-table-column>
+ <el-table-column prop="isReverted" label="鐘舵��" width="80" align="center">
+ <template #default="scope">
+ <el-tag
+ :type="scope.row.isReverted ? 'success' : 'danger'"
+ size="small">
+ {{ scope.row.isReverted ? '宸叉挙閿�' : '鏈夋晥' }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔" width="120" align="center">
+ <template #default="scope">
+ <el-button
+ v-if="!scope.row.isReverted"
+ type="danger"
+ size="mini"
+ @click="cancelSingleSplit(scope.row.newBarcode)"
+ :disabled="hasPicked(scope.row.newBarcode)">
+ 鍙栨秷
+ </el-button>
+ <span v-else style="color: #909399;">宸叉挙閿�</span>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <!-- 鎵归噺鎿嶄綔鍖哄煙 -->
+ <div style="margin-top: 15px; padding: 10px; background: #f5f7fa; border-radius: 4px;">
+ <div style="display: flex; justify-content: space-between; align-items: center;">
+ <div>
+ <span style="font-size: 14px; color: #606266;">
+ 鎵归噺鎿嶄綔: 鍙互鍙栨秷鏁翠釜鎷嗗寘閾炬垨閫夋嫨鍗曚釜鎷嗗寘璁板綍鍙栨秷
+ </span>
+ <div style="font-size: 12px; color: #909399; margin-top: 5px;">
+ 瀹屾暣鎷嗗寘閾惧寘鍚粠鏈�鍘熷鏉$爜寮�濮嬬殑鎵�鏈夋媶鍖呮搷浣�
+ </div>
+ </div>
+ <div>
+ <el-button
+ type="danger"
+ @click="cancelWholeSplitChain"
+ :disabled="!canCancelWholeChain"
+ :loading="revertSplitLoading">
+ 鍙栨秷鏁翠釜鎷嗗寘閾�
+ </el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="custom-dialog-footer">
+ <el-button @click="closeSplitChainDialog">鍏抽棴</el-button>
+ </div>
+ </div>
+ </div>
+</div>
+
+ <!-- 鎵归噺鍥炲簱寮圭獥 -->
+ <div v-if="showBatchReturnDialog" class="custom-dialog-overlay">
+ <div class="custom-dialog-wrapper">
+ <div class="custom-dialog">
+ <div class="custom-dialog-header">
+ <h3>鎵樼洏鍥炲簱</h3>
+ <el-button type="text" @click="closeBatchReturnDialog" class="close-button">脳</el-button>
+ </div>
+ <div class="custom-dialog-body">
+ <el-form :model="batchReturnForm" :rules="batchReturnFormRules" ref="batchReturnFormRef" label-width="100px">
+ <el-form-item label="璁㈠崟缂栧彿">
+ <el-input v-model="batchReturnForm.orderNo" disabled></el-input>
+ </el-form-item>
+ <el-form-item label="鎵樼洏缂栧彿">
+ <el-input v-model="batchReturnForm.palletCode" disabled></el-input>
+ </el-form-item>
+ <el-form-item label="鏈嫞閫夋暟閲�">
+ <el-input v-model="batchReturnForm.unpickedQuantity" disabled></el-input>
+ </el-form-item>
+ <el-form-item label="鏈嫞閫夋潯鏁�">
+ <el-input v-model="batchReturnForm.unpickedCount" disabled></el-input>
+ </el-form-item>
+ </el-form>
+ </div>
+ <div class="custom-dialog-footer">
+ <el-button @click="closeBatchReturnDialog">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleBatchReturnConfirm" :loading="batchReturnLoading">纭鍥炲簱</el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- 鍙栬蛋绌虹寮圭獥 -->
+ <div v-if="showEmptyPalletDialog" class="custom-dialog-overlay">
+ <div class="custom-dialog-wrapper">
+ <div class="custom-dialog">
+ <div class="custom-dialog-header">
+ <h3>鍙栬蛋绌虹</h3>
+ <el-button type="text" @click="closeEmptyPalletDialog" class="close-button">脳</el-button>
+ </div>
+ <div class="custom-dialog-body">
+ <el-form :model="emptypalletOutForm" :rules="emptypalletOutFormRules" ref="emptypalletOutFormRef" label-width="100px">
+ <el-form-item label="璁㈠崟缂栧彿">
+ <el-input v-model="emptypalletOutForm.orderNo" disabled></el-input>
+ </el-form-item>
+ <el-form-item label="鎵樼洏缂栧彿" prop="palletCode">
+ <el-input
+ v-model="emptypalletOutForm.palletCode"
+ placeholder="鎵弿鎵樼洏鐮�"
+ @keyup.enter.native="onEmptyPalletScan"
+ @change="onEmptyPalletScan"
+ clearable>
+ </el-input>
+ </el-form-item>
+ </el-form>
+ </div>
+ <div class="custom-dialog-footer">
+ <el-button @click="closeEmptyPalletDialog">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleEmptyPalletConfirm" :loading="emptypalletOutLoading">纭鍙栬蛋绌虹</el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <print-view ref="childs" @parentcall="parentcall"></print-view>
+ </div>
+</template>
+
+<script>
+import http from '@/api/http.js'
+import { ref, defineComponent } from "vue";
+import { ElMessage } from 'element-plus'
+import { useRoute } from 'vue-router'
+import printView from "@/extension/outbound/extend/printView.vue"
+
+export default defineComponent({
+ name: 'BatchOutboundPicking',
+ components: {printView},
+ data() {
+ return {
+ scanData: {
+ orderNo: '',
+ palletCode: '',
+ barcode: ''
+ },
+ unpickedList: [],
+ pickedList: [],
+ selectedPickedRows: [],
+ summary: {
+ unpickedCount: 0,
+ unpickedQuantity: 0,
+ pickedCount: 0
+ },
+ palletStatus: '鏈煡',
+
+ // 寮圭獥鐘舵��
+ showCustomSplitDialog: false,
+ showRevertSplitDialog: false,
+ showBatchReturnDialog: false,
+ showEmptyPalletDialog: false,
+ showSplitChainDialog: false, // 鏂板锛氭媶鍖呴摼淇℃伅寮圭獥
+
+ // 鍔犺浇鐘舵��
+ splitLoading: false,
+ revertSplitLoading: false,
+ batchReturnLoading: false,
+ emptypalletOutLoading: false,
+ splitChainLoading: false, // 鏂板锛氭媶鍖呴摼鍔犺浇鐘舵��
+
+ // 琛ㄥ崟鏁版嵁
+ splitForm: {
+ orderNo: '',
+ palletCode: '',
+ originalBarcode: '',
+ materielCode: '',
+ splitQuantity: 0,
+ maxQuantity: 0
+ },
+
+ revertSplitForm: {
+ newBarcode: ''
+ },
+
+ batchReturnForm: {
+ orderNo: '',
+ palletCode: '',
+ unpickedCount: 0,
+ unpickedQuantity: 0
+ },
+
+ emptypalletOutForm: {
+ orderNo: '',
+ palletCode: ''
+ },
+
+ // 鏂板锛氭媶鍖呴摼鐩稿叧鏁版嵁
+ splitChainInfo: {
+ originalBarcode: '',
+ totalSplitTimes: 0,
+ splitChain: []
+ },
+
+ // 楠岃瘉瑙勫垯
+ splitFormRules: {
+ originalBarcode: [
+ { required: true, message: '璇疯緭鍏ュ師鏉$爜', trigger: 'blur' }
+ ],
+ splitQuantity: [
+ { required: true, message: '璇疯緭鍏ユ媶鍖呮暟閲�', trigger: 'blur' },
+ { type: 'number', min: 0.01, message: '鎷嗗寘鏁伴噺蹇呴』澶т簬0', trigger: 'blur' }
+ ]
+ },
+
+ revertSplitFormRules: {
+ newBarcode: [
+ { required: true, message: '璇疯緭鍏ユ柊鏉$爜', trigger: 'blur' }
+ ]
+ },
+
+ emptypalletOutFormRules: {
+ palletCode: [
+ { required: true, message: '璇疯緭鍏ユ墭鐩樼爜', trigger: 'blur' }
+ ]
+ },
+
+ isProcessing: false
+ }
+ },
+ computed: {
+ // 鏄惁鍙互鍙栨秷鏁翠釜鎷嗗寘閾�
+ canCancelWholeChain() {
+ return this.splitChainInfo.splitChain &&
+ this.splitChainInfo.splitChain.some(item => !item.isReverted);
+ }
+ },
+ mounted() {
+ if (this.$route.query.orderNo) {
+ this.scanData.orderNo = this.$route.query.orderNo;
+ this.splitForm.orderNo = this.$route.query.orderNo;
+ this.batchReturnForm.orderNo = this.$route.query.orderNo;
+ this.emptypalletOutForm.orderNo = this.$route.query.orderNo;
+ }
+ this.$nextTick(() => {
+ this.$refs.palletInput.focus();
+ });
+ },
+ methods: {
+ goBack(){
+ this.$router.back()
+ },
+
+ // 鍒嗘嫞鐩稿叧鏂规硶
+ async confirmPicking() {
+ if (this.isProcessing) return;
+
+ if (!this.scanData.orderNo || !this.scanData.palletCode || !this.scanData.barcode) {
+ this.$message.warning('璇峰厛鎵弿鎵樼洏鐮佸拰鐗╂枡鏉$爜');
+ this.focusBarcodeInput();
+ return;
+ }
+
+ this.isProcessing = true;
+
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/confirm-picking', {
+ orderNo: this.scanData.orderNo,
+ palletCode: this.scanData.palletCode,
+ barcode: this.scanData.barcode
+ });
+ if (res.status) {
+ this.$message.success('鎷i�夌‘璁ゆ垚鍔�');
+ this.scanData.barcode = '';
+ await this.loadPalletData();
+ if(res.data && res.data.splitResults && res.data.splitResults.length>0){
+ this.$refs.childs.open(res.data.splitResults);
+ }
+ this.$nextTick(() => {
+ this.$refs.barcodeInput.focus();
+ });
+ } else {
+ this.$message.error(res.message || '鎷i�夌‘璁ゅけ璐�');
+ this.focusBarcodeInput(true);
+ }
+ } catch (error) {
+ this.$message.error('鎷i�夌‘璁ゅけ璐�: ' + (error.message || '缃戠粶閿欒'));
+ this.focusBarcodeInput(true);
+ } finally {
+ this.isProcessing = false;
+ }
+ },
+
+ // 鎷嗗寘鐩稿叧鏂规硶
+ openSplitDialog() {
+ if (!this.scanData.palletCode) {
+ this.$message.warning('璇峰厛鎵弿鎵樼洏鐮�');
+ return;
+ }
+ this.showCustomSplitDialog = true;
+ this.resetSplitForm();
+ this.splitForm.orderNo = this.scanData.orderNo;
+ this.splitForm.palletCode = this.scanData.palletCode;
+ },
+
+ async onSplitBarcodeScan() {
+ if (!this.splitForm.originalBarcode) return;
+ this.splitForm.originalBarcode = this.splitForm.originalBarcode.replace(/\n/g, '').trim();
+
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/split-package-info', {
+ orderNo: this.splitForm.orderNo,
+ palletCode: this.splitForm.palletCode,
+ barcode: this.splitForm.originalBarcode
+ });
+
+ if (res.status) {
+ this.splitForm.materielCode = res.data.materielCode;
+ this.splitForm.maxQuantity = res.data.remainQuantity;
+ this.splitForm.splitQuantity = Math.min(1, this.splitForm.maxQuantity);
+ } else {
+ this.$message.error(res.message || '鑾峰彇鎷嗗寘淇℃伅澶辫触');
+ }
+ } catch (error) {
+ this.$message.error('鑾峰彇鎷嗗寘淇℃伅澶辫触');
+ }
+ },
+
+ async handleSplitPackage() {
+ if (this.$refs.splitFormRef) {
+ this.$refs.splitFormRef.validate(async (valid) => {
+ if (valid) {
+ this.splitLoading = true;
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/split-package', {
+ orderNo: this.splitForm.orderNo,
+ palletCode: this.splitForm.palletCode,
+ originalBarcode: this.splitForm.originalBarcode,
+ splitQuantity: this.splitForm.splitQuantity
+ });
+ if (res.status) {
+ this.$message.success('鎷嗗寘鎴愬姛');
+ this.showCustomSplitDialog = false;
+ await this.loadPalletData();
+ } else {
+ this.$message.error(res.message || '鎷嗗寘澶辫触');
+ }
+ } catch (error) {
+ this.$message.error('鎷嗗寘澶辫触');
+ } finally {
+ this.splitLoading = false;
+ }
+ }
+ });
+ }
+ },
+// 鍦ㄦ媶鍖呭脊绐椾腑鏌ョ湅鎷嗗寘閾�
+async viewSplitChainFromSplit(barcode) {
+ if (!barcode) {
+ this.$message.warning('璇峰厛杈撳叆鏉$爜');
+ return;
+ }
+
+ // 鍏堝叧闂媶鍖呭脊绐�
+ this.closeCustomSplitDialog();
+
+ await this.$nextTick();
+
+ // 鐒跺悗鎵撳紑鎷嗗寘閾句俊鎭脊绐�
+ await this.viewSplitChain(barcode);
+},
+ // 鎾ら攢鎷嗗寘
+ async onRevertSplitBarcodeScan() {
+ if (!this.revertSplitForm.newBarcode) return;
+ this.revertSplitForm.newBarcode = this.revertSplitForm.newBarcode.replace(/\n/g, '').trim();
+
+ // 鏂板锛氭壂鎻忓悗鑷姩鏄剧ず鎷嗗寘閾句俊鎭�
+ await this.viewSplitChain(this.revertSplitForm.newBarcode);
+ },
+
+ async handleRevertSplit() {
+ if (this.$refs.revertSplitFormRef) {
+ this.$refs.revertSplitFormRef.validate(async (valid) => {
+ if (valid) {
+ this.revertSplitLoading = true;
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/cancel-split', {
+ orderNo: this.scanData.orderNo,
+ palletCode: this.scanData.palletCode,
+ newBarcode: this.revertSplitForm.newBarcode
+ });
+ if (res.status) {
+ this.$message.success('鎾ら攢鎷嗗寘鎴愬姛');
+ this.showRevertSplitDialog = false;
+ await this.loadPalletData();
+ } else {
+ this.$message.error(res.message || '鎾ら攢鎷嗗寘澶辫触');
+ }
+ } catch (error) {
+ this.$message.error('鎾ら攢鎷嗗寘澶辫触');
+ } finally {
+ this.revertSplitLoading = false;
+ }
+ }
+ });
+ }
+ },
+// 鏌ユ壘瀹屾暣鎷嗗寘閾撅紙浠庢牴鏉$爜寮�濮嬶級
+async findRootChain(currentBarcode) {
+ this.splitChainLoading = true;
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/find-root-split-chain', {
+ orderNo: this.scanData.orderNo,
+ barcode: currentBarcode
+ });
+
+ if (res.status) {
+ this.splitChainInfo = res.data;
+ this.$message.success('宸插姞杞藉畬鏁存媶鍖呴摼');
+ } else {
+ this.$message.error(res.message || '鏌ユ壘瀹屾暣鎷嗗寘閾惧け璐�');
+ }
+ } catch (error) {
+ this.$message.error('鏌ユ壘瀹屾暣鎷嗗寘閾惧け璐�');
+ } finally {
+ this.splitChainLoading = false;
+ }
+},
+ // 鎷嗗寘閾剧浉鍏虫柟娉�
+ // 鏌ョ湅鎷嗗寘閾句俊鎭�
+async viewSplitChain(barcode) {
+ if (!barcode) {
+ this.$message.warning('璇峰厛杈撳叆鏉$爜');
+ return;
+ }
+
+ this.splitChainLoading = true;
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/split-package-chain-info', {
+ orderNo: this.scanData.orderNo,
+ barcode: barcode
+ });
+
+ if (res.status) {
+ this.splitChainInfo = res.data;
+
+ // 鏄剧ず鎻愮ず淇℃伅锛屽憡璇夌敤鎴疯繖鏄粈涔堢被鍨嬬殑鎷嗗寘閾�
+ let chainType = "褰撳墠鏉$爜鐨勬媶鍖呴摼";
+ if (this.splitChainInfo.chainType === 'root') {
+ chainType = "瀹屾暣鎷嗗寘閾撅紙浠庡師濮嬫潯鐮佸紑濮嬶級";
+ } else if (this.splitChainInfo.chainType === 'branch') {
+ chainType = "鍒嗘敮鎷嗗寘閾�";
+ }
+
+ this.$message.info(`宸插姞杞�${chainType}锛屽叡${this.splitChainInfo.totalSplitTimes}娆℃媶鍖卄);
+ this.showSplitChainDialog = true;
+ } else {
+ this.$message.error(res.message || '鑾峰彇鎷嗗寘閾句俊鎭け璐�');
+ }
+ } catch (error) {
+ this.$message.error('鑾峰彇鎷嗗寘閾句俊鎭け璐�');
+ } finally {
+ this.splitChainLoading = false;
+ }
+},
+
+ // 鍏抽棴鎷嗗寘閾句俊鎭脊绐�
+ closeSplitChainDialog() {
+ this.showSplitChainDialog = false;
+
+ },
+ // 鍦ㄦ挙閿�鎷嗗寘寮圭獥涓煡鐪嬫媶鍖呴摼
+async viewSplitChainFromRevert(barcode) {
+ if (!barcode) {
+ this.$message.warning('璇峰厛杈撳叆鏉$爜');
+ return;
+ }
+
+ // 鍏堝叧闂挙閿�鎷嗗寘寮圭獥
+ this.closeRevertSplitDialog();
+
+ await this.$nextTick();
+
+ // 鐒跺悗鎵撳紑鎷嗗寘閾句俊鎭脊绐�
+ await this.viewSplitChain(barcode);
+},
+// 蹇�熼噸鏂版墦寮�鎷嗗寘閾惧脊绐�
+async quickReopenSplitChainDialog(barcode) {
+ if (!barcode) return;
+
+ this.showSplitChainDialog = true;
+ this.splitChainLoading = true;
+
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/split-package-chain-info', {
+ orderNo: this.scanData.orderNo,
+ barcode: barcode
+ });
+
+ if (res.status) {
+ this.splitChainInfo = res.data;
+ }
+ } catch (error) {
+ console.error('閲嶆柊鍔犺浇鎷嗗寘閾句俊鎭け璐�:', error);
+ } finally {
+ this.splitChainLoading = false;
+ }
+},
+ // 鍙栨秷鍗曚釜鎷嗗寘璁板綍
+async cancelSingleSplit(newBarcode) {
+ // 鍏堣褰曞綋鍓嶄俊鎭紝鐒跺悗鍏抽棴寮圭獥
+ const originalBarcode = this.splitChainInfo.originalBarcode;
+ this.closeSplitChainDialog();
+
+ await this.$nextTick();
+
+ try {
+ await this.$confirm(
+ `纭畾瑕佸彇娑堟潯鐮� ${newBarcode} 鐨勬媶鍖呮搷浣滃悧锛焋,
+ '鍙栨秷鍗曚釜鎷嗗寘',
+ {
+ confirmButtonText: '纭畾鍙栨秷',
+ cancelButtonText: '鍐嶆兂鎯�',
+ type: 'warning'
+ }
+ );
+
+ this.revertSplitLoading = true;
+
+ const res = await http.post('/api/OutboundBatchPicking/cancel-split', {
+ orderNo: this.scanData.orderNo,
+ palletCode: this.scanData.palletCode,
+ newBarcode: newBarcode
+ });
+
+ if (res.status) {
+ this.$message.success('鍙栨秷鎷嗗寘鎴愬姛');
+ await this.loadPalletData();
+ // 閲嶆柊鎵撳紑寮圭獥鏄剧ず鏇存柊鍚庣殑鐘舵��
+ await this.viewSplitChain(originalBarcode);
+ } else {
+ this.$message.error(res.message || '鍙栨秷鎷嗗寘澶辫触');
+ await this.viewSplitChain(originalBarcode);
+ }
+ } catch (error) {
+ if (error === 'cancel') {
+ // 鐢ㄦ埛鍙栨秷鍚庨噸鏂版墦寮�寮圭獥
+ await this.viewSplitChain(originalBarcode);
+ } else {
+ this.$message.error('鍙栨秷鎷嗗寘澶辫触');
+ await this.viewSplitChain(originalBarcode);
+ }
+ } finally {
+ this.revertSplitLoading = false;
+ }
+},
+
+// 鍙栨秷鏁翠釜鎷嗗寘閾�
+async cancelWholeSplitChain() {
+ // 鍏堣褰曞綋鍓嶆媶鍖呴摼淇℃伅锛岀劧鍚庡叧闂脊绐�
+ const originalBarcode = this.splitChainInfo.originalBarcode;
+ this.closeSplitChainDialog();
+
+ // 缁欎竴鐐规椂闂磋寮圭獥瀹屽叏鍏抽棴
+ await this.$nextTick();
+
+ try {
+ // 鐜板湪鏄剧ず纭瀵硅瘽妗嗭紝纭繚瀹冨湪鏈�鍓嶉潰
+ await this.$confirm(
+ `纭畾瑕佸彇娑堟暣涓媶鍖呴摼鍚楋紵\n杩欏皢鍙栨秷浠庢潯鐮� ${originalBarcode} 寮�濮嬬殑鎵�鏈夋媶鍖呮搷浣溿�俙,
+ '鍙栨秷鎷嗗寘閾剧‘璁�',
+ {
+ confirmButtonText: '纭畾鍙栨秷',
+ cancelButtonText: '鍐嶆兂鎯�',
+ type: 'warning',
+ center: true,
+ closeOnClickModal: false
+ }
+ );
+
+ // 鐢ㄦ埛纭鍚庢墽琛屽彇娑堟搷浣�
+ this.revertSplitLoading = true;
+
+ const res = await http.post('/api/OutboundBatchPicking/cancel-split-chain', {
+ orderNo: this.scanData.orderNo,
+ palletCode: this.scanData.palletCode,
+ startBarcode: originalBarcode
+ });
+
+ console.log('鍙栨秷鎷嗗寘閾惧搷搴�:', res);
+
+ if (res.status) {
+ this.$message.success('鍙栨秷鎷嗗寘閾炬垚鍔�');
+ await this.loadPalletData();
+ // 鍙�夛細閲嶆柊鎵撳紑鎷嗗寘閾句俊鎭脊绐楁樉绀烘洿鏂板悗鐨勭姸鎬�
+ // await this.viewSplitChain(originalBarcode);
+ } else {
+ this.$message.error(res.message || '鍙栨秷鎷嗗寘閾惧け璐�');
+ // 澶辫触鍚庨噸鏂版墦寮�寮圭獥
+ await this.viewSplitChain(originalBarcode);
+ }
+ } catch (error) {
+ // 鐢ㄦ埛鍙栨秷鎿嶄綔
+ if (error === 'cancel') {
+ console.log('鐢ㄦ埛鍙栨秷浜嗘媶鍖呴摼鎿嶄綔');
+ // 鐢ㄦ埛鍙栨秷鍚庨噸鏂版墦寮�寮圭獥
+ await this.viewSplitChain(originalBarcode);
+ } else {
+ console.error('鍙栨秷鎷嗗寘閾鹃敊璇�:', error);
+ this.$message.error('鍙栨秷鎷嗗寘閾惧け璐�: ' + error.message);
+ // 鍑洪敊鍚庨噸鏂版墦寮�寮圭獥
+ await this.viewSplitChain(originalBarcode);
+ }
+ } finally {
+ this.revertSplitLoading = false;
+ }
+},
+
+ // 妫�鏌ユ潯鐮佹槸鍚﹀凡琚垎鎷�
+ hasPicked(barcode) {
+ return this.pickedList.some(item => item.currentBarcode === barcode);
+ },
+
+ // 鏍煎紡鍖栨棩鏈熸椂闂�
+ formatDateTime(dateTime) {
+ if (!dateTime) return '';
+ const date = new Date(dateTime);
+ return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')} ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`;
+ },
+
+ // 鍥炲簱鐩稿叧鏂规硶
+ openBatchReturnDialog() {
+ if (!this.scanData.palletCode) {
+ this.$message.warning('璇峰厛鎵弿鎵樼洏鐮�');
+ return;
+ }
+ this.showBatchReturnDialog = true;
+ this.batchReturnForm.orderNo = this.scanData.orderNo;
+ this.batchReturnForm.palletCode = this.scanData.palletCode;
+ this.batchReturnForm.unpickedCount = this.summary.unpickedCount;
+ this.batchReturnForm.unpickedQuantity = this.summary.unpickedQuantity;
+ },
+
+ async handleBatchReturnConfirm() {
+ this.batchReturnLoading = true;
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/return-stock', {
+ orderNo: this.scanData.orderNo,
+ palletCode: this.scanData.palletCode
+ });
+ if (res.status) {
+ this.$message.success('鍥炲簱鎴愬姛');
+ this.showBatchReturnDialog = false;
+ await this.loadPalletData();
+ } else {
+ this.$message.error(res.message || '鍥炲簱澶辫触');
+ }
+ } catch (error) {
+ this.$message.error('鍥炲簱澶辫触');
+ } finally {
+ this.batchReturnLoading = false;
+ }
+ },
+
+ // 鍙栫┖绠辨柟娉�
+ handleEmptyPallet() {
+ this.showEmptyPalletDialog = true;
+ this.emptypalletOutForm.orderNo = this.scanData.orderNo;
+ this.emptypalletOutForm.palletCode = '';
+ },
+
+ async handleEmptyPalletConfirm() {
+ this.emptypalletOutLoading = true;
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/remove-empty-pallet', {
+ orderNo: this.emptypalletOutForm.orderNo,
+ palletCode: this.emptypalletOutForm.palletCode
+ });
+ if (res.status) {
+ this.$message.success('鍙栬蛋绌虹鎴愬姛');
+ this.showEmptyPalletDialog = false;
+ await this.loadPalletData();
+ } else {
+ this.$message.error(res.message || '鍙栬蛋绌虹澶辫触');
+ }
+ } catch (error) {
+ this.$message.error('鍙栬蛋绌虹澶辫触');
+ } finally {
+ this.emptypalletOutLoading = false;
+ }
+ },
+
+ // 鏁版嵁鍔犺浇鏂规硶
+ async loadPalletData() {
+ if (!this.scanData.orderNo || !this.scanData.palletCode) return;
+
+ await this.loadUnpickedList();
+ await this.loadPickedList();
+ await this.loadPalletStatus();
+ },
+
+ async loadUnpickedList() {
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/pallet-locks', {
+ orderNo: this.scanData.orderNo,
+ palletCode: this.scanData.palletCode
+ });
+ if (res.status) {
+ this.unpickedList = res.data || [];
+ this.summary.unpickedCount = this.unpickedList.length;
+ this.summary.unpickedQuantity = this.unpickedList.reduce((sum, item) => sum + (item.remainQuantity || 0), 0);
+ }
+ } catch (error) {
+ this.$message.error('鍔犺浇鏈嫞閫夊垪琛ㄥけ璐�');
+ }
+ },
+
+ async loadPickedList() {
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/pallet-picked-list', {
+ orderNo: this.scanData.orderNo,
+ palletCode: this.scanData.palletCode
+ });
+ if (res.status) {
+ this.pickedList = res.data || [];
+ this.summary.pickedCount = this.pickedList.length;
+ }
+ } catch (error) {
+ this.$message.error('鍔犺浇宸叉嫞閫夊垪琛ㄥけ璐�');
+ }
+ },
+
+ async loadPalletStatus() {
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/pallet-status', {
+ orderNo: this.scanData.orderNo,
+ palletCode: this.scanData.palletCode
+ });
+ if (res.status) {
+ this.palletStatus = res.data.statusText || '鏈煡';
+ }
+ } catch (error) {
+ this.palletStatus = '鏈煡';
+ }
+ },
+
+ // 鎵爜鐩稿叧鏂规硶
+ onPalletScan() {
+ this.scanData.palletCode = this.scanData.palletCode.replace(/\n/g, '').trim();
+ if (!this.scanData.palletCode) return;
+
+ this.loadPalletData();
+ this.$nextTick(() => {
+ this.$refs.barcodeInput.focus();
+ });
+ },
+
+ onBarcodeScan() {
+ this.scanData.barcode = this.scanData.barcode.replace(/\n/g, '').trim();
+ if (!this.scanData.barcode) return;
+ this.confirmPicking();
+ },
+
+ focusBarcodeInput(selectText = false) {
+ this.$nextTick(() => {
+ const input = this.$refs.barcodeInput;
+ if (input && input.$el && input.$el.querySelector('input')) {
+ const inputEl = input.$el.querySelector('input');
+ inputEl.focus();
+ if (selectText) {
+ inputEl.select();
+ }
+ }
+ });
+ },
+
+ handlePickedSelectionChange(selection) {
+ this.selectedPickedRows = selection;
+ },
+
+ async batchCancelSelected() {
+ if (this.selectedPickedRows.length === 0) {
+ this.$message.warning('璇峰厛閫夋嫨瑕佸彇娑堢殑椤�');
+ return;
+ }
+
+ this.$confirm(`纭畾瑕佸彇娑堥�変腑鐨� ${this.selectedPickedRows.length} 椤瑰悧锛焋, '鎻愮ず', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ }).then(async () => {
+ try {
+ for (const row of this.selectedPickedRows) {
+ try {
+ const res = await http.post('/api/OutboundBatchPicking/cancel-picking', {
+ orderNo: this.scanData.orderNo,
+ palletCode: this.scanData.palletCode,
+ barcode: row.currentBarcode
+ });
+ if (!res.status) {
+ this.$message.warning(`鍙栨秷鎷i�夊け璐�: ${row.currentBarcode} - ${res.message}`);
+ }
+ } catch (error) {
+ this.$message.warning(`鍙栨秷鎷i�夊け璐�: ${row.currentBarcode} - ${error.message}`);
+ }
+ }
+ this.$message.success('鎵归噺鍙栨秷瀹屾垚');
+ await this.loadPalletData();
+ this.selectedPickedRows = [];
+ } catch (error) {
+ this.$message.error('鎵归噺鍙栨秷鎿嶄綔澶辫触');
+ }
+ });
+ },
+
+ // 閲嶇疆鏂规硶
+ resetSplitForm() {
+ this.splitForm.originalBarcode = '';
+ this.splitForm.materielCode = '';
+ this.splitForm.splitQuantity = 0;
+ this.splitForm.maxQuantity = 0;
+ },
+
+ closeCustomSplitDialog() {
+ this.showCustomSplitDialog = false;
+ this.resetSplitForm();
+ },
+
+ openRevertSplitDialog() {
+ this.showRevertSplitDialog = true;
+ this.revertSplitForm.newBarcode = '';
+ },
+
+ closeRevertSplitDialog() {
+ this.showRevertSplitDialog = false;
+ this.revertSplitForm.newBarcode = '';
+ },
+
+ closeBatchReturnDialog() {
+ this.showBatchReturnDialog = false;
+ },
+
+ onEmptyPalletScan() {
+ if (!this.emptypalletOutForm.palletCode) return;
+ this.emptypalletOutForm.palletCode = this.emptypalletOutForm.palletCode.replace(/\n/g, '').trim();
+ },
+
+ closeEmptyPalletDialog() {
+ this.showEmptyPalletDialog = false;
+ this.emptypalletOutForm.palletCode = '';
+ },
+
+ parentcall() {
+ // 鎵撳嵃鍥炶皟
+ }
+ }
+})
+</script>
+
+<style scoped>
+.OutboundPicking-container {
+ padding: 20px;
+}
+
+.scanner-form {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+ flex-wrap: wrap;
+}
+
+.scanner-form .el-input {
+ width: 200px;
+}
+
+.summary-info {
+ display: flex;
+ gap: 20px;
+ flex-wrap: wrap;
+}
+
+.table-actions {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 10px;
+ padding: 0 10px;
+}
+
+.selection-count {
+ font-size: 12px;
+ color: #909399;
+}
+
+/* 鑷畾涔夊脊绐楁牱寮� */
+:deep(.el-message-box) {
+ z-index: 10010 !important;
+}
+
+:deep(.el-overlay) {
+ z-index: 10009 !important;
+}
+
+:deep(.el-message) {
+ z-index: 10011 !important;
+}
+
+.custom-dialog-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 2000; /* 淇濇寔涓�涓悎鐞嗙殑 z-index */
+}
+
+.custom-dialog-wrapper {
+ position: relative;
+ z-index: 2001;
+}
+
+.custom-dialog {
+ background: white;
+ border-radius: 4px;
+ width: 500px;
+ max-width: 90vw;
+ max-height: 90vh;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ overflow: auto;
+}
+
+.custom-dialog-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 20px 20px 10px;
+ border-bottom: 1px solid #ebeef5;
+}
+
+.custom-dialog-header h3 {
+ margin: 0;
+ color: #303133;
+}
+
+.close-button {
+ font-size: 18px;
+ color: #909399;
+ padding: 0;
+ width: 24px;
+ height: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.close-button:hover {
+ color: #409EFF;
+ background-color: transparent;
+}
+
+.custom-dialog-body {
+ padding: 20px;
+}
+
+.custom-dialog-footer {
+ padding: 10px 20px 20px;
+ text-align: right;
+ border-top: 1px solid #ebeef5;
+}
+
+.custom-dialog-footer .el-button {
+ margin-left: 10px;
+}
+
+@media (max-width: 768px) {
+ .custom-dialog {
+ width: 95vw;
+ margin: 10px;
+ }
+
+ .scanner-form {
+ flex-direction: column;
+ align-items: stretch;
+ }
+ /* 纭繚纭瀵硅瘽妗嗗湪鏈�鍓嶉潰 */
+.el-message-box__wrapper {
+ z-index: 10001 !important;
+}
+
+.el-message {
+ z-index: 10002 !important;
+}
+ .scanner-form .el-input {
+ width: 100%;
+ }
+}
+</style>
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue"
index 96cbf3e..2fc26e1 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/PickingConfirm.vue"
@@ -28,7 +28,7 @@
<el-button type="success" @click="confirmPicking">纭鎷i��</el-button>
<!-- <el-button type="warning" @click="openSplitDialog">鎷嗗寘</el-button>
<el-button type="info" @click="openRevertSplitDialog">鎾ら攢鎷嗗寘</el-button> -->
-
+ <el-button type="info" @click="handleEmptyPallet">鍙栫┖绠�</el-button>
<el-button type="primary" @click="openBatchReturnDialog">鍥炲簱</el-button>
<!-- <el-button type="danger" @click="handleDirectOutbound">鐩存帴鍑哄簱</el-button> -->
@@ -250,6 +250,49 @@
</div>
</div>
</div>
+
+ <!-- 鍙栬蛋绌虹-->
+ <div v-if="showEmptyPalletDialog" class="custom-dialog-overlay">
+ <div class="custom-dialog-wrapper">
+ <div class="custom-dialog">
+ <div class="custom-dialog-header">
+ <h3>鍙栬蛋绌虹</h3>
+ <el-button
+ type="text"
+ @click="closeEmptyPalletDialog"
+ class="close-button">
+ 脳
+ </el-button>
+ </div>
+ <div class="custom-dialog-body">
+ <el-form
+ :model="emptypalletOutForm"
+ :rules="emptypalletOutFormRules"
+ ref="emptypalletOutFormRef"
+ label-width="100px">
+ <el-form-item label="璁㈠崟缂栧彿">
+ <el-input v-model="emptypalletOutForm.orderNo" disabled></el-input>
+ </el-form-item>
+ <el-form-item label="鎵樼洏缂栧彿" prop="palletCode">
+ <el-input
+ v-model="emptypalletOutForm.palletCode"
+ placeholder="鎵弿鎵樼洏鐮�"
+ @keyup.enter.native="onEmptyPalletScan"
+ @change="onEmptyPalletScan"
+ clearable>
+ </el-input>
+ </el-form-item>
+ </el-form>
+ </div>
+ <div class="custom-dialog-footer">
+ <el-button @click="closeEmptyPalletDialog">鍙栨秷</el-button>
+ <el-button type="primary" @click="handleEmptyPalletConfirm" :loading="emptypalletOutLoading">纭鍙栬蛋绌虹</el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
<!-- 鐩存帴鍑哄簱寮圭獥 -->
<div v-if="showDirectOutDialog" class="custom-dialog-overlay">
<div class="custom-dialog-wrapper">
@@ -290,7 +333,7 @@
</div>
</div>
</div>
- </div>
+
<print-view ref="childs" @parentcall="parentcall"></print-view>
</template>
@@ -431,6 +474,20 @@
{ required: true, validator: validateDirectOutPalletCode, trigger: 'blur' }
]
},
+
+ showEmptyPalletDialog: false, // 鍙栬蛋绌虹寮圭獥鏄剧ず鐘舵��
+ emptypalletOutLoading: false, // 鍙栬蛋绌虹鍔犺浇鐘舵��
+ emptypalletOutForm: {
+ orderNo: '',
+ palletCode: ''
+ },
+ emptypalletOutFormRules: {
+ palletCode: [
+ { required: true, validator: validateDirectOutPalletCode, trigger: 'blur' }
+ ]
+ },
+
+
returnForm: {
orderNo: '',
palletCode: '',
@@ -598,7 +655,7 @@
});
if (res.status) {
- this.$message.success('鍥炲簱鎴愬姛');
+ this.$message.success(res.message);
this.showBatchReturnDialog = false;
this.loadData();
} else {
@@ -708,6 +765,109 @@
handleDirectOutbound() {
this.openDirectOutDialog();
},
+
+ // 鎵撳紑鍙栬蛋绌虹寮圭獥
+ openEmptyPalletDialog() {
+ console.log('鎵撳紑鍙栬蛋绌虹寮圭獥');
+ this.showEmptyPalletDialog = true;
+
+ // 閲嶇疆琛ㄥ崟
+ this.resetEmptyPalletForm();
+
+ // 璁剧疆璁㈠崟淇℃伅
+ this.emptypalletOutForm.orderNo = this.scanData.orderNo;
+
+ // 娓呴櫎琛ㄥ崟楠岃瘉
+ this.$nextTick(() => {
+ if (this.$refs.emptyPalletFormRef) {
+ this.$refs.emptyPalletFormRef.clearValidate();
+ }
+ });
+ },
+
+ // 鍏抽棴鍙栬蛋绌虹寮圭獥
+ closeEmptyPalletDialog() {
+ this.showEmptyPalletDialog = false;
+ this.resetEmptyPalletForm();
+
+ // 娓呴櫎琛ㄥ崟楠岃瘉
+ if (this.$refs.emptyPalletFormRef) {
+ this.$refs.emptyPalletFormRef.clearValidate();
+ }
+ },
+
+ // 鍙栬蛋绌虹鎵樼洏鐮佹壂鐮�
+ onEmptyPalletScan() {
+ if (!this.emptypalletOutForm.palletCode) return;
+
+ this.emptypalletOutForm.palletCode = this.emptypalletOutForm.palletCode.replace(/\n/g, '').trim();
+
+ // 娓呴櫎楠岃瘉鐘舵��
+ if (this.$refs.emptyPalletFormRef) {
+ this.$refs.emptyPalletFormRef.clearValidate(['palletCode']);
+ }
+ },
+
+ // 鍙栬蛋绌虹纭
+ async handleEmptyPalletConfirm() {
+ // 琛ㄥ崟楠岃瘉
+ if (this.$refs.emptyPalletFormRef) {
+ this.$refs.emptyPalletFormRef.validate((valid) => {
+ if (valid) {
+ this.submitEmptyPallet();
+ } else {
+ this.$message.warning('璇锋壂鎻忔墭鐩樼爜');
+ return false;
+ }
+ });
+ } else {
+ // 濡傛灉娌℃湁琛ㄥ崟寮曠敤锛屼娇鐢ㄥ師鏈夌殑楠岃瘉
+ if (!this.emptypalletOutForm.palletCode) {
+ this.$message.warning('璇锋壂鎻忔墭鐩樼爜');
+ return;
+ }
+
+ this.submitEmptyPallet();
+ }
+ },
+
+ // 鎻愪氦鍙栬蛋绌虹璇锋眰
+ async submitEmptyPallet() {
+ this.emptypalletOutLoading = true;
+
+ try {
+ const res = await this.http.post('/api/OutboundPicking/remove-empty-pallet', {
+ orderNo: this.emptypalletOutForm.orderNo,
+ palletCode: this.emptypalletOutForm.palletCode
+ });
+ debugger;
+ if (res.status) {
+ this.$message.success('鍙栬蛋绌虹鎴愬姛');
+ this.showEmptyPalletDialog = false;
+ this.loadData();
+ } else {
+ this.$message.error(res.message || '鍙栬蛋绌虹澶辫触');
+ }
+ } catch (error) {
+ this.$message.error('鍙栬蛋绌虹澶辫触');
+ } finally {
+ this.emptypalletOutLoading = false;
+ }
+ },
+
+ // 閲嶇疆鍙栬蛋绌虹琛ㄥ崟
+ resetEmptyPalletForm() {
+ this.emptypalletOutForm.palletCode = '';
+ },
+
+ // 淇敼鍘熸湁鐨勫彇璧扮┖绠辨寜閽偣鍑讳簨浠�
+ handleEmptyPallet() {
+ this.openEmptyPalletDialog();
+ },
+
+
+
+
async loadData() {
if (!this.scanData.orderNo || !this.scanData.palletCode) {
return;
@@ -775,21 +935,16 @@
if (res.status) {
successCount++;
+ this.$message.success(`鎴愬姛鍙栨秷`);
} else {
errorCount++;
- console.error(`鍙栨秷鎷i�夊け璐�: ${row.Barcode}`, res.message);
+ this.$message.warning(`鍙栨秷鎷i�夊け璐�: ${row.currentBarcode} - ${res.message}`);
}
} catch (error) {
errorCount++;
- console.error(`鍙栨秷鎷i�夊け璐�: ${row.Barcode}`, error);
+ this.$message.warning(`鍙栨秷鎷i�夊け璐�: ${row.currentBarcode} - ${error.message}` );
}
- }
-
- if (errorCount === 0) {
- this.$message.success(`鎴愬姛鍙栨秷 ${successCount} 椤筦);
- } else {
- this.$message.warning(`鎴愬姛鍙栨秷 ${successCount} 椤癸紝澶辫触 ${errorCount} 椤筦);
- }
+ }
this.loadData();
this.selectedPickedRows = [];
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/allocateoutboundOrder.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/allocateoutboundOrder.vue"
index 46ae5a5..555ac55 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/allocateoutboundOrder.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/allocateoutboundOrder.vue"
@@ -38,7 +38,7 @@
const table = ref({
key: "id",
footer: "Foots",
- cnName: "璋冩嫧鍗�(澶栭儴浠撳簱璋冩櫤浠�)",
+ cnName: "璋冩嫧鍗�(鏅轰粨璋冨嚭澶栭儴浠�)",
name: "outboundOrder",
url: "/OutboundOrder/",
sortName: "id",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/outboundOrder.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/outboundOrder.vue"
index 270d8d1..47ab893 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/outboundOrder.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/outbound/outboundOrder.vue"
@@ -114,6 +114,7 @@
type: "select",
dataKey: "outOrderType",
data: [],
+ hidden:true
},
{
title: "鍗曟嵁鐘舵��",
@@ -168,6 +169,7 @@
width: 150,
align: "left",
bind: { key: "outOrderType", data: [] },
+ hidden:true
},
{
field: "businessType",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/locationStatusChangeRecord.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/locationStatusChangeRecord.vue"
index a22ee58..d66e4d4 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/locationStatusChangeRecord.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/locationStatusChangeRecord.vue"
@@ -44,9 +44,9 @@
});
const searchFormOptions = ref([
[
- { title: "璐т綅鍙�", field: "locationCode" },
- { title: "鍗曟嵁缂栧彿", field: "orderNo" },
- { title: "浠诲姟鍙�", field: "taskNum" },
+ { title: "璐т綅鍙�", field: "locationCode" ,type:"like"},
+ { title: "鍗曟嵁缂栧彿", field: "orderNo",type:"like"},
+ { title: "浠诲姟鍙�", field: "taskNum" ,type:"like"},
],
[
{
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue"
index f7d65a4..7e8e7dd 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/record/stockQuantityChangeRecord.vue"
@@ -39,15 +39,15 @@
});
const searchFormOptions = ref([
[
- { title: "鎵樼洏鍙�", field: "palleCode" },
- { title: "鐗╂枡缂栧彿", field: "materielCode" },
- { title: "鍗曟嵁缂栧彿", field: "orderNo" },
+ { title: "鎵樼洏鍙�", field: "palleCode" ,type:"like"},
+ { title: "鐗╂枡缂栧彿", field: "materielCode",type:"like" },
+ { title: "鍗曟嵁缂栧彿", field: "orderNo" ,type:"like"},
{ title: "鍙樺姩绫诲瀷", field: "changeType" ,type: "selectList",dataKey: "stockChangeType",data: [],},
],
[
- { title: "鎵规鍙�", field: "batchNo" },
- { title: "浠诲姟鍙�", field: "taskNum" },
- { title: "搴忓垪鍙�", field: "serilNumber" },
+ { title: "鎵规鍙�", field: "batchNo" ,type:"like"},
+ { title: "浠诲姟鍙�", field: "taskNum" ,type:"like"},
+ { title: "搴忓垪鍙�", field: "serilNumber" ,type:"like"},
],
]);
const columns = ref([
@@ -90,6 +90,13 @@
align: "left",
},
{
+ field: "barcode",
+ title: "鏉$爜",
+ type: "string",
+ width: 150,
+ align: "left",
+ },
+ {
field: "batchNo",
title: "鎵规鍙�",
type: "string",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/stock/stockInfo.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/stock/stockInfo.vue"
index a84110c..8d1282f 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/stock/stockInfo.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/stock/stockInfo.vue"
@@ -92,6 +92,7 @@
width: 100,
align: "left",
bind: { key: "warehouses", data: [] },
+ hidden:true
},
{
field: "creater",
@@ -113,7 +114,7 @@
type: "string",
width: 100,
align: "left",
- hidden:true
+ // hidden:true
},
{
field: "modifyDate",
@@ -121,7 +122,7 @@
type: "datetime",
width: 160,
align: "left",
- hidden:true
+ // hidden:true
},
{
field: "remark",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-shm" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-shm"
index 281e03c..12ed131 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-shm"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/CodeChunks.db-shm"
Binary files differ
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-shm" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-shm"
index 5c3038d..57bd494 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-shm"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/.vs/WIDESEA_WMSServer/CopilotIndices/17.14.878.3237/SemanticSymbols.db-shm"
Binary files differ
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_AllocateService/AllocateService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_AllocateService/AllocateService.cs"
index 7d707ca..1908f29 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_AllocateService/AllocateService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_AllocateService/AllocateService.cs"
@@ -1,4 +1,6 @@
-锘縰sing Microsoft.Extensions.Logging;
+锘縰sing Autofac.Core;
+using MailKit.Search;
+using Microsoft.Extensions.Logging;
using SqlSugar;
using SqlSugar.Extensions;
using System;
@@ -60,7 +62,7 @@
{
1 => await AddAllocateOrder(allocateOrder),
2 => await UpdateAllocateOrder(allocateOrder),
- 3 => DeleteAllocateOrder(allocateOrder),
+ 3 => await DeleteAllocateOrder(allocateOrder),
_ => WebResponseContent.Instance.OK(),
};
@@ -81,24 +83,7 @@
}
allocateOrder.OrderNo = CreateCodeByRule(nameof(RuleCodeEnum.AllocateOrderCodeRule));
Db.InsertNav(allocateOrder).Include(x => x.Details).ExecuteCommand();
- if (Enum.TryParse<BusinessTypeEnum>(allocateOrder.BusinessType, out var businessType))
- {
- if (businessType == BusinessTypeEnum.鏅轰粨璋冨閮ㄤ粨搴�)
- {
- var inboundOrders = ConvertToInboundOrders(allocateOrder);
- await _inboundService.InbounOrderService.ReceiveInboundOrder(inboundOrders, 1);
- }
- else if (businessType == BusinessTypeEnum.澶栭儴浠撳簱璋冩櫤浠�)
- {
- var outboundOrders = ConvertToOutboundOrders(allocateOrder);
- await _outboundService.OutboundOrderService.ReceiveOutboundOrder(outboundOrders, 1);
- }
- else
- {
- // 澶勭悊鏈畾涔夌殑鏋氫妇鍊硷紙濡傛湭鏉ユ柊澧炰絾鏈疄鐜扮殑绫诲瀷锛�
- throw new NotSupportedException($"涓嶆敮鎸佺殑涓氬姟绫诲瀷鏋氫妇鍊�: {businessType}");
- }
- }
+ await AddInOutData(allocateOrder);
return WebResponseContent.Instance.OK();
}
catch (Exception ex)
@@ -107,6 +92,39 @@
return WebResponseContent.Instance.Error(ex.Message);
}
}
+
+ private async Task AddInOutData(Dt_AllocateOrder allocateOrder)
+ {
+ if (Enum.TryParse<BusinessTypeEnum>(allocateOrder.BusinessType, out var businessType))
+ {
+ if (businessType == BusinessTypeEnum.澶栭儴浠撳簱璋冩櫤浠�)
+ {
+ allocateOrder.OrderType = InOrderTypeEnum.AllocatInbound.ObjToInt();
+ var inboundOrders = ConvertToInboundOrders(allocateOrder);
+ await _inboundService.InbounOrderService.ReceiveInboundOrder(inboundOrders, 1);
+ }
+ else if (businessType == BusinessTypeEnum.鏅轰粨璋冨閮ㄤ粨搴� || businessType == BusinessTypeEnum.鏅轰粨璋冩櫤浠�)
+ {
+ if (businessType == BusinessTypeEnum.鏅轰粨璋冨閮ㄤ粨搴�)
+ {
+ allocateOrder.OrderType = InOrderTypeEnum.AllocatOutbound.ObjToInt();
+ }
+ else if (businessType == BusinessTypeEnum.鏅轰粨璋冩櫤浠�)
+ {
+ allocateOrder.OrderType = InOrderTypeEnum.InternalAllocat.ObjToInt();
+ }
+
+ var outboundOrders = ConvertToOutboundOrders(allocateOrder);
+ await _outboundService.OutboundOrderService.ReceiveOutboundOrder(outboundOrders, 1);
+ }
+ else
+ {
+ // 澶勭悊鏈畾涔夌殑鏋氫妇鍊硷紙濡傛湭鏉ユ柊澧炰絾鏈疄鐜扮殑绫诲瀷锛�
+ throw new NotSupportedException($"涓嶆敮鎸佺殑涓氬姟绫诲瀷鏋氫妇鍊�: {businessType}");
+ }
+ }
+ }
+
public async Task<WebResponseContent> UpdateAllocateOrder(Dt_AllocateOrder model)
{
try
@@ -178,7 +196,7 @@
_unitOfWorkManage.BeginTran();
foreach (var item in deletePurchaseOrderDetails)
{
- // _allocateOrderDetailRepository.DeleteAndMoveIntoHty(item, OperateTypeEnum.鑷姩鍒犻櫎);
+ // _allocateOrderDetailRepository.DeleteAndMoveIntoHty(item, OperateTypeEnum.鑷姩鍒犻櫎);
_allocateOrderDetailRepository.DeleteData(item);
}
@@ -186,6 +204,10 @@
_allocateOrderDetailRepository.AddData(allocateOrderDetails);
BaseDal.UpdateData(allocateOrder);
+
+ DeleteInOutData(model.UpperOrderNo, allocateOrder);
+ await AddInOutData(allocateOrder);
+
_unitOfWorkManage.CommitTran();
@@ -199,7 +221,7 @@
}
}
- public WebResponseContent DeleteAllocateOrder(Dt_AllocateOrder model)
+ public async Task<WebResponseContent> DeleteAllocateOrder(Dt_AllocateOrder model)
{
try
{
@@ -221,6 +243,9 @@
_allocateOrderDetailRepository.DeleteData(item);
}
BaseDal.DeleteData(allocateOrder);
+
+ DeleteInOutData(model.UpperOrderNo, allocateOrder);
+
_unitOfWorkManage.CommitTran();
return WebResponseContent.Instance.OK();
}
@@ -232,8 +257,33 @@
}
}
+ private void DeleteInOutData(string upperOrderNo, Dt_AllocateOrder allocateOrder)
+ {
+ if (Enum.TryParse<BusinessTypeEnum>(allocateOrder.BusinessType, out var businessType))
+ {
+ if (businessType == BusinessTypeEnum.澶栭儴浠撳簱璋冩櫤浠�)
+ {
+ _inboundService.InbounOrderService.Db.Deleteable<Dt_InboundOrder>().Where(x => x.UpperOrderNo == upperOrderNo).ExecuteCommand();
+
+ _inboundService.InboundOrderDetailService.Db.Deleteable<Dt_InboundOrderDetail>()
+ .Where(p => SqlFunc.Subqueryable<Dt_InboundOrder>().Where(s => s.Id == p.OrderId && s.UpperOrderNo == upperOrderNo).Any()).ExecuteCommand();
+ }
+ else if (businessType == BusinessTypeEnum.鏅轰粨璋冨閮ㄤ粨搴� || businessType == BusinessTypeEnum.鏅轰粨璋冩櫤浠�)
+ {
+ _outboundService.OutboundOrderService.Db.Deleteable<Dt_OutboundOrder>().Where(x => x.UpperOrderNo == upperOrderNo).ExecuteCommand();
+ _outboundService.OutboundOrderDetailService.Db.Deleteable<Dt_OutboundOrderDetail>()
+ .Where(p => SqlFunc.Subqueryable<Dt_OutboundOrder>().Where(s => s.Id == p.OrderId && s.UpperOrderNo == upperOrderNo).Any()).ExecuteCommand();
+ }
+ }
+ }
+
public List<Dt_InboundOrder> ConvertToInboundOrders(Dt_AllocateOrder allocateOrder)
{
+ var distinctDetails = allocateOrder.Details
+ .GroupBy(d => d.Barcode)
+ .Select(g => g.First())
+ .ToList();
+
return new List<Dt_InboundOrder>()
{
new Dt_InboundOrder(){
@@ -241,16 +291,16 @@
InboundOrderNo=allocateOrder.OrderNo,
UpperOrderNo=allocateOrder.UpperOrderNo,
SupplierId=allocateOrder.SupplierId,
- OrderType=InOrderTypeEnum.Allocat.ObjToInt(),
+ OrderType= allocateOrder.OrderType ,
OrderStatus=allocateOrder.OrderStatus,
CreateType=allocateOrder.CreateType,
BusinessType=allocateOrder.BusinessType,
IsBatch=allocateOrder.IsBatch,
FactoryArea=allocateOrder.FactoryArea,
Remark=allocateOrder.Remark,
- Details=allocateOrder.Details.Select(detail=>new Dt_InboundOrderDetail
+ Details=distinctDetails.Select(detail=>new Dt_InboundOrderDetail
{
- OrderId= detail.OrderId,
+ OrderId= 0,
MaterielCode=detail.MaterielCode,
MaterielName="",
BatchNo=detail.BatchNo,
@@ -260,6 +310,7 @@
OrderDetailStatus=detail.OrderDetailStatus,
Unit=detail.Unit,
RowNo=0,
+ lineNo=detail.LineNo,
SupplyCode=detail.SupplyCode,
WarehouseCode=detail.WarehouseCode,
Barcode=detail.Barcode,
@@ -273,12 +324,24 @@
public Dt_OutboundOrder ConvertToOutboundOrders(Dt_AllocateOrder allocateOrder)
{
+
+ var distinctDetails = allocateOrder.Details
+ .GroupBy(d => string.IsNullOrEmpty(d.Barcode)
+ ? $"{d.MaterielCode}_{d.BatchNo}_{d.SupplyCode}_{d.WarehouseCode}"
+ : d.Barcode)
+ .Select(g => new
+ {
+ Detail = g.First(),
+ //姹囨�诲垎缁勫唴鐨勬暟閲�
+ Qty = g.Sum(x => x.BarcodeQty ?? x.OrderQuantity)
+ }).ToList();
+
return new Dt_OutboundOrder()
{
WarehouseId = allocateOrder.WarehouseId,
OrderNo = allocateOrder.OrderNo,
UpperOrderNo = allocateOrder.UpperOrderNo,
- OrderType = OutOrderTypeEnum.Allocate.ObjToInt(),
+ OrderType = allocateOrder.OrderType,
OrderStatus = allocateOrder.OrderStatus,
CreateType = allocateOrder.CreateType,
BusinessType = allocateOrder.BusinessType,
@@ -287,20 +350,23 @@
Remark = allocateOrder.Remark,
DepartmentCode = "",
DepartmentName = "",
- Details = allocateOrder.Details.Select(detail => new Dt_OutboundOrderDetail
+ Details = distinctDetails.Select(item => new Dt_OutboundOrderDetail
{
- OrderId = detail.OrderId,
- MaterielCode = detail.MaterielCode,
+ OrderId = 0,
+ MaterielCode = item.Detail.MaterielCode,
MaterielName = "",
- BatchNo = detail.BatchNo,
- OrderQuantity = detail.OrderQuantity,
+ BatchNo = item.Detail.BatchNo,
+ OrderQuantity = item.Detail.OrderQuantity,
+ BarcodeQty = (decimal)item.Detail.BarcodeQty,
+ BarcodeUnit = item.Detail.BarcodeUnit,
LockQuantity = 0,
+ lineNo = item.Detail.LineNo,
OverOutQuantity = 0,
- OrderDetailStatus = detail.OrderDetailStatus,
- Unit = detail.Unit,
+ OrderDetailStatus = item.Detail.OrderDetailStatus,
+ Unit = item.Detail.Unit,
RowNo = 0,
- SupplyCode = detail.SupplyCode,
- WarehouseCode = detail.WarehouseCode,
+ SupplyCode = item.Detail.SupplyCode,
+ WarehouseCode = item.Detail.WarehouseCode,
}).ToList()
};
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/DailySequenceService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/DailySequenceService.cs"
index 6d287d8..73c8b3b 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/DailySequenceService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/DailySequenceService.cs"
@@ -10,6 +10,7 @@
using System.Threading.Tasks;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
+using WIDESEA_Core.Seed;
using WIDESEA_IBasicService;
using WIDESEA_Model.Models;
using WIDESEA_Model.Models.Basic;
@@ -193,28 +194,43 @@
private async Task UpdateSequenceInDatabase(DateTime date, string sequenceKey, int value)
{
- var sequence = await Repository.Db.Queryable<DT_DailySequence>()
- .Where(x => x.SequenceDate == date && x.SequenceKey == sequenceKey)
- .FirstAsync();
-
- if (sequence != null)
+ try
{
- sequence.CurrentValue = value;
-
- await Repository.Db.Updateable(sequence).ExecuteCommandAsync();
- }
- else
- {
- // 濡傛灉鏁版嵁搴撹褰曚笉瀛樺湪锛屽垯鍒涘缓
- sequence = new DT_DailySequence
+ using SqlSugarClient sugarClient = new SqlSugarClient(new ConnectionConfig
{
- SequenceDate = date,
- SequenceKey = sequenceKey,
- CurrentValue = value,
+ IsAutoCloseConnection = true,
+ DbType = DbType.SqlServer,
+ ConnectionString = DBContext.ConnectionString
+ });
+ var result = await sugarClient.Updateable<DT_DailySequence>()
+ .SetColumns(it => new DT_DailySequence()
+ {
+ CurrentValue = value,
+ })
+ .Where(it => it.SequenceDate == date && it.SequenceKey == sequenceKey)
+ .ExecuteCommandAsync();
- };
- await Repository.Db.Insertable(sequence).ExecuteCommandAsync();
+ if (result == 0)
+ {
+ // 濡傛灉娌℃湁鏇存柊鍒拌褰曪紝鍙兘鏄娆′娇鐢紝鎻掑叆鏂拌褰�
+ var newSequence = new DT_DailySequence
+ {
+ SequenceKey = sequenceKey,
+ SequenceDate = date,
+ CurrentValue = value,
+ Creater="admin",
+ CreateDate=DateTime.Now,
+ };
+ await sugarClient.Insertable(newSequence).ExecuteCommandAsync();
+ }
}
+ catch (Exception ex)
+ {
+ // 璁板綍鏃ュ織骞堕噸鏂版姏鍑哄紓甯�
+ Console.WriteLine($"鏇存柊搴忓垪澶辫触: {ex.Message}");
+ throw;
+ }
+
}
public async Task CleanOldSequencesAsync(int keepDays = 30)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs"
index 9d98d85..34e8220 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/InvokeMESService.cs"
@@ -10,6 +10,8 @@
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
+using WIDESEA_Common.OrderEnum;
+using WIDESEA_Common.StockEnum;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_DTO.Allocate;
@@ -17,6 +19,7 @@
using WIDESEA_DTO.Inbound;
using WIDESEA_DTO.Outbound;
using WIDESEA_IBasicService;
+using WIDESEA_IOutboundService;
using WIDESEA_Model.Models;
namespace WIDESEA_BasicService
@@ -32,7 +35,11 @@
private readonly IRepository<Dt_StockInfoDetail> _stockInfoDetailRepository;
private readonly IRepository<Dt_StockInfo> _stockInfoRepository;
private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository;
- public InvokeMESService(IHttpClientFactory httpClientFactory, ILogger<InvokeMESService> logger, IRepository<Dt_FeedbackToMes> feedbacktomesRepository, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_InboundOrder> inboundOrderRepository)
+
+ private readonly IOutboundOrderService _outboundOrderService;
+ private readonly IOutboundOrderDetailService _outboundOrderDetailService;
+ private readonly IOutStockLockInfoService _outStockLockInfoService;
+ public InvokeMESService(IHttpClientFactory httpClientFactory, ILogger<InvokeMESService> logger, IRepository<Dt_FeedbackToMes> feedbacktomesRepository, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRepository<Dt_StockInfo> stockInfoRepository, IRepository<Dt_InboundOrder> inboundOrderRepository, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IOutStockLockInfoService outStockLockInfoService)
{
_httpClientFactory = httpClientFactory;
_logger = logger;
@@ -40,6 +47,9 @@
_stockInfoDetailRepository = stockInfoDetailRepository;
_stockInfoRepository = stockInfoRepository;
_inboundOrderRepository = inboundOrderRepository;
+ _outboundOrderService = outboundOrderService;
+ _outboundOrderDetailService = outboundOrderDetailService;
+ _outStockLockInfoService = outStockLockInfoService;
}
/// <summary>
@@ -50,8 +60,8 @@
/// <exception cref="HttpRequestException"></exception>
public async Task<ResponseModel> FeedbackInbound(FeedbackInboundRequestModel model)
{
- string json =JsonConvert.SerializeObject(model, new JsonSerializerSettings
- {
+ string json = JsonConvert.SerializeObject(model, new JsonSerializerSettings
+ {
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
});
var content = new StringContent(json, Encoding.UTF8, "application/json");
@@ -70,7 +80,7 @@
return JsonConvert.DeserializeObject<ResponseModel>(body);
}
-
+
/// <summary>
/// 鍑哄簱鍙嶉
/// </summary>
@@ -224,7 +234,8 @@
.ToList();
var feeds = _feedbacktomesRepository.Db.Queryable<Dt_FeedbackToMes>().Where(x => x.OrderNo == orderNo && x.ReportStatus == 1).Select(o => o.PalletCode).ToList();
var unreports = stockinfos.Where(x => !feeds.Contains(x.PalletCode)).ToList();
- if (unreports!=null && !unreports.Any()) {
+ if (unreports != null && !unreports.Any())
+ {
return WebResponseContent.Instance.Error("娌℃湁闇�瑕佸洖浼犵殑鏁版嵁");
}
foreach (var item in unreports)
@@ -241,14 +252,14 @@
reqTime = DateTime.Now.ToString(),
business_type = inboundOrder.BusinessType,
factoryArea = inboundOrder.FactoryArea,
- operationType=1,
- Operator= inboundOrder.Operator,
+ operationType = 1,
+ Operator = inboundOrder.Operator,
orderNo = inboundOrder.UpperOrderNo,
status = inboundOrder.OrderStatus,
details = new List<FeedbackInboundDetailsModel>()
};
-
+
var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.SupplyCode, item.BatchNo, item.InboundOrderRowNo, item.BarcodeUnit, item.WarehouseCode })
.Select(group => new FeedbackInboundDetailsModel
{
@@ -256,9 +267,9 @@
supplyCode = group.Key.SupplyCode,
batchNo = group.Key.BatchNo,
lineNo = group.Key.InboundOrderRowNo,
- qty = group.Sum(x=>x.BarcodeQty),
+ qty = group.Sum(x => x.BarcodeQty),
// warehouseCode = group.Key.WarehouseCode=="0"?"1072": group.Key.WarehouseCode,
- warehouseCode =group.Key.WarehouseCode,
+ warehouseCode = group.Key.WarehouseCode,
unit = group.Key.BarcodeUnit,
barcodes = group.Select(row => new FeedbackBarcodesModel
{
@@ -284,7 +295,280 @@
}
}
+ else if (inout == 2)
+ {
+ foreach (var orderNo in orderNos)
+ {
+ var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().FirstAsync(x => x.OrderNo == orderNo);
+ if (outboundOrder != null && outboundOrder.IsBatch == 0)
+ {
+ await HandleOutboundOrderToMESCompletion(outboundOrder, orderNo);
+ }
+ else if (outboundOrder != null && outboundOrder.IsBatch == 1)
+ {
+ await HandleOutboundOrderBatchToMESCompletion(outboundOrder, orderNo);
+ }
+ }
+
+ }
return WebResponseContent.Instance.OK();
}
+ private async Task HandleOutboundOrderBatchToMESCompletion(Dt_OutboundOrder outboundOrder, string orderNo)
+ {
+
+ try
+ {
+ if (outboundOrder.ReturnToMESStatus == 1)
+ {
+ return;
+ }
+ var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id)
+ .Where((o, item) => item.OrderNo == orderNo && item.ReturnToMESStatus != 1)
+ .Select((o, item) => o)
+ .ToListAsync();
+
+ var detailids = new List<int>();
+ var allCompleted = true;
+ foreach (var detail in orderDetails.Where(x => x.ReturnToMESStatus == 0).ToList())
+ {
+ if (detail.OverOutQuantity >= detail.NeedOutQuantity)
+ {
+ detailids.Add(detail.Id);
+ }
+ else
+ {
+ allCompleted = false;
+ }
+ }
+ if (orderDetails.Any(x => x.ReturnToMESStatus == 2))
+ {
+ allCompleted = false;
+ }
+
+ int newStatus = allCompleted ? (int)OutOrderStatusEnum.鍑哄簱瀹屾垚 : (int)OutOrderStatusEnum.鍑哄簱涓�;
+
+ if (outboundOrder.OrderStatus != newStatus)
+ {
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.OrderStatus == newStatus)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+
+ }
+ var documentno = UniqueValueGenerator.Generate();
+ var feedmodel = new FeedbackOutboundRequestModel
+ {
+ reqCode = Guid.NewGuid().ToString(),
+ reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
+ business_type = outboundOrder.BusinessType,
+ factoryArea = outboundOrder.FactoryArea,
+ operationType = 1,
+ Operator = outboundOrder.Operator,
+ orderNo = outboundOrder.UpperOrderNo,
+ documentsNO = documentno,
+ status = outboundOrder.OrderStatus,
+ details = new List<FeedbackOutboundDetailsModel>()
+ };
+
+
+ foreach (var detail in orderDetails.Where(x => detailids.Contains(x.Id)).ToList())
+ {
+ // 鑾峰彇璇ユ槑缁嗗搴旂殑鏉$爜淇℃伅锛堜粠閿佸畾璁板綍锛�
+ var detailLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo && detailids.Contains(x.OrderDetailId) &&
+ x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ .ToListAsync();
+
+ var detailModel = new FeedbackOutboundDetailsModel
+ {
+ materialCode = detail.MaterielCode,
+ lineNo = detail.lineNo, // 娉ㄦ剰锛氳繖閲屽彲鑳介渶瑕佽皟鏁村瓧娈靛悕
+ warehouseCode = detail.WarehouseCode,
+ qty = detail.OverOutQuantity, // 浣跨敤璁㈠崟鏄庣粏鐨勫凡鍑哄簱鏁伴噺
+ currentDeliveryQty = detail.OverOutQuantity,
+ unit = detail.Unit,
+ barcodes = detailLocks.Select(lockInfo => new WIDESEA_DTO.Outbound.BarcodesModel
+ {
+ barcode = lockInfo.CurrentBarcode,
+ supplyCode = lockInfo.SupplyCode,
+ batchNo = lockInfo.BatchNo,
+ unit = lockInfo.Unit,
+ qty = lockInfo.PickedQty // 鏉$爜绾у埆鐨勬暟閲忎粛鐢ㄩ攣瀹氳褰�
+ }).ToList()
+ };
+
+ feedmodel.details.Add(detailModel);
+ }
+
+ var result = await FeedbackOutbound(feedmodel);
+ if (result != null && result.code == 200)
+ {
+
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(it => new Dt_OutboundOrderDetail
+ {
+ ReturnToMESStatus = 1,
+ documentsNO = documentno,
+ })
+ .Where(x => detailids.Contains(x.Id))
+ .ExecuteCommandAsync();
+
+ if (allCompleted && newStatus == (int)OutOrderStatusEnum.鍑哄簱瀹屾垚)
+ {
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.ReturnToMESStatus == 1)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+ }
+ }
+ else
+ {
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(it => new Dt_OutboundOrderDetail
+ {
+ ReturnToMESStatus = 2,
+ documentsNO = documentno,
+ })
+ .Where(x => detailids.Contains(x.Id))
+ .ExecuteCommandAsync();
+ }
+
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"CheckAndUpdateOrderStatus澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
+ }
+ }
+
+
+ private async Task HandleOutboundOrderToMESCompletion(Dt_OutboundOrder outboundOrder, string orderNo)
+ {
+
+ try
+ {
+ if (outboundOrder.ReturnToMESStatus == 1)
+ {
+ return;
+ }
+ var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id)
+ .Where((o, item) => item.OrderNo == orderNo)
+ .Select((o, item) => o)
+ .ToListAsync();
+
+ bool allCompleted = true;
+ foreach (var detail in orderDetails)
+ {
+ if (detail.OverOutQuantity < detail.NeedOutQuantity)
+ {
+ allCompleted = false;
+ break;
+ }
+ }
+
+ int newStatus = allCompleted ? (int)OutOrderStatusEnum.鍑哄簱瀹屾垚 : (int)OutOrderStatusEnum.鍑哄簱涓�;
+
+ if (outboundOrder.OrderStatus != newStatus)
+ {
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.OrderStatus == newStatus)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+
+ }
+ //鍙湁姝e父鍒嗘嫞瀹屾垚鏃舵墠鍚慚ES鍙嶉
+ if (allCompleted && newStatus == (int)OutOrderStatusEnum.鍑哄簱瀹屾垚)
+ {
+ var feedmodel = new FeedbackOutboundRequestModel
+ {
+ reqCode = Guid.NewGuid().ToString(),
+ reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
+ business_type = outboundOrder.BusinessType,
+ factoryArea = outboundOrder.FactoryArea,
+ operationType = 1,
+ Operator = outboundOrder.Operator,
+ orderNo = outboundOrder.UpperOrderNo,
+ documentsNO = outboundOrder.OrderNo,
+ status = outboundOrder.OrderStatus,
+ details = new List<FeedbackOutboundDetailsModel>()
+ };
+
+
+ foreach (var detail in orderDetails)
+ {
+ // 鑾峰彇璇ユ槑缁嗗搴旂殑鏉$爜淇℃伅锛堜粠閿佸畾璁板綍锛�
+ var detailLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.OrderDetailId == detail.Id &&
+ x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ .ToListAsync();
+
+ var detailModel = new FeedbackOutboundDetailsModel
+ {
+ materialCode = detail.MaterielCode,
+ lineNo = detail.lineNo, // 娉ㄦ剰锛氳繖閲屽彲鑳介渶瑕佽皟鏁村瓧娈靛悕
+ warehouseCode = detail.WarehouseCode,
+ qty = detail.OverOutQuantity, // 浣跨敤璁㈠崟鏄庣粏鐨勫凡鍑哄簱鏁伴噺
+ currentDeliveryQty = detail.OverOutQuantity,
+ unit = detail.Unit,
+ barcodes = detailLocks.Select(lockInfo => new WIDESEA_DTO.Outbound.BarcodesModel
+ {
+ barcode = lockInfo.CurrentBarcode,
+ supplyCode = lockInfo.SupplyCode,
+ batchNo = lockInfo.BatchNo,
+ unit = lockInfo.Unit,
+ qty = lockInfo.PickedQty // 鏉$爜绾у埆鐨勬暟閲忎粛鐢ㄩ攣瀹氳褰�
+ }).ToList()
+ };
+
+ feedmodel.details.Add(detailModel);
+ }
+
+ var result = await FeedbackOutbound(feedmodel);
+ if (result != null && result.code == 200)
+ {
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(x => x.ReturnToMESStatus == 1)
+ .Where(x => x.OrderId == outboundOrder.Id)
+ .ExecuteCommandAsync();
+
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.ReturnToMESStatus == 1)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"CheckAndUpdateOrderStatus澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
+ }
+
+ }
+
+ }
+
+ public static class UniqueValueGenerator
+ {
+ // 鍘熷瓙璁℃暟鍣紙绾跨▼瀹夊叏锛屾瘡娆¢�掑1锛岄伩鍏嶅悓涓�Ticks閲嶅锛�
+ private static long _counter = 0;
+
+ /// <summary>
+ /// 鐢熸垚鍞竴鍊硷紙鏀寔楂樺苟鍙戯級
+ /// </summary>
+ /// <returns>鏍煎紡锛歽yyyMMdd + Ticks + 3浣嶈鏁板櫒锛堝2025112563867890123001锛�</returns>
+ public static string Generate()
+ {
+ var now = DateTime.Now;
+ string datePart = now.ToString("yyyyMMdd");
+ long ticksPart = now.Ticks;
+
+ // 鍘熷瓙閫掑璁℃暟鍣紙鍙栨ā1000锛岀‘淇濊鏁板櫒浠�3浣嶏紝鎺у埗闀垮害锛�
+ long counterPart = Interlocked.Increment(ref _counter) % 1000;
+
+ // 鎷兼帴锛氳鏁板櫒琛�0涓�3浣嶏紙閬垮厤浣嶆暟涓嶄竴鑷达級
+ return $"{datePart}{ticksPart}{counterPart:D3}";
+ }
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs"
index 48640ac..edb4c46 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/LocationInfoService.cs"
@@ -189,6 +189,10 @@
if (first != null)
{
locationCaches.Add(new LocationCache { LocationCode = first.LocationCode, DateTime = DateTime.Now });
+ Db.Updateable<Dt_LocationInfo>().SetColumns(x => new Dt_LocationInfo
+ {
+ LocationStatus = (int)LocationStatusEnum.InStockLock,
+ }).Where(x => x.Id == first.Id).ExecuteCommand();
}
return first;
@@ -213,7 +217,7 @@
{
return Repository.QueryData(x => locationCodes.Contains(x.LocationCode));
}
-
+
public List<LocationTypeDto> GetLocationTypes()
{
return _locationTypeRepository.Db.Queryable<Dt_LocationType>().Select(x =>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/MaterialUnitService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/MaterialUnitService.cs"
index e0c46ef..7c48c96 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/MaterialUnitService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/MaterialUnitService.cs"
@@ -156,6 +156,18 @@
return ConvertAsync(materialData, quantity, materialData.PurchaseUnit, materialData.StockUnit);
}
+ public async Task<MaterialWithUnitConversionResult> ConvertFromToStockAsync(string materialCode,string fromUom, decimal quantity)
+ {
+ var materialData = await GetMaterialWithUnitsAsync(materialCode);
+
+ // 濡傛灉棰嗘枡鍗曚綅鍜屽簱瀛樺崟浣嶇浉鍚岋紝鐩存帴杩斿洖
+ if (fromUom.Equals(materialData.StockUnit, StringComparison.OrdinalIgnoreCase))
+ return new MaterialWithUnitConversionResult(quantity, materialData.StockUnit, false);
+
+ return ConvertAsync(materialData, quantity, fromUom, materialData.StockUnit);
+ }
+
+
/// <summary>
/// 棰嗘枡鍗曚綅杞簱瀛樺崟浣�
/// </summary>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/WIDESEA_BasicService.csproj" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/WIDESEA_BasicService.csproj"
index 555f689..c909530 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/WIDESEA_BasicService.csproj"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_BasicService/WIDESEA_BasicService.csproj"
@@ -8,6 +8,7 @@
<ItemGroup>
<ProjectReference Include="..\WIDESEA_IBasicService\WIDESEA_IBasicService.csproj" />
+ <ProjectReference Include="..\WIDESEA_IOutboundService\WIDESEA_IOutboundService.csproj" />
<ProjectReference Include="..\WIDESEA_IRecordService\WIDESEA_IRecordService.csproj" />
</ItemGroup>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/CommonEnum/PalletTypeEnum.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/CommonEnum/PalletTypeEnum.cs"
index f9a2413..a7d5abd 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/CommonEnum/PalletTypeEnum.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/CommonEnum/PalletTypeEnum.cs"
@@ -35,4 +35,18 @@
/// </summary>
LargestPallet = 4
}
+
+
+
+
+ public enum PalletStatusEnum
+ {
+ 鏈紑濮� = 0,
+ 鎷i�変腑 = 1,
+ 宸插畬鎴� = 2,
+ 鏃犱换鍔� = 3
+ }
+
+
+
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InboundOrderMenu.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InboundOrderMenu.cs"
index 4365b1b..61b81fc 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InboundOrderMenu.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/InboundOrderMenu.cs"
@@ -70,11 +70,17 @@
/// 璋冩嫧鍏ュ簱鍗�
/// </summary>
[Description("璋冩嫧鍏ュ簱鍗�")]
- Allocat = 115,
+ AllocatInbound = 115,
+
+ [Description("璋冩嫧鍑哄簱鍗�")]
+ AllocatOutbound = 215,
[Description("閲嶆鍥炲簱")]
ReCheck =116,
+ [Description("鏅轰粨璋冩櫤浠撳叆搴撳崟")]
+ InternalAllocat = 117,
+
/// <summary>
/// 閿�鍞��璐у崟
/// </summary>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutboundOrderEnum.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutboundOrderEnum.cs"
index 879747f..805fb4f 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutboundOrderEnum.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/OutboundOrderEnum.cs"
@@ -21,11 +21,17 @@
[Description("鍑哄簱涓�")]
鍑哄簱涓� = 1,
+
+
/// <summary>
/// 鍑哄簱瀹屾垚
/// </summary>
[Description("鍑哄簱瀹屾垚")]
鍑哄簱瀹屾垚 = 2,
+
+ [Description("閮ㄥ垎瀹屾垚")]
+
+ 閮ㄥ垎瀹屾垚 =3,
/// <summary>
/// 鍏抽棴
@@ -97,4 +103,6 @@
[Description("鍏朵粬鍑哄簱鍗�")]
Other = 235
}
+
+
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/OutLockStockStatusEnum.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/OutLockStockStatusEnum.cs"
index 2cc1115..dc7d6c1 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/OutLockStockStatusEnum.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/OutLockStockStatusEnum.cs"
@@ -16,6 +16,18 @@
// 宸插嚭搴� = 4,
// 宸插洖搴� = 5
//}
+
+ // 鏋氫妇瀹氫箟
+ public enum BatchStatusEnum
+ {
+ 鍒嗛厤涓� = 0,
+ 鎵ц涓� = 1,
+ 宸插畬鎴� = 2,
+ 宸插洖搴� = 3,
+ 宸插彇娑� = 4,
+
+ }
+
public enum SplitPackageStatusEnum
{
宸叉媶鍖� = 1,
@@ -23,6 +35,8 @@
宸叉嫞閫� = 3,
宸插洖搴� = 4,
}
+
+
public enum OutLockStockStatusEnum
{
[Description("宸插垎閰�")]
@@ -52,6 +66,12 @@
[Description("宸插洖搴�")]
宸插洖搴� =8,
+ [Description("宸查噴鏀�")]
+ 宸查噴鏀� =9,
+
+ [Description("宸插彇璧�")]
+ 宸插彇璧� =10,
+
[Description("鎾ら攢")]
鎾ら攢 = 99
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockStatusEmun.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockStatusEmun.cs"
index d10b600..65e71f1 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockStatusEmun.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/StockStatusEmun.cs"
@@ -40,6 +40,9 @@
Lock,
}
+
+
+
/// <summary>
/// 搴撳瓨鐘舵�侊細 <br/>
/// 1锛岀粍鐩樻殏瀛�<br/>
@@ -98,7 +101,10 @@
[Description("鐩樼偣搴撳瓨瀹屾垚")]
鐩樼偣搴撳瓨瀹屾垚 = 32,
- [Description("缁勭洏鎾ら攢")]
+ [Description("宸叉竻鐞�")]
+ 宸叉竻鐞� = 33,
+
+ [Description("缁勭洏鎾ら攢")]
缁勭洏鎾ら攢 = 99,
[Description("鍏ュ簱鎾ら攢")]
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/Helper/SqlSugarHelper.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/Helper/SqlSugarHelper.cs"
new file mode 100644
index 0000000..d093097
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Core/Helper/SqlSugarHelper.cs"
@@ -0,0 +1,29 @@
+锘縰sing SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_Core.DB;
+using WIDESEA_Core.Seed;
+
+namespace WIDESEA_Core.Helper
+{
+ public class SqlSugarHelper
+ {
+ //澶氬簱鎯呭喌涓嬩娇鐢ㄨ鏄庯細
+ //濡傛灉鏄浐瀹氬搴撳彲浠ヤ紶 new SqlSugarScope(List<ConnectionConfig>,db=>{}) 鏂囨。锛氬绉熸埛
+ //濡傛灉鏄笉鍥哄畾澶氬簱 鍙互鐪嬫枃妗aas鍒嗗簱
+ //鐢ㄥ崟渚嬫ā寮�
+ public static SqlSugarScope DbWMS = new SqlSugarScope(new ConnectionConfig()
+ {
+ ConnectionString = DBContext.GetMainConnectionDb().Connection,
+ //ConnectionString = AppSettings.app(MainDb.ConnectionStringWCS),
+ DbType = DbType.SqlServer,//鏁版嵁搴撶被鍨�
+ IsAutoCloseConnection = true //涓嶈鎴恡rue瑕佹墜鍔╟lose
+ },
+ db =>
+ {
+ });
+ }
+}
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Allocate/AllocateDto.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Allocate/AllocateDto.cs"
index e823023..1a979ff 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Allocate/AllocateDto.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Allocate/AllocateDto.cs"
@@ -146,6 +146,8 @@
/// </summary>
[JsonProperty("unit")]
public string Unit { get; set; }
+
+ public DateTime validDate { get; set; }
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/BatchOutBoundDto.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/BatchOutBoundDto.cs"
new file mode 100644
index 0000000..e889a73
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/BatchOutBoundDto.cs"
@@ -0,0 +1,169 @@
+锘縰sing SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace WIDESEA_DTO.Outbound
+{
+
+
+ public class PalletLockInfoDto
+ {
+ public int Id { get; set; }
+ public string OrderNo { get; set; }
+ public string BatchNo { get; set; }
+ public string MaterielCode { get; set; }
+ public string CurrentBarcode { get; set; }
+ public decimal AssignQuantity { get; set; }
+ public decimal PickedQty { get; set; }
+ public int Status { get; set; }
+ public string LocationCode { get; set; }
+ public string PalletCode { get; set; }
+ public bool CanSplit { get; set; }
+ public bool CanPick { get; set; }
+ }
+
+ #region 璇锋眰DTO
+
+ public class ConfirmPickingRequest
+ {
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鎵樼洏鍙蜂笉鑳戒负绌�")]
+ public string PalletCode { get; set; }
+
+ [Required(ErrorMessage = "鏉$爜涓嶈兘涓虹┖")]
+ public string Barcode { get; set; }
+ }
+
+ public class CancelPickingRequest
+ {
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鎵樼洏鍙蜂笉鑳戒负绌�")]
+ public string PalletCode { get; set; }
+
+ [Required(ErrorMessage = "鏉$爜涓嶈兘涓虹┖")]
+ public string Barcode { get; set; }
+
+ public int PickingHistoryId { get; set; }
+ }
+
+
+
+ public class CancelSplitRequest
+ {
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鎵樼洏鍙蜂笉鑳戒负绌�")]
+ public string PalletCode { get; set; }
+
+ [Required(ErrorMessage = "鏂版潯鐮佷笉鑳戒负绌�")]
+ public string NewBarcode { get; set; }
+ }
+
+ public class ReturnStockRequest
+ {
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鎵樼洏鍙蜂笉鑳戒负绌�")]
+ public string PalletCode { get; set; }
+ }
+ public class CancelSplitDto
+ {
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鎵樼洏鍙蜂笉鑳戒负绌�")]
+ public string PalletCode { get; set; }
+
+ [Required(ErrorMessage = "鏂版潯鐮佷笉鑳戒负绌�")]
+ public string NewBarcode { get; set; }
+ }
+
+ public class ReturnStockDto
+ {
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鎵樼洏鍙蜂笉鑳戒负绌�")]
+ public string PalletCode { get; set; }
+ }
+
+ public class PalletLocksDto
+ {
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鎵樼洏鍙蜂笉鑳戒负绌�")]
+ public string PalletCode { get; set; }
+ }
+
+ #endregion
+
+ #region DTO绫�
+
+ public class PalletPickedInfoDto
+ {
+ public int Id { get; set; }
+ public string OrderNo { get; set; }
+ public int OrderDetailId { get; set; }
+ public string PalletCode { get; set; }
+ public string Barcode { get; set; }
+ public string MaterielCode { get; set; }
+ public decimal PickedQty { get; set; }
+ public DateTime PickTime { get; set; }
+ public string Operator { get; set; }
+ public string LocationCode { get; set; }
+ }
+
+ public class PalletStatusDto
+ {
+ public string OrderNo { get; set; }
+ public string PalletCode { get; set; }
+ public int Status { get; set; }
+ public string StatusText { get; set; }
+ public int TotalItems { get; set; }
+ public int CompletedItems { get; set; }
+ public int PendingItems { get; set; }
+ }
+
+ public class SplitPackageInfoDto
+ {
+ public string OrderNo { get; set; }
+ public string PalletCode { get; set; }
+ public string Barcode { get; set; }
+ public string MaterielCode { get; set; }
+ public decimal RemainQuantity { get; set; }
+ public decimal AssignQuantity { get; set; }
+ public decimal PickedQty { get; set; }
+ }
+
+ public class EmptyPalletRemovalDto
+ {
+ public string OrderNo { get; set; }
+ public string PalletCode { get; set; }
+ public DateTime RemovalTime { get; set; }
+ public string Operator { get; set; }
+ public int CompletedItemsCount { get; set; }
+ public decimal TotalPickedQuantity { get; set; }
+ }
+
+ public class RemoveEmptyPalletDto
+ {
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鎵樼洏鍙蜂笉鑳戒负绌�")]
+ public string PalletCode { get; set; }
+ }
+ #endregion
+
+}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderAddDTO.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderAddDTO.cs"
index d764beb..dedb25f 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderAddDTO.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderAddDTO.cs"
@@ -92,13 +92,16 @@
/// </summary>
public string orderNo { get; set; }
+ public string documentsNO { get; set; }
+
public string business_type { get; set; }
public int status { get; set; }
public string factoryArea { get; set; }
public string Operator { get; set; }
- public List<FeedbackOutboundDetailsModel> details { get; set; }
+
+ public List<FeedbackOutboundDetailsModel> details { get; set; }
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderGetDTO.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderGetDTO.cs"
index 8381ea6..bbb4ca0 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderGetDTO.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Outbound/OutboundOrderGetDTO.cs"
@@ -2,6 +2,7 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -37,8 +38,20 @@
{
public int OutStockLockInfoId { get; set; }
public string MaterielCode { get; set; }
- public decimal SplitQuantity { get; set; }
+
public string Operator { get; set; }
+
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鎵樼洏鍙蜂笉鑳戒负绌�")]
+ public string PalletCode { get; set; }
+
+ [Required(ErrorMessage = "鍘熸潯鐮佷笉鑳戒负绌�")]
+ public string OriginalBarcode { get; set; }
+
+ [Range(0.001, double.MaxValue, ErrorMessage = "鎷嗗寘鏁伴噺蹇呴』澶т簬0")]
+ public decimal SplitQuantity { get; set; }
}
public class ConfirmPickingDto
{
@@ -77,10 +90,7 @@
public string OrderNo { get; set; }
}
- public class CancelPickingRequest
- {
- public int PickingHistoryId { get; set; }
- }
+
public class BackToStockRequest
{
@@ -261,6 +271,29 @@
public string Barcode { get; set; }
}
+
+
+ public class CancelSplitChainDto
+ {
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鎵樼洏鍙蜂笉鑳戒负绌�")]
+ public string PalletCode { get; set; }
+
+ [Required(ErrorMessage = "璧峰鏉$爜涓嶈兘涓虹┖")]
+ public string StartBarcode { get; set; }
+ }
+
+ public class SplitPackageChainInfoRequestDto
+ {
+ [Required(ErrorMessage = "璁㈠崟鍙蜂笉鑳戒负绌�")]
+ public string OrderNo { get; set; }
+
+ [Required(ErrorMessage = "鏉$爜涓嶈兘涓虹┖")]
+ public string Barcode { get; set; }
+ }
+
public class SplitPackageDto
{
public string OrderNo { get; set; }
@@ -295,4 +328,6 @@
//public decimal SplitQuantity { get; set; }
//public decimal RemainQuantity { get; set; }
}
+
+
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Stock/StockSelectViewDTO.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Stock/StockSelectViewDTO.cs"
index 0ff3981..0497a6f 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Stock/StockSelectViewDTO.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Stock/StockSelectViewDTO.cs"
@@ -19,6 +19,14 @@
public string LocationCode { get; set; }
-
+
+ public string Barcode { get; set; }
+
+
+ public string BatchNo { get; set; }
+ public string SupplyCode { get; set; }
+ public DateTime StockCreateDate { get; set; }
+ public int StockId { get; set; }
+ public int? OrderDetailId { get; set; }
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Task/WMSTaskDTO.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Task/WMSTaskDTO.cs"
index 03e71c3..2adbcca 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Task/WMSTaskDTO.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_DTO/Task/WMSTaskDTO.cs"
@@ -81,4 +81,15 @@
public int[] taskIds { get; set; }
}
+
+ public class GenerateOutboundBatchTasksDto
+ {
+ public string orderNo { get; set; }
+
+ public int orderDetailId { get; set; }
+
+ public decimal batchQuantity { get; set; }
+
+ public string outboundPlatform { get; set; }
+ }
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IBasicService/IMaterialUnitService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IBasicService/IMaterialUnitService.cs"
index 9e544d6..d06b50e 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IBasicService/IMaterialUnitService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IBasicService/IMaterialUnitService.cs"
@@ -20,6 +20,8 @@
Task<Dictionary<string, MaterialWithUnitConversionResult>> BatchConvertPurchaseToStockAsync(List<BatchConversionRequest> requests);
Task<MaterialWithUnitConversionResult> ConvertAsync(string materialCode, decimal quantity, string fromUnit, string toUnit);
Task<MaterialWithUnitConversionResult> ConvertIssueToStockAsync(string materialCode, decimal quantity);
+
+ Task<MaterialWithUnitConversionResult> ConvertFromToStockAsync(string materialCode, string fromUom, decimal quantity);
Task<MaterialWithUnitConversionResult> ConvertPurchaseToStockAsync(string materialCode, decimal quantity);
Task<decimal?> GetConversionRatioAsync(string materialCode, string fromUnit, string toUnit);
Task<string> GetIssueUnitAsync(string materialCode);
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutStockLockInfoService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutStockLockInfoService.cs"
index a97e67f..d4e589f 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutStockLockInfoService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutStockLockInfoService.cs"
@@ -26,7 +26,7 @@
Task<List<Dt_OutStockLockInfo>> GetByPalletCode(string palletCode, int? status = null);
Task<LockInfoDetailDto> GetLockInfoDetail(int lockInfoId);
- Dt_OutStockLockInfo GetOutStockLockInfo(Dt_OutboundOrder outboundOrder,Dt_OutboundOrderDetail outboundOrderDetail,Dt_StockInfo outStock, decimal assignQuantity, string barcode = null);
+ Dt_OutStockLockInfo GetOutStockLockInfo(Dt_OutboundOrder outboundOrder,Dt_OutboundOrderDetail outboundOrderDetail,Dt_StockInfo outStock, decimal assignQuantity, string barcode = null, string outboundBatchNo = "");
List<Dt_OutStockLockInfo> GetOutStockLockInfos(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail outboundOrderDetail, List<Dt_StockInfo> outStocks, int? taskNum = null);
Task<List<Dt_OutStockLockInfo>> GetPalletLockInfos(string palletCode);
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundBatchPickingService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundBatchPickingService.cs"
new file mode 100644
index 0000000..37d8a2f
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundBatchPickingService.cs"
@@ -0,0 +1,29 @@
+锘縰sing WIDESEA_Core;
+using WIDESEA_Core.BaseRepository;
+using WIDESEA_DTO.Outbound;
+using WIDESEA_Model.Models;
+
+namespace WIDESEA_IOutboundService
+{
+ public interface IOutboundBatchPickingService
+ {
+ IRepository<Dt_PickingRecord> Repository { get; }
+
+ Task<WebResponseContent> BatchReturnStock(string orderNo, string palletCode);
+ Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode);
+ Task<WebResponseContent> CancelSplitPackage(string orderNo, string palletCode, string newBarcode);
+
+ Task<WebResponseContent> CancelSplitPackageChain(string orderNo, string palletCode, string startBarcode);
+
+ Task<List<Dt_SplitPackageRecord>> GetSplitPackageChain(string orderNo, string startBarcode);
+ Task<string> FindRootBarcode(string orderNo, string startBarcode);
+ Task<WebResponseContent> GetSplitPackageChainInfo(string orderNo, string barcode);
+ Task<WebResponseContent> ConfirmBatchPicking(string orderNo, string palletCode, string barcode);
+ Task<List<PalletLockInfoDto>> GetPalletLockInfos(string orderNo, string palletCode);
+ Task<List<PalletPickedInfoDto>> GetPalletPickedList(string orderNo, string palletCode);
+ Task<PalletStatusDto> GetPalletStatus(string orderNo, string palletCode);
+ Task<SplitPackageInfoDto> GetSplitPackageInfo(string orderNo, string palletCode, string barcode);
+ Task<WebResponseContent> ManualSplitPackage(string orderNo, string palletCode, string originalBarcode, decimal splitQuantity);
+ Task<WebResponseContent> RemoveEmptyPallet(string orderNo, string palletCode);
+ }
+}
\ No newline at end of file
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundOrderDetailService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundOrderDetailService.cs"
index 3525497..3cb776c 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundOrderDetailService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundOrderDetailService.cs"
@@ -23,6 +23,6 @@
WebResponseContent LockOutboundStockDataUpdate(List<Dt_StockInfo> stockInfos, List<Dt_OutboundOrderDetail> outboundOrderDetails, List<Dt_OutStockLockInfo> outStockLockInfos, List<Dt_LocationInfo> locationInfos, LocationStatusEnum locationStatus = LocationStatusEnum.Lock, List<Dt_Task>? tasks = null);
(List<Dt_StockInfo>, Dt_OutboundOrderDetail, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) AssignStockOutbound(Dt_OutboundOrderDetail outboundOrderDetail, List<StockSelectViewDTO> stockSelectViews);
//List<Dt_OutboundOrderDetail> GetOutboundStockDataById(int id);
-
+ Task<(List<Dt_StockInfo>, List<Dt_OutboundOrderDetail>, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>)> AssignStockForBatch(Dt_OutboundOrderDetail orderDetail, decimal batchQuantity, string batchNo);
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs"
index 34899a9..f5620fc 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs"
@@ -13,7 +13,8 @@
List<Dt_StockInfo> GetStockInfos(string materielCode, string lotNo, string supplyCode, List<string> locationCodes);
List<Dt_StockInfo> GetUseableStocks(string materielCode, string batchNo,string supplyCode);
-
+
+ Dt_StockInfo GetStockInfoByPalletCode(string palletCode);
void AddMaterielGroup(Dt_StockInfo stockInfo);
(List<Dt_StockInfo>, Dictionary<int, decimal>) GetOutboundStocks(List<Dt_StockInfo> stockInfos, string materielCode, decimal needQuantity, out decimal residueQuantity);
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs"
index 43c9e48..2b3b106 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_ITaskInfoService/ITaskService.cs"
@@ -48,6 +48,8 @@
WebResponseContent GenerateOutboundTask(int orderDetailId, List<StockSelectViewDTO> stockSelectViews);
+ Task<WebResponseContent> GenerateOutboundBatchTasksAsync(int orderDetailId, decimal batchQuantity, string outStation);
+
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs"
index 0d63ad2..f65373c 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs"
@@ -96,8 +96,11 @@
item.Unit = purchaseToStockResult.Unit;
item.OrderQuantity = purchaseToStockResult.Quantity;
}
+ if (model.OrderType != InOrderTypeEnum.AllocatInbound.ObjToInt())
+ {
+ model.InboundOrderNo = CreateCodeByRule(nameof(RuleCodeEnum.InboundOrderRule));
+ }
- model.InboundOrderNo = CreateCodeByRule(nameof(RuleCodeEnum.InboundOrderRule));
Db.InsertNav(model).Include(x => x.Details).ExecuteCommand();
}
return WebResponseContent.Instance.OK();
@@ -121,6 +124,10 @@
if (inboundOrder.Details == null || inboundOrder.Details.Count == 0)
{
return WebResponseContent.Instance.Error($"鏈壘鍒板叆搴撳崟鏄庣粏淇℃伅");
+ }
+ if (inboundOrder.OrderStatus != InOrderStatusEnum.鏈紑濮�.ObjToInt())
+ {
+ return WebResponseContent.Instance.Error($"璇ヨ鍗曠姸鎬佷笉鍏佽淇敼");
}
List<Dt_InboundOrderDetail> inboundOrderDetails = new List<Dt_InboundOrderDetail>();
List<Dt_InboundOrderDetail> updateInboundOrderDetails = new List<Dt_InboundOrderDetail>();
@@ -226,6 +233,10 @@
{
return WebResponseContent.Instance.Error($"鏈壘鍒板叆搴撳崟鏄庣粏淇℃伅");
}
+ if (inboundOrder.OrderStatus != InOrderStatusEnum.鏈紑濮�.ObjToInt())
+ {
+ return WebResponseContent.Instance.Error($"璇ヨ鍗曠姸鎬佷笉鍏佽鍒犻櫎");
+ }
//Db.DeleteNav(inboundOrder).Include(x => x.Details).ExecuteCommand();
_unitOfWorkManage.BeginTran();
//BaseDal.DeleteAndMoveIntoHty(inboundOrder, OperateTypeEnum.鑷姩鍒犻櫎);
@@ -330,12 +341,12 @@
if (!result2.Item1) return content = WebResponseContent.Instance.Error(result2.Item2);
// materielGroupDTO.WarehouseCode
- var code = _warehouseAreaRepository.Db.Queryable<Dt_WarehouseArea>().Where(x => x.Code == materielGroupDTO.WarehouseType).Select(x=>x.Code).First();
- if(string.IsNullOrEmpty(code))
+ var code = _warehouseAreaRepository.Db.Queryable<Dt_WarehouseArea>().Where(x => x.Code == materielGroupDTO.WarehouseType).Select(x => x.Code).First();
+ if (string.IsNullOrEmpty(code))
{
return content = WebResponseContent.Instance.Error($"浠撳簱涓病鏈夎{materielGroupDTO.WarehouseType}缂栧彿銆�");
}
-
+
Dt_InboundOrder inboundOrder = GetInboundOrder(materielGroupDTO.OrderNo);
@@ -357,10 +368,10 @@
if (stockInfo == null)
{
- stockInfo = new Dt_StockInfo() { PalletType = (int)PalletTypeEnum.None,LocationType=materielGroupDTO.locationType.ObjToInt() };
+ stockInfo = new Dt_StockInfo() { PalletType = (int)PalletTypeEnum.None, LocationType = materielGroupDTO.locationType.ObjToInt() };
stockInfo.Details = new List<Dt_StockInfoDetail>();
}
-
+
foreach (var item in dbinboundOrderDetails)
{
stockInfo.Details.Add(new Dt_StockInfoDetail
@@ -374,15 +385,15 @@
SupplyCode = item.SupplyCode,
WarehouseCode = materielGroupDTO.WarehouseType,
StockQuantity = item.OrderQuantity,
- BarcodeQty=item.BarcodeQty,
- BarcodeUnit=item.BarcodeUnit,
- FactoryArea= inboundOrder.FactoryArea,
- Status = 0,
+ BarcodeQty = item.BarcodeQty,
+ BarcodeUnit = item.BarcodeUnit,
+ FactoryArea = inboundOrder.FactoryArea,
+ Status = 0,
OrderNo = inboundOrder.InboundOrderNo,
BusinessType = inboundOrder.BusinessType,
-
+
});
-
+
item.ReceiptQuantity = item.BarcodeQty;
item.OrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt();
item.WarehouseCode = materielGroupDTO.WarehouseType;
@@ -429,7 +440,7 @@
WebResponseContent content = new WebResponseContent();
try
- {
+ {
(bool, string, object?) result2 = ModelValidate.ValidateModelData(materielGroupDTO);
if (!result2.Item1) return content = WebResponseContent.Instance.Error(result2.Item2);
@@ -439,7 +450,8 @@
return content = WebResponseContent.Instance.Error($"鍖哄煙涓病鏈夎{materielGroupDTO.WarehouseCode}缂栧彿銆�");
}
- if(_stockRepository.QueryFirst(x=>x.PalletCode == materielGroupDTO.PalletCode)!=null){
+ if (_stockRepository.QueryFirst(x => x.PalletCode == materielGroupDTO.PalletCode) != null)
+ {
return WebResponseContent.Instance.Error("璇ユ墭鐩樺凡缁忕粍杩囩洏");
}
@@ -458,7 +470,7 @@
{
if (stockInfo == null)
{
- stockInfo = new Dt_StockInfo() { PalletType = PalletTypeEnum.Empty.ObjToInt(), StockStatus = StockStatusEmun.缁勭洏鏆傚瓨.ObjToInt(), PalletCode = materielGroupDTO.PalletCode,LocationType= materielGroupDTO.WarehouseCode.ObjToInt() };
+ stockInfo = new Dt_StockInfo() { PalletType = PalletTypeEnum.Empty.ObjToInt(), StockStatus = StockStatusEmun.缁勭洏鏆傚瓨.ObjToInt(), PalletCode = materielGroupDTO.PalletCode, LocationType = materielGroupDTO.WarehouseCode.ObjToInt() };
stockInfo.Details = new List<Dt_StockInfoDetail>();
}
else
@@ -639,25 +651,31 @@
{
return WebResponseContent.Instance.Error("鎵樼洏鍙蜂笉鑳戒负绌�");
}
- var stock= _stockRepository.Db.Queryable<Dt_StockInfo>().Includes(o=>o.Details).First(x => x.PalletCode == palletCode );
+ var stock = _stockRepository.Db.Queryable<Dt_StockInfo>().Includes(o => o.Details).First(x => x.PalletCode == palletCode && x.StockStatus == (int)StockStatusEmun.缁勭洏鏆傚瓨);
if (stock == null)
{
return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩樺彿{palletCode}瀵瑰簲鐨勫簱瀛樿褰�");
+ }
+
+ if (stock.Details == null || !stock.Details.Any())
+ {
+ _stockRepository.DeleteData(stock);
+ return WebResponseContent.Instance.OK();
}
// 鑾峰彇搴撳瓨璇︽儏鍏宠仈鐨勬墍鏈夊叆搴撳崟鍙�
var relatedOrderNos = stock.Details.Select(d => d.OrderNo).First();
// 鏌ヨ鎵�鏈夊叧鑱旂殑鍏ュ簱鍗曪紙鍚鎯咃級
var inboundOrders = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>()
- .Includes(x => x.Details)
- .Where(x => relatedOrderNos==x.InboundOrderNo)
+ .Includes(x => x.Details)
+ .Where(x => relatedOrderNos == x.InboundOrderNo)
.First();
var barcodes = stock.Details.Select(d => d.Barcode).ToList();
- // 鍖归厤搴撳瓨鏉$爜瀵瑰簲鐨勫叆搴撳崟鏄庣粏
- var matchedInboundDetails = inboundOrders.Details
- ?.Where(d => barcodes.Contains(d.Barcode))
- .ToList();
+ // 鍖归厤搴撳瓨鏉$爜瀵瑰簲鐨勫叆搴撳崟鏄庣粏
+ var matchedInboundDetails = inboundOrders.Details
+ ?.Where(d => barcodes.Contains(d.Barcode))
+ .ToList();
foreach (var detail in matchedInboundDetails)
{
detail.ReceiptQuantity = 0;
@@ -667,7 +685,8 @@
_stockDetailRepository.DeleteData(stock.Details);
_stockRepository.DeleteData(stock);
- return WebResponseContent.Instance.OK();
+
+ return WebResponseContent.Instance.OK("鎵樼洏鎾ら攢鎴愬姛");
}
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Allocate/Dt_AllocateOrderDetail.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Allocate/Dt_AllocateOrderDetail.cs"
index c5cf770..73a6f5c 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Allocate/Dt_AllocateOrderDetail.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Allocate/Dt_AllocateOrderDetail.cs"
@@ -120,5 +120,7 @@
/// </summary>
[SugarColumn(IsNullable = true, ColumnDescription = "鍥炰紶MES")]
public int ReturnToMESStatus { get; set; } = 0;
+ [SugarColumn(IsNullable = true, ColumnDescription = "杩囨湡鏃ユ湡")]
+ public DateTime ValidDate { get; set; }
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundBatch.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundBatch.cs"
new file mode 100644
index 0000000..7f75efd
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundBatch.cs"
@@ -0,0 +1,68 @@
+锘縰sing SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_Core.DB.Models;
+
+namespace WIDESEA_Model.Models.Outbound
+{
+
+
+ /// <summary>
+ /// 鍑哄簱鎵规琛�
+ /// </summary>
+ [SugarTable("Dt_OutboundBatch")]
+ public class Dt_OutboundBatch : BaseEntity
+ {
+ /// <summary>
+ /// 涓婚敭ID锛堣嚜澧烇級
+ /// </summary>
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] //
+ public int Id { get; set; }
+
+ /// <summary>
+ /// 鎵规鍙�
+ /// </summary>
+ [SugarColumn(ColumnName = "BatchNo", Length = 50, IsNullable = false)]
+ public string BatchNo { get; set; }
+
+ /// <summary>
+ /// 璁㈠崟鍙�
+ /// </summary>
+ [SugarColumn(ColumnName = "OrderNo", Length = 50, IsNullable = false)]
+ public string OrderNo { get; set; }
+
+ /// <summary>
+ /// 璁㈠崟鏄庣粏ID
+ /// </summary>
+ [SugarColumn(ColumnName = "OrderDetailId", IsNullable = false)]
+ public int OrderDetailId { get; set; }
+
+ /// <summary>
+ /// 鎵规鍒嗛厤鏁伴噺
+ /// </summary>
+ [SugarColumn(ColumnName = "BatchQuantity", IsNullable = false)] // 绮惧害18锛屽皬鏁颁綅2
+ public decimal BatchQuantity { get; set; }
+
+ /// <summary>
+ /// 宸插畬鎴愭暟閲忥紙榛樿0锛�
+ /// </summary>
+ [SugarColumn(ColumnName = "CompletedQuantity", DefaultValue = "0")] // 榛樿鍊�0
+ public decimal CompletedQuantity { get; set; } = 0; // 浠g爜灞傞粯璁ゅ�硷紝涓庢暟鎹簱榛樿鍊间竴鑷�
+
+ /// <summary>
+ /// 鎵规鐘舵�侊紙榛樿0锛�
+ /// </summary>
+ [SugarColumn(ColumnName = "BatchStatus", DefaultValue = "0")]
+ public int BatchStatus { get; set; } = 0;
+
+
+ /// <summary>
+ /// 鎿嶄綔浜�
+ /// </summary>
+ [SugarColumn(ColumnName = "Operator", Length = 50, IsNullable = true)] // 鍙┖
+ public string Operator { get; set; }
+ }
+}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundLockInfo.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundLockInfo.cs"
index 02db493..50a2684 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundLockInfo.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundLockInfo.cs"
@@ -131,6 +131,13 @@
[SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "鎿嶄綔鑰�")]
public string Operator { get; set; }
+
+ public decimal BarcodeQty { get; set; }
+
+ public string BarcodeUnit { get; set; }
+
+ public string OutboundBatchNo { get; set; }
+
[Navigate(NavigateType.OneToOne, nameof(StockInfo))]//涓�瀵逛竴 SchoolId鏄疭tudentA绫婚噷闈㈢殑
public Dt_StockInfo StockInfo { get; set; } //涓嶈兘璧嬪�煎彧鑳芥槸null
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrder.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrder.cs"
index 8b8350f..7b5bfc7 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrder.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrder.cs"
@@ -104,7 +104,7 @@
public string Operator { get; set; }
/// <summary>
- /// 鍥炰紶MES
+ /// 鍥炰紶MES 0鏈洖浼狅紝1鍥炰紶鎴愬姛锛� 2鍥炰紶澶辫触
/// </summary>
[SugarColumn(IsNullable = true, ColumnDescription = "鍥炰紶MES")]
public int ReturnToMESStatus { get; set; } = 0;
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrderDetail.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrderDetail.cs"
index a12854c..95fcf3b 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrderDetail.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundOrderDetail.cs"
@@ -143,9 +143,11 @@
public decimal NeedOutQuantity => OrderQuantity - MoveQty;
public decimal PickedQty { get; set; }
- /// <summary>
- /// 铏氭嫙鍑哄叆搴撴暟閲�
- /// </summary>
- public decimal NoStockOutQty { get; set; }
+
+ public string documentsNO { get; set; }
+
+ public decimal AllocatedQuantity { get; set; }
+
+ public string BatchAllocateStatus { get; set; }
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_PickingRecord.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_PickingRecord.cs"
index 798a774..2d6a2fa 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_PickingRecord.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_PickingRecord.cs"
@@ -44,7 +44,13 @@
public int StockId { get; set; }
+ public string BatchNo { get; set; }
+ public bool IsCancelled { get; set; }
+
+ public DateTime? CancelTime { get; set; }
+
+ public string CancelOperator { get; set; }
public string FactoryArea { get; set; }
}
@@ -107,6 +113,7 @@
public DateTime RevertTime { get; set; }
+ public string RevertOperator { get; set; }
public int PreviousSplitRecordId { get; set; }
[SugarColumn(IsNullable = true)]
@@ -115,6 +122,28 @@
public decimal StockBeforeSplit { get; set; }
public decimal AssignBeforeSplit { get; set; }
}
-
+
+
+ /// <summary>
+ /// 绌虹鍙栬蛋璁板綍琛�
+ /// </summary>
+ public class Dt_EmptyPalletRemoval
+ {
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+ public int Id { get; set; }
+
+ public string OrderNo { get; set; }
+
+ public string PalletCode { get; set; }
+
+ public DateTime RemovalTime { get; set; }
+
+ public string Operator { get; set; }
+
+ public int CompletedItemsCount { get; set; }
+
+ public decimal TotalPickedQuantity { get; set; }
+ }
+
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutStockLockInfoService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutStockLockInfoService.cs"
index 489eb5a..ef15c2e 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutStockLockInfoService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutStockLockInfoService.cs"
@@ -43,7 +43,7 @@
Dt_OutboundOrderDetail outboundOrderDetail,
Dt_StockInfo outStock,
decimal assignQuantity,
- string barcode = null)
+ string barcode = null,string outboundBatchNo = "")
{
// 鑾峰彇搴撳瓨鏄庣粏淇℃伅
var stockDetails = outStock.Details
@@ -108,8 +108,11 @@
MaterielCode = outboundOrderDetail.MaterielCode,
BatchNo = firstAvailableDetail.BatchNo,
Unit = firstAvailableDetail.Unit,
+ BarcodeQty = firstAvailableDetail.BarcodeQty,
+ BarcodeUnit = firstAvailableDetail.BarcodeUnit,
FactoryArea = firstAvailableDetail.FactoryArea,
lineNo = outboundOrderDetail.lineNo,
+ OutboundBatchNo= outboundBatchNo
};
}
@@ -252,7 +255,7 @@
public List<Dt_OutStockLockInfo> GetByOrderDetailId(int orderDetailId, OutLockStockStatusEnum? outStockStatus)
{
- return BaseDal.QueryData(x => x.OrderDetailId == orderDetailId && outStockStatus == null ? true : x.Status == outStockStatus.ObjToInt());
+ return BaseDal.QueryData(x => x.OrderDetailId == orderDetailId );
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundBatchPickingService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundBatchPickingService.cs"
new file mode 100644
index 0000000..bbd2251
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundBatchPickingService.cs"
@@ -0,0 +1,1441 @@
+锘縰sing Microsoft.Extensions.Logging;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using WIDESEA_BasicService;
+using WIDESEA_Common.CommonEnum;
+using WIDESEA_Common.OrderEnum;
+using WIDESEA_Common.StockEnum;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseRepository;
+using WIDESEA_Core.BaseServices;
+using WIDESEA_DTO.Outbound;
+using WIDESEA_IAllocateService;
+using WIDESEA_IBasicService;
+using WIDESEA_IOutboundService;
+using WIDESEA_IStockService;
+using WIDESEA_Model.Models;
+using WIDESEA_Model.Models.Basic;
+using WIDESEA_Model.Models.Outbound;
+using static WIDESEA_OutboundService.OutboundBatchPickingService;
+
+namespace WIDESEA_OutboundService
+{
+ public class OutboundBatchPickingService : ServiceBase<Dt_PickingRecord, IRepository<Dt_PickingRecord>>, IOutboundBatchPickingService
+ {
+
+
+ private readonly IUnitOfWorkManage _unitOfWorkManage;
+ public IRepository<Dt_PickingRecord> Repository => BaseDal;
+
+ private readonly IStockInfoService _stockInfoService;
+ private readonly IStockService _stockService;
+ private readonly IOutStockLockInfoService _outStockLockInfoService;
+ private readonly IStockInfoDetailService _stockInfoDetailService;
+ private readonly ILocationInfoService _locationInfoService;
+ private readonly IOutboundOrderDetailService _outboundOrderDetailService;
+ private readonly IOutboundOrderService _outboundOrderService;
+ private readonly ISplitPackageService _splitPackageService;
+ private readonly IRepository<Dt_Task> _taskRepository;
+ private readonly IESSApiService _eSSApiService;
+ private readonly IInvokeMESService _invokeMESService;
+ private readonly IDailySequenceService _dailySequenceService;
+ private readonly IAllocateService _allocateService;
+ private readonly IRepository<Dt_OutboundBatch> _outboundBatchRepository;
+ private readonly ILogger<OutboundPickingService> _logger;
+
+ private Dictionary<string, string> stations = new Dictionary<string, string>
+ {
+ {"2-1","2-9" },
+ {"3-1","3-9" },
+
+ };
+
+ private Dictionary<string, string> movestations = new Dictionary<string, string>
+ {
+ {"2-1","2-5" },
+ {"3-1","3-5" },
+
+ };
+
+ public OutboundBatchPickingService(IRepository<Dt_PickingRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IStockService stockService,
+ IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, ILocationInfoService locationInfoService,
+ IOutboundOrderDetailService outboundOrderDetailService, ISplitPackageService splitPackageService, IOutboundOrderService outboundOrderService,
+ IRepository<Dt_Task> taskRepository, IESSApiService eSSApiService, ILogger<OutboundPickingService> logger, IInvokeMESService invokeMESService, IDailySequenceService dailySequenceService, IAllocateService allocateService, IRepository<Dt_OutboundBatch> outboundBatchRepository) : base(BaseDal)
+ {
+ _unitOfWorkManage = unitOfWorkManage;
+ _stockInfoService = stockInfoService;
+ _stockService = stockService;
+ _outStockLockInfoService = outStockLockInfoService;
+ _stockInfoDetailService = stockInfoDetailService;
+ _locationInfoService = locationInfoService;
+ _outboundOrderDetailService = outboundOrderDetailService;
+ _splitPackageService = splitPackageService;
+ _outboundOrderService = outboundOrderService;
+ _taskRepository = taskRepository;
+ _eSSApiService = eSSApiService;
+ _logger = logger;
+ _invokeMESService = invokeMESService;
+ _dailySequenceService = dailySequenceService;
+ _allocateService = allocateService;
+ _outboundBatchRepository = outboundBatchRepository;
+ }
+
+ // <summary>
+ /// 鑾峰彇鎵樼洏鐨勯攣瀹氫俊鎭�
+ /// </summary>
+ public async Task<List<PalletLockInfoDto>> GetPalletLockInfos(string orderNo, string palletCode)
+ {
+ var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
+ .Select(x => new
+ {
+ x.Id,
+ x.OrderNo,
+ x.BatchNo,
+ x.MaterielCode,
+ x.CurrentBarcode,
+ x.AssignQuantity,
+ x.PickedQty,
+ x.Status,
+ x.LocationCode,
+ x.PalletCode
+ }).ToListAsync();
+
+ var lockInfoDtos = lockInfos.Select(x => new PalletLockInfoDto
+ {
+ Id = x.Id,
+ OrderNo = x.OrderNo,
+ BatchNo = x.BatchNo,
+ MaterielCode = x.MaterielCode,
+ CurrentBarcode = x.CurrentBarcode,
+ AssignQuantity = x.AssignQuantity,
+ PickedQty = x.PickedQty,
+ Status = x.Status,
+ LocationCode = x.LocationCode,
+ PalletCode = x.PalletCode,
+ CanSplit = (x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� && x.AssignQuantity - x.PickedQty > 0),
+ CanPick = (x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� && x.PickedQty < x.AssignQuantity)
+ }).ToList();
+
+ return lockInfoDtos;
+ }
+ #region 鏌ヨ鏂规硶
+
+ /// <summary>
+ /// 鑾峰彇鎵樼洏鐨勫凡鎷i�夊垪琛�
+ /// </summary>
+ public async Task<List<PalletPickedInfoDto>> GetPalletPickedList(string orderNo, string palletCode)
+ {
+ var pickedList = await Db.Queryable<Dt_PickingRecord>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ !x.IsCancelled)
+ .Select(x => new PalletPickedInfoDto
+ {
+ Id = x.Id,
+ OrderNo = x.OrderNo,
+ OrderDetailId = x.OrderDetailId,
+ PalletCode = x.PalletCode,
+ Barcode = x.Barcode,
+ MaterielCode = x.MaterielCode,
+ PickedQty = x.PickQuantity,
+ PickTime = x.PickTime,
+ Operator = x.Operator,
+ LocationCode = x.LocationCode
+ })
+ .ToListAsync();
+
+ return pickedList;
+ }
+
+ /// <summary>
+ /// 鑾峰彇鎵樼洏鐘舵��
+ /// </summary>
+ public async Task<PalletStatusDto> GetPalletStatus(string orderNo, string palletCode)
+ {
+ // 鑾峰彇鎵樼洏鐨勯攣瀹氫俊鎭�
+ var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
+ .ToListAsync();
+
+ if (!lockInfos.Any())
+ {
+ return new PalletStatusDto
+ {
+ OrderNo = orderNo,
+ PalletCode = palletCode,
+ Status = (int)PalletStatusEnum.鏃犱换鍔�,
+ StatusText = "鏃犱换鍔�",
+ TotalItems = 0,
+ CompletedItems = 0,
+ PendingItems = 0
+ };
+ }
+
+ var totalItems = lockInfos.Count;
+ var completedItems = lockInfos.Count(x => x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�);
+ var pendingItems = lockInfos.Count(x => x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�);
+
+ var status = PalletStatusEnum.鎷i�変腑;
+ if (pendingItems == 0 && completedItems > 0)
+ {
+ status = PalletStatusEnum.宸插畬鎴�;
+ }
+ else if (pendingItems > 0 && completedItems == 0)
+ {
+ status = PalletStatusEnum.鏈紑濮�;
+ }
+ else if (pendingItems > 0 && completedItems > 0)
+ {
+ status = PalletStatusEnum.鎷i�変腑;
+ }
+
+ return new PalletStatusDto
+ {
+ OrderNo = orderNo,
+ PalletCode = palletCode,
+ Status = (int)status,
+ StatusText = GetPalletStatusText(status),
+ TotalItems = totalItems,
+ CompletedItems = completedItems,
+ PendingItems = pendingItems
+ };
+ }
+
+ /// <summary>
+ /// 鑾峰彇鎷嗗寘淇℃伅
+ /// </summary>
+ public async Task<SplitPackageInfoDto> GetSplitPackageInfo(string orderNo, string palletCode, string barcode)
+ {
+ // 鏌ユ壘閿佸畾淇℃伅
+ var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ x.CurrentBarcode == barcode
+ //&& x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�
+ )
+ .FirstAsync();
+
+ if (lockInfo == null)
+ throw new Exception("鏈壘鍒版湁鏁堢殑閿佸畾淇℃伅");
+
+ // 璁$畻鍓╀綑鍙媶鏁伴噺
+ var remainQuantity = lockInfo.AssignQuantity - lockInfo.PickedQty;
+
+ return new SplitPackageInfoDto
+ {
+ OrderNo = orderNo,
+ PalletCode = palletCode,
+ Barcode = barcode,
+ MaterielCode = lockInfo.MaterielCode,
+ RemainQuantity = remainQuantity,
+ AssignQuantity = lockInfo.AssignQuantity,
+ PickedQty = lockInfo.PickedQty
+ };
+ }
+
+ #endregion
+
+ #region 鍙栬蛋绌虹閫昏緫
+
+ /// <summary>
+ /// 鍙栬蛋绌虹 - 娓呯悊宸插畬鎴愭嫞閫夌殑鎵樼洏鏁版嵁
+ /// </summary>
+ public async Task<WebResponseContent> RemoveEmptyPallet(string orderNo, string palletCode)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+
+ // 楠岃瘉鎵樼洏鏄惁鍙互鍙栬蛋锛堝繀椤诲叏閮ㄥ畬鎴愭嫞閫夛級
+ var validationResult = await ValidateEmptyPalletRemoval(orderNo, palletCode);
+ if (!validationResult.IsValid)
+ return WebResponseContent.Instance.Error(validationResult.ErrorMessage);
+
+ var completedLocks = validationResult.Data;
+
+ // 娓呯悊閿佸畾璁板綍锛堟爣璁颁负宸插畬鎴愶級
+ await CleanupCompletedLocks(completedLocks);
+
+ // 鏇存柊鐩稿叧璁㈠崟鐘舵��
+ await UpdateOrderStatusAfterPalletRemoval(orderNo);
+
+ // 璁板綍鎿嶄綔鍘嗗彶
+ // await RecordEmptyPalletRemoval(orderNo, palletCode, completedLocks);
+
+ _unitOfWorkManage.CommitTran();
+
+ return WebResponseContent.Instance.OK("鍙栬蛋绌虹鎴愬姛");
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"鍙栬蛋绌虹澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"鍙栬蛋绌虹澶辫触锛歿ex.Message}");
+ }
+ }
+
+ /// <summary>
+ /// 楠岃瘉绌虹鍙栬蛋鏉′欢
+ /// </summary>
+ private async Task<ValidationResult<List<Dt_OutStockLockInfo>>> ValidateEmptyPalletRemoval(string orderNo, string palletCode)
+ {
+ // 鑾峰彇鎵樼洏鐨勬墍鏈夐攣瀹氳褰�
+ var lockInfos = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
+ .ToListAsync();
+
+ if (!lockInfos.Any())
+ return ValidationResult<List<Dt_OutStockLockInfo>>.Error("璇ユ墭鐩樻病鏈夐攣瀹氳褰�");
+
+ // 妫�鏌ユ槸鍚︽湁鏈畬鎴愮殑閿佸畾璁板綍
+ var unfinishedLocks = lockInfos.Where(x =>
+ x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� ||
+ x.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�).ToList();
+
+ if (unfinishedLocks.Any())
+ {
+ var unfinishedCount = unfinishedLocks.Count;
+ var unfinishedQty = unfinishedLocks.Sum(x => x.AssignQuantity - x.PickedQty);
+ return ValidationResult<List<Dt_OutStockLockInfo>>.Error(
+ $"鎵樼洏杩樻湁{unfinishedCount}鏉℃湭瀹屾垚璁板綍锛屽墿浣欐暟閲弡unfinishedQty}锛屼笉鑳藉彇璧扮┖绠�");
+ }
+
+ // 鑾峰彇宸插畬鎴愮殑閿佸畾璁板綍
+ var completedLocks = lockInfos.Where(x =>
+ x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�).ToList();
+
+ if (!completedLocks.Any())
+ return ValidationResult<List<Dt_OutStockLockInfo>>.Error("璇ユ墭鐩樻病鏈夊凡瀹屾垚鎷i�夌殑璁板綍");
+
+ return ValidationResult<List<Dt_OutStockLockInfo>>.Success(completedLocks);
+ }
+
+ /// <summary>
+ /// 娓呯悊宸插畬鎴愮殑閿佸畾璁板綍
+ /// </summary>
+ private async Task CleanupCompletedLocks(List<Dt_OutStockLockInfo> completedLocks)
+ {
+ foreach (var lockInfo in completedLocks)
+ {
+ // 鏍囪閿佸畾璁板綍涓哄凡鍙栬蛋锛堝彲浠ユ柊澧炵姸鎬佹垨鐩存帴鍒犻櫎锛屾牴鎹笟鍔¢渶姹傦級
+ // 杩欓噷鎴戜滑灏嗗叾鐘舵�佹洿鏂颁负"宸插彇璧�"锛屽苟璁板綍鍙栬蛋鏃堕棿
+ lockInfo.Status = (int)OutLockStockStatusEnum.宸插彇璧�;
+ lockInfo.Operator = App.User.UserName;
+ await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+ // 鍚屾椂娓呯悊瀵瑰簲鐨勫簱瀛樿褰曠姸鎬�
+ await CleanupStockInfo(lockInfo);
+ }
+ }
+
+ /// <summary>
+ /// 娓呯悊搴撳瓨淇℃伅
+ /// </summary>
+ private async Task CleanupStockInfo(Dt_OutStockLockInfo lockInfo)
+ {
+ var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .FirstAsync(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId);
+
+ if (stockDetail != null)
+ {
+ // 濡傛灉搴撳瓨宸茬粡鍑哄簱瀹屾垚锛屾爣璁颁负宸叉竻鐞�
+ if (stockDetail.Status == (int)StockStatusEmun.鍑哄簱瀹屾垚)
+ {
+ stockDetail.Status = (int)StockStatusEmun.宸叉竻鐞�;
+ await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+ }
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊璁㈠崟鐘舵��
+ /// </summary>
+ private async Task UpdateOrderStatusAfterPalletRemoval(string orderNo)
+ {
+ // 妫�鏌ヨ鍗曟槸鍚︽墍鏈夋墭鐩橀兘宸插畬鎴�
+ var allLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo)
+ .ToListAsync();
+
+ var unfinishedPallets = allLocks
+ .GroupBy(x => x.PalletCode)
+ .Where(g => g.Any(x => x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� ||
+ x.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�))
+ .ToList();
+
+ // 濡傛灉娌℃湁鏈畬鎴愮殑鎵樼洏锛屾洿鏂拌鍗曠姸鎬佷负鍑哄簱瀹屾垚
+ if (!unfinishedPallets.Any())
+ {
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => new Dt_OutboundOrder
+ {
+ OrderStatus = (int)OutOrderStatusEnum.鍑哄簱瀹屾垚,
+ })
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+ }
+ }
+
+ /// <summary>
+ /// 璁板綍绌虹鍙栬蛋鍘嗗彶
+ /// </summary>
+ private async Task RecordEmptyPalletRemoval(string orderNo, string palletCode, List<Dt_OutStockLockInfo> completedLocks)
+ {
+ var removalRecord = new Dt_EmptyPalletRemoval
+ {
+ OrderNo = orderNo,
+ PalletCode = palletCode,
+ RemovalTime = DateTime.Now,
+ Operator = App.User.UserName,
+ CompletedItemsCount = completedLocks.Count,
+ TotalPickedQuantity = completedLocks.Sum(x => x.PickedQty)
+ };
+
+ await Db.Insertable(removalRecord).ExecuteCommandAsync();
+ }
+
+ #endregion
+
+ #region 杈呭姪鏂规硶
+
+ private string GetPalletStatusText(PalletStatusEnum status)
+ {
+ return status switch
+ {
+ PalletStatusEnum.鏈紑濮� => "鏈紑濮�",
+ PalletStatusEnum.鎷i�変腑 => "鎷i�変腑",
+ PalletStatusEnum.宸插畬鎴� => "宸插畬鎴�",
+ PalletStatusEnum.鏃犱换鍔� => "鏃犱换鍔�",
+ _ => "鏈煡"
+ };
+ }
+
+ #endregion
+ #region 鍒嗘壒鍒嗘嫞
+
+ /// <summary>
+ /// 鍒嗘壒鍒嗘嫞纭
+ /// </summary>
+ public async Task<WebResponseContent> ConfirmBatchPicking(string orderNo, string palletCode, string barcode)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+
+ // 1. 楠岃瘉鍒嗘嫞璇锋眰
+ var validationResult = await ValidatePickingRequest(orderNo, palletCode, barcode);
+ if (!validationResult.IsValid)
+ return WebResponseContent.Instance.Error(validationResult.ErrorMessage);
+
+ var (lockInfo, orderDetail, stockDetail, batch) = validationResult.Data;
+
+ // 浣跨敤閿佸畾淇℃伅鐨勫垎閰嶆暟閲忎綔涓哄疄闄呭垎鎷f暟閲�
+ var actualPickedQty = lockInfo.AssignQuantity;
+
+ // 2. 鎵ц鍒嗘嫞閫昏緫
+ var pickingResult = await ExecutePickingLogic(lockInfo, orderDetail, stockDetail, actualPickedQty);
+
+ // 3. 鏇存柊鎵规鍜岃鍗曟暟鎹�
+ await UpdateBatchAndOrderData(batch, orderDetail, actualPickedQty, orderNo);
+
+ // 4. 璁板綍鎷i�夊巻鍙�
+ await RecordPickingHistory(pickingResult, orderNo, palletCode);
+
+ _unitOfWorkManage.CommitTran();
+
+ return WebResponseContent.Instance.OK("鍒嗘嫞鎴愬姛", new
+ {
+ PickedQuantity = actualPickedQty,
+ Barcode = barcode,
+ MaterialCode = lockInfo.MaterielCode
+ });
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"鍒嗘嫞澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Barcode: {barcode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"鍒嗘嫞澶辫触锛歿ex.Message}");
+ }
+ }
+ /// <summary>
+ /// 鍙栨秷鍒嗘嫞
+ /// </summary>
+ public async Task<WebResponseContent> CancelPicking(string orderNo, string palletCode, string barcode)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+
+ // 鏌ユ壘鍒嗘嫞璁板綍
+ var pickingRecord = await Db.Queryable<Dt_PickingRecord>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ x.Barcode == barcode &&
+ !x.IsCancelled)
+ .OrderByDescending(x => x.PickTime)
+ .FirstAsync();
+
+ if (pickingRecord == null)
+ return WebResponseContent.Instance.Error("鏈壘鍒板垎鎷h褰�");
+
+ // 鎭㈠閿佸畾淇℃伅鍜屽簱瀛�
+ await RevertPickingData(pickingRecord);
+
+ //鏇存柊鎵规鍜岃鍗曟暟鎹�
+ await RevertBatchAndOrderData(pickingRecord);
+
+ // 鏍囪鍒嗘嫞璁板綍涓哄凡鍙栨秷
+ pickingRecord.IsCancelled = true;
+ pickingRecord.CancelTime = DateTime.Now;
+ pickingRecord.CancelOperator = App.User.UserName;
+ await Db.Updateable(pickingRecord).ExecuteCommandAsync();
+
+ _unitOfWorkManage.CommitTran();
+
+ return WebResponseContent.Instance.OK("鍙栨秷鍒嗘嫞鎴愬姛");
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"鍙栨秷鍒嗘嫞澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"鍙栨秷鍒嗘嫞澶辫触锛歿ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 鎵嬪姩鎷嗗寘
+
+ /// <summary>
+ /// 鎵嬪姩鎷嗗寘
+ /// </summary>
+ public async Task<WebResponseContent> ManualSplitPackage(string orderNo, string palletCode, string originalBarcode, decimal splitQuantity)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+
+ // 楠岃瘉鎷嗗寘璇锋眰
+ var validationResult = await ValidateSplitRequest(orderNo, palletCode, originalBarcode, splitQuantity);
+ if (!validationResult.IsValid)
+ return WebResponseContent.Instance.Error(validationResult.ErrorMessage);
+
+ var (lockInfo, stockDetail) = validationResult.Data;
+
+ // . 鎵ц鎷嗗寘閫昏緫
+ var splitResult = await ExecuteSplitLogic(lockInfo, stockDetail, splitQuantity, palletCode);
+
+ _unitOfWorkManage.CommitTran();
+
+ return WebResponseContent.Instance.OK("鎵嬪姩鎷嗗寘鎴愬姛", new
+ {
+ NewBarcode = splitResult.NewBarcode,
+ OriginalBarcode = originalBarcode,
+ SplitQuantity = splitQuantity
+ });
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"鎵嬪姩鎷嗗寘澶辫触 - OrderNo: {orderNo}, Barcode: {originalBarcode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"鎵嬪姩鎷嗗寘澶辫触锛歿ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 鍙栨秷鎷嗗寘
+
+ #region 鍙栨秷鎷嗗寘 - 淇鐗堟湰
+
+ /// <summary>
+ /// 鍙栨秷鎷嗗寘 - 鏀寔澶氭鎷嗗寘鐨勬儏鍐�
+ /// </summary>
+ public async Task<WebResponseContent> CancelSplitPackage(string orderNo, string palletCode, string newBarcode)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+
+ // 1. 鏌ユ壘鎷嗗寘璁板綍骞堕獙璇�
+ var validationResult = await ValidateCancelSplitRequest(orderNo, palletCode, newBarcode);
+ if (!validationResult.IsValid)
+ return WebResponseContent.Instance.Error(validationResult.ErrorMessage);
+
+ var (splitRecord, newLockInfo, newStockDetail) = validationResult.Data;
+
+ // 2. 鏌ユ壘鍘熷閿佸畾淇℃伅
+ var originalLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .FirstAsync(x => x.Id == splitRecord.OutStockLockInfoId);
+
+ // 3. 妫�鏌ヨ鏉$爜鏄惁琚啀娆℃媶鍖�
+ var childSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+ .Where(x => x.OriginalBarcode == newBarcode && !x.IsReverted)
+ .ToListAsync();
+
+ if (childSplitRecords.Any())
+ {
+ return WebResponseContent.Instance.Error("璇ユ潯鐮佸凡琚啀娆℃媶鍖咃紝璇峰厛鍙栨秷鍚庣画鐨勬媶鍖呮搷浣�");
+ }
+
+ // 4. 鎵ц鍙栨秷鎷嗗寘閫昏緫
+ await ExecuteCancelSplitLogic(splitRecord, originalLockInfo, newLockInfo, newStockDetail);
+
+ _unitOfWorkManage.CommitTran();
+
+ return WebResponseContent.Instance.OK("鍙栨秷鎷嗗寘鎴愬姛");
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"鍙栨秷鎷嗗寘澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Barcode: {newBarcode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"鍙栨秷鎷嗗寘澶辫触锛歿ex.Message}");
+ }
+ }
+
+ /// <summary>
+ /// 鎵ц鍙栨秷鎷嗗寘閫昏緫 - 淇鐗堟湰
+ /// </summary>
+ private async Task ExecuteCancelSplitLogic(Dt_SplitPackageRecord splitRecord,
+ Dt_OutStockLockInfo originalLockInfo, Dt_OutStockLockInfo newLockInfo,
+ Dt_StockInfoDetail newStockDetail)
+ {
+ // 1. 鎭㈠鍘熼攣瀹氫俊鎭�
+ // 娉ㄦ剰锛氳繖閲岄渶瑕佺疮鍔狅紝鑰屼笉鏄畝鍗曠殑璧嬪�硷紝鍥犱负鍙兘鏈夊娆℃媶鍖�
+ originalLockInfo.AssignQuantity += splitRecord.SplitQty;
+ originalLockInfo.OrderQuantity += splitRecord.SplitQty;
+
+ // 濡傛灉鍘熼攣瀹氫俊鎭殑鐘舵�佹槸鎷i�夊畬鎴愶紝闇�瑕侀噸鏂拌缃负鍑哄簱涓�
+ if (originalLockInfo.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ {
+ originalLockInfo.Status = (int)OutLockStockStatusEnum.鍑哄簱涓�;
+ }
+
+ await _outStockLockInfoService.Db.Updateable(originalLockInfo).ExecuteCommandAsync();
+
+ // 2. 鎭㈠鍘熷簱瀛樻槑缁�
+ var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .FirstAsync(x => x.Barcode == splitRecord.OriginalBarcode && x.StockId == splitRecord.StockId);
+
+ originalStock.StockQuantity += splitRecord.SplitQty;
+
+ // 濡傛灉鍘熷簱瀛樼姸鎬佹槸鍑哄簱瀹屾垚锛岄渶瑕侀噸鏂拌缃负鍑哄簱閿佸畾
+ if (originalStock.Status == (int)StockStatusEmun.鍑哄簱瀹屾垚)
+ {
+ originalStock.Status = (int)StockStatusEmun.鍑哄簱閿佸畾;
+ }
+
+ await _stockInfoDetailService.Db.Updateable(originalStock).ExecuteCommandAsync();
+
+ // 3. 鍒犻櫎鏂伴攣瀹氫俊鎭�
+ await _outStockLockInfoService.Db.Deleteable<Dt_OutStockLockInfo>()
+ .Where(x => x.Id == newLockInfo.Id)
+ .ExecuteCommandAsync();
+
+ // 4. 鍒犻櫎鏂板簱瀛樻槑缁�
+ await _stockInfoDetailService.Db.Deleteable<Dt_StockInfoDetail>()
+ .Where(x => x.Barcode == newLockInfo.CurrentBarcode)
+ .ExecuteCommandAsync();
+
+ // 5. 鏍囪鎷嗗寘璁板綍涓哄凡鎾ら攢
+ splitRecord.IsReverted = true;
+ splitRecord.RevertTime = DateTime.Now;
+ splitRecord.RevertOperator = App.User.UserName;
+ await _splitPackageService.Db.Updateable(splitRecord).ExecuteCommandAsync();
+
+ // 6. 妫�鏌ュ苟鏇存柊鎵规鍜岃鍗曠姸鎬�
+ await CheckAndUpdateBatchStatus(originalLockInfo.BatchNo);
+ await CheckAndUpdateOrderStatus(originalLockInfo.OrderNo);
+ }
+
+ /// <summary>
+ /// 楠岃瘉鍙栨秷鎷嗗寘璇锋眰 - 澧炲己鐗堟湰
+ /// </summary>
+ private async Task<ValidationResult<(Dt_SplitPackageRecord, Dt_OutStockLockInfo, Dt_StockInfoDetail)>> ValidateCancelSplitRequest(
+ string orderNo, string palletCode, string newBarcode)
+ {
+ // 鏌ユ壘鎷嗗寘璁板綍
+ var splitRecord = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+ .Where(x => x.NewBarcode == newBarcode &&
+ x.OrderNo == orderNo &&
+ !x.IsReverted)
+ .FirstAsync();
+
+ if (splitRecord == null)
+ return ValidationResult<(Dt_SplitPackageRecord, Dt_OutStockLockInfo, Dt_StockInfoDetail)>.Error("鏈壘鍒版媶鍖呰褰�");
+
+ // 鏌ユ壘鏂伴攣瀹氫俊鎭�
+ var newLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.CurrentBarcode == newBarcode &&
+ x.PalletCode == palletCode &&
+ x.OrderNo == orderNo)
+ .FirstAsync();
+
+ if (newLockInfo == null)
+ return ValidationResult<(Dt_SplitPackageRecord, Dt_OutStockLockInfo, Dt_StockInfoDetail)>.Error("鏈壘鍒版柊閿佸畾淇℃伅");
+
+ // 妫�鏌ユ柊鏉$爜鏄惁宸茶鍒嗘嫞
+ var pickingRecord = await Db.Queryable<Dt_PickingRecord>()
+ .Where(x => x.Barcode == newBarcode && !x.IsCancelled)
+ .FirstAsync();
+
+ if (pickingRecord != null)
+ return ValidationResult<(Dt_SplitPackageRecord, Dt_OutStockLockInfo, Dt_StockInfoDetail)>.Error("璇ユ潯鐮佸凡琚垎鎷o紝鏃犳硶鍙栨秷鎷嗗寘");
+
+ // 妫�鏌ユ柊鏉$爜鏄惁琚啀娆℃媶鍖�
+ var childSplitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+ .Where(x => x.OriginalBarcode == newBarcode && !x.IsReverted)
+ .ToListAsync();
+
+ if (childSplitRecords.Any())
+ {
+ var childBarcodes = string.Join(", ", childSplitRecords.Select(x => x.NewBarcode));
+ return ValidationResult<(Dt_SplitPackageRecord, Dt_OutStockLockInfo, Dt_StockInfoDetail)>.Error(
+ $"璇ユ潯鐮佸凡琚啀娆℃媶鍖咃紝鐢熸垚鐨勬柊鏉$爜锛歿childBarcodes}锛岃鍏堝彇娑堝悗缁媶鍖�");
+ }
+
+ var newStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .FirstAsync(x => x.Barcode == newBarcode);
+
+ return ValidationResult<(Dt_SplitPackageRecord, Dt_OutStockLockInfo, Dt_StockInfoDetail)>.Success((splitRecord, newLockInfo, newStockDetail));
+ }
+
+ #endregion
+
+ #region 鎵归噺鍙栨秷鎷嗗寘閾�
+
+ /// <summary>
+ /// 鎵归噺鍙栨秷鎷嗗寘閾� - 鍙栨秷鏌愪釜鏉$爜鍙婂叾鎵�鏈夊悗缁媶鍖�
+ /// </summary>
+ public async Task<WebResponseContent> CancelSplitPackageChain(string orderNo, string palletCode, string startBarcode)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+
+ // 1. 鏌ユ壘鎵�鏈夌浉鍏崇殑鎷嗗寘璁板綍锛堝舰鎴愭媶鍖呴摼锛�
+ var splitChain = await GetSplitPackageChain(orderNo, startBarcode);
+
+ if (!splitChain.Any())
+ return WebResponseContent.Instance.Error("鏈壘鍒版媶鍖呰褰�");
+
+ // 2. 鎸夋媶鍖呴『搴忓�掑簭鍙栨秷锛堜粠鏈�鏂扮殑寮�濮嬪彇娑堬級
+ var reversedChain = splitChain.OrderByDescending(x => x.SplitTime).ToList();
+
+ foreach (var splitRecord in reversedChain)
+ {
+ await CancelSingleSplitPackage(splitRecord, palletCode);
+ }
+
+ _unitOfWorkManage.CommitTran();
+
+ return WebResponseContent.Instance.OK($"鎴愬姛鍙栨秷鎷嗗寘閾撅紝鍏眥reversedChain.Count}娆℃媶鍖呮搷浣�");
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"鍙栨秷鎷嗗寘閾惧け璐� - OrderNo: {orderNo}, StartBarcode: {startBarcode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"鍙栨秷鎷嗗寘閾惧け璐ワ細{ex.Message}");
+ }
+ }
+
+ /// <summary>
+ /// 鑾峰彇鎷嗗寘閾� - 鏌ユ壘鏌愪釜鏉$爜鐨勬墍鏈夋媶鍖呰褰曪紙鍖呮嫭鍚庣画鎷嗗寘锛�
+ /// </summary>
+ public async Task<List<Dt_SplitPackageRecord>> GetSplitPackageChain(string orderNo, string startBarcode)
+ {
+ var allSplitRecords = new List<Dt_SplitPackageRecord>();
+ var visitedBarcodes = new HashSet<string>(); // 闃叉寰幆寮曠敤
+
+ // 浣跨敤闃熷垪杩涜骞垮害浼樺厛鎼滅储
+ var queue = new Queue<string>();
+ queue.Enqueue(startBarcode);
+ visitedBarcodes.Add(startBarcode);
+
+ while (queue.Count > 0)
+ {
+ var currentBarcode = queue.Dequeue();
+
+ // 鏌ユ壘浠ュ綋鍓嶆潯鐮佷负鍘熸潯鐮佺殑鎵�鏈夋媶鍖呰褰�
+ var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+ .Where(x => x.OriginalBarcode == currentBarcode &&
+ x.OrderNo == orderNo &&
+ !x.IsReverted)
+ .ToListAsync();
+
+ foreach (var record in splitRecords)
+ {
+ // 閬垮厤閲嶅澶勭悊
+ if (!visitedBarcodes.Contains(record.NewBarcode))
+ {
+ allSplitRecords.Add(record);
+ queue.Enqueue(record.NewBarcode);
+ visitedBarcodes.Add(record.NewBarcode);
+ }
+ }
+ }
+
+ return allSplitRecords;
+ }
+
+ /// <summary>
+ /// 鍙栨秷鍗曚釜鎷嗗寘璁板綍
+ /// </summary>
+ private async Task CancelSingleSplitPackage(Dt_SplitPackageRecord splitRecord, string palletCode)
+ {
+ // 鏌ユ壘鐩稿叧鏁版嵁
+ var newLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.CurrentBarcode == splitRecord.NewBarcode &&
+ x.PalletCode == palletCode)
+ .FirstAsync();
+
+ var newStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .FirstAsync(x => x.Barcode == splitRecord.NewBarcode);
+
+ var originalLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .FirstAsync(x => x.Id == splitRecord.OutStockLockInfoId);
+
+ // 鎵ц鍙栨秷閫昏緫
+ await ExecuteCancelSplitLogic(splitRecord, originalLockInfo, newLockInfo, newStockDetail);
+ }
+ #endregion
+
+ #region 鎷嗗寘淇℃伅鏌ヨ澧炲己
+
+ /// <summary>
+ /// 鑾峰彇鎷嗗寘閾句俊鎭�
+ /// </summary>
+ public async Task<WebResponseContent> GetSplitPackageChainInfo(string orderNo, string barcode)
+ {
+ try
+ {
+ var splitChain = await GetSplitPackageChain(orderNo, barcode);
+
+ var chainInfo = new SplitPackageChainInfoDto
+ {
+ OriginalBarcode = barcode,
+ TotalSplitTimes = splitChain.Count,
+ SplitChain = splitChain.Select(x => new SplitChainItemDto
+ {
+ SplitTime = x.SplitTime,
+ OriginalBarcode = x.OriginalBarcode,
+ NewBarcode = x.NewBarcode,
+ SplitQuantity = x.SplitQty,
+ Operator = x.Operator,
+ IsReverted = x.IsReverted
+ }).ToList()
+ };
+
+ return WebResponseContent.Instance.OK("鑾峰彇鎴愬姛", chainInfo);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"鑾峰彇鎷嗗寘閾句俊鎭け璐� - OrderNo: {orderNo}, Barcode: {barcode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error("鑾峰彇鎷嗗寘閾句俊鎭け璐�");
+ }
+ }
+
+
+ /// <summary>
+ /// 鏌ユ壘鏍规潯鐮�
+ /// </summary>
+ public async Task<string> FindRootBarcode(string orderNo, string startBarcode)
+ {
+ var currentBarcode = startBarcode;
+ var visited = new HashSet<string>();
+
+ while (!string.IsNullOrEmpty(currentBarcode) && !visited.Contains(currentBarcode))
+ {
+ visited.Add(currentBarcode);
+
+ // 鏌ユ壘褰撳墠鏉$爜鏄惁鏄敱鍏朵粬鏉$爜鎷嗗寘鑰屾潵
+ var parentRecord = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+ .Where(x => x.NewBarcode == currentBarcode &&
+ x.OrderNo == orderNo &&
+ !x.IsReverted)
+ .FirstAsync();
+
+ if (parentRecord == null)
+ {
+ // 娌℃湁鐖剁骇鎷嗗寘璁板綍锛岃鏄庤繖鏄牴鏉$爜
+ return currentBarcode;
+ }
+
+ currentBarcode = parentRecord.OriginalBarcode;
+ }
+
+ // 濡傛灉鍑虹幇寰幆寮曠敤锛岃繑鍥炶捣濮嬫潯鐮�
+ return startBarcode;
+ }
+ #endregion
+
+ #region 鏇存柊鎵规鐘舵�佹鏌�
+
+ /// <summary>
+ /// 妫�鏌ュ苟鏇存柊鎵规鐘舵��
+ /// </summary>
+ private async Task CheckAndUpdateBatchStatus(string batchNo)
+ {
+ var batch = await _outboundBatchRepository.Db.Queryable<Dt_OutboundBatch>()
+ .FirstAsync(x => x.BatchNo == batchNo);
+
+ if (batch != null)
+ {
+ // 閲嶆柊璁$畻鎵规瀹屾垚鏁伴噺
+ var batchLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.BatchNo == batchNo)
+ .ToListAsync();
+
+ var completedQuantity = batchLocks.Where(x => x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ .Sum(x => x.PickedQty);
+
+ batch.CompletedQuantity = completedQuantity;
+
+ // 鏇存柊鎵规鐘舵��
+ if (batch.CompletedQuantity >= batch.BatchQuantity)
+ {
+ batch.BatchStatus = (int)BatchStatusEnum.宸插畬鎴�;
+ }
+ else if (batch.CompletedQuantity > 0)
+ {
+ batch.BatchStatus = (int)BatchStatusEnum.鎵ц涓�;
+ }
+ else
+ {
+ batch.BatchStatus = (int)BatchStatusEnum.鍒嗛厤涓�;
+ }
+
+ await _outboundBatchRepository.Db.Updateable(batch).ExecuteCommandAsync();
+ }
+ }
+
+ #endregion
+
+ #region DTO绫�
+
+
+
+ public class SplitPackageChainInfoDto
+ {
+ public string OriginalBarcode { get; set; }
+ public string RootBarcode { get; set; } // 鏂板锛氭牴鏉$爜
+ public int TotalSplitTimes { get; set; }
+ public string ChainType { get; set; } // "root" 鎴� "branch"
+ public List<SplitChainItemDto> SplitChain { get; set; }
+ }
+
+ public class SplitChainItemDto
+ {
+ public DateTime SplitTime { get; set; }
+ public string OriginalBarcode { get; set; }
+ public string NewBarcode { get; set; }
+ public decimal SplitQuantity { get; set; }
+ public string Operator { get; set; }
+ public bool IsReverted { get; set; }
+ }
+
+ #endregion
+
+ #endregion
+
+ #region 鍒嗘壒鍥炲簱
+
+ /// <summary>
+ /// 鍒嗘壒鍥炲簱 - 閲婃斁鏈嫞閫夌殑搴撳瓨
+ /// </summary>
+ public async Task<WebResponseContent> BatchReturnStock(string orderNo, string palletCode)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+
+ // 鏌ユ壘鎵樼洏涓婃湭瀹屾垚鐨勯攣瀹氳褰�
+ var unfinishedLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+ .ToListAsync();
+
+ if (!unfinishedLocks.Any())
+ return WebResponseContent.Instance.Error("璇ユ墭鐩樻病鏈夋湭瀹屾垚鐨勯攣瀹氳褰�");
+
+ // 鎸夋壒娆″垎缁勫鐞�
+ var batchGroups = unfinishedLocks.GroupBy(x => x.BatchNo);
+
+ foreach (var batchGroup in batchGroups)
+ {
+ var batchNo = batchGroup.Key;
+ var batchLocks = batchGroup.ToList();
+
+ // 閲婃斁搴撳瓨鍜岄攣瀹氳褰�
+ foreach (var lockInfo in batchLocks)
+ {
+ await ReleaseLockAndStock(lockInfo);
+ }
+
+ // 鏇存柊鎵规鐘舵��
+ await UpdateBatchStatusForReturn(batchNo, batchLocks);
+
+ // 鏇存柊璁㈠崟鏄庣粏鐨勫凡鍒嗛厤鏁伴噺
+ await UpdateOrderDetailAfterReturn(batchLocks);
+ }
+
+ _unitOfWorkManage.CommitTran();
+
+ return WebResponseContent.Instance.OK("鍒嗘壒鍥炲簱鎴愬姛");
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"鍒嗘壒鍥炲簱澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"鍒嗘壒鍥炲簱澶辫触锛歿ex.Message}");
+ }
+ }
+
+ #endregion
+
+ #region 楠岃瘉鏂规硶
+ private async Task<ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail, Dt_OutboundBatch)>> ValidatePickingRequest(
+ string orderNo, string palletCode, string barcode)
+ {
+ // 鏌ユ壘閿佸畾淇℃伅
+ var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ x.CurrentBarcode == barcode &&
+ x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+ .FirstAsync();
+
+ if (lockInfo == null)
+ return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail, Dt_OutboundBatch)>.Error("鏈壘鍒版湁鏁堢殑閿佸畾淇℃伅");
+
+ // 妫�鏌ユ槸鍚﹀凡缁忓垎鎷e畬鎴�
+ if (lockInfo.PickedQty >= lockInfo.AssignQuantity)
+ return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail, Dt_OutboundBatch)>.Error("璇ユ潯鐮佸凡鍒嗘嫞瀹屾垚");
+
+ // 鑾峰彇鍏宠仈鏁版嵁
+ var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .FirstAsync(x => x.Id == lockInfo.OrderDetailId);
+
+ var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .FirstAsync(x => x.Barcode == barcode && x.StockId == lockInfo.StockId);
+
+ // 楠岃瘉搴撳瓨鏁伴噺
+ if (stockDetail.StockQuantity < lockInfo.AssignQuantity)
+ return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail, Dt_OutboundBatch)>.Error(
+ $"搴撳瓨鏁伴噺涓嶈冻锛岄渶瑕侊細{lockInfo.AssignQuantity}锛屽疄闄咃細{stockDetail.StockQuantity}");
+
+ var batch = await _outboundBatchRepository.Db.Queryable<Dt_OutboundBatch>()
+ .FirstAsync(x => x.BatchNo == lockInfo.OutboundBatchNo);
+
+ return ValidationResult<(Dt_OutStockLockInfo, Dt_OutboundOrderDetail, Dt_StockInfoDetail, Dt_OutboundBatch)>.Success((lockInfo, orderDetail, stockDetail, batch));
+ }
+
+ private async Task<ValidationResult<(Dt_OutStockLockInfo, Dt_StockInfoDetail)>> ValidateSplitRequest(
+ string orderNo, string palletCode, string originalBarcode, decimal splitQuantity)
+ {
+ var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode == palletCode &&
+ x.CurrentBarcode == originalBarcode &&
+ x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+ .FirstAsync();
+
+ if (lockInfo == null)
+ return ValidationResult<(Dt_OutStockLockInfo, Dt_StockInfoDetail)>.Error("鏈壘鍒版湁鏁堢殑閿佸畾淇℃伅");
+
+ var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .FirstAsync(x => x.Barcode == originalBarcode && x.StockId == lockInfo.StockId);
+
+ if (stockDetail.StockQuantity < splitQuantity)
+ return ValidationResult<(Dt_OutStockLockInfo, Dt_StockInfoDetail)>.Error("鎷嗗寘鏁伴噺涓嶈兘澶т簬搴撳瓨鏁伴噺");
+
+ if (lockInfo.AssignQuantity - lockInfo.PickedQty < splitQuantity)
+ return ValidationResult<(Dt_OutStockLockInfo, Dt_StockInfoDetail)>.Error("鎷嗗寘鏁伴噺涓嶈兘澶т簬鏈嫞閫夋暟閲�");
+
+ return ValidationResult<(Dt_OutStockLockInfo, Dt_StockInfoDetail)>.Success((lockInfo, stockDetail));
+ }
+
+ #endregion
+
+ #region 鏍稿績閫昏緫鏂规硶
+
+ private async Task<PickingResult> ExecutePickingLogic(
+ Dt_OutStockLockInfo lockInfo, Dt_OutboundOrderDetail orderDetail,
+ Dt_StockInfoDetail stockDetail, decimal actualPickedQty)
+ {
+ // 鏇存柊閿佸畾淇℃伅
+ lockInfo.PickedQty += actualPickedQty;
+ if (lockInfo.PickedQty >= lockInfo.AssignQuantity)
+ {
+ lockInfo.Status = (int)OutLockStockStatusEnum.鎷i�夊畬鎴�;
+ }
+ await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+ // 鏇存柊搴撳瓨
+ stockDetail.StockQuantity -= actualPickedQty;
+ stockDetail.OutboundQuantity += actualPickedQty;
+
+ if (stockDetail.StockQuantity <= 0)
+ {
+ stockDetail.Status = (int)StockStatusEmun.鍑哄簱瀹屾垚;
+ }
+ await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+
+ return new PickingResult
+ {
+ FinalLockInfo = lockInfo,
+ ActualPickedQty = actualPickedQty
+ };
+ }
+
+ private async Task<RevertPickingResult> RevertPickingData(Dt_PickingRecord pickingRecord)
+ {
+ // 鎭㈠閿佸畾淇℃伅
+ var lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .FirstAsync(x => x.Id == pickingRecord.OutStockLockId);
+
+ lockInfo.PickedQty -= pickingRecord.PickQuantity;
+ lockInfo.Status = (int)OutLockStockStatusEnum.鍑哄簱涓�;
+ await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+ // 鎭㈠搴撳瓨
+ var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .FirstAsync(x => x.Barcode == pickingRecord.Barcode);
+
+ stockDetail.StockQuantity += pickingRecord.PickQuantity;
+ stockDetail.OutboundQuantity -= pickingRecord.PickQuantity;
+ stockDetail.Status = (int)StockStatusEmun.鍑哄簱閿佸畾;
+ await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+
+ return new RevertPickingResult
+ {
+ LockInfo = lockInfo,
+ StockDetail = stockDetail
+ };
+ }
+
+ private async Task<SplitResultDto> ExecuteSplitLogic(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail,
+ decimal splitQuantity, string palletCode)
+ {
+ // 鐢熸垚鏂版潯鐮�
+ string newBarcode = await GenerateNewBarcode();
+
+ // 鍒涘缓鏂板簱瀛樻槑缁�
+ var newStockDetail = new Dt_StockInfoDetail
+ {
+ StockId = stockDetail.StockId,
+ MaterielCode = stockDetail.MaterielCode,
+ OrderNo = stockDetail.OrderNo,
+ BatchNo = stockDetail.BatchNo,
+ StockQuantity = splitQuantity,
+ OutboundQuantity = 0,
+ Barcode = newBarcode,
+ Status = (int)StockStatusEmun.鍑哄簱閿佸畾,
+ SupplyCode = stockDetail.SupplyCode,
+ Unit = stockDetail.Unit,
+ BarcodeQty=stockDetail.BarcodeQty,
+ BarcodeUnit=stockDetail.BarcodeUnit,
+ BusinessType=stockDetail.BusinessType,
+ InboundOrderRowNo=stockDetail.InboundOrderRowNo,
+
+
+ };
+ await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync();
+
+ // 鏇存柊鍘熷簱瀛樻槑缁�
+ stockDetail.StockQuantity -= splitQuantity;
+ await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+
+
+ var newLockInfo = new Dt_OutStockLockInfo
+ {
+ OrderNo = lockInfo.OrderNo,
+ OrderDetailId = lockInfo.OrderDetailId,
+ BatchNo = lockInfo.BatchNo,
+ MaterielCode = lockInfo.MaterielCode,
+ MaterielName = lockInfo.MaterielName,
+ StockId = lockInfo.StockId,
+ OrderQuantity = splitQuantity,
+ //OriginalQuantity = quantity,
+ AssignQuantity = splitQuantity,
+ PickedQty = 0,
+ LocationCode = lockInfo.LocationCode,
+ PalletCode = lockInfo.PalletCode,
+ TaskNum = lockInfo.TaskNum,
+ Status = (int)OutLockStockStatusEnum.鍑哄簱涓�,
+ Unit = lockInfo.Unit,
+ SupplyCode = lockInfo.SupplyCode,
+ OrderType = lockInfo.OrderType,
+ CurrentBarcode = newBarcode,
+ // OriginalLockQuantity = quantity,
+ IsSplitted = 1,
+ ParentLockId = lockInfo.Id,
+ Operator = App.User.UserName,
+ FactoryArea = lockInfo.FactoryArea,
+ lineNo = lockInfo.lineNo,
+ WarehouseCode = lockInfo.WarehouseCode,
+ BarcodeQty = lockInfo.BarcodeQty,
+ BarcodeUnit = lockInfo.BarcodeUnit,
+
+ };
+
+ await _outStockLockInfoService.Db.Insertable(newLockInfo).ExecuteCommandAsync();
+
+ // 鏇存柊鍘熼攣瀹氫俊鎭�
+ lockInfo.AssignQuantity -= splitQuantity;
+ lockInfo.OrderQuantity -= splitQuantity;
+ await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+ // 璁板綍鎷嗗寘鍘嗗彶
+ await RecordSplitHistory(lockInfo, stockDetail, splitQuantity, newBarcode);
+
+ return new SplitResultDto { NewBarcode = newBarcode };
+ }
+
+ private async Task ExecuteCancelSplitLogic(Dt_SplitPackageRecord splitRecord, Dt_OutStockLockInfo newLockInfo, Dt_StockInfoDetail newStockDetail)
+ {
+ // 鎭㈠鍘熷簱瀛�
+ var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .FirstAsync(x => x.Barcode == splitRecord.OriginalBarcode && x.StockId == splitRecord.StockId);
+
+ originalStock.StockQuantity += splitRecord.SplitQty;
+ await _stockInfoDetailService.Db.Updateable(originalStock).ExecuteCommandAsync();
+
+ // 鎭㈠鍘熼攣瀹氫俊鎭�
+ var originalLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .FirstAsync(x => x.Id == splitRecord.OutStockLockInfoId);
+
+ originalLockInfo.AssignQuantity += splitRecord.SplitQty;
+ originalLockInfo.OrderQuantity += splitRecord.SplitQty;
+ await _outStockLockInfoService.Db.Updateable(originalLockInfo).ExecuteCommandAsync();
+
+ // 鍒犻櫎鏂板簱瀛樻槑缁�
+ await _stockInfoDetailService.Db.Deleteable<Dt_StockInfoDetail>()
+ .Where(x => x.Barcode == newLockInfo.CurrentBarcode)
+ .ExecuteCommandAsync();
+
+ // 鍒犻櫎鏂伴攣瀹氫俊鎭�
+ await _outStockLockInfoService.Db.Deleteable<Dt_OutStockLockInfo>()
+ .Where(x => x.Id == newLockInfo.Id)
+ .ExecuteCommandAsync();
+
+ // 鏍囪鎷嗗寘璁板綍涓哄凡鎾ら攢
+ splitRecord.IsReverted = true;
+ splitRecord.RevertTime = DateTime.Now;
+ splitRecord.RevertOperator = App.User.UserName;
+ await _splitPackageService.Db.Updateable(splitRecord).ExecuteCommandAsync();
+ }
+
+ #endregion
+
+ #region 鏁版嵁鏇存柊鏂规硶
+
+ private async Task UpdateBatchAndOrderData(Dt_OutboundBatch batch, Dt_OutboundOrderDetail orderDetail, decimal pickedQty, string orderNo)
+ {
+ // 鏇存柊鎵规瀹屾垚鏁伴噺
+ batch.CompletedQuantity += pickedQty;
+ if (batch.CompletedQuantity >= batch.BatchQuantity)
+ {
+ batch.BatchStatus = (int)BatchStatusEnum.宸插畬鎴�;
+ }
+ await _outboundBatchRepository.Db.Updateable(batch).ExecuteCommandAsync();
+
+ // 鏇存柊璁㈠崟鏄庣粏
+ orderDetail.OverOutQuantity += pickedQty;
+ orderDetail.AllocatedQuantity -= pickedQty;
+ await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+
+ // 妫�鏌ヨ鍗曠姸鎬�
+ await CheckAndUpdateOrderStatus(orderNo);
+ }
+
+ private async Task RevertBatchAndOrderData(Dt_PickingRecord pickingRecord)
+ {
+ // 鎭㈠鎵规瀹屾垚鏁伴噺
+ var batch = await _outboundBatchRepository.Db.Queryable<Dt_OutboundBatch>()
+ .FirstAsync(x => x.BatchNo == pickingRecord.BatchNo);
+
+ batch.CompletedQuantity -= pickingRecord.PickQuantity;
+ batch.BatchStatus = (int)BatchStatusEnum.鎵ц涓�;
+ await _outboundBatchRepository.Db.Updateable(batch).ExecuteCommandAsync();
+
+ // 鎭㈠璁㈠崟鏄庣粏
+ var orderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .FirstAsync(x => x.Id == pickingRecord.OrderDetailId);
+
+ orderDetail.OverOutQuantity -= pickingRecord.PickQuantity;
+ orderDetail.AllocatedQuantity += pickingRecord.PickQuantity;
+ await _outboundOrderDetailService.Db.Updateable(orderDetail).ExecuteCommandAsync();
+
+ // 閲嶆柊妫�鏌ヨ鍗曠姸鎬�
+ await CheckAndUpdateOrderStatus(pickingRecord.OrderNo);
+ }
+
+ private async Task ReleaseLockAndStock(Dt_OutStockLockInfo lockInfo)
+ {
+ // 鎭㈠搴撳瓨鐘舵��
+ var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .FirstAsync(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId);
+
+ if (stockDetail != null)
+ {
+ stockDetail.Status = (int)StockStatusEmun.鍏ュ簱瀹屾垚;
+ await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+ }
+
+ // 鏇存柊閿佸畾璁板綍鐘舵�佷负鍥炲簱
+ lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
+ await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+ }
+
+ private async Task UpdateBatchStatusForReturn(string batchNo, List<Dt_OutStockLockInfo> returnedLocks)
+ {
+ var batch = await _outboundBatchRepository.Db.Queryable<Dt_OutboundBatch>()
+ .FirstAsync(x => x.BatchNo == batchNo);
+
+ // 璁$畻鍥炲簱鏁伴噺
+ var returnedQty = returnedLocks.Sum(x => x.AssignQuantity - x.PickedQty);
+ batch.CompletedQuantity -= returnedQty;
+
+ if (batch.CompletedQuantity <= 0)
+ {
+ batch.BatchStatus = (int)BatchStatusEnum.宸插洖搴�;
+ }
+ else
+ {
+ batch.BatchStatus = (int)BatchStatusEnum.鎵ц涓�;
+ }
+
+ batch.Operator = App.User.UserName;
+ await _outboundBatchRepository.Db.Updateable(batch).ExecuteCommandAsync();
+ }
+
+ private async Task UpdateOrderDetailAfterReturn(List<Dt_OutStockLockInfo> returnedLocks)
+ {
+ var orderDetailGroups = returnedLocks.GroupBy(x => x.OrderDetailId);
+
+ foreach (var group in orderDetailGroups)
+ {
+ var orderDetailId = group.Key;
+ var returnedQty = group.Sum(x => x.AssignQuantity - x.PickedQty);
+
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(x => x.AllocatedQuantity == x.AllocatedQuantity - returnedQty)
+ .Where(x => x.Id == orderDetailId)
+ .ExecuteCommandAsync();
+ }
+ }
+
+ #endregion
+
+ #region 杈呭姪鏂规硶
+
+ private async Task<string> GenerateNewBarcode()
+ {
+ var seq = await _dailySequenceService.GetNextSequenceAsync();
+ return "WSLOT" + DateTime.Now.ToString("yyyyMMdd") + seq.ToString().PadLeft(5, '0');
+ }
+
+ private async Task RecordSplitHistory(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail, decimal splitQty, string newBarcode)
+ {
+ var splitHistory = new Dt_SplitPackageRecord
+ {
+ OrderNo = lockInfo.OrderNo,
+ OutStockLockInfoId = lockInfo.Id,
+ StockId = stockDetail.StockId,
+ Operator = App.User.UserName,
+ OriginalBarcode = stockDetail.Barcode,
+ NewBarcode = newBarcode,
+ SplitQty = splitQty,
+ SplitTime = DateTime.Now,
+ Status = (int)SplitPackageStatusEnum.宸叉媶鍖�
+ };
+
+ await _splitPackageService.Db.Insertable(splitHistory).ExecuteCommandAsync();
+ }
+
+ private async Task RecordPickingHistory(PickingResult result, string orderNo, string palletCode)
+ {
+ var pickingRecord = new Dt_PickingRecord
+ {
+ OrderNo = orderNo,
+ // BatchNo = result.FinalLockInfo.BatchNo,
+ OrderDetailId = result.FinalLockInfo.OrderDetailId,
+ PalletCode = palletCode,
+ Barcode = result.FinalLockInfo.CurrentBarcode,
+ MaterielCode = result.FinalLockInfo.MaterielCode,
+ PickQuantity = result.ActualPickedQty,
+ PickTime = DateTime.Now,
+ Operator = App.User.UserName,
+ OutStockLockId = result.FinalLockInfo.Id,
+ // IsCancelled = false
+ };
+
+ await Db.Insertable(pickingRecord).ExecuteCommandAsync();
+ }
+
+ private async Task CheckAndUpdateOrderStatus(string orderNo)
+ {
+ var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .LeftJoin<Dt_OutboundOrder>((detail, order) => detail.OrderId == order.Id)
+ .Where((detail, order) => order.OrderNo == orderNo)
+ .Select((detail, order) => detail)
+ .ToListAsync();
+
+ bool allCompleted = orderDetails.All(x => x.OverOutQuantity >= x.NeedOutQuantity);
+
+ var orderStatus = allCompleted ? (int)OutOrderStatusEnum.鍑哄簱瀹屾垚 : (int)OutOrderStatusEnum.鍑哄簱涓�;
+
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.OrderStatus == orderStatus)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+ }
+
+ #endregion
+
+ #region DTO绫�
+
+ public class PickingResult
+ {
+ public Dt_OutStockLockInfo FinalLockInfo { get; set; }
+ public decimal ActualPickedQty { get; set; }
+ }
+
+ public class RevertPickingResult
+ {
+ public Dt_OutStockLockInfo LockInfo { get; set; }
+ public Dt_StockInfoDetail StockDetail { get; set; }
+ }
+
+ public class SplitResultDto
+ {
+ public string NewBarcode { get; set; }
+ }
+
+ public class ValidationResult<T>
+ {
+ public bool IsValid { get; set; }
+ public string ErrorMessage { get; set; }
+ public T Data { get; set; }
+
+ public static ValidationResult<T> Success(T data) => new ValidationResult<T> { IsValid = true, Data = data };
+ public static ValidationResult<T> Error(string message) => new ValidationResult<T> { IsValid = false, ErrorMessage = message };
+ }
+
+ #endregion
+ }
+
+
+ // 鏀寔绫�
+ public class SplitResultDto
+ {
+ public string NewBarcode { get; set; }
+ }
+}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderDetailService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderDetailService.cs"
index 954e8fc..c992e3d 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderDetailService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderDetailService.cs"
@@ -21,9 +21,9 @@
private readonly IUnitOfWorkManage _unitOfWorkManage;
public IRepository<Dt_OutboundOrderDetail> Repository => BaseDal;
-
+
private readonly IStockService _stockService;
-
+
private readonly IOutStockLockInfoService _outStockLockInfoService;
private readonly ILocationInfoService _locationInfoService;
private readonly IBasicService _basicService;
@@ -49,7 +49,8 @@
/// <summary>
/// 鍒嗛厤鍑哄簱搴撳瓨 鎸夊厛杩涘厛鍑哄師鍒欏垎閰�
/// </summary>
- public (List<Dt_StockInfo>, List<Dt_OutboundOrderDetail>, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) AssignStockOutbound(List<Dt_OutboundOrderDetail> outboundOrderDetails)
+ public (List<Dt_StockInfo>, List<Dt_OutboundOrderDetail>, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>)
+ AssignStockOutbound(List<Dt_OutboundOrderDetail> outboundOrderDetails)
{
if (!outboundOrderDetails.Any())
{
@@ -61,8 +62,14 @@
throw new Exception("璇峰嬁鍚屾椂鎿嶄綔澶氫釜鍗曟嵁鏄庣粏");
}
+ var orderId = outboundOrderDetails.First().OrderId;
var outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
- .First(x => x.Id == outboundOrderDetails.First().OrderId);
+ .First(x => x.Id == orderId);
+
+ if (!CanReassignOrder(outboundOrder))
+ {
+ throw new Exception($"璁㈠崟{outboundOrder.OrderNo}鐘舵�佷笉鍏佽閲嶆柊鍒嗛厤搴撳瓨");
+ }
List<Dt_StockInfo> outStocks = new List<Dt_StockInfo>();
List<Dt_OutStockLockInfo> outStockLockInfos = new List<Dt_OutStockLockInfo>();
@@ -70,14 +77,14 @@
// 鎸夌墿鏂欏拰鎵规鍒嗙粍澶勭悊
var groupDetails = outboundOrderDetails
- .GroupBy(x => new { x.MaterielCode, x.BatchNo ,x.SupplyCode})
+ .GroupBy(x => new { x.MaterielCode, x.BatchNo, x.SupplyCode })
.Select(x => new
{
MaterielCode = x.Key.MaterielCode,
BatchNo = x.Key.BatchNo,
SupplyCode = x.Key.SupplyCode,
Details = x.ToList(),
- TotalNeedQuantity = x.Sum(v => v.OrderQuantity - v.OverOutQuantity - v.LockQuantity-v.MoveQty)
+ TotalNeedQuantity = CalculateReassignNeedQuantity(x.ToList())
})
.Where(x => x.TotalNeedQuantity > 0)
.ToList();
@@ -87,68 +94,121 @@
var needQuantity = item.TotalNeedQuantity;
// 鑾峰彇鍙敤搴撳瓨锛堟寜鍏堣繘鍏堝嚭鎺掑簭锛�
- List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(item.MaterielCode, item.BatchNo,item.SupplyCode);
+ List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(item.MaterielCode, item.BatchNo, item.SupplyCode);
+
if (!stockInfos.Any())
{
- throw new Exception($"鐗╂枡[{item.MaterielCode}]鎵规[{item.BatchNo}]鏈壘鍒板彲鍒嗛厤搴撳瓨");
+ throw new Exception($"鐗╂枡[{item.MaterielCode}]鎵规[{item.BatchNo}]渚涘簲鍟哰{item.SupplyCode}]鏈壘鍒板彲鍒嗛厤搴撳瓨");
}
// 鍒嗛厤搴撳瓨锛堟寜鍏堣繘鍏堝嚭锛�
- var (autoAssignStocks, stockAllocations) = _stockService.StockInfoService.GetOutboundStocks(
- stockInfos, item.MaterielCode, needQuantity, out decimal residueQuantity);
+ var (autoAssignStocks, stockAllocations) = _stockService.StockInfoService.GetOutboundStocks(stockInfos, item.MaterielCode, needQuantity, out decimal residueQuantity);
- if (residueQuantity > 0 && residueQuantity == needQuantity)
+ // 妫�鏌ュ垎閰嶇粨鏋滐細濡傛灉瀹屽叏鏃犳硶鍒嗛厤锛堝垎閰嶆暟閲忎负0锛夛紝鍒欐姤閿�
+ decimal allocatedQuantity = needQuantity - residueQuantity;
+ if (allocatedQuantity <= 0)
{
- throw new Exception($"鐗╂枡[{item.MaterielCode}]搴撳瓨涓嶈冻锛岄渶瑕亄needQuantity}锛屽彲鐢▄needQuantity - residueQuantity}");
+ throw new Exception($"鐗╂枡[{item.MaterielCode}]鎵规[{item.BatchNo}]搴撳瓨涓嶈冻锛岄渶瑕亄needQuantity}锛屼絾鏃犳硶鍒嗛厤浠讳綍搴撳瓨");
}
outStocks.AddRange(autoAssignStocks);
// 鎸夊厛杩涘厛鍑哄師鍒欏垎閰嶉攣瀹氭暟閲忓埌鍚勪釜鏄庣粏
- DistributeLockQuantityByFIFO(item.Details, autoAssignStocks, stockAllocations, outStockLockInfos, outboundOrder);
+ var distributionResult = DistributeLockQuantityByFIFO(item.Details, autoAssignStocks, stockAllocations, outStockLockInfos, outboundOrder);
+
+ if (!distributionResult.success)
+ {
+ throw new Exception(distributionResult.message);
+ }
+
+ // 鏇存柊鍑哄簱鍗曟槑缁嗙姸鎬�
+ UpdateOrderDetailStatus(item.Details, allocatedQuantity, needQuantity);
}
- locationInfos.AddRange(_locationInfoService.GetLocationInfos(outStocks.Select(x => x.LocationCode).Distinct().ToList()));
+ if (outStocks.Any())
+ {
+ locationInfos.AddRange(_locationInfoService.GetLocationInfos(
+ outStocks.Select(x => x.LocationCode).Distinct().ToList()));
+ }
return (outStocks, outboundOrderDetails, outStockLockInfos, locationInfos);
}
/// <summary>
- /// 鎸夊厛杩涘厛鍑哄師鍒欏垎閰嶉攣瀹氭暟閲忓埌鍚勪釜鏄庣粏
+ /// 妫�鏌ヨ鍗曟槸鍚﹀厑璁搁噸鏂板垎閰�
/// </summary>
- private void DistributeLockQuantityByFIFO(
- List<Dt_OutboundOrderDetail> details,
- List<Dt_StockInfo> assignStocks,
- Dictionary<int, decimal> stockAllocations,
- List<Dt_OutStockLockInfo> outStockLockInfos,
- Dt_OutboundOrder outboundOrder)
+ private bool CanReassignOrder(Dt_OutboundOrder outboundOrder)
{
- // 鎸夊厛杩涘厛鍑烘帓搴忓嚭搴撳崟鏄庣粏锛堝亣璁惧厛鍒涘缓鐨勬槑缁嗛渶瑕佷紭鍏堟弧瓒筹級
+ // 鍏佽閲嶆柊鍒嗛厤鐨勭姸鎬�
+ var allowedStatus = new[] {OutOrderStatusEnum.鏈紑濮�, OutOrderStatusEnum.鍑哄簱涓�,OutOrderStatusEnum.閮ㄥ垎瀹屾垚};
+
+ return allowedStatus.Contains((OutOrderStatusEnum)outboundOrder.OrderStatus);
+ }
+
+ /// <summary>
+ /// 閲嶆柊璁$畻闇�姹傛暟閲忥紙鑰冭檻閲嶆柊鍒嗛厤鐨勫満鏅級
+ /// </summary>
+ private decimal CalculateReassignNeedQuantity(List<Dt_OutboundOrderDetail> details)
+ {
+ decimal totalNeed = 0;
+
+ foreach (var detail in details)
+ {
+ // 鍏抽敭淇敼锛氶噸鏂板垎閰嶆椂锛屽彧鑰冭檻鏈嚭搴撶殑閮ㄥ垎锛屽拷鐣ラ攣瀹氭暟閲�
+ // 鍥犱负閿佸畾鏁伴噺鍦ㄥ洖搴撴椂宸茬粡琚噸缃�
+ decimal remainingNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.MoveQty;
+
+ if (remainingNeed > 0)
+ {
+ totalNeed += remainingNeed;
+ }
+ }
+
+ return totalNeed;
+ }
+ private (bool success, string message) DistributeLockQuantityByFIFO(
+ List<Dt_OutboundOrderDetail> details,
+ List<Dt_StockInfo> assignStocks,
+ Dictionary<int, decimal> stockAllocations,
+ List<Dt_OutStockLockInfo> outStockLockInfos,
+ Dt_OutboundOrder outboundOrder)
+ {
+ // 鎸夊厛杩涘厛鍑烘帓搴忓嚭搴撳崟鏄庣粏锛圛d灏忕殑浼樺厛锛�
var sortedDetails = details
- .Where(d => d.OrderQuantity - d.OverOutQuantity - d.LockQuantity -d.MoveQty> 0) // 鍙鐞嗚繕闇�瑕佸垎閰嶇殑鏁伴噺
+ .Where(d => d.OrderQuantity - d.OverOutQuantity - d.LockQuantity - d.MoveQty > 0)
.OrderBy(x => x.Id)
.ToList();
- if (!sortedDetails.Any()) return;
+ if (!sortedDetails.Any())
+ return (true, "鏃犻渶鍒嗛厤");
// 鑾峰彇鎵�鏈夊垎閰嶄簡搴撳瓨鐨勬槑缁嗭紝鎸夊厛杩涘厛鍑烘帓搴�
var allocatedStockDetails = assignStocks
.SelectMany(x => x.Details)
- .Where(x => stockAllocations.ContainsKey(x.Id))
+ .Where(x => stockAllocations.ContainsKey(x.Id) && stockAllocations[x.Id] > 0)
.OrderBy(x => x.CreateDate)
.ThenBy(x => x.StockId)
.ToList();
+ if (!allocatedStockDetails.Any())
+ {
+ return (false, "娌℃湁鍙垎閰嶇殑搴撳瓨鏄庣粏");
+ }
+
+ decimal totalNeedQuantity = sortedDetails.Sum(d =>
+ d.OrderQuantity - d.OverOutQuantity - d.LockQuantity - d.MoveQty);
+ decimal allocatedQuantity = 0;
+
// 涓烘瘡涓簱瀛樻槑缁嗗垱寤哄垎閰嶈褰�
foreach (var stockDetail in allocatedStockDetails)
{
- if (!stockAllocations.TryGetValue(stockDetail.Id, out decimal allocatedQuantity))
+ if (!stockAllocations.TryGetValue(stockDetail.Id, out decimal allocatedQuantityForStock))
continue;
- if (allocatedQuantity <= 0) continue;
+ if (allocatedQuantityForStock <= 0) continue;
var stockInfo = assignStocks.First(x => x.Id == stockDetail.StockId);
- decimal remainingAllocate = allocatedQuantity;
+ decimal remainingAllocate = allocatedQuantityForStock;
// 鎸夐『搴忓垎閰嶇粰鍚勪釜鍑哄簱鍗曟槑缁�
foreach (var detail in sortedDetails)
@@ -156,7 +216,7 @@
if (remainingAllocate <= 0) break;
// 璁$畻杩欎釜鏄庣粏杩橀渶瑕佸垎閰嶇殑鏁伴噺
- var detailNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.LockQuantity-detail.MoveQty;
+ var detailNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.LockQuantity - detail.MoveQty;
if (detailNeed <= 0) continue;
// 鍒嗛厤鏁伴噺
@@ -165,7 +225,7 @@
// 楠岃瘉鏉$爜鏄惁瀛樺湪
if (string.IsNullOrEmpty(stockDetail.Barcode))
{
- throw new Exception($"搴撳瓨鏄庣粏ID[{stockDetail.Id}]鐨勬潯鐮佷负绌�");
+ return (false, $"搴撳瓨鏄庣粏ID[{stockDetail.Id}]鐨勬潯鐮佷负绌�");
}
// 鍒涘缓鍑哄簱閿佸畾淇℃伅
@@ -176,38 +236,242 @@
// 鏇存柊鏄庣粏鐨勯攣瀹氭暟閲�
detail.LockQuantity += assignQuantity;
remainingAllocate -= assignQuantity;
+ allocatedQuantity += assignQuantity;
}
- // 濡傛灉杩樻湁鍓╀綑鍒嗛厤鏁伴噺锛岄噸鏂板垎閰嶆垨璁板綍璀﹀憡
+ // 濡傛灉杩樻湁鍓╀綑鍒嗛厤鏁伴噺锛岃褰曡鍛�
if (remainingAllocate > 0)
{
- // 閲嶆柊鍒嗛厤缁欏叾浠栭渶瑕佸垎閰嶇殑鏄庣粏
- foreach (var detail in sortedDetails)
+ _logger.LogWarning($"搴撳瓨鍒嗛厤鍚庝粛鏈夊墿浣欐暟閲忔湭鍒嗛厤: {remainingAllocate}, 鏉$爜: {stockDetail.Barcode}");
+ }
+ }
+
+ // 楠岃瘉鏄惁鑷冲皯鍒嗛厤浜嗕竴閮ㄥ垎
+ if (allocatedQuantity <= 0)
+ {
+ return (false, "搴撳瓨鍒嗛厤澶辫触锛屾棤娉曞垎閰嶄换浣曟暟閲�");
+ }
+
+ // 璁板綍鍒嗛厤缁撴灉
+ if (allocatedQuantity < totalNeedQuantity)
+ {
+ _logger.LogWarning($"搴撳瓨閮ㄥ垎鍒嗛厤锛岄渶瑕亄totalNeedQuantity}锛屽疄闄呭垎閰峽allocatedQuantity}");
+ }
+ else
+ {
+ _logger.LogInformation($"搴撳瓨瀹屽叏鍒嗛厤锛屽垎閰嶆暟閲弡allocatedQuantity}");
+ }
+
+ return (true, "鍒嗛厤鎴愬姛");
+ }
+
+
+ /// <summary>
+ /// 涓哄垎鎵瑰垎閰嶅簱瀛�
+ /// </summary>
+ public async Task<(List<Dt_StockInfo>, List<Dt_OutboundOrderDetail>, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>)>
+ AssignStockForBatch(Dt_OutboundOrderDetail orderDetail, decimal batchQuantity, string batchNo)
+ {
+ if (orderDetail == null)
+ {
+ throw new Exception("鏈壘鍒板嚭搴撳崟鏄庣粏淇℃伅");
+ }
+
+ var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+ .FirstAsync(x => x.Id == orderDetail.OrderId);
+
+ List<Dt_StockInfo> outStocks = new List<Dt_StockInfo>();
+ List<Dt_OutStockLockInfo> outStockLockInfos = new List<Dt_OutStockLockInfo>();
+ List<Dt_LocationInfo> locationInfos = new List<Dt_LocationInfo>();
+
+ // 鎸夌墿鏂欏拰鎵规鍒嗙粍澶勭悊锛堣繖閲屽彧鏈変竴涓槑缁嗭級
+ var groupDetails = new List<Dt_OutboundOrderDetail> { orderDetail }
+ .GroupBy(x => new { x.MaterielCode, x.BatchNo, x.SupplyCode })
+ .Select(x => new
+ {
+ MaterielCode = x.Key.MaterielCode,
+ BatchNo = x.Key.BatchNo,
+ SupplyCode = x.Key.SupplyCode,
+ Details = x.ToList(),
+ TotalNeedQuantity = batchQuantity // 浣跨敤鍒嗘壒鏁伴噺
+ })
+ .Where(x => x.TotalNeedQuantity > 0)
+ .ToList();
+
+ foreach (var item in groupDetails)
+ {
+ var needQuantity = item.TotalNeedQuantity;
+
+ // 鑾峰彇鍙敤搴撳瓨锛堟寜鍏堣繘鍏堝嚭鎺掑簭锛�
+ List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(item.MaterielCode, item.BatchNo, item.SupplyCode);
+ if (!stockInfos.Any())
+ {
+ throw new Exception($"鐗╂枡[{item.MaterielCode}]鎵规[{item.BatchNo}]鏈壘鍒板彲鍒嗛厤搴撳瓨");
+ }
+
+ // 鍒嗛厤搴撳瓨锛堟寜鍏堣繘鍏堝嚭锛�
+ var (autoAssignStocks, stockAllocations) = _stockService.StockInfoService.GetOutboundStocks(stockInfos, item.MaterielCode, needQuantity, out decimal residueQuantity);
+
+ // 妫�鏌ュ垎閰嶇粨鏋�
+ decimal allocatedQuantity = needQuantity - residueQuantity;
+ if (allocatedQuantity <= 0)
+ {
+ throw new Exception($"鐗╂枡[{item.MaterielCode}]鎵规[{item.BatchNo}]搴撳瓨涓嶈冻锛岄渶瑕亄needQuantity}锛屼絾鏃犳硶鍒嗛厤浠讳綍搴撳瓨");
+ }
+
+ outStocks.AddRange(autoAssignStocks);
+
+ // 鎸夊厛杩涘厛鍑哄師鍒欏垎閰嶉攣瀹氭暟閲忓埌鍚勪釜鏄庣粏
+ var distributionResult = DistributeLockQuantityByFIFO(item.Details, autoAssignStocks, stockAllocations, outStockLockInfos, outboundOrder, batchNo);
+
+ if (!distributionResult.success)
+ {
+ throw new Exception(distributionResult.message);
+ }
+
+ // 鏇存柊鍑哄簱鍗曟槑缁嗙姸鎬�
+ UpdateOrderDetailStatus(item.Details, allocatedQuantity, needQuantity);
+ }
+
+ if (outStocks.Any())
+ {
+ locationInfos.AddRange(_locationInfoService.GetLocationInfos(
+ outStocks.Select(x => x.LocationCode).Distinct().ToList()));
+
+
+ }
+
+ return (outStocks, groupDetails.SelectMany(x => x.Details).ToList(), outStockLockInfos, locationInfos);
+ }
+
+ /// <summary>
+ /// 鎸夊厛杩涘厛鍑哄師鍒欏垎閰嶉攣瀹氭暟閲�
+ /// </summary>
+ private (bool success, string message) DistributeLockQuantityByFIFO(
+ List<Dt_OutboundOrderDetail> details,
+ List<Dt_StockInfo> assignStocks,
+ Dictionary<int, decimal> stockAllocations,
+ List<Dt_OutStockLockInfo> outStockLockInfos,
+ Dt_OutboundOrder outboundOrder,
+ string batchNo)
+ {
+ var sortedDetails = details
+ .Where(d => d.OrderQuantity - d.OverOutQuantity - d.AllocatedQuantity > 0)
+ .OrderBy(x => x.Id)
+ .ToList();
+
+ if (!sortedDetails.Any())
+ return (true, "鏃犻渶鍒嗛厤");
+
+ // 鑾峰彇鎵�鏈夊垎閰嶄簡搴撳瓨鐨勬槑缁嗭紝鎸夊厛杩涘厛鍑烘帓搴�
+ var allocatedStockDetails = assignStocks
+ .SelectMany(x => x.Details)
+ .Where(x => stockAllocations.ContainsKey(x.Id) && stockAllocations[x.Id] > 0)
+ .OrderBy(x => x.CreateDate)
+ .ThenBy(x => x.StockId)
+ .ToList();
+
+ if (!allocatedStockDetails.Any())
+ {
+ return (false, "娌℃湁鍙垎閰嶇殑搴撳瓨鏄庣粏");
+ }
+
+ decimal totalNeedQuantity = sortedDetails.Sum(d =>
+ d.OrderQuantity - d.OverOutQuantity - d.AllocatedQuantity);
+ decimal allocatedQuantity = 0;
+
+ // 涓烘瘡涓簱瀛樻槑缁嗗垱寤哄垎閰嶈褰�
+ foreach (var stockDetail in allocatedStockDetails)
+ {
+ if (!stockAllocations.TryGetValue(stockDetail.Id, out decimal allocatedQuantityForStock))
+ continue;
+
+ if (allocatedQuantityForStock <= 0) continue;
+
+ var stockInfo = assignStocks.First(x => x.Id == stockDetail.StockId);
+ decimal remainingAllocate = allocatedQuantityForStock;
+
+ // 鎸夐『搴忓垎閰嶇粰鍚勪釜鍑哄簱鍗曟槑缁�
+ foreach (var detail in sortedDetails)
+ {
+ if (remainingAllocate <= 0) break;
+
+ // 璁$畻杩欎釜鏄庣粏杩橀渶瑕佸垎閰嶇殑鏁伴噺
+ var detailNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.AllocatedQuantity;
+ if (detailNeed <= 0) continue;
+
+ // 鍒嗛厤鏁伴噺
+ var assignQuantity = Math.Min(remainingAllocate, detailNeed);
+
+ // 楠岃瘉鏉$爜鏄惁瀛樺湪
+ if (string.IsNullOrEmpty(stockDetail.Barcode))
{
- if (remainingAllocate <= 0) break;
-
- var detailNeed = detail.OrderQuantity - detail.OverOutQuantity - detail.LockQuantity;
- if (detailNeed <= 0) continue;
-
- var assignQuantity = Math.Min(remainingAllocate, detailNeed);
-
- var lockInfo = _outStockLockInfoService.GetOutStockLockInfo(
- outboundOrder, detail, stockInfo, assignQuantity, stockDetail.Barcode);
- outStockLockInfos.Add(lockInfo);
-
- detail.LockQuantity += assignQuantity;
- remainingAllocate -= assignQuantity;
+ return (false, $"搴撳瓨鏄庣粏ID[{stockDetail.Id}]鐨勬潯鐮佷负绌�");
}
- // 濡傛灉杩樻湁鍓╀綑锛岃褰曡鍛婁絾涓嶆姏鍑哄紓甯�
- if (remainingAllocate > 0)
- {
- _logger.LogWarning($"搴撳瓨鍒嗛厤鍚庝粛鏈夊墿浣欐暟閲忔湭鍒嗛厤: {remainingAllocate}, 鏉$爜: {stockDetail.Barcode}");
- }
+
+ // 鍒涘缓鍑哄簱閿佸畾淇℃伅
+ var lockInfo = _outStockLockInfoService.GetOutStockLockInfo(
+ outboundOrder, detail, stockInfo, assignQuantity, stockDetail.Barcode, batchNo);
+ outStockLockInfos.Add(lockInfo);
+
+ // 鏇存柊鏄庣粏鐨勫凡鍒嗛厤鏁伴噺
+ detail.AllocatedQuantity += assignQuantity;
+ remainingAllocate -= assignQuantity;
+ allocatedQuantity += assignQuantity;
+ }
+
+ // 濡傛灉杩樻湁鍓╀綑鍒嗛厤鏁伴噺锛岃褰曡鍛�
+ if (remainingAllocate > 0)
+ {
+ _logger.LogWarning($"搴撳瓨鍒嗛厤鍚庝粛鏈夊墿浣欐暟閲忔湭鍒嗛厤: {remainingAllocate}, 鏉$爜: {stockDetail.Barcode}");
+ }
+ }
+
+ // 楠岃瘉鏄惁鑷冲皯鍒嗛厤浜嗕竴閮ㄥ垎
+ if (allocatedQuantity <= 0)
+ {
+ return (false, "搴撳瓨鍒嗛厤澶辫触锛屾棤娉曞垎閰嶄换浣曟暟閲�");
+ }
+
+ // 璁板綍鍒嗛厤缁撴灉
+ if (allocatedQuantity < totalNeedQuantity)
+ {
+ _logger.LogWarning($"搴撳瓨閮ㄥ垎鍒嗛厤锛岄渶瑕亄totalNeedQuantity}锛屽疄闄呭垎閰峽allocatedQuantity}");
+ }
+ else
+ {
+ _logger.LogInformation($"搴撳瓨瀹屽叏鍒嗛厤锛屽垎閰嶆暟閲弡allocatedQuantity}");
+ }
+
+ return (true, "鍒嗛厤鎴愬姛");
+ }
+
+
+ private void UpdateOrderDetailStatus(List<Dt_OutboundOrderDetail> details,
+ decimal allocatedQuantity, decimal needQuantity)
+ {
+ foreach (var detail in details)
+ {
+ var detailNeed = detail.OrderQuantity - detail.LockQuantity - detail.OverOutQuantity - detail.MoveQty;
+
+ if (detailNeed <= 0)
+ {
+ // 璇ユ槑缁嗗凡瀹屽叏鍒嗛厤
+ detail.OrderDetailStatus = OrderDetailStatusEnum.AssignOver.ObjToInt();
+ }
+ else if (allocatedQuantity < needQuantity)
+ {
+ // 鏁翠綋閮ㄥ垎鍒嗛厤锛岃鏄庣粏鍙兘杩樻湁闇�姹�
+ detail.OrderDetailStatus = OrderDetailStatusEnum.AssignOverPartial.ObjToInt();
+ }
+ else
+ {
+ // 鏁翠綋瀹屽叏鍒嗛厤
+ detail.OrderDetailStatus = OrderDetailStatusEnum.AssignOver.ObjToInt();
}
}
}
-
/// <summary>
/// 鍑哄簱搴撳瓨鍒嗛厤鍚庯紝鏇存柊鏁版嵁搴撴暟鎹�
/// </summary>
@@ -218,8 +482,8 @@
/// <param name="locationStatus"></param>
/// <param name="tasks"></param>
/// <returns></returns>
- public WebResponseContent LockOutboundStockDataUpdate(List<Dt_StockInfo> stockInfos, List<Dt_OutboundOrderDetail> outboundOrderDetails,
- List<Dt_OutStockLockInfo> outStockLockInfos, List<Dt_LocationInfo> locationInfos,
+ public WebResponseContent LockOutboundStockDataUpdate(List<Dt_StockInfo> stockInfos, List<Dt_OutboundOrderDetail> outboundOrderDetails,
+ List<Dt_OutStockLockInfo> outStockLockInfos, List<Dt_LocationInfo> locationInfos,
LocationStatusEnum locationStatus = LocationStatusEnum.Lock, List<Dt_Task>? tasks = null)
{
try
@@ -227,7 +491,7 @@
// 鏇存柊搴撳瓨鐘舵��
stockInfos.ForEach(x => x.StockStatus = (int)StockStatusEmun.鍑哄簱閿佸畾);
_stockService.StockInfoService.Repository.UpdateData(stockInfos);
-
+
// 鏇存柊搴撳瓨鏄庣粏
var stockDetails = stockInfos.SelectMany(x => x.Details).ToList();
_stockService.StockInfoDetailService.Repository.UpdateData(stockDetails);
@@ -280,84 +544,244 @@
SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_InboundOrderDetail.OrderId).FirstLetterToLower());
if (searchParameters != null)
{
- sugarQueryable1 = sugarQueryable1.Where(x => x.OrderId== searchParameters.Value.ObjToInt());
- var dataList = sugarQueryable1.ToPageList(options.Page, options.Rows, ref totalCount);
+ sugarQueryable1 = sugarQueryable1.Where(x => x.OrderId == searchParameters.Value.ObjToInt());
+ var dataList = sugarQueryable1.ToPageList(options.Page, options.Rows, ref totalCount);
return new PageGridData<Dt_OutboundOrderDetail>(totalCount, dataList);
}
}
-
+
}
}
- return new PageGridData<Dt_OutboundOrderDetail> ();
+ return new PageGridData<Dt_OutboundOrderDetail>();
}
- public (List<Dt_StockInfo>, Dt_OutboundOrderDetail, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) AssignStockOutbound(Dt_OutboundOrderDetail outboundOrderDetail, List<StockSelectViewDTO> stockSelectViews)
+ public (List<Dt_StockInfo>, Dt_OutboundOrderDetail, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>)
+ AssignStockOutbound(Dt_OutboundOrderDetail outboundOrderDetail, List<StockSelectViewDTO> stockSelectViews)
{
+ // 楠岃瘉鐢ㄦ埛閫夋嫨
(bool, string) checkResult = CheckSelectStockDeital(outboundOrderDetail, stockSelectViews);
if (!checkResult.Item1) throw new Exception(checkResult.Item2);
Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.Id == outboundOrderDetail.OrderId);
- var originalNeedQuantity = outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity;
+ var originalNeedQuantity = outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity - outboundOrderDetail.MoveQty;
- var needQuantity = originalNeedQuantity;
+ List<Dt_StockInfo> outStocks = new List<Dt_StockInfo>();
+ List<Dt_OutStockLockInfo> outStockLockInfos = new List<Dt_OutStockLockInfo>();
- List<Dt_StockInfo> outStocks = _stockService.StockInfoService.GetStockInfosByPalletCodes(stockSelectViews.Select(x => x.PalletCode).ToList());
- var assignQuantity =0m;
- outStocks.ForEach(x =>
- {
- x.Details.ForEach(v =>
- {
- assignQuantity += v.StockQuantity - v.OutboundQuantity;
- });
- });
+ decimal remainingNeedQuantity = originalNeedQuantity;
+ decimal totalAssignedFromUserSelection = 0;
- outboundOrderDetail.LockQuantity += assignQuantity;
- outStocks.ForEach(x =>
+ // 鎸夊厛杩涘厛鍑烘帓搴忕敤鎴烽�夋嫨鐨勫簱瀛�
+ var userSelectedStocks = _stockService.StockInfoService.GetStockInfosByPalletCodes(
+ stockSelectViews.Select(x => x.PalletCode).ToList());
+
+ var sortedUserSelectedStocks = userSelectedStocks
+ .OrderBy(x => x.CreateDate)
+ .ToList();
+
+ // 鍒嗛厤鐢ㄦ埛閫夋嫨鐨勫簱瀛�
+ foreach (var stock in sortedUserSelectedStocks)
{
- x.Details.ForEach(v =>
+ if (remainingNeedQuantity <= 0) break;
+
+ // 鑾峰彇鐢ㄦ埛瀵硅鎵樼洏鐨勯�夋嫨鏁伴噺
+ var userSelection = stockSelectViews.FirstOrDefault(x => x.PalletCode == stock.PalletCode);
+ if (userSelection == null) continue;
+
+ // 璁$畻璇ユ墭鐩樺疄闄呭彲鐢ㄦ暟閲�
+ var availableQuantity = CalculateAvailableQuantity(stock, outboundOrderDetail.MaterielCode,
+ outboundOrderDetail.BatchNo, outboundOrderDetail.SupplyCode);
+
+ // 纭畾鍒嗛厤鏁伴噺锛氬彇鐢ㄦ埛閫夋嫨鏁伴噺銆佸彲鐢ㄦ暟閲忓拰鍓╀綑闇�姹傜殑鏈�灏忓��
+ var assignQuantity = Math.Min(
+ Math.Min(userSelection.UseableQuantity, availableQuantity),
+ remainingNeedQuantity);
+
+ if (assignQuantity <= 0) continue;
+
+ // 鎵ц鍒嗛厤
+ var actualAssigned = AssignStockQuantity(stock, outboundOrderDetail, assignQuantity);
+ if (actualAssigned > 0)
{
- v.OutboundQuantity = v.StockQuantity;
- });
- });
- needQuantity -= assignQuantity;
- if (outboundOrderDetail.OrderQuantity > outboundOrderDetail.LockQuantity)
- {
- List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(outboundOrderDetail.MaterielCode, outboundOrderDetail.BatchNo,"");
- stockInfos = stockInfos.Where(x => !stockSelectViews.Select(v => v.PalletCode).Contains(x.PalletCode)).ToList();
- var (autoAssignStocks, stockAllocations) = _stockService.StockInfoService.GetOutboundStocks(stockInfos, outboundOrderDetail.MaterielCode, needQuantity, out decimal residueQuantity);
- outboundOrderDetail.LockQuantity += needQuantity - residueQuantity;
- outStocks.AddRange(autoAssignStocks);
- outboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.AssignOver.ObjToInt();
- if (residueQuantity > 0)
- {
- outboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.AssignOverPartial.ObjToInt();
+ outStocks.Add(stock);
+ totalAssignedFromUserSelection += actualAssigned;
+ remainingNeedQuantity -= actualAssigned;
+
+ // 鍒涘缓閿佸畾璁板綍
+ var lockInfo = CreateOutStockLockInfo(outboundOrder, outboundOrderDetail, stock, actualAssigned);
+ outStockLockInfos.Add(lockInfo);
}
}
- List<Dt_OutStockLockInfo> outStockLockInfos = _outStockLockInfoService.GetOutStockLockInfos(outboundOrder, outboundOrderDetail, outStocks);
+ // 妫�鏌ョ敤鎴烽�夋嫨鏄惁鑷冲皯鍒嗛厤浜嗕竴閮ㄥ垎
+ if (totalAssignedFromUserSelection <= 0)
+ {
+ throw new Exception("鐢ㄦ埛閫夋嫨鐨勫簱瀛樻棤娉曞垎閰嶄换浣曟暟閲�");
+ }
+
+ // 濡傛灉鐢ㄦ埛閫夋嫨鐨勫簱瀛樹笉澶燂紝鑷姩鍒嗛厤鍓╀綑閮ㄥ垎
+ decimal autoAssignedQuantity = 0;
+ if (remainingNeedQuantity > 0)
+ {
+ List<Dt_StockInfo> autoStocks = _stockService.StockInfoService.GetUseableStocks(
+ outboundOrderDetail.MaterielCode, outboundOrderDetail.BatchNo, "");
+
+ // 鎺掗櫎鐢ㄦ埛宸查�夋嫨鐨勬墭鐩�
+ autoStocks = autoStocks
+ .Where(x => !stockSelectViews.Select(v => v.PalletCode).Contains(x.PalletCode))
+ .ToList();
+
+ var (autoAssignStocks, stockAllocations) = _stockService.StockInfoService.GetOutboundStocks(
+ autoStocks, outboundOrderDetail.MaterielCode, remainingNeedQuantity, out decimal residueQuantity);
+
+ // 妫�鏌ヨ嚜鍔ㄥ垎閰嶇粨鏋�
+ autoAssignedQuantity = remainingNeedQuantity - residueQuantity;
+ if (autoAssignedQuantity <= 0 && remainingNeedQuantity > 0)
+ {
+ // 閮ㄥ垎鍒嗛厤鏄彲浠ユ帴鍙楃殑锛岃褰曡鍛婁絾涓嶆姤閿�
+ _logger.LogWarning($"鑷姩鍒嗛厤澶辫触锛屽墿浣欓渶姹倇remainingNeedQuantity}鏃犳硶婊¤冻");
+ }
+ else if (autoAssignedQuantity > 0)
+ {
+ outStocks.AddRange(autoAssignStocks);
+
+ // 涓鸿嚜鍔ㄥ垎閰嶇殑搴撳瓨鍒涘缓閿佸畾璁板綍
+ var autoLockInfos = CreateLockInfosForAutoAssign(outboundOrder, outboundOrderDetail, autoAssignStocks, stockAllocations);
+ outStockLockInfos.AddRange(autoLockInfos);
+ }
+ }
+
+ // 鏇存柊閿佸畾鏁伴噺
+ outboundOrderDetail.LockQuantity += totalAssignedFromUserSelection + autoAssignedQuantity;
+
+ // 鏇存柊鐘舵��
+ UpdateOrderDetailStatus(outboundOrderDetail, remainingNeedQuantity - autoAssignedQuantity);
List<Dt_LocationInfo> locationInfos = _locationInfoService.GetLocationInfos(outStocks.Select(x => x.LocationCode).ToList());
return (outStocks, outboundOrderDetail, outStockLockInfos, locationInfos);
}
- private (bool, string) CheckSelectStockDeital(Dt_OutboundOrderDetail outboundOrderDetail, List<StockSelectViewDTO> stockSelectViews)
+
+ // 杈呭姪鏂规硶
+ private decimal CalculateAvailableQuantity(Dt_StockInfo stock, string materielCode, string batchNo, string supplyCode)
{
- if (outboundOrderDetail == null)
- {
- return (false, "鏈壘鍒板嚭搴撳崟鏄庣粏淇℃伅");
- }
- if (outboundOrderDetail.OrderDetailStatus != OrderDetailStatusEnum.New.ObjToInt() && outboundOrderDetail.OrderDetailStatus != OrderDetailStatusEnum.AssignOverPartial.ObjToInt())
- {
- return (false, "璇ユ槑缁嗕笉鍙搷浣�");
- }
- if (stockSelectViews.Sum(x => x.UseableQuantity) > outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity)
- {
- return (false, "閫夋嫨鏁伴噺瓒呭嚭鍗曟嵁鏁伴噺");
- }
- return (true, "鎴愬姛");
+ var relevantDetails = stock.Details
+ .Where(d => d.MaterielCode == materielCode &&
+ (string.IsNullOrEmpty(batchNo) || d.BatchNo == batchNo) &&
+ (string.IsNullOrEmpty(supplyCode) || d.SupplyCode == supplyCode))
+ .ToList();
+
+ return relevantDetails.Sum(d => d.StockQuantity - d.OutboundQuantity);
}
+ private decimal AssignStockQuantity(Dt_StockInfo stock, Dt_OutboundOrderDetail detail, decimal assignQuantity)
+ {
+ decimal remainingAssign = assignQuantity;
+
+ // 鎸夊厛杩涘厛鍑哄垎閰嶅簱瀛樻槑缁�
+ var sortedDetails = stock.Details
+ .Where(d => d.MaterielCode == detail.MaterielCode &&
+ d.BatchNo == detail.BatchNo &&
+ (d.StockQuantity - d.OutboundQuantity) > 0)
+ .OrderBy(d => d.CreateDate)
+ .ToList();
+
+ foreach (var stockDetail in sortedDetails)
+ {
+ if (remainingAssign <= 0) break;
+
+ var available = stockDetail.StockQuantity - stockDetail.OutboundQuantity;
+ var assign = Math.Min(available, remainingAssign);
+
+ stockDetail.OutboundQuantity += assign;
+ remainingAssign -= assign;
+ }
+
+ return assignQuantity - remainingAssign; // 杩斿洖瀹為檯鍒嗛厤鏁伴噺
+ }
+
+ private Dt_OutStockLockInfo CreateOutStockLockInfo(Dt_OutboundOrder outboundOrder, Dt_OutboundOrderDetail detail,
+ Dt_StockInfo stock, decimal quantity)
+ {
+ var barcode = stock.Details
+ .Where(d => !string.IsNullOrEmpty(d.Barcode))
+ .Select(d => d.Barcode)
+ .FirstOrDefault();
+
+ return _outStockLockInfoService.GetOutStockLockInfo(outboundOrder, detail, stock, quantity, barcode);
+ }
+
+ private List<Dt_OutStockLockInfo> CreateLockInfosForAutoAssign(Dt_OutboundOrder outboundOrder,
+ Dt_OutboundOrderDetail detail, List<Dt_StockInfo> stocks, Dictionary<int, decimal> allocations)
+ {
+ var lockInfos = new List<Dt_OutStockLockInfo>();
+
+ foreach (var stock in stocks.OrderBy(x => x.CreateDate))
+ {
+ if (allocations.TryGetValue(stock.Id, out decimal quantity) && quantity > 0)
+ {
+ var lockInfo = CreateOutStockLockInfo(outboundOrder, detail, stock, quantity);
+ lockInfos.Add(lockInfo);
+ }
+ }
+
+ return lockInfos;
+ }
+
+ private void UpdateOrderDetailStatus(Dt_OutboundOrderDetail detail, decimal remainingQuantity)
+ {
+ if (remainingQuantity <= 0)
+ {
+ detail.OrderDetailStatus = OrderDetailStatusEnum.AssignOver.ObjToInt();
+ }
+ else
+ {
+ detail.OrderDetailStatus = OrderDetailStatusEnum.AssignOverPartial.ObjToInt();
+ }
+ }
+
+ private (bool, string) CheckSelectStockDeital(Dt_OutboundOrderDetail outboundOrderDetail, List<StockSelectViewDTO> stockSelectViews)
+ {
+ var needQuantity = outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity - outboundOrderDetail.MoveQty;
+
+ if (needQuantity <= 0)
+ {
+ return (false, "鍑哄簱鍗曟槑缁嗘棤闇�鍒嗛厤搴撳瓨");
+ }
+
+ // 妫�鏌ユ�婚�夋嫨鏁伴噺鏄惁澶т簬0
+ var totalSelected = stockSelectViews.Sum(x => x.UseableQuantity);
+ if (totalSelected <= 0)
+ {
+ return (false, "鐢ㄦ埛閫夋嫨鐨勫簱瀛樻暟閲忓繀椤诲ぇ浜�0");
+ }
+
+ // 妫�鏌ユ瘡涓墭鐩樼殑鍙敤鏁伴噺
+ foreach (var selection in stockSelectViews)
+ {
+ if (selection.UseableQuantity <= 0)
+ {
+ return (false, $"鎵樼洏[{selection.PalletCode}]鐨勯�夋嫨鏁伴噺蹇呴』澶т簬0");
+ }
+
+ var stock = _stockService.StockInfoService.GetStockInfoByPalletCode(selection.PalletCode);
+ if (stock == null)
+ {
+ return (false, $"鎵樼洏[{selection.PalletCode}]涓嶅瓨鍦�");
+ }
+
+ var available = CalculateAvailableQuantity(stock, outboundOrderDetail.MaterielCode,
+ outboundOrderDetail.BatchNo, outboundOrderDetail.SupplyCode);
+
+ if (available <= 0)
+ {
+ return (false, $"鎵樼洏[{selection.PalletCode}]娌℃湁鍙敤搴撳瓨");
+ }
+ }
+
+ return (true, "楠岃瘉閫氳繃");
+ }
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs"
index 7fd87d6..51bb24d 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderService.cs"
@@ -3,6 +3,8 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SqlSugar;
+using SqlSugar.Extensions;
+using WIDESEA_Common.OrderEnum;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
@@ -63,15 +65,17 @@
}
foreach (var item in model.Details)
{
- var issueoStockResult = await _materialUnitService.ConvertIssueToStockAsync(item.MaterielCode, item.BarcodeQty);
+ var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode,item.BarcodeUnit, item.BarcodeQty);
item.Unit = issueoStockResult.Unit;
item.OrderQuantity = issueoStockResult.Quantity;
- var moveissueoStockResult = await _materialUnitService.ConvertIssueToStockAsync(item.MaterielCode, item.BarcodeMoveQty);
+ var moveissueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeMoveQty);
item.MoveQty = moveissueoStockResult.Quantity;
}
-
- model.OrderNo = CreateCodeByRule(nameof(RuleCodeEnum.OutboundOrderRule));
+ if (model.OrderType != InOrderTypeEnum.AllocatOutbound.ObjToInt() || model.OrderType != InOrderTypeEnum.InternalAllocat.ObjToInt())
+ {
+ model.OrderNo = CreateCodeByRule(nameof(RuleCodeEnum.OutboundOrderRule));
+ }
Db.InsertNav(model).Include(x => x.Details).ExecuteCommand();
return WebResponseContent.Instance.OK();
@@ -94,6 +98,10 @@
if (outboundOrder.Details == null || outboundOrder.Details.Count == 0)
{
return WebResponseContent.Instance.Error($"鏈壘鍒板嚭搴撳崟鏄庣粏淇℃伅");
+ }
+ if (outboundOrder.OrderStatus != OutOrderStatusEnum.鏈紑濮�.ObjToInt())
+ {
+ return WebResponseContent.Instance.Error($"璇ヨ鍗曠姸鎬佷笉鍏佽淇敼");
}
List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>();
List<Dt_OutboundOrderDetail> updateoutboundOrderDetails = new List<Dt_OutboundOrderDetail>();
@@ -119,10 +127,10 @@
BarcodeQty = item.OrderQuantity,
BarcodeUnit = item.Unit,
};
- var issueoStockResult = await _materialUnitService.ConvertIssueToStockAsync(item.MaterielCode, item.BarcodeQty);
+ var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode,item.BarcodeUnit, item.BarcodeQty);
item.Unit = issueoStockResult.Unit;
item.OrderQuantity = issueoStockResult.Quantity;
- var moveissueoStockResult = await _materialUnitService.ConvertIssueToStockAsync(item.MaterielCode, item.BarcodeMoveQty);
+ var moveissueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeMoveQty);
item.MoveQty = moveissueoStockResult.Quantity;
outboundOrderDetails.Add(outboundOrderDetail);
@@ -140,10 +148,10 @@
outboundOrderDetail.BarcodeMoveQty = item.MoveQty;
outboundOrderDetail.BarcodeQty = item.OrderQuantity;
outboundOrderDetail.BarcodeUnit = item.Unit;
- var issueoStockResult = await _materialUnitService.ConvertIssueToStockAsync(item.MaterielCode, item.BarcodeQty);
+ var issueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeQty);
outboundOrderDetail.Unit = issueoStockResult.Unit;
outboundOrderDetail.OrderQuantity = issueoStockResult.Quantity;
- var moveissueoStockResult = await _materialUnitService.ConvertIssueToStockAsync(item.MaterielCode, item.BarcodeMoveQty);
+ var moveissueoStockResult = await _materialUnitService.ConvertFromToStockAsync(item.MaterielCode, item.BarcodeUnit, item.BarcodeMoveQty);
outboundOrderDetail.MoveQty = moveissueoStockResult.Quantity;
@@ -195,7 +203,10 @@
{
return WebResponseContent.Instance.Error($"鏈壘鍒板嚭搴撳崟鏄庣粏淇℃伅");
}
-
+ if (outboundOrder.OrderStatus != OutOrderStatusEnum.鏈紑濮�.ObjToInt())
+ {
+ return WebResponseContent.Instance.Error($"璇ヨ鍗曠姸鎬佷笉鍏佽鍒犻櫎");
+ }
_unitOfWorkManage.BeginTran();
//BaseDal.DeleteAndMoveIntoHty(outboundOrder, OperateTypeEnum.鑷姩鍒犻櫎);
foreach (var item in outboundOrder.Details)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
index 5cc1885..84ab0f8 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundPickingService.cs"
@@ -8,7 +8,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
+using System.Text.Json;
using System.Threading.Tasks;
+using WIDESEA_Common.CommonEnum;
using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.OrderEnum;
using WIDESEA_Common.StockEnum;
@@ -16,10 +18,13 @@
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
+using WIDESEA_Core.Enums;
using WIDESEA_Core.Helper;
+using WIDESEA_DTO.Allocate;
using WIDESEA_DTO.Basic;
using WIDESEA_DTO.Inbound;
using WIDESEA_DTO.Outbound;
+using WIDESEA_IAllocateService;
using WIDESEA_IBasicService;
using WIDESEA_IInboundService;
using WIDESEA_IOutboundService;
@@ -48,8 +53,7 @@
private readonly IESSApiService _eSSApiService;
private readonly IInvokeMESService _invokeMESService;
private readonly IDailySequenceService _dailySequenceService;
- private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository;
- private readonly IInboundOrderDetailService _inboundOrderDetailService;
+
private readonly ILogger<OutboundPickingService> _logger;
private Dictionary<string, string> stations = new Dictionary<string, string>
@@ -69,7 +73,7 @@
public OutboundPickingService(IRepository<Dt_PickingRecord> BaseDal, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, IStockService stockService,
IOutStockLockInfoService outStockLockInfoService, IStockInfoDetailService stockInfoDetailService, ILocationInfoService locationInfoService,
IOutboundOrderDetailService outboundOrderDetailService, ISplitPackageService splitPackageService, IOutboundOrderService outboundOrderService,
- IRepository<Dt_Task> taskRepository, IESSApiService eSSApiService, ILogger<OutboundPickingService> logger, IInvokeMESService invokeMESService, IDailySequenceService dailySequenceService, IRepository<Dt_InboundOrder> inboundOrderRepository, IInboundOrderDetailService inboundOrderDetailService) : base(BaseDal)
+ IRepository<Dt_Task> taskRepository, IESSApiService eSSApiService, ILogger<OutboundPickingService> logger, IInvokeMESService invokeMESService, IDailySequenceService dailySequenceService) : base(BaseDal)
{
_unitOfWorkManage = unitOfWorkManage;
_stockInfoService = stockInfoService;
@@ -85,10 +89,10 @@
_logger = logger;
_invokeMESService = invokeMESService;
_dailySequenceService = dailySequenceService;
- _inboundOrderRepository = inboundOrderRepository;
- _inboundOrderDetailService = inboundOrderDetailService;
}
+
+ #region 鏌ヨ鏂规硶
// 鑾峰彇鏈嫞閫夊垪琛�
public async Task<List<Dt_OutStockLockInfo>> GetUnpickedList(string orderNo, string palletCode)
{
@@ -151,6 +155,8 @@
return summary;
}
+ #endregion
+
#region 鏍稿績涓氬姟娴佺▼
/// <summary>
/// 鎷i��
@@ -164,7 +170,7 @@
try
{
_unitOfWorkManage.BeginTran();
-
+
var validationResult = await ValidatePickingRequest(orderNo, palletCode, barcode);
if (!validationResult.IsValid)
return WebResponseContent.Instance.Error(validationResult.ErrorMessage);
@@ -184,10 +190,10 @@
return WebResponseContent.Instance.Error(overPickingValidation.ErrorMessage);
}
- // 鎵ц鍒嗘嫞閫昏緫
+ // 鎵ц鍒嗘嫞閫昏緫锛堝彧澶勭悊搴撳瓨鍜岄攣瀹氾紝涓嶅鐞嗚鍗曪級
var pickingResult = await ExecutePickingLogic(lockInfo, orderDetail, stockDetail, orderNo, palletCode, barcode, actualQty);
- // 鏇存柊鐩稿叧鏁版嵁
+ // 缁熶竴鏇存柊璁㈠崟鏁版嵁锛堟墍鏈夊垎鏀兘鍦ㄨ繖閲屾洿鏂帮級
await UpdateOrderRelatedData(orderDetail.Id, pickingResult.ActualPickedQty, orderNo);
// 璁板綍鎿嶄綔鍘嗗彶
@@ -204,6 +210,7 @@
return WebResponseContent.Instance.Error($"鎷i�夌‘璁ゅけ璐ワ細{ex.Message}");
}
}
+
/// <summary>
/// 鍙栨秷鎷i��
/// </summary>
@@ -221,19 +228,19 @@
}
_unitOfWorkManage.BeginTran();
- // 1. 鍓嶇疆楠岃瘉
+ // 鍓嶇疆楠岃瘉
var validationResult = await ValidateCancelRequest(orderNo, palletCode, barcode);
if (!validationResult.IsValid)
return WebResponseContent.Instance.Error(validationResult.ErrorMessage);
var (pickingRecord, lockInfo, orderDetail) = validationResult.Data;
- // 2. 鎵ц鍙栨秷閫昏緫
+ //鎵ц鍙栨秷閫昏緫
await ExecuteCancelLogic(lockInfo, pickingRecord, orderDetail, orderNo);
_unitOfWorkManage.CommitTran();
- return WebResponseContent.Instance.OK($"鍙栨秷鍒嗘嫞鎴愬姛锛屾仮澶嶆暟閲忥細{pickingRecord.PickQuantity}");
+ return WebResponseContent.Instance.OK($"鍙栨秷鍒嗘嫞鎴愬姛");
}
catch (Exception ex)
{
@@ -255,11 +262,11 @@
{
_unitOfWorkManage.BeginTran();
- // 1. 鍩虹楠岃瘉
+
if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode))
return WebResponseContent.Instance.Error("璁㈠崟鍙峰拰鎵樼洏鐮佷笉鑳戒负绌�");
- // 2. 鑾峰彇搴撳瓨鍜屼换鍔′俊鎭�
+ // 鑾峰彇搴撳瓨鍜屼换鍔′俊鎭�
var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>().FirstAsync(x => x.PalletCode == palletCode);
if (stockInfo == null)
@@ -269,23 +276,37 @@
if (task == null)
return WebResponseContent.Instance.Error("鏈壘鍒板搴旂殑浠诲姟淇℃伅");
- // 3. 鍒嗘瀽闇�瑕佸洖搴撶殑璐х墿
- var returnAnalysis = await AnalyzeReturnItems(orderNo, palletCode, stockInfo.Id);
- if (!returnAnalysis.HasItemsToReturn)
- return await HandleNoReturnItems(orderNo, palletCode,task);
+ //鍒嗘瀽闇�瑕佸洖搴撶殑璐х墿
+ //var returnAnalysis = await AnalyzeReturnItems(orderNo, palletCode, stockInfo.Id);
+ //if (!returnAnalysis.HasItemsToReturn)
+ // return await HandleNoReturnItems(orderNo, palletCode, task);
- // 4. 鎵ц鍥炲簱鎿嶄綔
- await ExecuteReturnOperations(orderNo, palletCode, stockInfo, task, returnAnalysis);
+ var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockInfo.Id);
+ if (!statusAnalysis.HasItemsToReturn)
+ return await HandleNoReturnItems(orderNo, palletCode, task, stockInfo.Id);
- // 5. 鍒涘缓鍥炲簱浠诲姟
- await CreateReturnTaskAndHandleESS(orderNo, palletCode, task, returnAnalysis);
+ // 4. 妫�鏌ユ槸鍚︽湁杩涜涓殑浠诲姟
+ if (statusAnalysis.HasActiveTasks)
+ {
+ return WebResponseContent.Instance.Error($"鎵樼洏 {palletCode} 鏈夎繘琛屼腑鐨勪换鍔★紝涓嶈兘鎵ц鍥炲簱鎿嶄綔");
+ }
+
+ //鎵ц鍥炲簱鎿嶄綔
+ await ExecuteReturnOperations(orderNo, palletCode, stockInfo, task, statusAnalysis);
+
+ await ReleaseAllLocksForReallocation(orderNo, palletCode, statusAnalysis);
_unitOfWorkManage.CommitTran();
- // 6. 鏇存柊璁㈠崟鐘舵�侊紙涓嶈Е鍙慚ES鍥炰紶锛�
+
+ // 鍒涘缓鍥炲簱浠诲姟
+ await CreateReturnTaskAndHandleESS(orderNo, palletCode, task, TaskTypeEnum.InPick, task.PalletType);
+
+ // 鏇存柊璁㈠崟鐘舵�侊紙涓嶈Е鍙慚ES鍥炰紶锛�
await UpdateOrderStatusForReturn(orderNo);
- return WebResponseContent.Instance.OK($"鍥炲簱鎿嶄綔鎴愬姛锛屽叡鍥炲簱鏁伴噺锛歿returnAnalysis.TotalReturnQty}");
+ return WebResponseContent.Instance.OK($"鍥炲簱鎿嶄綔鎴愬姛");
+ //return WebResponseContent.Instance.OK($"鍥炲簱鎿嶄綔鎴愬姛锛屽叡鍥炲簱鏁伴噺锛歿statusAnalysis.TotalReturnQty}");
}
catch (Exception ex)
{
@@ -295,6 +316,71 @@
}
}
+ /// <summary>
+ /// 绌烘墭鐩樺彇璧版帴鍙o紙甯﹁鍗曞彿锛�
+ /// 楠岃瘉鎵樼洏鏄惁鐪熺殑涓虹┖锛屾竻鐞嗘暟鎹紝鏇存柊璁㈠崟鐘舵�侊紝鍒涘缓鍙栨墭鐩樹换鍔�
+ /// </summary>
+ public async Task<WebResponseContent> RemoveEmptyPallet(string orderNo, string palletCode)
+ {
+ try
+ {
+ _unitOfWorkManage.BeginTran();
+
+ if (string.IsNullOrEmpty(orderNo) || string.IsNullOrEmpty(palletCode))
+ return WebResponseContent.Instance.Error("璁㈠崟鍙峰拰鎵樼洏鐮佷笉鑳戒负绌�");
+
+ // 妫�鏌ヨ鍗曟槸鍚﹀瓨鍦�
+ var order = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+ .Where(x => x.OrderNo == orderNo)
+ .FirstAsync();
+
+ if (order == null)
+ return WebResponseContent.Instance.Error($"鏈壘鍒拌鍗� {orderNo}");
+
+ //妫�鏌ユ墭鐩樻槸鍚﹀瓨鍦ㄤ笖灞炰簬璇ヨ鍗�
+ var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
+ .Where(x => x.PalletCode == palletCode)
+ .FirstAsync();
+
+ if (stockInfo == null)
+ return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩� {palletCode} 瀵瑰簲鐨勫簱瀛樹俊鎭�");
+
+ var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockInfo.Id);
+
+ if (!statusAnalysis.CanRemove)
+ {
+ if (!statusAnalysis.IsEmptyPallet)
+ {
+ return WebResponseContent.Instance.Error($"鎵樼洏 {palletCode} 涓婅繕鏈夎揣鐗╋紝涓嶈兘鍙栬蛋");
+ }
+ if (statusAnalysis.HasActiveTasks)
+ {
+ return WebResponseContent.Instance.Error($"鎵樼洏 {palletCode} 杩樻湁杩涜涓殑浠诲姟锛屼笉鑳藉彇璧�");
+ }
+ }
+ // 娓呯悊闆跺簱瀛樻暟鎹�
+ await CleanupZeroStockData(stockInfo.Id);
+
+ // 鍒犻櫎鎴栧彇娑堢浉鍏充换鍔�
+ await HandleTaskCleanup(orderNo, palletCode);
+
+ // 鏇存柊璁㈠崟鐩稿叧鏁版嵁
+ await UpdateOrderData(orderNo, palletCode);
+
+
+ _unitOfWorkManage.CommitTran();
+
+ _logger.LogInformation($"绌烘墭鐩樺彇璧版搷浣滄垚鍔� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}, 鎿嶄綔浜�: {App.User.UserName}");
+
+ return WebResponseContent.Instance.OK("绌烘墭鐩樺彇璧版搷浣滄垚鍔�");
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"RemoveEmptyPallet澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"绌烘墭鐩樺彇璧板け璐�: {ex.Message}");
+ }
+ }
#endregion
#region 鍒嗘嫞纭绉佹湁鏂规硶
@@ -370,7 +456,7 @@
{
// 鏌ユ壘鍚屼竴璁㈠崟涓嬬殑璁板綍
lockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.OrderNo == orderNo && it.CurrentBarcode == barcode && it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� && it.AssignQuantity > it.PickedQty).FirstAsync();
+ .Where(it => it.OrderNo == orderNo && it.CurrentBarcode == barcode && it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� && it.AssignQuantity > it.PickedQty).FirstAsync();
if (lockInfo == null)
{
@@ -439,7 +525,7 @@
adjustedReason = adjustedReason != null
? $"{adjustedReason}锛岄槻瓒呮嫞闄愬埗锛氭渶缁堣皟鏁翠负{actualQty}"
: $"闃茶秴鎷i檺鍒讹細浠巤plannedQty}璋冩暣涓簕actualQty}";
- }
+ }
if (adjustedReason != null)
{
@@ -470,9 +556,11 @@
return ValidationResult<bool>.Success(true);
}
+
+
private async Task<PickingResult> ExecutePickingLogic(
- Dt_OutStockLockInfo lockInfo, Dt_OutboundOrderDetail orderDetail, Dt_StockInfoDetail stockDetail,
- string orderNo, string palletCode, string barcode, decimal actualQty)
+ Dt_OutStockLockInfo lockInfo, Dt_OutboundOrderDetail orderDetail, Dt_StockInfoDetail stockDetail,
+ string orderNo, string palletCode, string barcode, decimal actualQty)
{
decimal stockQuantity = stockDetail.StockQuantity;
var result = new PickingResult
@@ -486,50 +574,58 @@
if (actualQty < stockQuantity)
{
await HandleSplitPacking(lockInfo, stockDetail, actualQty, stockQuantity, result);
+ // 鎷嗗寘鍦烘櫙杩斿洖瀹為檯鎷i�夋暟閲�
+ result.ActualPickedQty = actualQty;
}
else if (actualQty == stockQuantity)
{
await HandleFullPicking(lockInfo, stockDetail, actualQty, result);
+ // 鏁村寘鎷i�夎繑鍥炲疄闄呮嫞閫夋暟閲�
+ result.ActualPickedQty = actualQty;
}
else
{
await HandlePartialPicking(lockInfo, stockDetail, actualQty, stockQuantity, result);
+ // 閮ㄥ垎鎷i�夎繑鍥炶皟鏁村悗鐨勬暟閲�
+ result.ActualPickedQty = result.ActualPickedQty; // 宸茬粡鍦ㄦ柟娉曞唴璋冩暣
}
return result;
}
-
private async Task HandleSplitPacking(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail,
- decimal actualQty, decimal stockQuantity, PickingResult result)
+ decimal actualQty, decimal stockQuantity, PickingResult result)
{
decimal remainingStockQty = stockQuantity - actualQty;
- // 1. 鏇存柊鍘熸潯鐮佸簱瀛�
+ // 鏇存柊鍘熸潯鐮佸簱瀛�
stockDetail.StockQuantity = remainingStockQty;
stockDetail.OutboundQuantity = remainingStockQty;
await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
- // 2. 鐢熸垚鏂版潯鐮�
+ // 鐢熸垚鏂版潯鐮�
string newBarcode = await GenerateNewBarcode();
- // 3. 鍒涘缓鏂伴攣瀹氫俊鎭�
+ // 鍒涘缓鏂伴攣瀹氫俊鎭�
var newLockInfo = await CreateSplitLockInfo(lockInfo, actualQty, newBarcode);
- // 4. 璁板綍鎷嗗寘鍘嗗彶
+ // 璁板綍鎷嗗寘鍘嗗彶
await RecordSplitHistory(lockInfo, stockDetail, actualQty, remainingStockQty, newBarcode);
- // 5. 鏇存柊鍘熼攣瀹氫俊鎭�
+ // 鏇存柊鍘熼攣瀹氫俊鎭�
lockInfo.AssignQuantity = remainingStockQty;
lockInfo.PickedQty = 0;
lockInfo.Operator = App.User.UserName;
await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
- // 6. 璁剧疆缁撴灉
+ // 璁剧疆缁撴灉
result.FinalLockInfo = newLockInfo;
result.FinalBarcode = newBarcode;
result.SplitResults.AddRange(CreateSplitResults(lockInfo, actualQty, remainingStockQty, newBarcode, stockDetail.Barcode));
- }
+
+
+ _logger.LogInformation($"鎷嗗寘鍒嗘嫞瀹屾垚 - OrderDetailId: {lockInfo.OrderDetailId}, 鍒嗘嫞鏁伴噺: {actualQty}");
+ }
private async Task HandleFullPicking(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail,
decimal actualQty, PickingResult result)
{
@@ -581,10 +677,10 @@
if (newOverOutQuantity > currentOrderDetail.NeedOutQuantity)
{
-
+
_logger.LogError($"闃茶秴鎷f鏌ュけ璐� - OrderDetailId: {orderDetailId}, 宸插嚭搴�: {newOverOutQuantity}, 闇�姹�: {currentOrderDetail.NeedOutQuantity}, 鏈鍒嗘嫞: {pickedQty}");
-
+
decimal adjustedQty = currentOrderDetail.NeedOutQuantity - currentOrderDetail.OverOutQuantity;
if (adjustedQty > 0)
@@ -647,7 +743,73 @@
#endregion
#region 鍙栨秷鍒嗘嫞绉佹湁鏂规硶
+ private async Task<ValidationResult<bool>> ValidateDataConsistencyBeforeCancel(CancelPickingContext context)
+ {
+ try
+ {
+ // 楠岃瘉璁㈠崟鏄庣粏鏁版嵁
+ var currentOrderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .FirstAsync(x => x.Id == context.OrderDetail.Id);
+ if (currentOrderDetail.OverOutQuantity < context.PickingRecord.PickQuantity)
+ return ValidationResult<bool>.Error($"璁㈠崟鏄庣粏宸插嚭搴撴暟閲�({currentOrderDetail.OverOutQuantity})灏忎簬鍙栨秷鏁伴噺({context.PickingRecord.PickQuantity})");
+
+ if (currentOrderDetail.PickedQty < context.PickingRecord.PickQuantity)
+ return ValidationResult<bool>.Error($"璁㈠崟鏄庣粏宸叉嫞閫夋暟閲�({currentOrderDetail.PickedQty})灏忎簬鍙栨秷鏁伴噺({context.PickingRecord.PickQuantity})");
+
+ // 楠岃瘉閿佸畾淇℃伅鏁版嵁
+ var currentLockInfo = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .FirstAsync(x => x.Id == context.LockInfo.Id);
+
+ if (currentLockInfo.PickedQty < context.PickingRecord.PickQuantity)
+ return ValidationResult<bool>.Error($"閿佸畾淇℃伅宸叉嫞閫夋暟閲�({currentLockInfo.PickedQty})灏忎簬鍙栨秷鏁伴噺({context.PickingRecord.PickQuantity})");
+
+ ////// 楠岃瘉搴撳瓨鏁版嵁
+ ////var currentStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ //// .FirstAsync(x => x.Barcode == context.PickingRecord.Barcode && x.StockId == context.PickingRecord.StockId);
+
+ ////if (currentStockDetail == null)
+ //// return ValidationResult<bool>.Error($"鏈壘鍒板搴旂殑搴撳瓨鏄庣粏璁板綍");
+
+ ////if (currentStockDetail.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt() ||
+ //// currentStockDetail.Status == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt())
+ //// return ValidationResult<bool>.Error($"鏉$爜{context.PickingRecord.Barcode}宸茬粡鍥炲簱锛屾棤娉曞彇娑堝垎鎷�");
+
+ // 楠岃瘉鐘舵�佹祦杞殑鍚堟硶鎬�
+ if (!await CanCancelPicking(currentLockInfo, null))
+ return ValidationResult<bool>.Error($"褰撳墠鐘舵�佷笉鍏佽鍙栨秷鍒嗘嫞");
+
+ return ValidationResult<bool>.Success(true);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"鍙栨秷鍒嗘嫞鏁版嵁涓�鑷存�ч獙璇佸け璐�: {ex.Message}");
+ return ValidationResult<bool>.Error($"鏁版嵁楠岃瘉澶辫触: {ex.Message}");
+ }
+ }
+
+ private async Task<bool> CanCancelPicking(Dt_OutStockLockInfo lockInfo, Dt_StockInfoDetail stockDetail)
+ {
+ // 閿佸畾淇℃伅鐘舵�佹鏌�
+ if (lockInfo.Status != (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ return false;
+
+ ////// 搴撳瓨鐘舵�佹鏌�
+ ////if (stockDetail.Status == StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt())
+ //// return false;
+
+ // 濡傛灉鏄媶鍖呰褰曪紝杩橀渶瑕佹鏌ョ埗閿佸畾淇℃伅鐘舵��
+ if (lockInfo.IsSplitted == 1 && lockInfo.ParentLockId.HasValue)
+ {
+ var parentLock = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .FirstAsync(x => x.Id == lockInfo.ParentLockId.Value);
+
+ if (parentLock == null || parentLock.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�)
+ return false;
+ }
+
+ return true;
+ }
private async Task<ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>> ValidateCancelRequest(string orderNo, string palletCode, string barcode)
{
// 鍩虹鍙傛暟楠岃瘉
@@ -676,7 +838,7 @@
if (lockInfo == null)
return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error("鏈壘鍒板搴旂殑鍑哄簱閿佸畾淇℃伅");
-
+
if (lockInfo.PickedQty < pickingRecord.PickQuantity)
{
return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error(
@@ -718,8 +880,8 @@
{
return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Error($"鏉$爜{barcode}宸茬粡鍥炲簱锛屼笉鑳藉彇娑堝垎鎷�");
}
- }
-
+ }
+
return ValidationResult<(Dt_PickingRecord, Dt_OutStockLockInfo, Dt_OutboundOrderDetail)>.Success((pickingRecord, lockInfo, orderDetail));
}
/// <summary>
@@ -755,30 +917,25 @@
stockDetail.Status == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
}
private async Task ExecuteCancelLogic(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord,
- Dt_OutboundOrderDetail orderDetail, string orderNo)
+ Dt_OutboundOrderDetail orderDetail, string orderNo)
{
decimal cancelQty = pickingRecord.PickQuantity;
- var currentStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.Barcode == pickingRecord.Barcode && it.StockId == pickingRecord.StockId)
- .FirstAsync();
-
- if (currentStockDetail != null &&
- (currentStockDetail.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt() ||
- currentStockDetail.Status == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt()))
+ // 鏁版嵁涓�鑷存�ч獙璇�
+ var context = new CancelPickingContext
{
- throw new Exception($"鏉$爜{pickingRecord.Barcode}宸茬粡鍥炲簱锛屾棤娉曞彇娑堝垎鎷�");
- }
- // 妫�鏌ュ彇娑堝悗鏁伴噺涓嶄細涓鸿礋鏁�
- decimal newOverOutQuantity = orderDetail.OverOutQuantity - cancelQty;
- decimal newPickedQty = orderDetail.PickedQty - cancelQty;
+ LockInfo = lockInfo,
+ PickingRecord = pickingRecord,
+ OrderDetail = orderDetail,
+ OrderNo = orderNo,
+ CancelQuantity = cancelQty
+ };
- if (newOverOutQuantity < 0 || newPickedQty < 0)
- {
- throw new Exception($"鍙栨秷鍒嗘嫞灏嗗鑷存暟鎹紓甯革細宸插嚭搴搟newOverOutQuantity}锛屽凡鎷i�墈newPickedQty}");
- }
+ var validationResult = await ValidateDataConsistencyBeforeCancel(context);
+ if (!validationResult.IsValid)
+ throw new Exception(validationResult.ErrorMessage);
- // 澶勭悊涓嶅悓绫诲瀷鐨勫彇娑�
+ // 澶勭悊涓嶅悓绫诲瀷鐨勫彇娑�
if (lockInfo.IsSplitted == 1 && lockInfo.ParentLockId.HasValue)
{
await HandleSplitBarcodeCancel(lockInfo, pickingRecord, cancelQty);
@@ -788,16 +945,23 @@
await HandleNormalBarcodeCancel(lockInfo, pickingRecord, cancelQty);
}
- // 鏇存柊璁㈠崟鏄庣粏
+ // 鏇存柊璁㈠崟鏄庣粏
await UpdateOrderDetailOnCancel(pickingRecord.OrderDetailId, cancelQty);
// 鍒犻櫎鎷i�夎褰�
- await Db.Deleteable<Dt_PickingRecord>()
+ var deleteResult = await Db.Deleteable<Dt_PickingRecord>()
.Where(x => x.Id == pickingRecord.Id)
.ExecuteCommandAsync();
- // 閲嶆柊妫�鏌ヨ鍗曠姸鎬�
+ if (deleteResult <= 0)
+ throw new Exception("鍒犻櫎鎷i�夎褰曞け璐�");
+
+ _logger.LogInformation($"鍒犻櫎鎷i�夎褰� - 璁板綍ID: {pickingRecord.Id}, 鏉$爜: {pickingRecord.Barcode}");
+
+ // 閲嶆柊妫�鏌ヨ鍗曠姸鎬�
await UpdateOrderStatusForReturn(orderNo);
+
+
}
private async Task HandleSplitBarcodeCancel(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, decimal cancelQty)
@@ -810,59 +974,85 @@
if (parentLockInfo == null)
throw new Exception("鏈壘鍒扮埗閿佸畾淇℃伅锛屾棤娉曞彇娑堟媶鍖呭垎鎷�");
+ // 妫�鏌ョ埗鏉$爜鍜屾媶鍖呮潯鐮佺殑鐘舵��
if (await IsLockInfoReturned(parentLockInfo))
- {
throw new Exception($"鐖舵潯鐮亄parentLockInfo.CurrentBarcode}宸茬粡鍥炲簱锛屾棤娉曞彇娑堟媶鍖呭垎鎷�");
- }
+
if (await IsLockInfoReturned(lockInfo))
- {
throw new Exception($"鎷嗗寘鏉$爜{lockInfo.CurrentBarcode}宸茬粡鍥炲簱锛屾棤娉曞彇娑堟媶鍖呭垎鎷�");
- }
+
// 鎭㈠鐖堕攣瀹氫俊鎭殑鍒嗛厤鏁伴噺
parentLockInfo.AssignQuantity += cancelQty;
+ parentLockInfo.Status = (int)OutLockStockStatusEnum.鍑哄簱涓�; // 鎭㈠涓哄嚭搴撲腑鐘舵��
await _outStockLockInfoService.Db.Updateable(parentLockInfo).ExecuteCommandAsync();
- // 鎭㈠搴撳瓨
- var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ // 鎭㈠鐖舵潯鐮佸簱瀛�
+ var parentStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.Where(x => x.Barcode == parentLockInfo.CurrentBarcode && x.StockId == parentLockInfo.StockId)
.FirstAsync();
- if (stockDetail != null)
+ if (parentStockDetail != null)
{
- stockDetail.StockQuantity += cancelQty;
- stockDetail.OutboundQuantity = stockDetail.StockQuantity;
- stockDetail.Status = StockStatusEmun.鍑哄簱閿佸畾.ObjToInt();
- await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+ parentStockDetail.StockQuantity += cancelQty;
+ parentStockDetail.OutboundQuantity = parentStockDetail.StockQuantity;
+ parentStockDetail.Status = StockStatusEmun.鍑哄簱閿佸畾.ObjToInt();
+ await _stockInfoDetailService.Db.Updateable(parentStockDetail).ExecuteCommandAsync();
+
+ _logger.LogInformation($"鎭㈠鐖舵潯鐮佸簱瀛� - 鏉$爜: {parentStockDetail.Barcode}, 鎭㈠鏁伴噺: {cancelQty}, 鏂板簱瀛�: {parentStockDetail.StockQuantity}");
+ }
+
+ // 澶勭悊鎷嗗寘浜х敓鐨勬柊鏉$爜搴撳瓨
+ var splitStockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .Where(x => x.Barcode == lockInfo.CurrentBarcode && x.StockId == lockInfo.StockId)
+ .FirstAsync();
+
+ if (splitStockDetail != null)
+ {
+ // 鍒犻櫎鎷嗗寘浜х敓鐨勬柊鏉$爜搴撳瓨璁板綍
+ await _stockInfoDetailService.Db.Deleteable(splitStockDetail).ExecuteCommandAsync();
+ _logger.LogInformation($"鍒犻櫎鎷嗗寘鏂版潯鐮佸簱瀛� - 鏉$爜: {splitStockDetail.Barcode}");
}
// 鏇存柊鎷嗗寘璁板綍鐘舵��
- await _splitPackageService.Db.Updateable<Dt_SplitPackageRecord>()
+ var updateCount = await _splitPackageService.Db.Updateable<Dt_SplitPackageRecord>()
.SetColumns(x => new Dt_SplitPackageRecord
{
Status = (int)SplitPackageStatusEnum.宸叉挙閿�,
IsReverted = true,
+ Operator = App.User.UserName,
+ RevertTime = DateTime.Now
})
.Where(x => x.NewBarcode == lockInfo.CurrentBarcode && !x.IsReverted)
.ExecuteCommandAsync();
+
+ _logger.LogInformation($"鏇存柊鎷嗗寘璁板綍鐘舵�� - 鏇存柊璁板綍鏁�: {updateCount}");
// 鍒犻櫎鎷嗗寘浜х敓鐨勯攣瀹氫俊鎭�
await _outStockLockInfoService.Db.Deleteable<Dt_OutStockLockInfo>()
.Where(x => x.Id == lockInfo.Id)
.ExecuteCommandAsync();
- }
+ _logger.LogInformation($"鍒犻櫎鎷嗗寘閿佸畾淇℃伅 - 閿佸畾ID: {lockInfo.Id}, 鏉$爜: {lockInfo.CurrentBarcode}");
+ }
private async Task HandleNormalBarcodeCancel(Dt_OutStockLockInfo lockInfo, Dt_PickingRecord pickingRecord, decimal cancelQty)
{
if (await IsLockInfoReturned(lockInfo))
- {
throw new Exception($"鏉$爜{lockInfo.CurrentBarcode}宸茬粡鍥炲簱锛屾棤娉曞彇娑堝垎鎷�");
- }
+
// 鎭㈠閿佸畾淇℃伅
lockInfo.PickedQty -= cancelQty;
if (lockInfo.PickedQty < 0) lockInfo.PickedQty = 0;
- lockInfo.Status = (int)OutLockStockStatusEnum.鍑哄簱涓�;
+ // 鍙湁褰撴嫞閫夋暟閲忓畬鍏ㄥ彇娑堟椂鎵嶆仮澶嶇姸鎬�
+ if (lockInfo.PickedQty == 0)
+ {
+ lockInfo.Status = (int)OutLockStockStatusEnum.鍑哄簱涓�;
+ }
+
+ lockInfo.Operator = App.User.UserName;
await _outStockLockInfoService.Db.Updateable(lockInfo).ExecuteCommandAsync();
+
+ _logger.LogInformation($"鎭㈠閿佸畾淇℃伅 - 閿佸畾ID: {lockInfo.Id}, 鎵e噺鎷i�夋暟閲�: {cancelQty}, 鏂板凡鎷i�夋暟閲�: {lockInfo.PickedQty}");
// 鎭㈠搴撳瓨
var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
@@ -873,36 +1063,57 @@
{
stockDetail.StockQuantity += cancelQty;
stockDetail.OutboundQuantity = stockDetail.StockQuantity;
- stockDetail.Status = StockStatusEmun.鍑哄簱閿佸畾.ObjToInt();
+
+ // 鎭㈠搴撳瓨鐘舵��
+ if (stockDetail.Status == StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt())
+ {
+ stockDetail.Status = StockStatusEmun.鍑哄簱閿佸畾.ObjToInt();
+ }
+
await _stockInfoDetailService.Db.Updateable(stockDetail).ExecuteCommandAsync();
+
+ _logger.LogInformation($"鎭㈠搴撳瓨 - 鏉$爜: {stockDetail.Barcode}, 鎭㈠鏁伴噺: {cancelQty}, " +
+ $"鏂板簱瀛�: {stockDetail.StockQuantity}, 鏂扮姸鎬�: {stockDetail.Status}");
+ }
+ else
+ {
+ _logger.LogWarning($"鏈壘鍒板簱瀛樿褰� - 鏉$爜: {pickingRecord.Barcode}, 搴撳瓨ID: {pickingRecord.StockId}");
}
}
-
private async Task UpdateOrderDetailOnCancel(int orderDetailId, decimal cancelQty)
{
- // 鑾峰彇鏈�鏂扮殑璁㈠崟鏄庣粏鏁版嵁
+ // 鑾峰彇鏈�鏂扮殑璁㈠崟鏄庣粏鏁版嵁锛堝甫閿侊級
var currentOrderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .With(SqlWith.RowLock)
.FirstAsync(x => x.Id == orderDetailId);
decimal newOverOutQuantity = currentOrderDetail.OverOutQuantity - cancelQty;
decimal newPickedQty = currentOrderDetail.PickedQty - cancelQty;
- // 妫�鏌ュ彇娑堝悗鏁伴噺涓嶄細涓鸿礋鏁�
- if (newOverOutQuantity < 0 || newPickedQty < 0)
- {
- throw new Exception($"鍙栨秷鍒嗘嫞灏嗗鑷村凡鍑哄簱鏁伴噺({newOverOutQuantity})鎴栧凡鎷i�夋暟閲�({newPickedQty})涓鸿礋鏁�");
- }
+ // 涓ユ牸妫�鏌ュ彇娑堝悗鏁伴噺涓嶄細涓鸿礋鏁�
+ if (newOverOutQuantity < 0)
+ throw new Exception($"鍙栨秷鍒嗘嫞灏嗗鑷村凡鍑哄簱鏁伴噺({newOverOutQuantity})涓鸿礋鏁�");
- await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ if (newPickedQty < 0)
+ throw new Exception($"鍙栨秷鍒嗘嫞灏嗗鑷村凡鎷i�夋暟閲�({newPickedQty})涓鸿礋鏁�");
+
+ // 鏇存柊璁㈠崟鏄庣粏
+ var updateResult = await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
.SetColumns(it => new Dt_OutboundOrderDetail
{
PickedQty = newPickedQty,
- OverOutQuantity = newOverOutQuantity,
+ OverOutQuantity = newOverOutQuantity
})
.Where(it => it.Id == orderDetailId)
.ExecuteCommandAsync();
- }
+ if (updateResult <= 0)
+ throw new Exception("鏇存柊璁㈠崟鏄庣粏澶辫触");
+
+ _logger.LogInformation($"鏇存柊璁㈠崟鏄庣粏 - OrderDetailId: {orderDetailId}, " +
+ $"鎵e噺宸插嚭搴�: {cancelQty}, 鏂板凡鍑哄簱: {newOverOutQuantity}, " +
+ $"鎵e噺宸叉嫞閫�: {cancelQty}, 鏂板凡鎷i��: {newPickedQty}");
+ }
#endregion
#region 鍥炲簱鎿嶄綔绉佹湁鏂规硶
@@ -946,58 +1157,6 @@
return task;
}
- private async Task<ReturnAnalysisResult> AnalyzeReturnItems(string orderNo, string palletCode, int stockId)
- {
- var result = new ReturnAnalysisResult();
-
- // 鎯呭喌1锛氳幏鍙栨湭鍒嗘嫞鐨勫嚭搴撻攣瀹氳褰�
- var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.OrderNo == orderNo &&
- it.PalletCode == palletCode &&
- it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
- .ToListAsync();
-
- if (remainingLocks.Any())
- {
- result.HasRemainingLocks = true;
- result.RemainingLocks = remainingLocks;
- result.RemainingLocksReturnQty = remainingLocks.Sum(x => x.AssignQuantity - x.PickedQty);
- }
-
- // 鎯呭喌2锛氭鏌ユ墭鐩樹笂鏄惁鏈夊叾浠栧簱瀛樿揣鐗�
- var palletStockGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.StockId == stockId &&
- (it.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt() ||
- it.Status == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() ||
- it.Status == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()))
- .Where(it => it.StockQuantity > 0)
- .ToListAsync();
-
- if (palletStockGoods.Any())
- {
- result.HasPalletStockGoods = true;
- result.PalletStockGoods = palletStockGoods;
- result.PalletStockReturnQty = palletStockGoods.Sum(x => x.StockQuantity);
- }
-
- // 鎯呭喌3锛氭鏌ユ媶鍖呰褰�
- var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
- .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode && !it.IsReverted && it.Status != (int)SplitPackageStatusEnum.宸插洖搴�)
- .ToListAsync();
-
- if (splitRecords.Any())
- {
- result.HasSplitRecords = true;
- result.SplitRecords = splitRecords;
- result.SplitReturnQty = await CalculateSplitReturnQuantity(splitRecords, stockId);
- }
-
- result.TotalReturnQty = result.RemainingLocksReturnQty + result.PalletStockReturnQty + result.SplitReturnQty;
- result.HasItemsToReturn = result.TotalReturnQty > 0;
-
- return result;
- }
-
private async Task<decimal> CalculateSplitReturnQuantity(List<Dt_SplitPackageRecord> splitRecords, int stockId)
{
decimal totalQty = 0;
@@ -1005,11 +1164,14 @@
foreach (var splitRecord in splitRecords)
{
+ if (splitRecord.Status != (int)SplitPackageStatusEnum.宸叉挙閿�)
+ continue;
// 妫�鏌ュ師鏉$爜
if (!processedBarcodes.Contains(splitRecord.OriginalBarcode))
{
var originalStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.Barcode == splitRecord.OriginalBarcode && it.StockId == stockId)
+ .Where(it => it.Barcode == splitRecord.OriginalBarcode && it.StockId == stockId &&
+ it.Status != StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt())
.FirstAsync();
if (originalStock != null && originalStock.StockQuantity > 0)
@@ -1023,7 +1185,7 @@
if (!processedBarcodes.Contains(splitRecord.NewBarcode))
{
var newStock = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
- .Where(it => it.Barcode == splitRecord.NewBarcode && it.StockId == stockId)
+ .Where(it => it.Barcode == splitRecord.NewBarcode && it.StockId == stockId && it.Status != StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt())
.FirstAsync();
if (newStock != null && newStock.StockQuantity > 0)
@@ -1037,57 +1199,225 @@
return totalQty;
}
- private async Task<WebResponseContent> HandleNoReturnItems(string orderNo, string palletCode,Dt_Task originalTask)
+ private async Task<WebResponseContent> HandleNoReturnItems(string orderNo, string palletCode, Dt_Task originalTask, int stockInfoId)
{
// 妫�鏌ユ槸鍚︽墍鏈夎揣鐗╅兘宸叉嫞閫夊畬鎴�
- var allPicked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode)
- .AnyAsync(it => it.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�);
+ //var allPicked = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ // .Where(it => it.OrderNo == orderNo && it.PalletCode == palletCode)
+ // .AnyAsync(it => it.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�);
- if (allPicked)
+ //if (allPicked)
+ //{
+ // // 鍒犻櫎鍘熷鍑哄簱浠诲姟 缁勭┖鐩� 绌虹洏鍥炲簱
+ // //await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
+ // return WebResponseContent.Instance.OK("鎵�鏈夎揣鐗╁凡鎷i�夊畬鎴愶紝鎵樼洏涓虹┖");
+ //}
+ //else
+ //{
+ // // 鍒犻櫎鍘熷鍑哄簱浠诲姟
+ // //await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
+ // return WebResponseContent.Instance.Error("娌℃湁闇�瑕佸洖搴撶殑鍓╀綑璐х墿");
+ //}
+ try
{
- // 鍒犻櫎鍘熷鍑哄簱浠诲姟
- await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
- return WebResponseContent.Instance.OK("鎵�鏈夎揣鐗╁凡鎷i�夊畬鎴愶紝鎵樼洏涓虹┖");
+ var locationtype = 0;
+ var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
+ .Where(x => x.PalletCode == palletCode)
+ .FirstAsync();
+
+ if (stockInfo == null)
+ {
+ var firstLocation = await _locationInfoService.Db.Queryable<Dt_LocationInfo>().FirstAsync(x => x.LocationCode == originalTask.SourceAddress);
+ locationtype = firstLocation?.LocationType ?? 1;
+ }
+ else
+ {
+ locationtype = stockInfo.LocationType;
+ _stockInfoService.DeleteData(stockInfo);
+ }
+
+ var targetAddress = originalTask.TargetAddress;
+
+ await CleanupZeroStockData(stockInfoId);
+
+
+ var emptystockInfo = new Dt_StockInfo() { PalletType = PalletTypeEnum.Empty.ObjToInt(), StockStatus = StockStatusEmun.缁勭洏鏆傚瓨.ObjToInt(), PalletCode = palletCode, LocationType = locationtype };
+ emptystockInfo.Details = new List<Dt_StockInfoDetail>();
+ _stockInfoService.AddMaterielGroup(emptystockInfo);
+ //绌烘墭鐩樺浣曞鐞� 杩樻湁涓�涓嚭搴撲换鍔¤澶勭悊銆�
+ originalTask.PalletType = PalletTypeEnum.Empty.ObjToInt();
+
+ await CreateReturnTaskAndHandleESS(orderNo, palletCode, originalTask, TaskTypeEnum.InEmpty, PalletTypeEnum.Empty.ObjToInt());
+
}
- else
+ catch (Exception ex)
{
- // 鍒犻櫎鍘熷鍑哄簱浠诲姟
- await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
- return WebResponseContent.Instance.Error("娌℃湁闇�瑕佸洖搴撶殑鍓╀綑璐х墿");
+ _logger.LogError($" HandleNoReturnItems 澶辫触: {ex.Message}");
+ return WebResponseContent.Instance.Error($" 鍥炲簱绌烘墭鐩樺け璐ワ紒");
}
- //绌烘墭鐩樺浣曞鐞� 杩樻湁涓�涓嚭搴撲换鍔¤澶勭悊銆�
-
+ return WebResponseContent.Instance.OK("绌烘墭鐩樺洖搴撲换鍔″垱寤烘垚鍔�");
+
}
private async Task ExecuteReturnOperations(string orderNo, string palletCode, Dt_StockInfo stockInfo,
- Dt_Task task, ReturnAnalysisResult analysis)
+ Dt_Task task, PalletStatusAnalysis analysis)
{
// 鎯呭喌1锛氬鐞嗘湭鍒嗘嫞鐨勫嚭搴撻攣瀹氳褰�
if (analysis.HasRemainingLocks)
{
await HandleRemainingLocksReturn(analysis.RemainingLocks, stockInfo.Id);
- // 鍏抽敭锛氭洿鏂拌鍗曟槑缁嗙殑宸叉嫞閫夋暟閲�
- await UpdateOrderDetailsOnReturn(analysis.RemainingLocks);
+ // await UpdateOrderDetailsOnReturn(analysis.RemainingLocks);
}
// 澶勭悊鎵樼洏涓婂叾浠栧簱瀛樿揣鐗�
if (analysis.HasPalletStockGoods)
{
- await HandlePalletStockGoodsReturn(analysis.PalletStockGoods);
+ var validStockGoods = analysis.PalletStockGoods
+ .Where(x => x.Status != StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt())
+ .ToList();
+
+ if (validStockGoods.Any())
+ {
+ await HandlePalletStockGoodsReturn(analysis.PalletStockGoods);
+ }
+ else
+ {
+ _logger.LogInformation("娌℃湁鏈夋晥鐨勫簱瀛樿揣鐗╅渶瑕佸洖搴�");
+ }
}
// 澶勭悊鎷嗗寘璁板綍
if (analysis.HasSplitRecords)
{
- await HandleSplitRecordsReturn(analysis.SplitRecords, orderNo, palletCode);
+ var validSplitRecords = analysis.SplitRecords
+ .Where(x => x.Status != (int)SplitPackageStatusEnum.宸叉嫞閫�)
+ .ToList();
+
+ if (validSplitRecords.Any())
+ {
+ await HandleSplitRecordsReturn(analysis.SplitRecords, orderNo, palletCode);
+ }
+ else
+ {
+ _logger.LogInformation("娌℃湁鏈夋晥鐨勬媶鍖呰褰曢渶瑕佸鐞�");
+ }
}
// 鏇存柊搴撳瓨涓昏〃鐘舵��
await UpdateStockInfoStatus(stockInfo);
}
+ /// <summary>
+ /// 瀹屽叏閲婃斁閿佸畾锛屽厑璁搁噸鏂板垎閰嶅簱瀛�
+ /// </summary>
+ private async Task ReleaseAllLocksForReallocation(string orderNo, string palletCode, PalletStatusAnalysis analysis)
+ {
+ _logger.LogInformation($"寮�濮嬮噴鏀鹃攣瀹氫互渚块噸鏂板垎閰� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
+
+ // 1. 澶勭悊鏈垎鎷g殑鍑哄簱閿佸畾璁板綍 - 瀹屽叏閲婃斁
+ if (analysis.HasRemainingLocks)
+ {
+ await ReleaseRemainingLocks(analysis.RemainingLocks);
+ }
+
+ // 2. 澶勭悊宸插洖搴撶殑閿佸畾璁板綍 - 鍒犻櫎鎴栨爣璁颁负鏃犳晥
+ await CleanupReturnedLocks(orderNo, palletCode);
+
+ // 3. 閲嶇疆璁㈠崟鏄庣粏鐨勯攣瀹氭暟閲�
+ await ResetOrderDetailLockQuantities(analysis);
+
+ _logger.LogInformation($"閿佸畾閲婃斁瀹屾垚 - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
+ }
+
+ /// <summary>
+ /// 閲婃斁鏈垎鎷g殑閿佸畾璁板綍
+ /// </summary>
+ private async Task ReleaseRemainingLocks(List<Dt_OutStockLockInfo> remainingLocks)
+ {
+ var lockIds = remainingLocks.Select(x => x.Id).ToList();
+
+ // 灏嗛攣瀹氳褰曠姸鎬佹敼涓�"宸查噴鏀�"锛屾垨鑰呯洿鎺ュ垹闄�
+ // 鏍囪涓哄凡閲婃斁
+ await _outStockLockInfoService.Db.Updateable<Dt_OutStockLockInfo>()
+ .SetColumns(it => new Dt_OutStockLockInfo
+ {
+ Status = (int)OutLockStockStatusEnum.宸查噴鏀�, // 闇�瑕佹柊澧炶繖涓姸鎬�
+ // ReleaseTime = DateTime.Now,
+ Operator = App.User.UserName
+ })
+ .Where(it => lockIds.Contains(it.Id))
+ .ExecuteCommandAsync();
+
+ // 鐩存帴鍒犻櫎锛堟洿褰诲簳锛�
+ // await _outStockLockInfoService.Db.Deleteable<Dt_OutStockLockInfo>()
+ // .Where(it => lockIds.Contains(it.Id))
+ // .ExecuteCommandAsync();
+
+ _logger.LogInformation($"閲婃斁{remainingLocks.Count}鏉℃湭鍒嗘嫞閿佸畾璁板綍");
+ }
+
+ /// <summary>
+ /// 娓呯悊宸插洖搴撶殑閿佸畾璁板綍
+ /// </summary>
+ private async Task CleanupReturnedLocks(string orderNo, string palletCode)
+ {
+ // 鏌ユ壘鎵�鏈夌姸鎬佷负鍥炲簱涓殑閿佸畾璁板綍骞堕噴鏀�
+ var returnedLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(it => it.OrderNo == orderNo &&
+ it.PalletCode == palletCode &&
+ it.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�)
+ .ToListAsync();
+
+ if (returnedLocks.Any())
+ {
+ var returnedLockIds = returnedLocks.Select(x => x.Id).ToList();
+
+ await _outStockLockInfoService.Db.Updateable<Dt_OutStockLockInfo>()
+ .SetColumns(it => new Dt_OutStockLockInfo
+ {
+ Status = (int)OutLockStockStatusEnum.宸查噴鏀�,
+ //ReleaseTime = DateTime.Now,
+ Operator = App.User.UserName
+ })
+ .Where(it => returnedLockIds.Contains(it.Id))
+ .ExecuteCommandAsync();
+
+ _logger.LogInformation($"娓呯悊{returnedLocks.Count}鏉″洖搴撲腑閿佸畾璁板綍");
+ }
+ }
+
+ /// <summary>
+ /// 閲嶇疆璁㈠崟鏄庣粏鐨勯攣瀹氭暟閲�
+ /// </summary>
+ private async Task ResetOrderDetailLockQuantities(PalletStatusAnalysis analysis)
+ {
+ // 鏀堕泦鎵�鏈夊彈褰卞搷鐨勮鍗曟槑缁咺D
+ var affectedOrderDetailIds = new HashSet<int>();
+
+ if (analysis.HasRemainingLocks)
+ {
+ foreach (var lockInfo in analysis.RemainingLocks)
+ {
+ affectedOrderDetailIds.Add(lockInfo.OrderDetailId);
+ }
+ }
+
+ // 閲嶇疆杩欎簺璁㈠崟鏄庣粏鐨勯攣瀹氭暟閲�
+ foreach (var orderDetailId in affectedOrderDetailIds)
+ {
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(it => new Dt_OutboundOrderDetail
+ {
+ LockQuantity = 0, // 閲嶇疆閿佸畾鏁伴噺
+ OrderDetailStatus = OrderDetailStatusEnum.New.ObjToInt() // 閲嶇疆鐘舵�佷负鏂板缓
+ })
+ .Where(it => it.Id == orderDetailId)
+ .ExecuteCommandAsync();
+ }
+
+ _logger.LogInformation($"閲嶇疆{affectedOrderDetailIds.Count}涓鍗曟槑缁嗙殑閿佸畾鏁伴噺");
+ }
private async Task HandleRemainingLocksReturn(List<Dt_OutStockLockInfo> remainingLocks, int stockId)
{
var lockIds = remainingLocks.Select(x => x.Id).ToList();
@@ -1105,7 +1435,13 @@
foreach (var lockInfo in remainingLocks)
{
decimal returnQty = lockInfo.AssignQuantity - lockInfo.PickedQty;
+ if (returnQty <= 0)
+ {
+ _logger.LogWarning($"閿佸畾璁板綍{lockInfo.Id}鏃犻渶鍥炲簱锛屽垎閰嶆暟閲�: {lockInfo.AssignQuantity}, 宸叉嫞閫�: {lockInfo.PickedQty}");
+ continue;
+ }
+ _logger.LogInformation($"澶勭悊閿佸畾璁板綍鍥炲簱 - 閿佸畾ID: {lockInfo.Id}, 鏉$爜: {lockInfo.CurrentBarcode}, 鍥炲簱鏁伴噺: {returnQty}");
// 鏌ユ壘瀵瑰簲鐨勫簱瀛樻槑缁�
var stockDetail = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.Where(it => it.Barcode == lockInfo.CurrentBarcode && it.StockId == lockInfo.StockId)
@@ -1121,23 +1457,23 @@
else
{
// 鍒涘缓鏂扮殑搴撳瓨璁板綍
- var newStockDetail = new Dt_StockInfoDetail
- {
- StockId = lockInfo.StockId,
- MaterielCode = lockInfo.MaterielCode,
- MaterielName = lockInfo.MaterielName,
- OrderNo = lockInfo.OrderNo,
- BatchNo = lockInfo.BatchNo,
- StockQuantity = returnQty,
- OutboundQuantity = 0,
- Barcode = lockInfo.CurrentBarcode,
- InboundOrderRowNo = "",
- Status = StockStatusEmun.鍏ュ簱纭.ObjToInt(),
- SupplyCode = lockInfo.SupplyCode,
- WarehouseCode = lockInfo.WarehouseCode,
- Unit = lockInfo.Unit,
- };
- await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync();
+ //var newStockDetail = new Dt_StockInfoDetail
+ //{
+ // StockId = lockInfo.StockId,
+ // MaterielCode = lockInfo.MaterielCode,
+ // MaterielName = lockInfo.MaterielName,
+ // OrderNo = lockInfo.OrderNo,
+ // BatchNo = lockInfo.BatchNo,
+ // StockQuantity = returnQty,
+ // OutboundQuantity = 0,
+ // Barcode = lockInfo.CurrentBarcode,
+ // InboundOrderRowNo = "",
+ // Status = StockStatusEmun.鍏ュ簱纭.ObjToInt(),
+ // SupplyCode = lockInfo.SupplyCode,
+ // WarehouseCode = lockInfo.WarehouseCode,
+ // Unit = lockInfo.Unit,
+ //};
+ //await _stockInfoDetailService.Db.Insertable(newStockDetail).ExecuteCommandAsync();
}
}
}
@@ -1180,24 +1516,42 @@
foreach (var stockGood in palletStockGoods)
{
_logger.LogInformation($"寰呭洖搴撹揣鐗� - 鏉$爜: {stockGood.Barcode}, 鏁伴噺: {stockGood.StockQuantity}, 褰撳墠鐘舵��: {stockGood.Status}");
-
- // 鎭㈠搴撳瓨鐘舵��
- stockGood.OutboundQuantity = 0;
- stockGood.Status = StockStatusEmun.鍏ュ簱纭.ObjToInt();
- await _stockInfoDetailService.Db.Updateable(stockGood).ExecuteCommandAsync();
+ if (stockGood.Status != StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt())
+ {
+ stockGood.OutboundQuantity = 0;
+ stockGood.Status = StockStatusEmun.鍏ュ簱纭.ObjToInt();
+ await _stockInfoDetailService.Db.Updateable(stockGood).ExecuteCommandAsync();
+
+ _logger.LogInformation($"搴撳瓨璐х墿鍥炲簱瀹屾垚 - 鏉$爜: {stockGood.Barcode}, 鏂扮姸鎬�: {stockGood.Status}");
+ }
+ else
+ {
+ _logger.LogWarning($"璺宠繃宸插嚭搴撳畬鎴愮殑璐х墿 - 鏉$爜: {stockGood.Barcode}");
+ }
}
}
private async Task HandleSplitRecordsReturn(List<Dt_SplitPackageRecord> splitRecords, string orderNo, string palletCode)
{
+ var validRecords = splitRecords.Where(x => x.Status != (int)SplitPackageStatusEnum.宸叉嫞閫�).ToList();
+
+ if (!validRecords.Any())
+ {
+ _logger.LogInformation("娌℃湁闇�瑕佸洖搴撶殑鎷嗗寘璁板綍");
+ return;
+ }
+
+ _logger.LogInformation($"鏇存柊{validRecords.Count}鏉℃媶鍖呰褰曠姸鎬佷负宸插洖搴�");
+
// 鏇存柊鎷嗗寘璁板綍鐘舵��
await _splitPackageService.Db.Updateable<Dt_SplitPackageRecord>()
.SetColumns(x => new Dt_SplitPackageRecord
{
Status = (int)SplitPackageStatusEnum.宸插洖搴�,
+ Operator = App.User.UserName
})
- .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode && !x.IsReverted)
+ .Where(x => validRecords.Select(r => r.Id).Contains(x.Id))
.ExecuteCommandAsync();
}
@@ -1216,7 +1570,7 @@
/// <param name="originalTask"></param>
/// <param name="analysis"></param>
/// <returns></returns>
- private async Task CreateReturnTaskAndHandleESS(string orderNo, string palletCode, Dt_Task originalTask, ReturnAnalysisResult analysis)
+ private async Task CreateReturnTaskAndHandleESS(string orderNo, string palletCode, Dt_Task originalTask, TaskTypeEnum taskTypeEnum, int palletType)
{
var firstLocation = await _locationInfoService.Db.Queryable<Dt_LocationInfo>()
.FirstAsync(x => x.LocationCode == originalTask.SourceAddress);
@@ -1230,22 +1584,26 @@
Grade = 0,
PalletCode = palletCode,
NextAddress = "",
- OrderNo = originalTask.OrderNo,
+ // OrderNo = originalTask.OrderNo,
+ OrderNo = orderNo,
Roadway = newLocation.RoadwayNo,
SourceAddress = stations[originalTask.TargetAddress],
TargetAddress = newLocation.LocationCode,
TaskStatus = TaskStatusEnum.New.ObjToInt(),
- TaskType = TaskTypeEnum.InPick.ObjToInt(),
- PalletType = originalTask.PalletType,
+ TaskType = taskTypeEnum.ObjToInt(),
+ PalletType = palletType,
WarehouseId = originalTask.WarehouseId
};
// 淇濆瓨鍥炲簱浠诲姟
await _taskRepository.Db.Insertable(returnTask).ExecuteCommandAsync();
- var targetAddress = originalTask.TargetAddress;
-
+ var targetAddress = originalTask.TargetAddress;
+
// 鍒犻櫎鍘熷鍑哄簱浠诲姟
- await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
+ _taskRepository.DeleteAndMoveIntoHty(originalTask, OperateTypeEnum.鑷姩瀹屾垚);
+ // await _taskRepository.Db.Deleteable(originalTask).ExecuteCommandAsync();
+
+
// 缁� ESS 鍙戦�佹祦鍔ㄤ俊鍙峰拰鍒涘缓浠诲姟
await SendESSCommands(palletCode, targetAddress, returnTask);
@@ -1269,18 +1627,15 @@
containerCode = palletCode
});
- if (moveResult)
+ //if (moveResult)
+ //{
+ // 2. 鍒涘缓鍥炲簱浠诲姟
+ var essTask = new TaskModel()
{
- // 2. 鍒涘缓鍥炲簱浠诲姟
- var essTask = new TaskModel()
- {
- taskType = "putaway",
- taskGroupCode = "",
- groupPriority = 0,
- tasks = new List<TasksType>
- {
- new()
- {
+ taskType = "putaway",
+ taskGroupCode = "",
+ groupPriority = 0,
+ tasks = new List<TasksType>{ new() {
taskCode = returnTask.TaskNum.ToString(),
taskPriority = 0,
taskDescribe = new TaskDescribeType
@@ -1293,13 +1648,12 @@
deadline = 0,
storageTag = ""
}
- }
- }
- };
+ } }
+ };
- var resultTask = await _eSSApiService.CreateTaskAsync(essTask);
- _logger.LogInformation($"ReturnRemaining 鍒涘缓浠诲姟鎴愬姛: {resultTask}");
- }
+ var resultTask = await _eSSApiService.CreateTaskAsync(essTask);
+ _logger.LogInformation($"ReturnRemaining 鍒涘缓浠诲姟鎴愬姛: {resultTask}");
+ //}
}
catch (Exception ex)
{
@@ -1342,15 +1696,19 @@
if (outboundOrder.OrderStatus != newStatus)
{
await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
- .SetColumns(x => x.OrderStatus == newStatus)
+ .SetColumns(x => new Dt_OutboundOrder
+ {
+ OrderStatus = newStatus,
+ Operator = App.User.UserName,
+ })
.Where(x => x.OrderNo == orderNo)
.ExecuteCommandAsync();
// 鍙湁姝e父鍒嗘嫞瀹屾垚鏃舵墠鍚慚ES鍙嶉
- if (allCompleted && newStatus == (int)OutOrderStatusEnum.鍑哄簱瀹屾垚)
- {
- await HandleOrderCompletion(outboundOrder, orderNo);
- }
+ //if (allCompleted && newStatus == (int)OutOrderStatusEnum.鍑哄簱瀹屾垚)
+ //{
+ // await HandleOrderCompletion(outboundOrder, orderNo);
+ //}
}
}
catch (Exception ex)
@@ -1358,6 +1716,8 @@
_logger.LogError($"CheckAndUpdateOrderStatus澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
}
}
+
+
private async Task UpdateOrderStatusForReturn(string orderNo)
{
@@ -1389,7 +1749,11 @@
if (outboundOrder.OrderStatus != newStatus)
{
await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
- .SetColumns(x => x.OrderStatus == newStatus)
+ .SetColumns(x => new Dt_OutboundOrder
+ {
+ OrderStatus = newStatus,
+ Operator = App.User.UserName,
+ })
.Where(x => x.OrderNo == orderNo)
.ExecuteCommandAsync();
@@ -1405,76 +1769,480 @@
private async Task HandleOrderCompletion(Dt_OutboundOrder outboundOrder, string orderNo)
{
// 璋冩嫧鍑哄簱鍜岄噸妫�鍑哄簱涓嶉渶瑕佸弽棣圡ES
- if (outboundOrder.OrderType == OutOrderTypeEnum.Allocate.ObjToInt() ||
- outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt())
+ if (outboundOrder.OrderType == OutOrderTypeEnum.Allocate.ObjToInt())
{
- return;
- }
-
- try
- {
- var feedmodel = new FeedbackOutboundRequestModel
+ var allocate = _allocateService.Repository.QueryData(x => x.UpperOrderNo == outboundOrder.UpperOrderNo).First();
+ var allocatefeedmodel = new AllocateDto
{
- reqCode = Guid.NewGuid().ToString(),
- reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
- business_type = outboundOrder.BusinessType,
- factoryArea = outboundOrder.FactoryArea,
- operationType = 1,
+ ReqCode = Guid.NewGuid().ToString(),
+ ReqTime = DateTime.Now.ToString(),
+ BusinessType = "3",
+
+ FactoryArea = outboundOrder.FactoryArea,
+ OperationType = 1,
Operator = App.User.UserName,
- orderNo = outboundOrder.UpperOrderNo,
- status = outboundOrder.OrderStatus,
- details = new List<FeedbackOutboundDetailsModel>()
- };
+ OrderNo = outboundOrder.UpperOrderNo,
+ // documentsNO = outboundOrder.OrderNo,
+ // status = outboundOrder.OrderStatus,
+ fromWarehouse = allocate?.FromWarehouse ?? "",
+ toWarehouse = allocate?.ToWarehouse ?? "",
+ Details = new List<AllocateDtoDetail>()
+ };
// 鍙幏鍙栧凡鎷i�夊畬鎴愮殑閿佸畾璁板綍
var lists = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
.Where(x => x.OrderNo == orderNo && x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
.ToListAsync();
var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.Unit, item.WarehouseCode })
- .Select(group => new FeedbackOutboundDetailsModel
+ .Select(group => new AllocateDtoDetail
{
- materialCode = group.Key.MaterielCode,
- lineNo = group.Key.lineNo,
- warehouseCode = group.Key.WarehouseCode,
- qty = group.Sum(x => x.PickedQty),
- currentDeliveryQty = group.Sum(x => x.PickedQty),
- unit = group.Key.Unit,
- barcodes = group.Select(row => new WIDESEA_DTO.Outbound.BarcodesModel
+ MaterialCode = group.Key.MaterielCode,
+ LineNo = group.Key.lineNo,
+ WarehouseCode = group.Key.WarehouseCode,
+ Qty = group.Sum(x => x.PickedQty),
+
+ Unit = group.Key.Unit,
+ Barcodes = group.Select(row => new BarcodeInfo
{
- barcode = row.CurrentBarcode,
- supplyCode = row.SupplyCode,
- batchNo = row.BatchNo,
- unit = row.Unit,
- qty = row.PickedQty
+ Barcode = row.CurrentBarcode,
+ SupplyCode = row.SupplyCode,
+ BatchNo = row.BatchNo,
+ Unit = row.Unit,
+ Qty = row.PickedQty
}).ToList()
+
+
}).ToList();
+ allocatefeedmodel.Details = groupedData;
- feedmodel.details = groupedData;
-
- var result = await _invokeMESService.FeedbackOutbound(feedmodel);
+ var result = await _invokeMESService.FeedbackAllocate(allocatefeedmodel);
if (result != null && result.code == 200)
- {
+ {
await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
- .SetColumns(x => x.ReturnToMESStatus == 1)
- .Where(x => x.OrderId == outboundOrder.Id)
- .ExecuteCommandAsync();
+ .SetColumns(x => x.ReturnToMESStatus == 1)
+ .Where(x => x.OrderId == outboundOrder.Id).ExecuteCommandAsync();
await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
- .SetColumns(x => x.ReturnToMESStatus == 1)
- .Where(x => x.OrderNo == orderNo)
- .ExecuteCommandAsync();
+ .SetColumns(x => new Dt_OutboundOrder
+ {
+ ReturnToMESStatus = 1,
+ Operator = App.User.UserName,
+ }).Where(x => x.OrderNo == orderNo).ExecuteCommandAsync();
}
}
- catch (Exception ex)
+ else if (outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt())
{
- _logger.LogError($"FeedbackOutbound澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
+
+ }
+ else
+ {
+ try
+ {
+ var feedmodel = new FeedbackOutboundRequestModel
+ {
+ reqCode = Guid.NewGuid().ToString(),
+ reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
+ business_type = outboundOrder.BusinessType,
+ factoryArea = outboundOrder.FactoryArea,
+ operationType = 1,
+ Operator = App.User.UserName,
+ orderNo = outboundOrder.UpperOrderNo,
+ documentsNO = outboundOrder.OrderNo,
+ status = outboundOrder.OrderStatus,
+ details = new List<FeedbackOutboundDetailsModel>()
+ };
+
+ // 鍙幏鍙栧凡鎷i�夊畬鎴愮殑閿佸畾璁板綍
+ var lists = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo && x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ .ToListAsync();
+
+ var groupedData = lists.GroupBy(item => new { item.MaterielCode, item.lineNo, item.Unit, item.WarehouseCode })
+ .Select(group => new FeedbackOutboundDetailsModel
+ {
+ materialCode = group.Key.MaterielCode,
+ lineNo = group.Key.lineNo,
+ warehouseCode = group.Key.WarehouseCode,
+ qty = group.Sum(x => x.PickedQty),
+ currentDeliveryQty = group.Sum(x => x.PickedQty),
+ unit = group.Key.Unit,
+ barcodes = group.Select(row => new WIDESEA_DTO.Outbound.BarcodesModel
+ {
+ barcode = row.CurrentBarcode,
+ supplyCode = row.SupplyCode,
+ batchNo = row.BatchNo,
+ unit = row.Unit,
+ qty = row.PickedQty
+ }).ToList()
+ }).ToList();
+
+ feedmodel.details = groupedData;
+
+ var result = await _invokeMESService.FeedbackOutbound(feedmodel);
+ if (result != null && result.code == 200)
+ {
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(x => x.ReturnToMESStatus == 1)
+ .Where(x => x.OrderId == outboundOrder.Id)
+ .ExecuteCommandAsync();
+
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => new Dt_OutboundOrder
+ {
+ ReturnToMESStatus = 1,
+ Operator = App.User.UserName,
+ })
+
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+ }
+
+ _logger.LogError($"FeedbackOutbound鎴愬姛 - OrderNo: {orderNo}, {JsonSerializer.Serialize(result)}");
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"FeedbackOutbound澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
+ }
}
}
#endregion
+ #region 绌烘墭鐩�
+
+ /// <summary>
+ /// 娓呯悊闆跺簱瀛樻暟鎹�
+ /// </summary>
+ private async Task CleanupZeroStockData(int stockId)
+ {
+ try
+ {
+ // 1. 鍒犻櫎搴撳瓨鏁伴噺涓�0鐨勬槑缁嗚褰�
+ var deleteDetailCount = await _stockInfoDetailService.Db.Deleteable<Dt_StockInfoDetail>()
+ .Where(x => x.StockId == stockId && x.StockQuantity == 0 && (x.Status == StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt() || x.Status ==
+ StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt()))
+ .ExecuteCommandAsync();
+
+ await _stockInfoService.Db.Deleteable<Dt_StockInfo>()
+ .Where(x => x.Id == stockId).ExecuteCommandAsync();
+
+ _logger.LogInformation($"娓呯悊闆跺簱瀛樻槑缁嗚褰� - StockId: {stockId}, 鍒犻櫎璁板綍鏁�: {deleteDetailCount}");
+
+
+
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning($"娓呯悊闆跺簱瀛樻暟鎹け璐� - StockId: {stockId}, Error: {ex.Message}");
+ // 娉ㄦ剰锛氭竻鐞嗗け璐ヤ笉搴旇褰卞搷涓绘祦绋�
+ }
+ }
+ /// <summary>
+ /// 澶勭悊浠诲姟娓呯悊锛堟寜璁㈠崟鍜屾墭鐩橈級
+ /// </summary>
+ private async Task HandleTaskCleanup(string orderNo, string palletCode)
+ {
+ try
+ {
+ // 1. 鏌ユ壘鎵�鏈変笌璇ヨ鍗曞拰鎵樼洏鐩稿叧鐨勪换鍔�
+ var tasks = await _taskRepository.Db.Queryable<Dt_Task>().Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode).ToListAsync();
+
+ if (tasks.Any())
+ {
+ foreach (var task in tasks)
+ {
+ task.TaskStatus = (int)TaskStatusEnum.Finish;
+ }
+ // await _taskRepository.Db.Updateable(tasks).ExecuteCommandAsync();
+
+ _taskRepository.DeleteAndMoveIntoHty(tasks, OperateTypeEnum.鑷姩瀹屾垚);
+ _logger.LogInformation($"瀹屾垚{tasks.Count}涓墭鐩樹换鍔� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
+ }
+
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning($"澶勭悊浠诲姟娓呯悊澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
+ throw new Exception($"浠诲姟娓呯悊澶辫触: {ex.Message}");
+ }
+ }
+ /// <summary>
+ /// 鏇存柊璁㈠崟鐩稿叧鏁版嵁
+ /// </summary>
+ private async Task UpdateOrderData(string orderNo, string palletCode)
+ {
+ try
+ {
+ // 妫�鏌ヨ鍗曟槸鍚﹁繕鏈夊叾浠栨墭鐩樺湪澶勭悊涓�
+ var otherActivePallets = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode != palletCode &&
+ (x.Status == (int)OutLockStockStatusEnum.鍑哄簱涓� || x.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�))
+ .AnyAsync();
+
+ var otherActiveTasks = await _taskRepository.Db.Queryable<Dt_Task>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.PalletCode != palletCode
+ // && x.TaskStatus.In((int)TaskStatusEnum.寰呮墽琛�, (int)TaskStatusEnum.鎵ц涓�)
+ )
+ .AnyAsync();
+
+ // 濡傛灉娌℃湁鍏朵粬鎵樼洏鍦ㄥ鐞嗭紝妫�鏌ヨ鍗曟槸鍚﹀簲璇ュ畬鎴�
+ if (!otherActivePallets && !otherActiveTasks)
+ {
+ await CheckAndUpdateOrderCompletion(orderNo);
+ }
+ else
+ {
+ _logger.LogInformation($"璁㈠崟 {orderNo} 杩樻湁鍏朵粬鎵樼洏鍦ㄥ鐞嗭紝涓嶆洿鏂拌鍗曠姸鎬�");
+ }
+
+ // 3. 鏇存柊鎷i�夎褰曠姸鎬侊紙鍙�夛級
+ await UpdatePickingRecordsStatus(orderNo, palletCode);
+
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning($"鏇存柊璁㈠崟鏁版嵁澶辫触 - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
+ throw new Exception($"鏇存柊璁㈠崟鏁版嵁澶辫触: {ex.Message}");
+ }
+ }
+
+ /// <summary>
+ /// 妫�鏌ュ苟鏇存柊璁㈠崟瀹屾垚鐘舵��
+ /// </summary>
+ private async Task CheckAndUpdateOrderCompletion(string orderNo)
+ {
+ var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id)
+ .Where((o, item) => item.OrderNo == orderNo)
+ .Select((o, item) => o)
+ .ToListAsync();
+
+ bool allCompleted = true;
+ foreach (var detail in orderDetails)
+ {
+ if (detail.OverOutQuantity < detail.NeedOutQuantity)
+ {
+ allCompleted = false;
+ break;
+ }
+ }
+
+ var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+ .FirstAsync(x => x.OrderNo == orderNo);
+
+ if (outboundOrder != null && allCompleted && outboundOrder.OrderStatus != (int)OutOrderStatusEnum.鍑哄簱瀹屾垚)
+ {
+ outboundOrder.OrderStatus = (int)OutOrderStatusEnum.鍑哄簱瀹屾垚;
+ outboundOrder.Operator = App.User.UserName;
+ await _outboundOrderService.Db.Updateable(outboundOrder).ExecuteCommandAsync();
+
+ _logger.LogInformation($"璁㈠崟 {orderNo} 宸叉爣璁颁负鍑哄簱瀹屾垚");
+
+ // 鍚慚ES鍙嶉璁㈠崟瀹屾垚锛堝鏋滈渶瑕侊級
+ await HandleOrderCompletion(outboundOrder, orderNo);
+ }
+ }
+
+ /// <summary>
+ /// 鏇存柊鎷i�夎褰曠姸鎬�
+ /// </summary>
+ private async Task UpdatePickingRecordsStatus(string orderNo, string palletCode)
+ {
+ try
+ {
+ // 鍙互灏嗙浉鍏崇殑鎷i�夎褰曟爣璁颁负宸插畬鎴�
+ var pickingRecords = await Db.Queryable<Dt_PickingRecord>()
+ .Where(x => x.OrderNo == orderNo && x.PalletCode == palletCode)
+ .ToListAsync();
+
+ // 杩欓噷鍙互鏍规嵁闇�瑕佹洿鏂版嫞閫夎褰曠殑鐘舵�佸瓧娈�
+ // 渚嬪锛歱ickingRecord.Status = (int)PickingStatusEnum.宸插畬鎴�;
+
+ _logger.LogInformation($"鎵惧埌{pickingRecords.Count}鏉℃嫞閫夎褰� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
+
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning($"鏇存柊鎷i�夎褰曠姸鎬佸け璐�: {ex.Message}");
+ }
+ }
+ #endregion
+
+
+
#region 杈呭姪鏂规硶
+ /// <summary>
+ /// 缁熶竴鍒嗘瀽鎵樼洏鐘舵�� - 杩斿洖鎵樼洏鐨勫畬鏁寸姸鎬佷俊鎭�
+ /// </summary>
+ private async Task<PalletStatusAnalysis> AnalyzePalletStatus(string orderNo, string palletCode, int stockId)
+ {
+ var result = new PalletStatusAnalysis
+ {
+ OrderNo = orderNo,
+ PalletCode = palletCode,
+ StockId = stockId
+ };
+
+ // 鍒嗘瀽鏈垎鎷g殑鍑哄簱閿佸畾璁板綍
+ var remainingLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(it => it.OrderNo == orderNo &&
+ it.PalletCode == palletCode &&
+ it.Status == (int)OutLockStockStatusEnum.鍑哄簱涓�)
+ .ToListAsync();
+
+ if (remainingLocks.Any())
+ {
+ result.HasRemainingLocks = true;
+ result.RemainingLocks = remainingLocks;
+ result.RemainingLocksReturnQty = remainingLocks.Sum(x => x.AssignQuantity - x.PickedQty);
+ _logger.LogInformation($"鍙戠幇{remainingLocks.Count}鏉℃湭鍒嗘嫞閿佸畾璁板綍锛屾�绘暟閲�: {result.RemainingLocksReturnQty}");
+ }
+
+ // 鍒嗘瀽鎵樼洏涓婄殑搴撳瓨璐х墿
+ var palletStockGoods = await _stockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
+ .Where(it => it.StockId == stockId &&
+ (it.Status == StockStatusEmun.鍏ュ簱纭.ObjToInt() ||
+ it.Status == StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt() ||
+ it.Status == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()))
+ .Where(it => it.StockQuantity > 0)
+ .ToListAsync();
+
+ if (palletStockGoods.Any())
+ {
+ result.HasPalletStockGoods = true;
+ result.PalletStockGoods = palletStockGoods;
+ result.PalletStockReturnQty = palletStockGoods.Sum(x => x.StockQuantity);
+ _logger.LogInformation($"鍙戠幇{palletStockGoods.Count}涓簱瀛樿揣鐗╋紝鎬绘暟閲�: {result.PalletStockReturnQty}");
+
+ // 璁板綍璇︾粏鐘舵�佸垎甯�
+ var statusGroups = palletStockGoods.GroupBy(x => x.Status);
+ foreach (var group in statusGroups)
+ {
+ _logger.LogInformation($"搴撳瓨鐘舵�亄group.Key}: {group.Count()}涓揣鐗╋紝鏁伴噺: {group.Sum(x => x.StockQuantity)}");
+ }
+ }
+
+ //鍒嗘瀽鎷嗗寘璁板綍
+ var splitRecords = await _splitPackageService.Db.Queryable<Dt_SplitPackageRecord>()
+ .Where(it => it.OrderNo == orderNo &&
+ it.PalletCode == palletCode &&
+ !it.IsReverted && it.Status != (int)SplitPackageStatusEnum.宸叉嫞閫� &&
+ it.Status != (int)SplitPackageStatusEnum.宸插洖搴�)
+ .ToListAsync();
+
+ if (splitRecords.Any())
+ {
+ result.HasSplitRecords = true;
+ result.SplitRecords = splitRecords;
+ result.SplitReturnQty = await CalculateSplitReturnQuantity(splitRecords, stockId);
+
+ _logger.LogInformation($"鍙戠幇{splitRecords.Count}鏉℃湭鎷i�夋媶鍖呰褰曪紝鎬绘暟閲�: {result.SplitReturnQty}");
+ }
+
+ // 4. 璁$畻鎬诲洖搴撴暟閲忓拰绌烘墭鐩樼姸鎬�
+ result.TotalReturnQty = result.RemainingLocksReturnQty + result.PalletStockReturnQty + result.SplitReturnQty;
+ result.HasItemsToReturn = result.TotalReturnQty > 0;
+ result.IsEmptyPallet = !result.HasItemsToReturn;
+
+ // 5. 妫�鏌ユ槸鍚︽湁杩涜涓殑浠诲姟
+ result.HasActiveTasks = await _taskRepository.Db.Queryable<Dt_Task>()
+ .Where(x => x.OrderNo == orderNo && x.TaskType == TaskTypeEnum.InPick.ObjToInt() &&
+ x.PalletCode == palletCode &&
+ x.TaskStatus == (int)TaskStatusEnum.New)
+ .AnyAsync();
+
+ _logger.LogInformation($"鎵樼洏鐘舵�佸垎鏋愬畬鎴� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}, " +
+ $"鎬诲洖搴撴暟閲�: {result.TotalReturnQty}, 鏄惁绌烘墭鐩�: {result.IsEmptyPallet}, " +
+ $"鏈夎繘琛屼腑浠诲姟: {result.HasActiveTasks}");
+
+ return result;
+ }
+
+ /// <summary>
+ /// 妫�鏌ユ墭鐩樻槸鍚︿负绌�
+ /// </summary>
+ private async Task<bool> IsPalletEmpty(string orderNo, string palletCode)
+ {
+ try
+ {
+ // 鑾峰彇搴撳瓨淇℃伅
+ var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
+ .Where(x => x.PalletCode == palletCode)
+ .FirstAsync();
+
+ if (stockInfo == null)
+ return false;
+
+ // 浣跨敤缁熶竴鐨勭姸鎬佸垎鏋�
+ var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockInfo.Id);
+ return statusAnalysis.IsEmptyPallet;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogWarning($"妫�鏌ユ墭鐩樻槸鍚︿负绌哄け璐� - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
+ return false;
+ }
+ }
+ /// <summary>
+ /// 妫�鏌ュ苟澶勭悊绌烘墭鐩�
+ /// </summary>
+ private async Task<bool> CheckAndHandleEmptyPallet(string orderNo, string palletCode)
+ {
+ try
+ {
+ // 1. 鑾峰彇搴撳瓨淇℃伅
+ var stockInfo = await _stockInfoService.Db.Queryable<Dt_StockInfo>()
+ .Where(x => x.PalletCode == palletCode)
+ .FirstAsync();
+
+ if (stockInfo == null)
+ {
+ _logger.LogWarning($"鏈壘鍒版墭鐩� {palletCode} 鐨勫簱瀛樹俊鎭�");
+ return false;
+ }
+
+ // 2. 浣跨敤缁熶竴鐨勭姸鎬佸垎鏋�
+ var statusAnalysis = await AnalyzePalletStatus(orderNo, palletCode, stockInfo.Id);
+
+ // 3. 妫�鏌ユ槸鍚︿负绌烘墭鐩樹笖娌℃湁杩涜涓殑浠诲姟
+ if (!statusAnalysis.IsEmptyPallet || statusAnalysis.HasActiveTasks)
+ {
+ return false;
+ }
+
+ _logger.LogInformation($"妫�娴嬪埌绌烘墭鐩橈紝寮�濮嬭嚜鍔ㄥ鐞� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
+
+ //// 娓呯悊闆跺簱瀛樻暟鎹�
+ //await CleanupZeroStockData(stockInfo.Id);
+
+ //// 鏇存柊搴撳瓨涓昏〃鐘舵�佷负绌烘墭鐩�
+ //await UpdateStockInfoAsEmpty(stockInfo);
+
+ //// 澶勭悊鍑哄簱閿佸畾璁板綍
+ //await HandleOutStockLockRecords(orderNo, palletCode);
+
+ //// 澶勭悊浠诲姟鐘舵��
+ //await HandleTaskStatusForEmptyPallet(orderNo, palletCode);
+
+ //// 鏇存柊璁㈠崟鏁版嵁
+ //await UpdateOrderDataForEmptyPallet(orderNo, palletCode);
+
+ ////璁板綍鎿嶄綔鍘嗗彶
+ //await RecordAutoEmptyPalletOperation(orderNo, palletCode);
+
+ _logger.LogInformation($"绌烘墭鐩樿嚜鍔ㄥ鐞嗗畬鎴� - 璁㈠崟: {orderNo}, 鎵樼洏: {palletCode}");
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"鑷姩澶勭悊绌烘墭鐩樺け璐� - OrderNo: {orderNo}, PalletCode: {palletCode}, Error: {ex.Message}");
+ return false;
+ }
+ }
private async Task<string> GenerateNewBarcode()
{
@@ -1507,10 +2275,12 @@
OriginalLockQuantity = quantity,
IsSplitted = 1,
ParentLockId = originalLock.Id,
- Operator= App.User.UserName,
- FactoryArea=originalLock.FactoryArea,
- lineNo=originalLock.lineNo,
- WarehouseCode=originalLock.WarehouseCode,
+ Operator = App.User.UserName,
+ FactoryArea = originalLock.FactoryArea,
+ lineNo = originalLock.lineNo,
+ WarehouseCode = originalLock.WarehouseCode,
+ BarcodeQty=originalLock.BarcodeQty,
+ BarcodeUnit=originalLock.BarcodeUnit,
};
@@ -1615,6 +2385,7 @@
}
return WebResponseContent.Instance.OK("鎷i�夌‘璁ゆ垚鍔�", new { SplitResults = new List<SplitResult>() });
}
+
#region 铏氭嫙鍑哄叆搴�
@@ -1871,6 +2642,56 @@
public List<Dt_StockInfoDetail> PalletStockGoods { get; set; } = new List<Dt_StockInfoDetail>();
public List<Dt_SplitPackageRecord> SplitRecords { get; set; } = new List<Dt_SplitPackageRecord>();
}
+ public class PalletStatusAnalysis
+ {
+ public string OrderNo { get; set; }
+ public string PalletCode { get; set; }
+ public int StockId { get; set; }
+ // 鍥炲簱鐩稿叧灞炴��
+ public bool HasItemsToReturn { get; set; }
+ public bool HasRemainingLocks { get; set; }
+ public bool HasPalletStockGoods { get; set; }
+ public bool HasSplitRecords { get; set; }
+ public decimal RemainingLocksReturnQty { get; set; }
+ public decimal PalletStockReturnQty { get; set; }
+ public decimal SplitReturnQty { get; set; }
+ public decimal TotalReturnQty { get; set; }
+ public List<Dt_OutStockLockInfo> RemainingLocks { get; set; } = new List<Dt_OutStockLockInfo>();
+ public List<Dt_StockInfoDetail> PalletStockGoods { get; set; } = new List<Dt_StockInfoDetail>();
+ public List<Dt_SplitPackageRecord> SplitRecords { get; set; } = new List<Dt_SplitPackageRecord>();
+
+ // 绌烘墭鐩樼浉鍏冲睘鎬�
+ public bool IsEmptyPallet { get; set; }
+ public bool HasActiveTasks { get; set; }
+
+ // 渚垮埄鏂规硶
+ public bool CanReturn => HasItemsToReturn && !HasActiveTasks;
+ public bool CanRemove => IsEmptyPallet && !HasActiveTasks;
+ }
+ public class PickingContext
+ {
+ public string OrderNo { get; set; }
+ public string PalletCode { get; set; }
+ public string Barcode { get; set; }
+ public string Operator { get; set; }
+ public Dt_OutStockLockInfo LockInfo { get; set; }
+ public Dt_OutboundOrderDetail OrderDetail { get; set; }
+ public Dt_StockInfoDetail StockDetail { get; set; }
+ public decimal ActualQuantity { get; set; }
+ public string AdjustedReason { get; set; }
+ }
+ public class CancelPickingContext
+ {
+ public string OrderNo { get; set; }
+ public string PalletCode { get; set; }
+ public string Barcode { get; set; }
+ public string Operator { get; set; }
+
+ public decimal CancelQuantity { get; set; }
+ public Dt_PickingRecord PickingRecord { get; set; }
+ public Dt_OutStockLockInfo LockInfo { get; set; }
+ public Dt_OutboundOrderDetail OrderDetail { get; set; }
+ }
#endregion
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/WIDESEA_OutboundService.csproj" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/WIDESEA_OutboundService.csproj"
index 3fa27c9..6f9f90f 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/WIDESEA_OutboundService.csproj"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_OutboundService/WIDESEA_OutboundService.csproj"
@@ -7,6 +7,8 @@
</PropertyGroup>
<ItemGroup>
+ <ProjectReference Include="..\WIDESEA_BasicService\WIDESEA_BasicService.csproj" />
+ <ProjectReference Include="..\WIDESEA_IAllocateService\WIDESEA_IAllocateService.csproj" />
<ProjectReference Include="..\WIDESEA_IBasicService\WIDESEA_IBasicService.csproj" />
<ProjectReference Include="..\WIDESEA_IInboundService\WIDESEA_IInboundService.csproj" />
<ProjectReference Include="..\WIDESEA_IOutboundService\WIDESEA_IOutboundService.csproj" />
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs"
index 5ff38f2..47b932e 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs"
@@ -22,6 +22,7 @@
public IRepository<Dt_StockInfo> Repository => BaseDal;
private readonly IRepository<Dt_StockInfoDetail> _stockInfoDetailRepository;
private readonly IOutboundOrderService _outboundOrderService;
+ //private readonly IOutboundOrderDetailService _outboundOrderDetailService;
private readonly ILocationInfoService _locationInfoService;
public StockInfoService(IRepository<Dt_StockInfo> BaseDal, IMapper mapper, IRepository<Dt_StockInfoDetail> stockInfoDetailRepository, IRecordService recordService, ILocationInfoService locationInfoService, IOutboundOrderService outboundOrderService) : base(BaseDal)
{
@@ -30,6 +31,7 @@
_recordService = recordService;
_locationInfoService = locationInfoService;
_outboundOrderService = outboundOrderService;
+ //_outboundOrderDetailService = outboundOrderDetailService;
}
/// <summary>
@@ -201,12 +203,9 @@
if (!string.IsNullOrEmpty(supplyCode))
{
query = query.Where(x => x.Details.Any(d => d.SupplyCode == supplyCode));
- }
+ }
- var stocks = query.ToList();
-
- return stocks.OrderBy(x => x.Details.Where(d => d.MaterielCode == materielCode && (string.IsNullOrEmpty(supplyCode) || d.SupplyCode == supplyCode) &&
- (string.IsNullOrEmpty(lotNo) || d.BatchNo == lotNo)).Min(d => d.CreateDate)).ToList();
+ return query.OrderBy(x => x.CreateDate).ToList();
//ISugarQueryable<Dt_LocationInfo> sugarQueryable = Db.Queryable<Dt_LocationInfo>().Where(x => locationCodes.Contains(x.LocationCode));
//ISugarQueryable<Dt_StockInfo> sugarQueryable1 = Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.Details.Any(v => v.MaterielCode == materielCode));
//return sugarQueryable.InnerJoin(sugarQueryable1, (a, b) => a.LocationCode == b.LocationCode).Select((a, b) => b).OrderBy(a => a.CreateDate).Includes(a => a.Details).ToList();
@@ -227,49 +226,133 @@
public List<Dt_StockInfo> GetStockInfosByPalletCodes(List<string> palletCodes)
{
- return Db.Queryable<Dt_StockInfo>().Where(x => palletCodes.Contains(x.PalletCode)).Includes(x => x.Details).ToList();
+ return Db.Queryable<Dt_StockInfo>().Where(x => palletCodes.Contains(x.PalletCode)).Includes(x => x.Details).OrderBy(x => x.CreateDate).ToList();
+ }
+ // 娣诲姞鑾峰彇鍗曚釜鎵樼洏搴撳瓨鐨勬柟娉曪紙濡傛灉涓嶅瓨鍦級
+ public Dt_StockInfo GetStockInfoByPalletCode(string palletCode)
+ {
+ return Db.Queryable<Dt_StockInfo>()
+ .Where(x => x.PalletCode == palletCode)
+ .Includes(x => x.Details)
+ .First();
}
-
/// <summary>
///
/// </summary>
/// <param name="orderId"></param>
/// <param name="materielCode"></param>
/// <returns></returns>
+ //public List<StockSelectViewDTO> GetStockSelectViews(int orderId, string materielCode)
+ //{
+ // try
+ // {
+ // Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.Id == orderId);
+ // if (outboundOrder == null)
+ // {
+ // throw new Exception($"鏈壘鍒板嚭搴撳崟淇℃伅");
+ // }
+
+ // List<string> locationCodes = _locationInfoService.GetCanOutLocationCodes();
+
+ // return BaseDal.QueryTabs<Dt_StockInfo, Dt_StockInfoDetail, StockSelectViewDTO>((a, b) => a.Id == b.StockId, (a, b) => new StockSelectViewDTO
+ // {
+ // LocationCode = a.LocationCode,
+ // MaterielCode = b.MaterielCode,
+ // MaterielName = b.MaterielName,
+ // Barcode=b.Barcode,
+ // PalletCode = a.PalletCode,
+ // UseableQuantity = b.StockQuantity - b.OutboundQuantity
+ // }, a => locationCodes.Contains(a.LocationCode), b => b.StockQuantity > b.OutboundQuantity && b.MaterielCode == materielCode, x => true).GroupBy(x => x.PalletCode).Select(x => new StockSelectViewDTO
+ // {
+ // LocationCode = x.FirstOrDefault()?.LocationCode ?? "",
+ // MaterielCode = x.FirstOrDefault()?.MaterielCode ?? "",
+ // MaterielName = x.FirstOrDefault()?.MaterielName ?? "",
+ // Barcode=x.FirstOrDefault()?.Barcode??"",
+ // PalletCode = x.Key,
+ // UseableQuantity = x.Sum(x => x.UseableQuantity)
+ // }).ToList();
+ // }
+ // catch (Exception ex)
+ // {
+ // return null;
+ // }
+
+ //}
+
public List<StockSelectViewDTO> GetStockSelectViews(int orderId, string materielCode)
{
- try
+ Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.Id == orderId);
+ if (outboundOrder == null)
{
- Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.Id == orderId);
- if (outboundOrder == null)
+ throw new Exception($"鏈壘鍒癐D涓簕orderId}鐨勫嚭搴撳崟淇℃伅");
+ }
+
+ // 鑾峰彇鍑哄簱鍗曟槑缁嗭紝鐢ㄤ簬纭畾闇�瑕佺殑鎵规鍜屼緵搴斿晢
+ var orderDetails = SqlSugarHelper.DbWMS.Queryable<Dt_OutboundOrderDetail>().Where(x => x.OrderId == orderId && x.MaterielCode == materielCode).ToList();
+
+ if (!orderDetails.Any())
+ {
+ throw new Exception($"鍑哄簱鍗晎orderId}涓湭鎵惧埌鐗╂枡{materielCode}鐨勬槑缁嗕俊鎭�");
+ }
+
+ List<string> locationCodes = _locationInfoService.GetCanOutLocationCodes();
+ var result = new List<StockSelectViewDTO>();
+
+ // 涓烘瘡涓嚭搴撳崟鏄庣粏鏌ヨ瀵瑰簲鐨勫簱瀛�
+ foreach (var orderDetail in orderDetails)
+ {
+ // 鏋勫缓鏌ヨ鏉′欢
+ var stockQuery = Db.Queryable<Dt_StockInfo>()
+ .Where(x => locationCodes.Contains(x.LocationCode))
+ .Where(x => x.StockStatus == (int)StockStatusEmun.鍏ュ簱瀹屾垚)
+ .Includes(x => x.Details);
+
+ // 鎵ц鏌ヨ骞舵寜鍏堣繘鍏堝嚭鎺掑簭
+ var stocks = stockQuery.ToList()
+ .Where(x => x.Details.Any(d =>
+ d.MaterielCode == materielCode &&
+ string.IsNullOrEmpty(orderDetail.BatchNo)?true: d.BatchNo == orderDetail.BatchNo&&
+ string.IsNullOrEmpty(orderDetail.BatchNo)?true:d.SupplyCode == orderDetail.SupplyCode &&
+ d.StockQuantity > d.OutboundQuantity
+ ))
+ .OrderBy(x => x.CreateDate)
+ .ToList();
+
+ foreach (var stock in stocks)
{
- throw new Exception($"鏈壘鍒板嚭搴撳崟淇℃伅");
+ var relevantDetails = stock.Details
+ .Where(d => d.MaterielCode == materielCode &&
+ string.IsNullOrEmpty(orderDetail.BatchNo) ? true : d.BatchNo == orderDetail.BatchNo &&
+ string.IsNullOrEmpty(orderDetail.BatchNo) ? true : d.SupplyCode == orderDetail.SupplyCode &&
+ d.StockQuantity > d.OutboundQuantity)
+ .ToList();
+
+ if (relevantDetails.Any())
+ {
+ var firstDetail = relevantDetails.First();
+ var useableQuantity = relevantDetails.Sum(d => d.StockQuantity - d.OutboundQuantity);
+
+ result.Add(new StockSelectViewDTO
+ {
+ LocationCode = stock.LocationCode,
+ MaterielCode = materielCode,
+ MaterielName = firstDetail.MaterielName,
+ BatchNo = orderDetail.BatchNo,
+ SupplyCode = orderDetail.SupplyCode,
+ Barcode = firstDetail.Barcode,
+ PalletCode = stock.PalletCode,
+ UseableQuantity = useableQuantity,
+ StockCreateDate = stock.CreateDate,
+ StockId = stock.Id,
+ OrderDetailId = orderDetail.Id // 鍏宠仈鍒板叿浣撶殑鍑哄簱鍗曟槑缁�
+ });
+ }
}
-
- List<string> locationCodes = _locationInfoService.GetCanOutLocationCodes();
-
- return BaseDal.QueryTabs<Dt_StockInfo, Dt_StockInfoDetail, StockSelectViewDTO>((a, b) => a.Id == b.StockId, (a, b) => new StockSelectViewDTO
- {
- LocationCode = a.LocationCode,
- MaterielCode = b.MaterielCode,
- MaterielName = b.MaterielName,
- PalletCode = a.PalletCode,
- UseableQuantity = b.StockQuantity - b.OutboundQuantity
- }, a => locationCodes.Contains(a.LocationCode), b => b.StockQuantity > b.OutboundQuantity && b.MaterielCode == materielCode, x => true).GroupBy(x => x.PalletCode).Select(x => new StockSelectViewDTO
- {
- LocationCode = x.FirstOrDefault()?.LocationCode ?? "",
- MaterielCode = x.FirstOrDefault()?.MaterielCode ?? "",
- MaterielName = x.FirstOrDefault()?.MaterielName ?? "",
- PalletCode = x.Key,
- UseableQuantity = x.Sum(x => x.UseableQuantity)
- }).ToList();
- }
- catch (Exception ex)
- {
- return null;
}
+ return result;
}
+
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
index 8682865..141197b 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs"
@@ -41,6 +41,7 @@
using WIDESEA_DTO.Allocate;
using WIDESEA_DTO.Basic;
using WIDESEA_DTO.Inbound;
+using WIDESEA_DTO.Outbound;
using WIDESEA_DTO.Task;
using WIDESEA_IAllocateService;
using WIDESEA_IBasicService;
@@ -50,6 +51,7 @@
using WIDESEA_IStockService;
using WIDESEA_ITaskInfoService;
using WIDESEA_Model.Models;
+using WIDESEA_Model.Models.Outbound;
namespace WIDESEA_TaskInfoService
{
@@ -64,6 +66,7 @@
private readonly IInboundOrderService _inboundOrderService;
private readonly IInboundOrderDetailService _inboundOrderDetailService;
+ private readonly IRepository<Dt_OutboundBatch> _OutboundBatchRepository;
private readonly IOutboundOrderService _outboundOrderService;
private readonly IOutboundOrderDetailService _outboundOrderDetailService;
private readonly IOutStockLockInfoService _outStockLockInfoService;
@@ -92,7 +95,7 @@
public List<int> TaskOutboundTypes => typeof(TaskTypeEnum).GetEnumIndexList();
- public TaskService(IRepository<Dt_Task> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_StockInfo> stockRepository, ILocationInfoService locationInfoService, IInboundOrderService inboundOrderService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IESSApiService eSSApiService, ILogger<TaskService> logger, IStockService stockService, IRecordService recordService, IInboundOrderDetailService inboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IInvokeMESService invokeMESService, IOutStockLockInfoService outStockLockInfoService, IAllocateService allocateService) : base(BaseDal)
+ public TaskService(IRepository<Dt_Task> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IRepository<Dt_StockInfo> stockRepository, ILocationInfoService locationInfoService, IInboundOrderService inboundOrderService, ILocationStatusChangeRecordService locationStatusChangeRecordService, IESSApiService eSSApiService, ILogger<TaskService> logger, IStockService stockService, IRecordService recordService, IInboundOrderDetailService inboundOrderDetailService, IOutboundOrderService outboundOrderService, IOutboundOrderDetailService outboundOrderDetailService, IInvokeMESService invokeMESService, IOutStockLockInfoService outStockLockInfoService, IAllocateService allocateService, IRepository<Dt_OutboundBatch> outboundBatchRepository) : base(BaseDal)
{
_mapper = mapper;
_unitOfWorkManage = unitOfWorkManage;
@@ -110,6 +113,7 @@
_invokeMESService = invokeMESService;
_outStockLockInfoService = outStockLockInfoService;
_allocateService = allocateService;
+ _OutboundBatchRepository = outboundBatchRepository;
}
@@ -126,7 +130,7 @@
if (int.TryParse(taskNum, out var newTaskNum))
{
- task = BaseDal.QueryFirst(x => x.TaskNum == newTaskNum);
+ task = await BaseDal.QueryFirstAsync(x => x.TaskNum == newTaskNum);
if (task == null)
{
return WebResponseContent.Instance.Error("鏈壘鍒颁换鍔′俊鎭�");
@@ -141,10 +145,28 @@
MethodInfo? methodInfo = GetType().GetMethod(((TaskTypeEnum)task.TaskType) + "TaskCompleted");
if (methodInfo != null)
{
- WebResponseContent? responseContent = (WebResponseContent?)methodInfo.Invoke(this, new object[] { task });
- if (responseContent != null)
+ object? taskResult = methodInfo.Invoke(this, new object[] { task });
+ if (taskResult is Task<WebResponseContent> asyncTask)
{
- return responseContent;
+ try
+ {
+ // 3. 寮傛绛夊緟 Task 瀹屾垚锛岃嚜鍔ㄨВ鏋愬嚭 WebResponseContent
+ WebResponseContent responseContent = await asyncTask;
+ if (responseContent != null)
+ {
+ return responseContent;
+ }
+ }
+ catch (AggregateException ex)
+ {
+ _logger.LogError($"TaskService TaskCompleted taskResult: {ex.Message} ");
+ return WebResponseContent.Instance.Error(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"Unexpected error in {task.TaskType}");
+ return WebResponseContent.Instance.Error(ex.Message);
+ }
}
}
return WebResponseContent.Instance.Error("鏈壘鍒颁换鍔$被鍨嬪搴斾笟鍔″鐞嗛�昏緫");
@@ -251,12 +273,12 @@
{
foreach (var inboundOrder in inboundOrders)
{
- if (inboundOrder.OrderType == InOrderTypeEnum.Allocat.ObjToInt())//璋冩嫧鍏ュ簱
+ if (inboundOrder.OrderType == InOrderTypeEnum.AllocatInbound.ObjToInt())//璋冩嫧鍏ュ簱
{
if (inboundOrder != null && inboundOrder.OrderStatus == InOrderStatusEnum.鍏ュ簱瀹屾垚.ObjToInt())
{
var allocate = _allocateService.Repository.QueryData(x => x.OrderNo == inboundOrder.InboundOrderNo).First();
- var feedmodel = new AllocateDto
+ var allocatefeedmodel = new AllocateDto
{
ReqCode = Guid.NewGuid().ToString(),
ReqTime = DateTime.Now.ToString(),
@@ -265,8 +287,8 @@
OperationType = 1,
Operator = inboundOrder.Operator,
OrderNo = inboundOrder.UpperOrderNo,
- fromWarehouse = allocate?.FromWarehouse??"",
- toWarehouse = allocate?.ToWarehouse??"",
+ fromWarehouse = allocate?.FromWarehouse ?? "",
+ toWarehouse = allocate?.ToWarehouse ?? "",
Details = new List<AllocateDtoDetail>()
};
@@ -289,9 +311,9 @@
Unit = row.Unit
}).ToList()
}).ToList();
- feedmodel.Details = groupedData;
+ allocatefeedmodel.Details = groupedData;
- var result = await _invokeMESService.FeedbackAllocate(feedmodel);
+ var result = await _invokeMESService.FeedbackAllocate(allocatefeedmodel);
if (result != null && result.code == 200)
{
_inboundOrderService.Db.Updateable<Dt_InboundOrder>().SetColumns(it => new Dt_InboundOrder { ReturnToMESStatus = 1 })
@@ -363,7 +385,14 @@
return WebResponseContent.Instance.OK();
}
- public WebResponseContent OutboundTaskCompleted(Dt_Task task)
+
+ public async Task<WebResponseContent> OutAllocateTaskCompleted(Dt_Task task)
+ {
+ _logger.LogInformation($"TaskService OutAllocateTaskCompleted: {task.TaskNum}");
+
+ return await OutboundTaskCompleted(task);
+ }
+ public async Task<WebResponseContent> OutboundTaskCompleted(Dt_Task task)
{
_logger.LogInformation($"TaskService OutboundTaskCompleted: {task.TaskNum}");
//鏌ヨ揣浣�
@@ -375,7 +404,7 @@
locationInfo.LocationStatus = LocationStatusEnum.Free.ObjToInt();
_locationInfoService.Repository.UpdateData(locationInfo);
- var outloks = _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>().Where(x => x.TaskNum == task.TaskNum).ToList();
+ var outloks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>().Where(x => x.TaskNum == task.TaskNum).ToListAsync();
var stockids = outloks.Select(x => x.StockId).ToList();
@@ -439,12 +468,22 @@
stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
_stockRepository.UpdateData(stockInfo);
+ var outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().First(x => x.OrderNo == task.OrderNo);
+
task.TaskStatus = TaskStatusEnum.Finish.ObjToInt();
BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? WIDESEA_Core.Enums.OperateTypeEnum.鑷姩瀹屾垚 : OperateTypeEnum.浜哄伐瀹屾垚);
_locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, beforelocationStatus, StockChangeType.Inbound.ObjToInt(), "", task.TaskNum);
+ if (outboundOrder != null)
+ {
+ await HandleOutboundOrderToMESCompletion(outboundOrder, outboundOrder.OrderNo);
+ }
+ else
+ {
+ _logger.LogInformation($"TaskService InEmptyTaskCompleted: {task.TaskNum} ,鏈壘鍒板嚭搴撳崟銆� ");
+ }
return content;
}
@@ -457,62 +496,260 @@
public async Task<WebResponseContent> InPickTaskCompleted(Dt_Task task)
{
_logger.LogInformation($"TaskService InPickTaskCompleted: {task.TaskNum}");
- //鏌ュ簱瀛�
- Dt_StockInfo stockInfo = _stockRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == task.PalletCode).First();
- if (stockInfo == null)
+ try
{
- return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩樺搴旂殑缁勭洏淇℃伅");
+ //鏌ュ簱瀛�
+ Dt_StockInfo stockInfo = await _stockRepository.Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.PalletCode == task.PalletCode).FirstAsync();
+ if (stockInfo == null)
+ {
+ _logger.LogInformation($"TaskService InPickTaskCompleted: 鏈壘鍒版墭鐩樺搴旂殑缁勭洏淇℃伅.{task.TaskNum}");
+ return WebResponseContent.Instance.Error($"鏈壘鍒版墭鐩樺搴旂殑缁勭洏淇℃伅");
+ }
+ if (stockInfo.Details.Count == 0 && stockInfo.PalletType != PalletTypeEnum.Empty.ObjToInt())
+ {
+ _logger.LogInformation($"TaskService InPickTaskCompleted: 鏈壘鍒拌鎵樼洏搴撳瓨鏄庣粏淇℃伅.{task.TaskNum}");
+ return WebResponseContent.Instance.Error($"鏈壘鍒拌鎵樼洏搴撳瓨鏄庣粏淇℃伅");
+ }
+ //鏌ヨ揣浣�
+ Dt_LocationInfo locationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress);
+ if (locationInfo == null)
+ {
+ _logger.LogInformation($"TaskService InPickTaskCompleted: 鏈壘鍒板搴旂殑缁堢偣璐т綅淇℃伅 {task.TaskNum}.");
+ return WebResponseContent.Instance.Error($"鏈壘鍒板搴旂殑缁堢偣璐т綅淇℃伅");
+ }
+
+ var beforelocationStatus = locationInfo.LocationStatus;
+ // 鑾峰彇鎵�鏈夊洖搴撲腑鐨勫嚭搴撻攣瀹氳褰�
+ var returnLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(it => it.OrderNo == task.OrderNo && it.PalletCode == task.PalletCode && it.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�)
+ .ToListAsync();
+ // 鏇存柊鍑哄簱閿佸畾璁板綍鐘舵�佷负鍥炲簱瀹屾垚
+ foreach (var lockInfo in returnLocks)
+ {
+ lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
+ }
+ _outStockLockInfoService.Db.Updateable(returnLocks).ExecuteCommand();
+
+ stockInfo.LocationCode = task.TargetAddress;
+ stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+ if (stockInfo.Details != null && stockInfo.Details.Any())
+ {
+ stockInfo.Details.ForEach(x =>
+ {
+ x.Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+ });
+ _stockService.StockInfoDetailService.Repository.UpdateData(stockInfo.Details);
+ }
+
+ _stockService.StockInfoService.Repository.UpdateData(stockInfo);
+
+ await ProcessStockDetailsForReturn(task, stockInfo.Id);
+
+ await DeleteZeroQuantityStockDetails(stockInfo.Id);
+
+ if (stockInfo.PalletType == PalletTypeEnum.Empty.ObjToInt())
+ {
+ locationInfo.LocationStatus = LocationStatusEnum.Pallet.ObjToInt();
+ }
+ else
+ {
+ locationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt();
+ }
+ _locationInfoService.Repository.UpdateData(locationInfo);
+ var outboundOrder = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().First(x => x.OrderNo == task.OrderNo);
+ task.TaskStatus = TaskStatusEnum.Finish.ObjToInt();
+
+ BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.鑷姩瀹屾垚 : OperateTypeEnum.浜哄伐瀹屾垚);
+ BaseDal.DeleteData(task);
+ _locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, beforelocationStatus, StockChangeType.Inbound.ObjToInt(), "", task.TaskNum);
+
+ if (outboundOrder != null)
+ {
+ await HandleOutboundOrderToMESCompletion(outboundOrder, outboundOrder.OrderNo);
+ }
+ else
+ {
+ _logger.LogInformation($"TaskService InPickTaskCompleted: {task.TaskNum} ,鏈壘鍒板嚭搴撳崟銆� ");
+ }
}
- if (stockInfo.Details.Count == 0 && stockInfo.PalletType != PalletTypeEnum.Empty.ObjToInt())
+ catch (Exception ex)
{
- return WebResponseContent.Instance.Error($"鏈壘鍒拌鎵樼洏搴撳瓨鏄庣粏淇℃伅");
+ _logger.LogInformation($"TaskService InPickTaskCompleted: {task.TaskNum} , {ex.Message}");
}
- //鏌ヨ揣浣�
- Dt_LocationInfo locationInfo = _locationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress);
- if (locationInfo == null)
+ return await Task.FromResult(WebResponseContent.Instance.OK());
+ }
+
+
+ private async Task HandleOutboundOrderToMESCompletion(Dt_OutboundOrder outboundOrder, string orderNo)
+ {
+ try
{
- return WebResponseContent.Instance.Error($"鏈壘鍒板搴旂殑缁堢偣璐т綅淇℃伅");
+ var orderDetails = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .LeftJoin<Dt_OutboundOrder>((o, item) => o.OrderId == item.Id)
+ .Where((o, item) => item.OrderNo == orderNo)
+ .Select((o, item) => o)
+ .ToListAsync();
+
+ bool allCompleted = true;
+ foreach (var detail in orderDetails)
+ {
+ if (detail.OverOutQuantity < detail.NeedOutQuantity)
+ {
+ allCompleted = false;
+ break;
+ }
+ }
+ _logger.LogInformation($"TaskService HandleOutboundOrderToMESCompletion: {outboundOrder.OrderNo} , {allCompleted}");
+ int newStatus = allCompleted ? (int)OutOrderStatusEnum.鍑哄簱瀹屾垚 : (int)OutOrderStatusEnum.鍑哄簱涓�;
+
+ if (outboundOrder.OrderStatus != newStatus)
+ {
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.OrderStatus == newStatus)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+
+ }
+ //鍙湁姝e父鍒嗘嫞瀹屾垚鏃舵墠鍚慚ES鍙嶉
+ if (allCompleted && newStatus == (int)OutOrderStatusEnum.鍑哄簱瀹屾垚)
+ {
+
+ if (outboundOrder.OrderType == OutOrderTypeEnum.Allocate.ObjToInt())
+ {
+ var allocate = _allocateService.Repository.QueryData(x => x.UpperOrderNo == outboundOrder.UpperOrderNo).First();
+ var allocatefeedmodel = new AllocateDto
+ {
+ ReqCode = Guid.NewGuid().ToString(),
+ ReqTime = DateTime.Now.ToString(),
+ BusinessType = "3",
+ FactoryArea = outboundOrder.FactoryArea,
+ OperationType = 1,
+ Operator = outboundOrder.Operator,
+ OrderNo = outboundOrder.UpperOrderNo,
+ // documentsNO = outboundOrder.OrderNo,
+ // status = outboundOrder.OrderStatus,
+ fromWarehouse = allocate?.FromWarehouse ?? "",
+ toWarehouse = allocate?.ToWarehouse ?? "",
+ Details = new List<AllocateDtoDetail>()
+
+ };
+ foreach (var detail in orderDetails)
+ {
+ // 鑾峰彇璇ユ槑缁嗗搴旂殑鏉$爜淇℃伅锛堜粠閿佸畾璁板綍锛�
+ var detailLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.OrderDetailId == detail.Id &&
+ x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ .ToListAsync();
+
+ var detailModel = new AllocateDtoDetail
+ {
+ MaterialCode = detail.MaterielCode,
+ LineNo = detail.lineNo, // 娉ㄦ剰锛氳繖閲屽彲鑳介渶瑕佽皟鏁村瓧娈靛悕
+ WarehouseCode = detail.WarehouseCode,
+ Qty = detail.OverOutQuantity, // 浣跨敤璁㈠崟鏄庣粏鐨勫凡鍑哄簱鏁伴噺
+ //currentDeliveryQty = detail.OverOutQuantity,
+ Unit = detail.Unit,
+ Barcodes = detailLocks.Select(lockInfo => new BarcodeInfo
+ {
+ Barcode = lockInfo.CurrentBarcode,
+ SupplyCode = lockInfo.SupplyCode,
+ BatchNo = lockInfo.BatchNo,
+ Unit = lockInfo.Unit,
+ Qty = lockInfo.PickedQty // 鏉$爜绾у埆鐨勬暟閲忎粛鐢ㄩ攣瀹氳褰�
+ }).ToList()
+ };
+
+ allocatefeedmodel.Details.Add(detailModel);
+ }
+
+ var result = await _invokeMESService.FeedbackAllocate(allocatefeedmodel);
+ if (result != null && result.code == 200)
+ {
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(x => x.ReturnToMESStatus == 1)
+ .Where(x => x.OrderId == outboundOrder.Id).ExecuteCommandAsync();
+
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => new Dt_OutboundOrder
+ {
+ ReturnToMESStatus = 1,
+ Operator = App.User.UserName,
+ }).Where(x => x.OrderNo == orderNo).ExecuteCommandAsync();
+ }
+ }
+ else if (outboundOrder.OrderType == OutOrderTypeEnum.ReCheck.ObjToInt())
+ {
+
+ }
+ else
+ {
+ var feedmodel = new FeedbackOutboundRequestModel
+ {
+ reqCode = Guid.NewGuid().ToString(),
+ reqTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
+ business_type = outboundOrder.BusinessType,
+ factoryArea = outboundOrder.FactoryArea,
+ operationType = 1,
+ Operator = outboundOrder.Operator,
+ orderNo = outboundOrder.UpperOrderNo,
+ documentsNO = outboundOrder.OrderNo,
+ status = outboundOrder.OrderStatus,
+ details = new List<FeedbackOutboundDetailsModel>()
+ };
+
+
+ foreach (var detail in orderDetails)
+ {
+ // 鑾峰彇璇ユ槑缁嗗搴旂殑鏉$爜淇℃伅锛堜粠閿佸畾璁板綍锛�
+ var detailLocks = await _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
+ .Where(x => x.OrderNo == orderNo &&
+ x.OrderDetailId == detail.Id &&
+ x.Status == (int)OutLockStockStatusEnum.鎷i�夊畬鎴�)
+ .ToListAsync();
+
+ var detailModel = new FeedbackOutboundDetailsModel
+ {
+ materialCode = detail.MaterielCode,
+ lineNo = detail.lineNo, // 娉ㄦ剰锛氳繖閲屽彲鑳介渶瑕佽皟鏁村瓧娈靛悕
+ warehouseCode = detail.WarehouseCode,
+ qty = detail.OverOutQuantity, // 浣跨敤璁㈠崟鏄庣粏鐨勫凡鍑哄簱鏁伴噺
+ currentDeliveryQty = detail.OverOutQuantity,
+ unit = detail.Unit,
+ barcodes = detailLocks.Select(lockInfo => new WIDESEA_DTO.Outbound.BarcodesModel
+ {
+ barcode = lockInfo.CurrentBarcode,
+ supplyCode = lockInfo.SupplyCode,
+ batchNo = lockInfo.BatchNo,
+ unit = lockInfo.Unit,
+ qty = lockInfo.PickedQty // 鏉$爜绾у埆鐨勬暟閲忎粛鐢ㄩ攣瀹氳褰�
+ }).ToList()
+ };
+
+ feedmodel.details.Add(detailModel);
+ }
+
+ var result = await _invokeMESService.FeedbackOutbound(feedmodel);
+ if (result != null && result.code == 200)
+ {
+ await _outboundOrderDetailService.Db.Updateable<Dt_OutboundOrderDetail>()
+ .SetColumns(x => x.ReturnToMESStatus == 1)
+ .Where(x => x.OrderId == outboundOrder.Id)
+ .ExecuteCommandAsync();
+
+ await _outboundOrderService.Db.Updateable<Dt_OutboundOrder>()
+ .SetColumns(x => x.ReturnToMESStatus == 1)
+ .Where(x => x.OrderNo == orderNo)
+ .ExecuteCommandAsync();
+ }
+ }
+ }
}
- // 鑾峰彇鎵�鏈夊洖搴撲腑鐨勫嚭搴撻攣瀹氳褰�
- var returnLocks = _outStockLockInfoService.Db.Queryable<Dt_OutStockLockInfo>()
- .Where(it => it.OrderNo == task.OrderNo && it.PalletCode == task.PalletCode && it.Status == (int)OutLockStockStatusEnum.鍥炲簱涓�)
- .ToList();
- // 鏇存柊鍑哄簱閿佸畾璁板綍鐘舵�佷负鍥炲簱瀹屾垚
- foreach (var lockInfo in returnLocks)
+ catch (Exception ex)
{
- lockInfo.Status = (int)OutLockStockStatusEnum.宸插洖搴�;
+ _logger.LogError($"CheckAndUpdateOrderStatus澶辫触 - OrderNo: {orderNo}, Error: {ex.Message}");
}
- _outStockLockInfoService.Db.Updateable(returnLocks).ExecuteCommand();
- await DeleteZeroQuantityStockDetails(stockInfo.Id);
-
- stockInfo.LocationCode = task.TargetAddress;
- stockInfo.StockStatus = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
- stockInfo.Details.ForEach(x =>
- {
- x.Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
- });
- _stockService.StockInfoService.Repository.UpdateData(stockInfo);
- _stockService.StockInfoDetailService.Repository.UpdateData(stockInfo.Details);
- await ProcessStockDetailsForReturn(task, stockInfo.Id);
-
-
-
- if (stockInfo.PalletType == PalletTypeEnum.Empty.ObjToInt())
- {
- locationInfo.LocationStatus = LocationStatusEnum.Pallet.ObjToInt();
- }
- else
- {
- locationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt();
- }
- _locationInfoService.Repository.UpdateData(locationInfo);
-
- task.TaskStatus = TaskStatusEnum.Finish.ObjToInt();
-
- BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.鑷姩瀹屾垚 : OperateTypeEnum.浜哄伐瀹屾垚);
-
- return WebResponseContent.Instance.OK();
}
/// <summary>
@@ -526,7 +763,7 @@
var deleteCount = await _stockService.StockInfoDetailService.Db.Deleteable<Dt_StockInfoDetail>()
.Where(x => x.StockId == stockId &&
x.StockQuantity == 0 &&
- (x.Status==StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt()|| x.Status==
+ (x.Status == StockStatusEmun.鍑哄簱瀹屾垚.ObjToInt() || x.Status ==
StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt())) // 鍙垹闄ゅ凡瀹屾垚鐘舵�佺殑闆跺簱瀛�
.ExecuteCommandAsync();
@@ -550,14 +787,14 @@
var stockDetails = await _stockService.StockInfoDetailService.Db.Queryable<Dt_StockInfoDetail>()
.Where(x => x.StockId == stockId &&
x.StockQuantity > 0 &&
- ( x.Status == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt()|| x.Status==
+ (x.Status == StockStatusEmun.鍑哄簱閿佸畾.ObjToInt() || x.Status ==
StockStatusEmun.鍏ュ簱纭.ObjToInt())) // 鍖呮嫭鍑哄簱閿佸畾鍜屽叆搴撶‘璁ょ殑
.ToListAsync();
foreach (var detail in stockDetails)
{
-
- detail.Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
+
+ detail.Status = StockStatusEmun.鍏ュ簱瀹屾垚.ObjToInt();
detail.OutboundQuantity = 0; // 娓呯┖鍑哄簱鏁伴噺
_logger.LogInformation($"鏇存柊搴撳瓨鏄庣粏鐘舵�� - 鏉$爜: {detail.Barcode}, 鏁伴噺: {detail.StockQuantity}");
@@ -597,11 +834,11 @@
task.TaskStatus = TaskStatusEnum.Finish.ObjToInt();
BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.鑷姩瀹屾垚 : OperateTypeEnum.浜哄伐瀹屾垚);
_stockService.StockInfoService.Repository.DeleteAndMoveIntoHty(stockInfo, App.User.UserId == 0 ? OperateTypeEnum.鑷姩瀹屾垚 : OperateTypeEnum.浜哄伐瀹屾垚);
- _stockRepository.Db.Deleteable(stockInfo).ExecuteCommand();
-
+ //_stockRepository.Db.Deleteable(stockInfo).ExecuteCommand();
+ _stockService.StockInfoService.DeleteData(stockInfo);
_locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, beforeStatus, StockChangeType.Outbound.ObjToInt(), stockInfo.Details.FirstOrDefault()?.OrderNo ?? "", task.TaskNum);
- return WebResponseContent.Instance.OK();
+ return await Task.FromResult(WebResponseContent.Instance.OK());
}
catch (Exception ex)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Inbound.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Inbound.cs"
index a7d3558..e72189b 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Inbound.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Inbound.cs"
@@ -29,10 +29,10 @@
{
try
{
- Dt_Task dbtask = Repository.QueryFirst(x => x.PalletCode == palletCode);
+ Dt_Task dbtask = Repository.Db.Queryable<Dt_Task>().Where(x => x.PalletCode == palletCode).OrderByDescending(x=>x.CreateDate).First();
if (dbtask != null)
{
- if (dbtask.TaskType == TaskTypeEnum.Outbound.ObjToInt())
+ if (dbtask.TaskType == TaskTypeEnum.Outbound.ObjToInt() || dbtask.TaskType == TaskTypeEnum.OutAllocate.ObjToInt())
{
return WebResponseContent.Instance.Error($"鍑哄簱寰呭垎鎷d换鍔�");
}
@@ -40,7 +40,7 @@
{
return WebResponseContent.Instance.Error($"璇ユ墭鐩樺凡鐢熸垚浠诲姟");
}
- }
+ }
Dt_StockInfo stockInfo = _stockRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletCode == palletCode).Includes(x => x.Details).First();
if (stockInfo == null)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Outbound.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Outbound.cs"
index c2f08d2..0cf697c 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Outbound.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Outbound.cs"
@@ -6,6 +6,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using WIDESEA_BasicService;
using WIDESEA_Common.CommonEnum;
using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.OrderEnum;
@@ -17,6 +18,8 @@
using WIDESEA_DTO.Basic;
using WIDESEA_DTO.Stock;
using WIDESEA_Model.Models;
+using WIDESEA_Model.Models.Basic;
+using WIDESEA_Model.Models.Outbound;
namespace WIDESEA_TaskInfoService
{
@@ -140,14 +143,22 @@
{
throw new Exception("鏈壘鍒板嚭搴撳崟鏄庣粏淇℃伅");
}
- if (outboundOrderDetails.FirstOrDefault(x => x.OrderDetailStatus > OrderDetailStatusEnum.New.ObjToInt() && x.OrderDetailStatus != OrderDetailStatusEnum.AssignOverPartial.ObjToInt()) != null)
+ //if (outboundOrderDetails.FirstOrDefault(x => x.OrderDetailStatus > OrderDetailStatusEnum.New.ObjToInt() && x.OrderDetailStatus != OrderDetailStatusEnum.AssignOverPartial.ObjToInt()) != null)
+ //{
+ // throw new Exception("鎵�閫夊嚭搴撳崟鏄庣粏瀛樺湪鍑哄簱涓垨宸插畬鎴�");
+ //}
+
+ if (outboundOrderDetails.FirstOrDefault(x => x.OrderDetailStatus > OrderDetailStatusEnum.Outbound.ObjToInt() && x.OrderDetailStatus != OrderDetailStatusEnum.AssignOverPartial.ObjToInt()) != null)
{
- throw new Exception("鎵�閫夊嚭搴撳崟鏄庣粏瀛樺湪鍑哄簱涓垨宸插畬鎴�");
+ throw new Exception("鎵�閫夊嚭搴撳崟鏄庣粏瀛樺湪宸插畬鎴愮姸鎬侊紝鏃犳硶閲嶆柊鍒嗛厤");
}
+
List<Dt_StockInfo>? stockInfos = null;
List<Dt_OutboundOrderDetail>? orderDetails = null;
List<Dt_OutStockLockInfo>? outStockLockInfos = null;
List<Dt_LocationInfo>? locationInfos = null;
+
+ CleanupPreviousInvalidLocks(outboundOrderDetails);
(List<Dt_StockInfo>, List<Dt_OutboundOrderDetail>, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) result = _outboundOrderDetailService.AssignStockOutbound(outboundOrderDetails);
if (result.Item1 != null && result.Item1.Count > 0)
@@ -182,10 +193,34 @@
else
{
throw new Exception("鏃犲簱瀛�");
- }
+ }
return (tasks, stockInfos, orderDetails, outStockLockInfos, locationInfos);
}
+ /// <summary>
+ /// 娓呯悊涔嬪墠鐨勬棤鏁堥攣瀹氳褰�
+ /// </summary>
+ private void CleanupPreviousInvalidLocks(List<Dt_OutboundOrderDetail> orderDetails)
+ {
+ var orderIds = orderDetails.Select(x => x.OrderId).Distinct().ToList();
+ var orderNos = _outboundOrderService.Db.Queryable<Dt_OutboundOrder>()
+ .Where(x => orderIds.Contains(x.Id))
+ .Select(x => x.OrderNo)
+ .ToList();
+ // 娓呯悊鐘舵�佷负"宸查噴鏀�"鎴�"鍥炲簱涓�"鐨勬棫閿佸畾璁板綍
+ foreach (var orderNo in orderNos)
+ {
+ _outStockLockInfoService.Db.Updateable<Dt_OutStockLockInfo>()
+ .SetColumns(x => new Dt_OutStockLockInfo
+ {
+ Status = (int)OutLockStockStatusEnum.宸查噴鏀�
+ })
+ .Where(x => x.OrderNo == orderNo &&
+ (x.Status == (int)OutLockStockStatusEnum.鍥炲簱涓� ||
+ x.Status == (int)OutLockStockStatusEnum.宸查噴鏀�))
+ .ExecuteCommand();
+ }
+ }
/// <summary>
/// 鐢熸垚鍑哄簱浠诲姟鍚庢暟鎹洿鏂板埌鏁版嵁搴�
@@ -206,7 +241,7 @@
if (stockInfos != null && stockInfos.Count > 0 && outboundOrderDetails != null && outboundOrderDetails.Count > 0 && outStockLockInfos != null && outStockLockInfos.Count > 0 && locationInfos != null && locationInfos.Count > 0)
{
stockInfos.ForEach(x =>
- {
+ {
x.StockStatus = StockStatusEmun.鍑哄簱閿佸畾.ObjToInt();
});
outboundOrderDetails.ForEach(x =>
@@ -218,7 +253,11 @@
{
_outboundOrderService.Repository.UpdateData(outboundOrder);
}
- outboundOrder.Operator = App.User.UserName;
+ else
+ {
+ outboundOrder.OrderStatus = OutOrderStatusEnum.鍑哄簱涓�.ObjToInt();
+ }
+ outboundOrder.Operator = App.User.UserName;
_outboundOrderService.Repository.UpdateData(outboundOrder);
WebResponseContent content = _outboundOrderDetailService.LockOutboundStockDataUpdate(stockInfos, outboundOrderDetails, outStockLockInfos, locationInfos, tasks: tasks);
@@ -239,6 +278,12 @@
{
_outboundOrderService.Repository.UpdateData(outboundOrder);
}
+ else
+ {
+ outboundOrder.OrderStatus = OutOrderStatusEnum.鍑哄簱涓�.ObjToInt();
+ }
+ outboundOrder.Operator = App.User.UserName;
+ _outboundOrderService.Repository.UpdateData(outboundOrder);
_outboundOrderDetailService.Repository.UpdateData(outboundOrderDetails);
}
_unitOfWorkManage.CommitTran();
@@ -471,10 +516,10 @@
throw new Exception("鏈壘鍒板嚭搴撳崟鏄庣粏淇℃伅");
}
- if (stockSelectViews.Sum(x => x.UseableQuantity) > outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity)
- {
- throw new Exception("閫夋嫨鏁伴噺瓒呭嚭鍗曟嵁鏁伴噺");
- }
+ //if (stockSelectViews.Sum(x => x.UseableQuantity) > outboundOrderDetail.OrderQuantity - outboundOrderDetail.LockQuantity)
+ //{
+ // throw new Exception("閫夋嫨鏁伴噺瓒呭嚭鍗曟嵁鏁伴噺");
+ //}
List<Dt_StockInfo>? stockInfos = null;
Dt_OutboundOrderDetail? orderDetail = null;
List<Dt_OutStockLockInfo>? outStockLockInfos = null;
@@ -484,7 +529,7 @@
(List<Dt_StockInfo>, Dt_OutboundOrderDetail, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) result = _outboundOrderDetailService.AssignStockOutbound(outboundOrderDetail, stockSelectViews);
if (result.Item1 != null && result.Item1.Count > 0)
{
- Dt_OutboundOrder outboundOrder = _outboundOrderService .Repository.QueryFirst(x => x.Id == outboundOrderDetail.OrderId);
+ Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.Id == outboundOrderDetail.OrderId);
TaskTypeEnum typeEnum = outboundOrder.OrderType switch
{
(int)OutOrderTypeEnum.Issue => TaskTypeEnum.Outbound,
@@ -586,5 +631,200 @@
}
+
+ #region 鍒嗘壒鍒嗛厤搴撳瓨
+
+ /// <summary>
+ /// 鍒嗘壒鍒嗛厤搴撳瓨
+ /// </summary>
+ public async Task<WebResponseContent> GenerateOutboundBatchTasksAsync(int orderDetailId, decimal batchQuantity, string outStation)
+ {
+ try
+ {
+ List<Dt_Task> tasks = new List<Dt_Task>();
+ List<Dt_StockInfo> stockInfos = new List<Dt_StockInfo>();
+ List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>();
+ List<Dt_OutStockLockInfo> outStockLockInfos = new List<Dt_OutStockLockInfo>();
+ List<Dt_LocationInfo> locationInfos = new List<Dt_LocationInfo>();
+
+ (List<Dt_Task>, List<Dt_StockInfo>?, List<Dt_OutboundOrderDetail>?, List<Dt_OutStockLockInfo>?, List<Dt_LocationInfo>?) result = await BatchAllocateStockDataHandle(orderDetailId, batchQuantity, outStation);
+
+ if (result.Item2 != null && result.Item2.Count > 0)
+ {
+ stockInfos.AddRange(result.Item2);
+ }
+ if (result.Item3 != null && result.Item3.Count > 0)
+ {
+ outboundOrderDetails.AddRange(result.Item3);
+ }
+ if (result.Item4 != null && result.Item4.Count > 0)
+ {
+ outStockLockInfos.AddRange(result.Item4);
+ }
+ if (result.Item5 != null && result.Item5.Count > 0)
+ {
+ locationInfos.AddRange(result.Item5);
+ }
+ if (result.Item1 != null && result.Item1.Count > 0)
+ {
+ tasks.AddRange(result.Item1);
+ }
+
+ WebResponseContent content = await GenerateOutboundTaskDataUpdateAsync(tasks, stockInfos, outboundOrderDetails, outStockLockInfos, locationInfos);
+ return content;
+ }
+ catch (Exception ex)
+ {
+ _unitOfWorkManage.RollbackTran();
+ _logger.LogError($"鍒嗘壒鍒嗛厤搴撳瓨澶辫触 - OrderDetailId: {orderDetailId}, Quantity: {batchQuantity}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error($"鍒嗘壒鍒嗛厤澶辫触锛歿ex.Message}");
+ }
+ }
+
+ /// <summary>
+ /// 鍒嗘壒鍒嗛厤搴撳瓨鏁版嵁澶勭悊
+ /// </summary>
+ public async Task<(List<Dt_Task>, List<Dt_StockInfo>?, List<Dt_OutboundOrderDetail>?, List<Dt_OutStockLockInfo>?, List<Dt_LocationInfo>?)>
+ BatchAllocateStockDataHandle( int orderDetailId, decimal batchQuantity, string outStation)
+ {
+ List<Dt_Task> tasks = new List<Dt_Task>();
+
+ // 鑾峰彇璁㈠崟鏄庣粏
+ var outboundOrderDetail = await _outboundOrderDetailService.Db.Queryable<Dt_OutboundOrderDetail>()
+ .FirstAsync(x => x.Id == orderDetailId );
+
+ if (outboundOrderDetail == null)
+ {
+ throw new Exception("鏈壘鍒板嚭搴撳崟鏄庣粏淇℃伅");
+ }
+ var outboundOrder = await _outboundOrderService.Db.Queryable<Dt_OutboundOrder>().FirstAsync(x => x.Id == outboundOrderDetail.OrderId);
+ if(outboundOrder == null)
+ {
+ throw new Exception("鏈壘鍒板嚭搴撳崟淇℃伅");
+ }
+ // 楠岃瘉璁㈠崟鏄庣粏鐘舵��
+ if (outboundOrderDetail.OrderDetailStatus > OrderDetailStatusEnum.New.ObjToInt() &&
+ outboundOrderDetail.OrderDetailStatus != OrderDetailStatusEnum.AssignOverPartial.ObjToInt())
+ {
+ throw new Exception("鎵�閫夊嚭搴撳崟鏄庣粏瀛樺湪鍑哄簱涓垨宸插畬鎴�");
+ }
+
+ // 楠岃瘉鍒嗛厤鏁伴噺
+ decimal allocatedQty = outboundOrderDetail.AllocatedQuantity;
+ decimal overOutQty = outboundOrderDetail.OverOutQuantity;
+ decimal needOutQty = outboundOrderDetail.NeedOutQuantity;
+ decimal availableQty = needOutQty - allocatedQty - overOutQty;
+
+ if (availableQty <= 0)
+ throw new Exception("鏃犲彲鍒嗛厤鏁伴噺");
+
+ if (batchQuantity > availableQty)
+ throw new Exception($"鍒嗛厤鏁伴噺涓嶈兘瓒呰繃鍙垎閰嶆暟閲弡availableQty}");
+
+ List<Dt_StockInfo>? stockInfos = null;
+ List<Dt_OutboundOrderDetail>? orderDetails = null;
+ List<Dt_OutStockLockInfo>? outStockLockInfos = null;
+ List<Dt_LocationInfo>? locationInfos = null;
+
+ // 鐢熸垚鎵规鍙�
+ string batchNo = await GenerateBatchNo();
+
+ // 鍒嗛厤搴撳瓨
+ (List<Dt_StockInfo>, List<Dt_OutboundOrderDetail>, List<Dt_OutStockLockInfo>, List<Dt_LocationInfo>) allocateResult =
+ await _outboundOrderDetailService.AssignStockForBatch(outboundOrderDetail, batchQuantity, batchNo);
+
+ if (allocateResult.Item1 != null && allocateResult.Item1.Count > 0)
+ {
+ // 鍒涘缓鍒嗘壒璁板綍
+ await CreateBatchRecord(outboundOrder.OrderNo, orderDetailId, batchQuantity, batchNo);
+
+ TaskTypeEnum typeEnum = outboundOrder.OrderType switch
+ {
+ (int)OutOrderTypeEnum.Issue => TaskTypeEnum.Outbound,
+ (int)OutOrderTypeEnum.Allocate => TaskTypeEnum.OutAllocate,
+ (int)OutOrderTypeEnum.Quality => TaskTypeEnum.OutQuality,
+ _ => TaskTypeEnum.Outbound
+ };
+
+ tasks = GetTasks(allocateResult.Item1, typeEnum, outStation);
+ tasks.ForEach(x =>
+ {
+ x.OrderNo = outboundOrder.OrderNo;
+ });
+
+ allocateResult.Item2.ForEach(x =>
+ {
+ x.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt();
+ });
+
+ allocateResult.Item3.ForEach(x =>
+ {
+ x.Status = OutLockStockStatusEnum.鍑哄簱涓�.ObjToInt();
+ });
+
+ stockInfos = allocateResult.Item1;
+ orderDetails = allocateResult.Item2;
+ outStockLockInfos = allocateResult.Item3;
+ locationInfos = allocateResult.Item4;
+ }
+ else
+ {
+ throw new Exception("鏃犲簱瀛�");
+ }
+
+ return (tasks, stockInfos, orderDetails, outStockLockInfos, locationInfos);
+ }
+
+
+
+
+
+ /// <summary>
+ /// 鏇存柊璁㈠崟鏄庣粏鐘舵��
+ /// </summary>
+ private void UpdateOrderDetailStatus(List<Dt_OutboundOrderDetail> details, decimal allocatedQuantity, decimal needQuantity)
+ {
+ foreach (var detail in details)
+ {
+ // 鏍规嵁鍒嗛厤鎯呭喌鏇存柊鐘舵��
+ if (allocatedQuantity >= needQuantity)
+ {
+ detail.OrderDetailStatus = OrderDetailStatusEnum.Outbound.ObjToInt();
+ }
+ else
+ {
+ detail.OrderDetailStatus = OrderDetailStatusEnum.AssignOverPartial.ObjToInt();
+ }
+ }
+ }
+
+
+
+ private async Task<string> GenerateBatchNo()
+ {
+ var batchNo = UniqueValueGenerator.Generate();
+
+ return $"Out{batchNo} ";
+ }
+
+ private async Task<Dt_OutboundBatch> CreateBatchRecord(string orderNo, int orderDetailId, decimal batchQuantity, string batchNo)
+ {
+ var batchRecord = new Dt_OutboundBatch
+ {
+ BatchNo = batchNo,
+ OrderNo = orderNo,
+ OrderDetailId = orderDetailId,
+ BatchQuantity = batchQuantity,
+ BatchStatus = (int)BatchStatusEnum.鍒嗛厤涓�,
+ Operator = App.User.UserName
+ };
+
+ await _OutboundBatchRepository.Db.Insertable(batchRecord).ExecuteCommandAsync();
+ return batchRecord;
+ }
+
+ #endregion
+
+
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WIDESEA_TaskInfoService.csproj" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WIDESEA_TaskInfoService.csproj"
index 51b297d..c586408 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WIDESEA_TaskInfoService.csproj"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_TaskInfoService/WIDESEA_TaskInfoService.csproj"
@@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
+ <ProjectReference Include="..\WIDESEA_BasicService\WIDESEA_BasicService.csproj" />
<ProjectReference Include="..\WIDESEA_IAllocateService\WIDESEA_IAllocateService.csproj" />
<ProjectReference Include="..\WIDESEA_IBasicService\WIDESEA_IBasicService.csproj" />
<ProjectReference Include="..\WIDESEA_IInboundService\WIDESEA_IInboundService.csproj" />
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Allocate/AllocateOrderController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Allocate/AllocateOrderController.cs"
index 31f6001..d1616ce 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Allocate/AllocateOrderController.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Allocate/AllocateOrderController.cs"
@@ -1,5 +1,6 @@
锘縰sing Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
+using Newtonsoft.Json;
using System.Data.Common;
using System.Diagnostics.Eventing.Reader;
using System.Threading.Tasks;
@@ -33,6 +34,7 @@
[HttpPost, Route("ReceiveAllocateOrder"), MethodParamsValidate, AllowAnonymous]
public async Task<WebResponseContent> ReceiveAllocateOrder([FromBody] AllocateDto model)
{
+ _logger.LogInformation("AllocateOrderController ReceiveAllocateOrder: " + JsonConvert.SerializeObject(model));
Dt_AllocateOrder allocateOrder = new Dt_AllocateOrder
{
OrderNo = model.OrderNo,
@@ -41,12 +43,20 @@
FactoryArea = model.FactoryArea,
IsBatch = model.IsBatch,
CreateType = model.OperationType,
- FromWarehouse=model.fromWarehouse,
- ToWarehouse=model.toWarehouse,
+ FromWarehouse = model.fromWarehouse,
+ ToWarehouse = model.toWarehouse,
Details = new List<Dt_AllocateOrderDetail>()
};
Enum.TryParse<BusinessTypeEnum>(allocateOrder.BusinessType, out var businessType);
-
+ //allocateOrder.OrderType = businessType == BusinessTypeEnum.鏅轰粨璋冨閮ㄤ粨搴� ? 215 : 115;
+ if (businessType == BusinessTypeEnum.鏅轰粨璋冨閮ㄤ粨搴�)
+ {
+ allocateOrder.OrderType = 215;
+ }
+ else if (businessType == BusinessTypeEnum.澶栭儴浠撳簱璋冩櫤浠�)
+ {
+ allocateOrder.OrderType = 115;
+ }
foreach (var detailDto in model.Details)
{
@@ -69,7 +79,9 @@
Barcode = barcodeDto.Barcode,
BatchNo = barcodeDto.BatchNo,
BarcodeQty = barcodeDto.Qty,
- BarcodeUnit = barcodeDto.Unit
+ BarcodeUnit = barcodeDto.Unit,
+ ValidDate = barcodeDto.validDate,
+
};
allocateOrder.Details.Add(orderDetail);
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Check/ReCheckOrderController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Check/ReCheckOrderController.cs"
new file mode 100644
index 0000000..216b453
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Check/ReCheckOrderController.cs"
@@ -0,0 +1,19 @@
+锘縰sing Microsoft.AspNetCore.Mvc;
+using WIDESEA_Core.BaseController;
+using WIDESEA_ICheckService;
+using WIDESEA_Model.Models.Check;
+
+namespace WIDESEA_WMSServer.Controllers.Check
+{
+ /// <summary>
+ /// 閲嶆鍗�
+ /// </summary>
+ [Route("api/ReCheckOrder")]
+ [ApiController]
+ public class ReCheckOrderController : ApiBaseController<IReCheckOrderService, Dt_ReCheckOrder>
+ {
+ public ReCheckOrderController(IReCheckOrderService service) : base(service)
+ {
+ }
+ }
+}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/ESSController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/ESSController.cs"
index 8740074..6cfedd4 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/ESSController.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/ESSController.cs"
@@ -46,8 +46,9 @@
_logger.LogInformation(" ESSController ContainerArrivalReport : CallId={CallId},ContainerCode={ContainerCode},SlotCode={SlotCode}", request.CallId, request.ContainerCode, request.SlotCode);
var response = new ApiResponse<ContainerArrivalResponseData>
{
- Code = 1
-
+ Code = 1,
+ Data = null,
+
};
// 鐢熸垚璇锋眰鐨勫敮涓�鏍囪瘑锛堝熀浜巆allId + 鏃堕棿鎴筹級
@@ -77,6 +78,11 @@
}
WebResponseContent result = await _taskService.RequestInboundTask(request.ContainerCode, request.SlotCode);
+ if (result != null && !string.IsNullOrEmpty(result.Message))
+ {
+ _logger.LogError(" ESSController ContainerArrivalReport RequestInboundTask: Message={Message}", result?.Message);
+ }
+
var cacheOptions = new MemoryCacheEntryOptions
{
@@ -87,17 +93,23 @@
{
Code = 0,
Msg = "",
- Data = new ContainerArrivalResponseData
- {
- direction = "100"
- }
+ Data = null,
};
if (result != null && !string.IsNullOrEmpty( result.Message ) && result.Message.Contains("璇ユ墭鐩樺凡鐢熸垚浠诲姟"))
{
+
+ response.Data = new ContainerArrivalResponseData
+ {
+ direction = "100"
+ };
return Ok(response);
}
if (result != null && result.Status)
- {
+ {
+ response.Data = new ContainerArrivalResponseData
+ {
+ direction = "100"
+ };
return Ok(response);
}
else
@@ -217,7 +229,7 @@
_logger.LogInformation("浠诲姟瀹屾垚: TaskCode={TaskCode}, Container={Container}, Robot={Robot}",
request.TaskCode, request.ContainerCode, request.RobotCode);
- _taskService.TaskCompleted(request.TaskCode);
+ await _taskService.TaskCompleted(request.TaskCode);
// 鏍规嵁涓嶅悓鐨勪换鍔$被鍨嬭繘琛岀壒娈婂鐞�
if (request.Weight.HasValue)
{
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs"
index 3ba7403..d17e070 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/InboundOrderController.cs"
@@ -30,13 +30,13 @@
private readonly WIDESEA_IBasicService.IErpApiService erpApiService;
private readonly WIDESEA_IBasicService.IInvokeMESService _invokeMESService;
-
+ public readonly IInboundService _inboundService;
private readonly IESSApiService _eSSApiService;
private readonly ILocationInfoService _locationInfoService;
private readonly IDailySequenceService _dailySequenceService;
private readonly IMaterialUnitService _materialUnitService;
private readonly ILogger<InboundOrderController> _logger;
- public InboundOrderController(IInboundOrderService service, WIDESEA_IBasicService.IErpApiService erpApiService, WIDESEA_IBasicService.IInvokeMESService invokeMESService, IESSApiService eSSApiService, IDailySequenceService dailySequenceService, ILocationInfoService locationInfoService, ILogger<InboundOrderController> logger, IMaterialUnitService materialUnitService) : base(service)
+ public InboundOrderController(IInboundOrderService service, WIDESEA_IBasicService.IErpApiService erpApiService, WIDESEA_IBasicService.IInvokeMESService invokeMESService, IESSApiService eSSApiService, IDailySequenceService dailySequenceService, ILocationInfoService locationInfoService, ILogger<InboundOrderController> logger, IMaterialUnitService materialUnitService, IInboundService inboundService) : base(service)
{
this.erpApiService = erpApiService;
_invokeMESService = invokeMESService;
@@ -45,17 +45,23 @@
_locationInfoService = locationInfoService;
_logger = logger;
_materialUnitService = materialUnitService;
+ _inboundService = inboundService;
}
[HttpPost, Route("Test"), AllowAnonymous, MethodParamsValidate]
public async Task<WebResponseContent> Test()
{
- // var purchaseToStockResult = await _materialUnitService.ConvertPurchaseToStockAsync("101001-00002", 10);
- // var pdddurchaseToStockResult = await _materialUnitService.ConvertPurchaseToStockAsync("100513-00210", 10);
+ // Service.Db.Deleteable<Dt_InboundOrder>().Where(x=>x.UpperOrderNo== "12020251100040").ExecuteCommand();
+ //_inboundService.InboundOrderDetailService.Db.Deleteable<Dt_InboundOrderDetail>()
+ // .Where(p => SqlFunc.Subqueryable<Dt_InboundOrder>().Where(s => s.Id == p.OrderId && s.UpperOrderNo == "12020251100040").Any()).ExecuteCommand();
- var sddd = _locationInfoService.AssignLocation();
- var code = sddd.LocationCode;
+ var purchaseToStockResult = await _materialUnitService.ConvertPurchaseToStockAsync("100513-00303", 1);
+
+ var pdddurchaseToStockResult = await _materialUnitService.ConvertFromToStockAsync("100513-00303", "W013", 1);
+
+ //var sddd = _locationInfoService.AssignLocation();
+ //var code = sddd.LocationCode;
//var ssss=await _dailySequenceService.GetNextSequenceAsync();
//var ddddssss = "WSLOT" + DateTime.Now.ToString("yyyyMMddHHmmss") + ssss.ToString().PadLeft(5, '0');
//erpApiService.GetSuppliersAsync();
@@ -88,7 +94,7 @@
//await erpApiService.GetMaterialInfoAsync(new WIDESEA_DTO.Basic.MaterialRequest());
- return WebResponseContent.Instance.OK(code);
+ return WebResponseContent.Instance.OK();
}
/// <summary>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundBatchPickingController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundBatchPickingController.cs"
new file mode 100644
index 0000000..563ca1d
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundBatchPickingController.cs"
@@ -0,0 +1,219 @@
+锘縰sing Microsoft.AspNetCore.Mvc;
+using WIDESEA_Core;
+using WIDESEA_Core.BaseController;
+using WIDESEA_DTO.Outbound;
+using WIDESEA_IOutboundService;
+using WIDESEA_Model.Models;
+using static WIDESEA_OutboundService.OutboundBatchPickingService;
+
+namespace WIDESEA_WMSServer.Controllers.Outbound
+{
+
+ [Route("api/OutboundBatchPicking")]
+ [ApiController]
+ public class OutboundBatchPickingController : ApiBaseController<IOutboundBatchPickingService, Dt_PickingRecord>
+ {
+ private readonly ISplitPackageService _splitPackageService;
+ private readonly IOutStockLockInfoService _outStockLockInfoService;
+ private readonly IOutboundBatchPickingService _outboundBatchPickingService;
+
+ private readonly ILogger<OutboundBatchPickingController> _logger;
+ public OutboundBatchPickingController(IOutboundBatchPickingService service, ISplitPackageService splitPackageService, IOutStockLockInfoService outStockLockInfoService, IOutboundBatchPickingService outboundBatchPickingService, ILogger<OutboundBatchPickingController> logger) : base(service)
+ {
+ _splitPackageService = splitPackageService;
+ _outStockLockInfoService = outStockLockInfoService;
+ _outboundBatchPickingService = outboundBatchPickingService;
+ _logger = logger;
+ }
+
+ /// <summary>
+ /// 鍒嗘嫞纭
+ /// </summary>
+ [HttpPost("confirm-picking")]
+ public async Task<WebResponseContent> ConfirmPicking([FromBody] ConfirmPickingDto dto)
+ {
+ return await _outboundBatchPickingService.ConfirmBatchPicking(dto.OrderNo, dto.PalletCode, dto.Barcode);
+ }
+
+ /// <summary>
+ /// 鍙栨秷鍒嗘嫞
+ /// </summary>
+ [HttpPost("cancel-picking")]
+ public async Task<WebResponseContent> CancelPicking([FromBody] CancelPickingDto dto)
+ {
+ return await _outboundBatchPickingService.CancelPicking(dto.OrderNo, dto.PalletCode, dto.Barcode);
+ }
+ /// <summary>
+ /// 鍙栨秷鎷嗗寘閾�
+ /// </summary>
+ [HttpPost("cancel-split-chain")]
+ public async Task<WebResponseContent> CancelSplitChain([FromBody] CancelSplitChainDto dto)
+ {
+ return await _outboundBatchPickingService.CancelSplitPackageChain(dto.OrderNo, dto.PalletCode, dto.StartBarcode);
+ }
+
+ /// <summary>
+ /// 鑾峰彇鎷嗗寘閾句俊鎭�
+ /// </summary>
+ [HttpPost("split-package-chain-info")]
+ public async Task<WebResponseContent> GetSplitPackageChainInfo([FromBody] SplitPackageChainInfoRequestDto dto)
+ {
+ return await _outboundBatchPickingService.GetSplitPackageChainInfo(dto.OrderNo, dto.Barcode);
+ }
+ /// <summary>
+ /// 鏌ユ壘瀹屾暣鎷嗗寘閾撅紙浠庢牴鏉$爜寮�濮嬶級
+ /// </summary>
+ [HttpPost("find-root-split-chain")]
+ public async Task<WebResponseContent> FindRootSplitChain([FromBody] SplitPackageChainInfoRequestDto dto)
+ {
+ try
+ {
+ // 鏌ユ壘鏍规潯鐮�
+ var rootBarcode = await _outboundBatchPickingService. FindRootBarcode(dto.OrderNo, dto.Barcode);
+
+ // 鑾峰彇瀹屾暣鎷嗗寘閾�
+ var splitChain = await _outboundBatchPickingService.GetSplitPackageChain(dto.OrderNo, rootBarcode);
+
+ var chainInfo = new SplitPackageChainInfoDto
+ {
+ OriginalBarcode = rootBarcode,
+ RootBarcode = rootBarcode,
+ TotalSplitTimes = splitChain.Count,
+ ChainType = "root",
+ SplitChain = splitChain.Select(x => new SplitChainItemDto
+ {
+ SplitTime = x.SplitTime,
+ OriginalBarcode = x.OriginalBarcode,
+ NewBarcode = x.NewBarcode,
+ SplitQuantity = x.SplitQty,
+ Operator = x.Operator,
+ IsReverted = x.IsReverted
+ }).ToList()
+ };
+
+ return WebResponseContent.Instance.OK("鑾峰彇鎴愬姛", chainInfo);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError($"鏌ユ壘瀹屾暣鎷嗗寘閾惧け璐� - OrderNo: {dto.OrderNo}, Barcode: {dto.Barcode}, Error: {ex.Message}");
+ return WebResponseContent.Instance.Error("鏌ユ壘瀹屾暣鎷嗗寘閾惧け璐�");
+ }
+ }
+ /// <summary>
+ /// 鎵嬪姩鎷嗗寘
+ /// </summary>
+ [HttpPost("split-package")]
+ public async Task<WebResponseContent> SplitPackage([FromBody] SplitPackageDto dto)
+ {
+ return await _outboundBatchPickingService.ManualSplitPackage(dto.OrderNo, dto.PalletCode, dto.OriginalBarcode, dto.SplitQuantity);
+ }
+ /// <summary>
+ /// 鍙栨秷鎷嗗寘
+ /// </summary>
+ [HttpPost("cancel-split")]
+ public async Task<WebResponseContent> CancelSplit([FromBody] CancelSplitDto dto)
+ {
+ return await _outboundBatchPickingService.CancelSplitPackage(dto.OrderNo, dto.PalletCode, dto.NewBarcode);
+ }
+
+ /// <summary>
+ /// 鍒嗘壒鍥炲簱
+ /// </summary>
+ [HttpPost("return-stock")]
+ public async Task<WebResponseContent> ReturnStock([FromBody] ReturnStockDto dto)
+ {
+ return await _outboundBatchPickingService.BatchReturnStock(dto.OrderNo, dto.PalletCode);
+ }
+
+ /// <summary>
+ /// 鑾峰彇鎵樼洏鐨勯攣瀹氫俊鎭�
+ /// </summary>
+ [HttpPost("pallet-locks")]
+ public async Task<WebResponseContent> GetPalletLocks([FromBody] PalletLocksDto dto)
+ {
+ try
+ {
+ var locks = await _outboundBatchPickingService.GetPalletLockInfos(dto.OrderNo, dto.PalletCode);
+ return WebResponseContent.Instance.OK("鑾峰彇鎴愬姛", locks);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"鑾峰彇鎵樼洏閿佸畾淇℃伅寮傚父 - OrderNo: {dto.OrderNo}, PalletCode: {dto.PalletCode}");
+ return WebResponseContent.Instance.Error("绯荤粺寮傚父锛岃绋嶅悗閲嶈瘯" + ex.Message);
+ }
+ }
+ /// <summary>
+ /// 鑾峰彇宸叉嫞閫夊垪琛�
+ /// </summary>
+ [HttpPost("pallet-picked-list")]
+ public async Task<WebResponseContent> GetPalletPickedList([FromBody] PalletLocksDto dto)
+ {
+ try
+ {
+ var pickedList = await _outboundBatchPickingService.GetPalletPickedList(dto.OrderNo, dto.PalletCode);
+ return WebResponseContent.Instance.OK("鑾峰彇鎴愬姛", pickedList);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"鑾峰彇宸叉嫞閫夊垪琛ㄥ紓甯� - OrderNo: {dto.OrderNo}, PalletCode: {dto.PalletCode}");
+ return WebResponseContent.Instance.Error("绯荤粺寮傚父锛岃绋嶅悗閲嶈瘯" + ex.Message);
+ }
+ }
+
+ /// <summary>
+ /// 鑾峰彇鎵樼洏鐘舵��
+ /// </summary>
+ [HttpPost("pallet-status")]
+ public async Task<WebResponseContent> GetPalletStatus([FromBody] PalletLocksDto dto)
+ {
+ try
+ {
+ var status = await _outboundBatchPickingService.GetPalletStatus(dto.OrderNo, dto.PalletCode);
+ return WebResponseContent.Instance.OK("鑾峰彇鎴愬姛", status);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"鑾峰彇鎵樼洏鐘舵�佸紓甯� - OrderNo: {dto.OrderNo}, PalletCode: {dto.PalletCode}");
+ return WebResponseContent.Instance.Error("绯荤粺寮傚父锛岃绋嶅悗閲嶈瘯" + ex.Message);
+ }
+ }
+
+ /// <summary>
+ /// 鑾峰彇鎷嗗寘淇℃伅
+ /// </summary>
+ [HttpPost("split-package-info")]
+ public async Task<WebResponseContent> GetSplitPackageInfo([FromBody] SplitPackageInfoDto dto)
+ {
+ try
+ {
+ var info = await _outboundBatchPickingService.GetSplitPackageInfo(dto.OrderNo, dto.PalletCode, dto.Barcode);
+ return WebResponseContent.Instance.OK("鑾峰彇鎴愬姛", info);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"鑾峰彇鎷嗗寘淇℃伅寮傚父 - OrderNo: {dto.OrderNo}, PalletCode: {dto.PalletCode}, Barcode: {dto.Barcode}");
+ return WebResponseContent.Instance.Error("绯荤粺寮傚父锛岃绋嶅悗閲嶈瘯" +ex.Message);
+ }
+ }
+
+ /// <summary>
+ /// 鍙栬蛋绌虹
+ /// </summary>
+ [HttpPost("remove-empty-pallet")]
+ public async Task<WebResponseContent> RemoveEmptyPallet([FromBody] RemoveEmptyPalletDto dto)
+ {
+ try
+ {
+ var result = await _outboundBatchPickingService.RemoveEmptyPallet(dto.OrderNo, dto.PalletCode);
+ return result;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, $"鍙栬蛋绌虹寮傚父 - OrderNo: {dto.OrderNo}, PalletCode: {dto.PalletCode}");
+ return WebResponseContent.Instance.Error("绯荤粺寮傚父锛岃绋嶅悗閲嶈瘯" +ex.Message);
+ }
+ }
+
+ }
+
+}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs"
index 53d317b..95ae57a 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Outbound/OutboundPickingController.cs"
@@ -92,13 +92,20 @@
return await Service.ReturnRemaining(dto.OrderNo, dto.PalletCode, "");
}
+ [HttpPost("remove-empty-pallet")]
+ public async Task<WebResponseContent> RemoveEmptyPallet ([FromBody] ConfirmPickingDto dto)
+ {
+ return await Service.RemoveEmptyPallet(dto.OrderNo, dto.PalletCode);
+ }
+
+
//[HttpPost("direct-outbound")]
//public async Task<WebResponseContent> DirectOutbound([FromBody] DirectOutboundRequest dto)
//{
// return await Service.DirectOutbound(dto);
-
+
//}
-
+
/// <summary>
/// 鎾ら攢鎷i��
/// </summary>
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs"
index 87d98a3..555a83d 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs"
@@ -25,7 +25,7 @@
/// <param name="orderId"></param>
/// <param name="materielCode"></param>
/// <returns></returns>
- [HttpPost, HttpGet, Route("GetStockSelectViews")]
+ [HttpPost, HttpGet, Route("GetStockSelectViews"),AllowAnonymous]
public List<StockSelectViewDTO> GetStockSelectViews(int orderId, string materielCode)
{
return Service.GetStockSelectViews(orderId, materielCode);
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs"
index adfa518..aed4552 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs"
@@ -1,8 +1,11 @@
-锘縰sing Microsoft.AspNetCore.Authorization;
+锘縰sing MailKit.Search;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+using System.Diagnostics;
using System.Threading.Tasks;
using WIDESEA_Common.CommonEnum;
+using WIDESEA_Common.TaskEnum;
using WIDESEA_Core;
using WIDESEA_Core.Attributes;
using WIDESEA_Core.BaseController;
@@ -24,12 +27,38 @@
{
}
-
+ [HttpPost, Route("AddTestTask"), AllowAnonymous, MethodParamsValidate]
+ public WebResponseContent AddTest(WMSTaskDTO wMSTaskDTO)
+ {
+ Dt_Task task = new Dt_Task
+ {
+ PalletCode = wMSTaskDTO.PalletCode,
+ PalletType = wMSTaskDTO.PalletType,
+ Roadway = "t",
+ TaskType = wMSTaskDTO.TaskType,
+ TaskStatus = wMSTaskDTO.TaskStatus,
+ SourceAddress = wMSTaskDTO.SourceAddress,
+ TargetAddress = wMSTaskDTO.TargetAddress,
+ CurrentAddress = "t",
+ NextAddress = "t",
+ WarehouseId = wMSTaskDTO.WarehouseId,
+ OrderNo = "testt",
+ Grade = wMSTaskDTO.Grade,
+ Dispatchertime = DateTime.Now,
- [HttpPost, Route("PalletOutboundTask"), AllowAnonymous, MethodParamsValidate]
+ };
+
+ Service.AddData(task);
+
+
+
+ return WebResponseContent.Instance.OK();
+ }
+
+ [HttpPost, Route("PalletOutboundTask"), AllowAnonymous, MethodParamsValidate]
public async Task<WebResponseContent> PalletOutboundTask(string endStation, string palletCode = "")
{
-
+
var result = await Service.PalletOutboundTask(endStation, palletCode);
return result;
@@ -44,7 +73,7 @@
[HttpPost, HttpGet, Route("GenerateOutboundTasks"), AllowAnonymous]
public async Task<WebResponseContent> GenerateOutboundTasks([FromBody] GenerateOutboundTasksDto data)
{
- return await Service.GenerateOutboundTasksAsync(data.taskIds,data.outboundPlatform);
+ return await Service.GenerateOutboundTasksAsync(data.taskIds, data.outboundPlatform);
}
/// <summary>
@@ -59,5 +88,17 @@
return Service.GenerateOutboundTask(orderDetailId, stockSelectViews);
}
+ /// <summary>
+ /// 鍒嗘壒鐢熸垚鍑哄簱浠诲姟
+ /// </summary>
+ /// <param name="data"></param>
+ /// <returns></returns>
+ [HttpPost, HttpGet, Route("GenerateOutboundBatchTasks"), AllowAnonymous]
+ public async Task<WebResponseContent> GenerateOutboundBatchTasks([FromBody] GenerateOutboundBatchTasksDto data)
+ {
+ return await Service.GenerateOutboundBatchTasksAsync(data.orderDetailId,data.batchQuantity, data.outboundPlatform);
+ }
+
+
}
}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Jobs/InventoryLockJob.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Jobs/InventoryLockJob.cs"
new file mode 100644
index 0000000..248f47e
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Jobs/InventoryLockJob.cs"
@@ -0,0 +1,22 @@
+锘縰sing Quartz;
+using SqlSugar;
+
+namespace WIDESEA_WMSServer.Jobs
+{
+ [DisallowConcurrentExecution]
+ public class InventoryLockJob : IJob
+ {
+ private readonly ILogger<ErpJob> _logger;
+ private readonly ISqlSugarClient _db;
+ public InventoryLockJob(ILogger<ErpJob> logger, ISqlSugarClient db )
+ {
+ _logger = logger;
+ _db = db;
+
+ }
+ public Task Execute(IJobExecutionContext context)
+ {
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs"
index ef722e9..c284b28 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS\346\227\240\344\273\223\345\202\250\347\211\210/WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs"
@@ -161,6 +161,15 @@
.ForJob(jobKey)
.WithIdentity("ErpJob-trigger")
.WithCronSchedule("0 0 10,14,20 * * ?"));
+
+ var inventoryLockJobKey = new JobKey("InventoryLockJob");
+ q.AddJob<InventoryLockJob>(opts => opts.WithIdentity(inventoryLockJobKey));
+
+ q.AddTrigger(opts => opts
+ .ForJob(inventoryLockJobKey)
+ .WithIdentity("InventoryLockJob-trigger")
+ .WithCronSchedule("0 0/10 * * * ?")); // 每10分钟执行一次
+
});
--
Gitblit v1.9.3