sgj
2026-03-09 87ebafb4f20d329babfc55c25727db8628f32bad
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
package com.fzzy.igds.timer;
 
import com.fzzy.igds.constant.Constant;
import com.fzzy.igds.data.IgdsBaseParam;
import com.fzzy.igds.domain.*;
import com.fzzy.igds.service.*;
import com.fzzy.igds.utils.ContextUtil;
import com.fzzy.igds.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
import java.text.ParseException;
import java.time.LocalDate;
import java.util.*;
 
/**
 * @Description 库存定时统计入口:通过框架定时任务调用,默认每天凌晨1点执行,统计昨天的库存信息
 * @Author CZT
 * @Date 2026/1/14 10:42
 */
@Slf4j
@Service
public class JobDepotStoreService {
 
    @Resource
    private CoreDeptService deptService;
    @Resource
    private InoutRecordService inoutRecordService;
    @Resource
    private InoutStockChangeService stockChangeService;
    @Resource
    private InoutLossOverService lossOverService;
    @Resource
    private DepotStoreService depotStoreService;
    @Resource
    private DepotService depotService;
 
    @Scheduled(cron = "0 0 1 * * ?")
    public void timer() {
        doExe();
    }
 
 
    /**
     * 手动执行库存统计
     * @param timeStr
     * @throws ParseException
     */
    public void doExeHand(String timeStr) throws ParseException {
 
        log.info("===============手动统计库存信息===============");
        //获取所有的库区信息
        List<Dept> listDept = deptService.listDept(null, ContextUtil.getCompanyId(), null);
        if (null == listDept || listDept.isEmpty()) {
            log.info("-----未获取到库区,不执行库存定时统计-----");
            return;
        }
 
        Date startTime = DateUtils.parseDate(timeStr, "yyyy-MM-dd");
 
        Date endTime = new Date();
        for (Dept dept : listDept) {
 
            //多天循环统计
            sumMoreDepotStore(startTime, endTime, dept);
        }
    }
 
    /**
     * 开始执行库存统计
     */
    public void doExe() {
 
        Date time = DateUtil.getNewByDay(new Date(), -1);
        log.info("===============系统定时统计库存信息===============");
        //获取所有的库区信息
        List<Dept> listDept = deptService.listDept(null, ContextUtil.getCompanyId(), null);
 
        if (null == listDept || listDept.isEmpty()) {
            log.info("-----未获取到库区,不执行库存定时统计-----");
            return;
        }
 
        Date startTime = null; //出入库最早时间
        for (Dept dept : listDept) {
 
            startTime = getStartTime(time, dept);
            if (null == startTime) {
                log.info("-----{}在{}未有库存相关数量更新,不执行库存统计-----", dept.getKqmc(), DateFormatUtils.format(time, "yyyy-MM-dd"));
                continue;
            }
 
            //多天循环统计
            sumMoreDepotStore(startTime, time, dept);
        }
    }
 
    /**
     * 多天循环遍历统计库存信息
     *
     * @param startTime
     * @param endTime
     * @param dept
     */
    public void sumMoreDepotStore(Date startTime, Date endTime, Dept dept) {
 
        log.info("-----统计库存信息,库区={},时间={}--->{}-----", dept.getKqmc(), DateFormatUtils.format(startTime, "yyyy-MM-dd"), DateFormatUtils.format(endTime, "yyyy-MM-dd"));
 
        //获取两个时间相差的天数
        LocalDate startDate = LocalDate.parse(DateFormatUtils.format(startTime, "yyyy-MM-dd"));
        LocalDate endDate = LocalDate.parse(DateFormatUtils.format(endTime, "yyyy-MM-dd"));
 
        //从最早天开始循环统计库存到当前天
        while (!startDate.isAfter(endDate)) {
 
            //统计库区库存
            sumDepotStore(startTime, dept);
            //对应时间加1天
            startTime = DateUtils.addDays(startTime, 1);
            //将日期加1天
            startDate = startDate.plusDays(1);
        }
 
    }
 
