自动化立体仓库 - WMS系统
zwl
3 天以前 73f677ac03ebcf0f9d2e865dd60d3e4a6c2bc2c9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package com.zy.asrs.task.support;
 
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.WrkMastService;
import com.zy.common.entity.Parameter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import java.math.BigInteger;
import java.util.List;
import java.util.Objects;
 
@Component
public class OutboundBatchSeqReleaseGuard {
 
    public static final long OUTBOUND_CRN_COMPLETE_WRK_STS = 25L;
    public static final long OUTBOUND_TASK_COMPLETE_WRK_STS = 14L;
    public static final long OUTBOUND_ERP_REPORT_PENDING_WRK_STS = 17L;
    public static final long OUTBOUND_FINISHED_WRK_STS = 15L;
 
    private static final int OUTBOUND_IO_TYPE = 101;
    private static final int DEFAULT_STATUS25_THRESHOLD = 1;
 
    @Autowired
    private WrkMastService wrkMastService;
 
    public String validateReady(String userNo, String batchSeq) {
        if (Cools.isEmpty(batchSeq)) {
            return "出库进仓编号(batchSeq)为空,跳过下发, userNo=" + normalizeUserNo(userNo);
        }
 
        List<WrkMast> rows = selectOutboundRows(userNo);
        if (rows == null || rows.isEmpty()) {
            return null;
        }
 
        boolean hasEarlierBatchSeq = false;
        String blockingBatchSeq = null;
        int status25Count = 0;
        for (WrkMast row : rows) {
            if (row == null) {
                continue;
            }
            if (Objects.equals(row.getWrkSts(), OUTBOUND_CRN_COMPLETE_WRK_STS)) {
                status25Count++;
            }
            String rowBatchSeq = normalizeBatchSeq(row.getBatchSeq());
            if (Cools.isEmpty(rowBatchSeq) || compareBatchSeqNatural(rowBatchSeq, batchSeq) >= 0) {
                continue;
            }
            hasEarlierBatchSeq = true;
            if (!isReleaseStatus(row.getWrkSts())
                    && (blockingBatchSeq == null || compareBatchSeqNatural(rowBatchSeq, blockingBatchSeq) < 0)) {
                blockingBatchSeq = rowBatchSeq;
            }
        }
 
        if (blockingBatchSeq != null) {
            return "出库进仓编号未释放,暂停后续下发, userNo=" + normalizeUserNo(userNo)
                    + ", blockingBatchSeq=" + blockingBatchSeq
                    + ", nextBatchSeq=" + normalizeBatchSeq(batchSeq);
        }
 
        int threshold = getStatus25Threshold();
        if (hasEarlierBatchSeq && status25Count >= threshold) {
            return "出库进仓编号25状态数量达到阀值,暂停后续下发, userNo=" + normalizeUserNo(userNo)
                    + ", status25Count=" + status25Count
                    + ", threshold=" + threshold
                    + ", nextBatchSeq=" + normalizeBatchSeq(batchSeq);
        }
        return null;
    }
 
    public boolean isReleaseStatus(Long wrkSts) {
        return Objects.equals(wrkSts, OUTBOUND_CRN_COMPLETE_WRK_STS)
                || Objects.equals(wrkSts, OUTBOUND_TASK_COMPLETE_WRK_STS)
                || Objects.equals(wrkSts, OUTBOUND_ERP_REPORT_PENDING_WRK_STS)
                || Objects.equals(wrkSts, OUTBOUND_FINISHED_WRK_STS);
    }
 
    private List<WrkMast> selectOutboundRows(String userNo) {
        EntityWrapper<WrkMast> wrapper = new EntityWrapper<>();
        if (Cools.isEmpty(userNo)) {
            wrapper.andNew().isNull("user_no").or().eq("user_no", "");
        } else {
            wrapper.eq("user_no", userNo);
        }
        wrapper.eq("io_type", OUTBOUND_IO_TYPE);
        return wrkMastService.selectList(wrapper);
    }
 
    private int getStatus25Threshold() {
        Parameter parameter = Parameter.get();
        if (parameter == null || Cools.isEmpty(parameter.getOutBatchSeqStatus25Threshold())) {
            return DEFAULT_STATUS25_THRESHOLD;
        }
        try {
            int threshold = Integer.parseInt(parameter.getOutBatchSeqStatus25Threshold().trim());
            return threshold <= 0 ? DEFAULT_STATUS25_THRESHOLD : threshold;
        } catch (NumberFormatException ignored) {
            return DEFAULT_STATUS25_THRESHOLD;
        }
    }
 
    private static int compareBatchSeqNatural(String left, String right) {
        String safeLeft = normalizeBatchSeq(left);
        String safeRight = normalizeBatchSeq(right);
        int leftIndex = 0;
        int rightIndex = 0;
        while (leftIndex < safeLeft.length() && rightIndex < safeRight.length()) {
            char leftChar = safeLeft.charAt(leftIndex);
            char rightChar = safeRight.charAt(rightIndex);
            if (Character.isDigit(leftChar) && Character.isDigit(rightChar)) {
                int leftStart = leftIndex;
                int rightStart = rightIndex;
                while (leftIndex < safeLeft.length() && Character.isDigit(safeLeft.charAt(leftIndex))) {
                    leftIndex++;
                }
                while (rightIndex < safeRight.length() && Character.isDigit(safeRight.charAt(rightIndex))) {
                    rightIndex++;
                }
                String leftNumber = safeLeft.substring(leftStart, leftIndex);
                String rightNumber = safeRight.substring(rightStart, rightIndex);
                int compare = new BigInteger(leftNumber).compareTo(new BigInteger(rightNumber));
                if (compare != 0) {
                    return compare;
                }
                compare = Integer.compare(leftNumber.length(), rightNumber.length());
                if (compare != 0) {
                    return compare;
                }
                continue;
            }
            int compare = Character.compare(leftChar, rightChar);
            if (compare != 0) {
                return compare;
            }
            leftIndex++;
            rightIndex++;
        }
        return Integer.compare(safeLeft.length(), safeRight.length());
    }
 
    private static String normalizeBatchSeq(String value) {
        return Cools.isEmpty(value) ? "" : value;
    }
 
    private static String normalizeUserNo(String value) {
        return Cools.isEmpty(value) ? "" : value;
    }
}