    /**
     * 根据时间,统计更新当天的库存信息
     *
     * @param time
     * @param dept
     */
    public void sumDepotStore(Date time, Dept dept) {
        //更改为当天的23点50分
        time = DateUtils.addMinutes(DateUtil.getNextZero(time), -10);
 
        log.info("-----统计库存信息,库区={},时间={}-----", dept.getKqmc(), DateFormatUtils.format(time, "yyyy-MM-dd"));
        //设置参数
        IgdsBaseParam param = new IgdsBaseParam();
        param.setStart(DateUtil.getCurZero(time));
        param.setEnd(DateUtil.getNextZero(time));
        param.setDeptId(dept.getId());
 
        //用于存放数量变动的仓库
        Set<String> set = new HashSet<>();
 
        //统计仓库的数量
        Map<String, Double> map1 = new HashMap<>();
        Map<String, Double> map2 = new HashMap<>();
        Map<String, Double> map3 = new HashMap<>();
 
        boolean inTag = false;
        boolean outTag = false;
        //获取出入库信息统计仓库数量
        List<InoutRecord> inoutRecords = inoutRecordService.getCompleteInoutByTime("complete_time", param);
        if (null != inoutRecords && !inoutRecords.isEmpty()) {
            for (InoutRecord inoutRecord : inoutRecords) {
                set.add(inoutRecord.getDepotId());
 
                map1.putIfAbsent(inoutRecord.getDepotId(), 0.0);
 
                //统计数量
                if (Constant.TYPE_IN.equals(inoutRecord.getType())) {
                    inTag = true;
                    map1.put(inoutRecord.getDepotId(), map1.get(inoutRecord.getDepotId()) + inoutRecord.getRecordWeight());
                }
                if (Constant.TYPE_OUT.equals(inoutRecord.getType())) {
                    outTag = true;
                    map1.put(inoutRecord.getDepotId(), map1.get(inoutRecord.getDepotId()) - inoutRecord.getRecordWeight());
                }
            }
        }
 
        //获取倒仓信息统计仓库数量
        List<InoutStockChange> stockChanges = stockChangeService.getDataByTime("change_date", param);
        if (null != stockChanges && !stockChanges.isEmpty()) {
            for (InoutStockChange stockChange : stockChanges) {
                set.add(stockChange.getDepotIdIn());
                set.add(stockChange.getDepotIdOut());
 
                map2.putIfAbsent(stockChange.getDepotIdIn(), 0.0);
                map2.putIfAbsent(stockChange.getDepotIdOut(), 0.0);
 
                //统计数量
                map2.put(stockChange.getDepotIdIn(), map2.get(stockChange.getDepotIdIn()) + stockChange.getNumber());
                map2.put(stockChange.getDepotIdOut(), map2.get(stockChange.getDepotIdOut()) - stockChange.getNumber());
            }
        }
 
        //获取损益信息统计仓库数量
        List<InoutLossOver> lossOvers = lossOverService.getDataByTime("loss_time", param);
        if (null != lossOvers && !lossOvers.isEmpty()) {
            for (InoutLossOver lossOver : lossOvers) {
                set.add(lossOver.getDepotId());
 
                map3.putIfAbsent(lossOver.getDepotId(), 0.0);
 
                //统计数量
                if (Constant.TYPE_LOSS.equals(lossOver.getType())) {
                    map1.put(lossOver.getDepotId(), map1.get(lossOver.getDepotId()) - lossOver.getAmount());
                }
                if (Constant.TYPE_OVER.equals(lossOver.getType())) {
                    map1.put(lossOver.getDepotId(), map1.get(lossOver.getDepotId()) + lossOver.getAmount());
                }
            }
        }
 
        Double sum = 0.0;
        Depot depot;
        for (String s : set) {
            sum = 0.0;
            if (null != map1.get(s)) {
                sum += map1.get(s);
            }
            if (null != map2.get(s)) {
                sum += map2.get(s);
            }
            if (null != map3.get(s)) {
                sum += map3.get(s);
            }
 
            //获取上一条数据
            DepotStore lastData = depotStoreService.getLastData(s, time);
 
            if (null == lastData) {
                lastData = new DepotStore();
 
                lastData.setStorageReal(0.0);
 
                if (inTag) {
                    //设置入库时间
                    lastData.setStoreDate(time);
                }
                if (outTag) {
                    //设置出库时间
                    lastData.setOutDate(time);
                }
            }
 
            //主键ID规则:yyyyMMddHHmm_仓库编码
            lastData.setId(DateFormatUtils.format(time, "yyyyMMddHHmm") + "_" + s);
 
            lastData.setCompanyId(dept.getCompanyId());
            lastData.setDeptId(dept.getId());
            lastData.setDepotId(s);
 
            lastData.setUpdateTime(time);
            lastData.setUpdateBy("系统定时统计");
 
            //获取仓库信息
            depot = depotService.getCacheDepot(dept.getCompanyId(), s);
            if (null != depot) {
                lastData.setDepotStatus(depot.getDepotStatus());
                lastData.setFoodVariety(depot.getFoodVariety());
                lastData.setFoodLevel(depot.getFoodLevel());
                lastData.setFoodLocation(depot.getFoodLocation());
                lastData.setFoodLocationId(depot.getFoodLocationId());
                lastData.setFoodType(depot.getFoodType());
                lastData.setFoodYear(depot.getFoodYear());
            }
 
            lastData.setStorageReal(lastData.getStorageReal() + sum);
            lastData.setCreateTime(new Date()); //设置为最新时间,其他系统可以通过此时间查询数据是否有更新修改,同步到省平台接口。
            lastData.setCreateBy("系统定时统计");
            lastData.setRemark("系统统计" + DateFormatUtils.format(time, "yyyy-MM-dd") + "日库存");
 
            depotStoreService.updateAndSave(lastData);
 
        }
 
    }
 
 
    /**
     * 根据时间,统计更新当天的库存信息
     *
     * @param dept
     */
    public Date getStartTime(Date time, Dept dept) {
 
        Date startTime = time; //出入库最早时间
        Date time1 = null; //出入库最早时间
        Date time2 = null; //倒仓最早时间
        Date time3 = null; //损益最早时间
 
        //获取当天有更新的出入库信息
        IgdsBaseParam param = new IgdsBaseParam();
        param.setStart(DateUtil.getCurZero(time));
        param.setEnd(DateUtil.getNextZero(time));
        //获取当天有更新的出入库信息
        param.setDeptId(dept.getId());
        List<InoutRecord> inoutRecords = inoutRecordService.getCompleteInoutByTime("update_time", param);
        if (null != inoutRecords && !inoutRecords.isEmpty()) {
            time1 = inoutRecords.get(0).getCompleteTime();
        }
 
        //获取当天有更新的倒仓数据
        List<InoutStockChange> stockChanges = stockChangeService.getDataByTime("update_time", param);
        if (null != stockChanges && !stockChanges.isEmpty()) {
            time2 = stockChanges.get(0).getChangeDate();
        }
 
        //获取当天有更新的损益数据
        List<InoutLossOver> lossOvers = lossOverService.getDataByTime("update_time", param);
        if (null != lossOvers && !lossOvers.isEmpty()) {
            time3 = lossOvers.get(0).getLossTime();
        }
 
        if (null == time1 && null == time2 && null == time3) {
            return null;
        }
        if (null != time1 && time1.before(startTime)) {
            startTime = time1;
        }
        if (null != time2 && time2.before(startTime)) {
            startTime = time2;
        }
        if (null != time3 && time3.before(startTime)) {
            startTime = time3;
        }
        return startTime;
    }
 
}