|
|
@@ -0,0 +1,398 @@
|
|
|
+package com.yr.warehouse.admin.service.statistics.impl;
|
|
|
+
|
|
|
+import com.alibaba.fastjson2.JSONArray;
|
|
|
+import com.alibaba.fastjson2.JSONObject;
|
|
|
+import com.supplychain.api.response.areastaff.AreaStaffResponse;
|
|
|
+import com.yr.bluecat.common.redis.RedisComponent;
|
|
|
+import com.yr.shopping.admin.support.response.DriverDeviceSalesResponse;
|
|
|
+import com.yr.warehouse.admin.common.menu.BoolEnum;
|
|
|
+import com.yr.warehouse.admin.component.areastaff.AreaStaffComponent;
|
|
|
+import com.yr.warehouse.admin.component.driver.DriverDeviceSalesComponent;
|
|
|
+import com.yr.warehouse.admin.driver.data.DriverDeviceStockSnapshot;
|
|
|
+import com.yr.warehouse.admin.driver.data.DriverEquipmentLossRecord;
|
|
|
+import com.yr.warehouse.admin.driver.data.DriverGoodsLossRecord;
|
|
|
+import com.yr.warehouse.admin.driver.data.DriverOnRouteDetailLog;
|
|
|
+import com.yr.warehouse.admin.driver.mapper.DriverDeviceStockSnapshotMapper;
|
|
|
+import com.yr.warehouse.admin.driver.mapper.DriverEquipmentLossRecordMapper;
|
|
|
+import com.yr.warehouse.admin.driver.mapper.DriverGoodsLossRecordMapper;
|
|
|
+import com.yr.warehouse.admin.driver.mapper.DriverOnRouteDetailLogMapper;
|
|
|
+import com.yr.warehouse.admin.replenish.vo.DriverGoodsOrderNumVo;
|
|
|
+import com.yr.warehouse.admin.service.statistics.DriverStatistics;
|
|
|
+import com.yr.warehouse.admin.service.statistics.logic.DriverStatisticsMergeLogic;
|
|
|
+import com.yr.warehouse.admin.service.statistics.mapstruct.DriverStatisticsMapStruct;
|
|
|
+import com.yr.warehouse.admin.statistics.mapper.BillingQuantityStatisticsMapper;
|
|
|
+import jakarta.annotation.Resource;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 司机统计服务实现类
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class DriverStatisticsImpl implements DriverStatistics {
|
|
|
+ @Resource
|
|
|
+ private RedisComponent redisComponent;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private AreaStaffComponent areaStaffComponent;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DriverDeviceSalesComponent driverDeviceSalesComponent;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DriverStatisticsMergeLogic driverStatisticsMergeLogic;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private BillingQuantityStatisticsMapper billingQuantityStatisticsMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DriverDeviceStockSnapshotMapper driverDeviceStockSnapshotMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DriverGoodsLossRecordMapper driverGoodsLossRecordMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DriverEquipmentLossRecordMapper driverEquipmentLossRecordMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private DriverOnRouteDetailLogMapper driverOnRouteDetailLogMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void cargoDamageStatistics(LocalDate statDate) {
|
|
|
+ // 开始时间 = statDate - 1 day 04:00:00
|
|
|
+ LocalDateTime beginTime = statDate.minusDays(1).atTime(4, 0, 0);
|
|
|
+ // 结束时间 = statDate 03:59:59
|
|
|
+ LocalDateTime endTime = statDate.atTime(3, 59, 59);
|
|
|
+ // 货损统计业务开始
|
|
|
+ log.info(String.format("司机货损统计开始:开始时间[%s], 结束时间[%s]", beginTime, endTime));
|
|
|
+
|
|
|
+ // 司机设备库存 - 不含商品id - 需锚定司机设备库存, 保证异常情况后重新查询时设备库存值不变
|
|
|
+ List<DriverGoodsOrderNumVo> deviceInventoryNumVos = queryDriverDeviceInventoryNum(beginTime, endTime);
|
|
|
+ // 司机拣货单开单数 - 含商品id
|
|
|
+ List<DriverGoodsOrderNumVo> pickingBillingQuantityNumVos = billingQuantityStatisticsMapper.queryPickingBillingQuantity(beginTime, endTime);
|
|
|
+ // 司机整件单开单数 - 含商品id
|
|
|
+ List<DriverGoodsOrderNumVo> aggregationBillingQuantityNumVos = billingQuantityStatisticsMapper.queryAggregationBillingQuantity(beginTime, endTime);
|
|
|
+ // 未出库取消数 - 含商品id
|
|
|
+ List<DriverGoodsOrderNumVo> unOutStockCancelNumVos = billingQuantityStatisticsMapper.queryUnOutStockCancelNum(beginTime, endTime);
|
|
|
+ // 已出库取消数 - 含商品id
|
|
|
+ List<DriverGoodsOrderNumVo> outStockCancelNumVos = billingQuantityStatisticsMapper.queryOutStockCancelNum(beginTime, endTime);
|
|
|
+ // 查询司机补货数 - 含商品id
|
|
|
+ List<DriverGoodsOrderNumVo> driverReplenishNumVos = billingQuantityStatisticsMapper.queryDriverReplenishNum(beginTime, endTime);
|
|
|
+ // 查询设备补货数 - 不含商品id
|
|
|
+ List<DriverGoodsOrderNumVo> deviceReplenishNumVos = billingQuantityStatisticsMapper.queryDeviceReplenishNum(beginTime, endTime);
|
|
|
+ // 查询司机回仓数 - 含商品id
|
|
|
+ List<DriverGoodsOrderNumVo> driverReturnNumVos = billingQuantityStatisticsMapper.queryDriverReturnNum(beginTime, endTime);
|
|
|
+ // 司机设备销量统计 - 不含商品id
|
|
|
+ List<DriverDeviceSalesResponse> driverDeviceSalesResponses = driverDeviceSalesComponent.list(beginTime, endTime);
|
|
|
+ List<DriverGoodsOrderNumVo> driverDeviceSalesNumVos = DriverStatisticsMapStruct.INSTANCE.driverDeviceSalesToVo(driverDeviceSalesResponses);
|
|
|
+
|
|
|
+ // 提取所有数据中的司机ID并去重
|
|
|
+ List<Long> areaStaffIds = driverStatisticsMergeLogic.getAreaStaffIds(driverDeviceSalesNumVos,
|
|
|
+ pickingBillingQuantityNumVos,
|
|
|
+ aggregationBillingQuantityNumVos,
|
|
|
+ unOutStockCancelNumVos,
|
|
|
+ outStockCancelNumVos,
|
|
|
+ driverReplenishNumVos,
|
|
|
+ deviceReplenishNumVos,
|
|
|
+ driverReturnNumVos);
|
|
|
+
|
|
|
+ List<AreaStaffResponse> areaStaffResponses = areaStaffComponent.searchByStaffIds(areaStaffIds);
|
|
|
+ Map<Long, AreaStaffResponse> areaStaffMap = areaStaffResponses.stream().collect(Collectors.toMap(AreaStaffResponse::getId, areaStaffResponse -> areaStaffResponse));
|
|
|
+
|
|
|
+ // 生成司机货损记录
|
|
|
+ List<DriverGoodsLossRecord> driverGoodsLossRecords = generatorDriverGoodsLossRecord(statDate,
|
|
|
+ areaStaffIds,
|
|
|
+ areaStaffMap,
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffId(pickingBillingQuantityNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffId(aggregationBillingQuantityNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffId(unOutStockCancelNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffId(outStockCancelNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffId(driverReplenishNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffId(driverReturnNumVos));
|
|
|
+
|
|
|
+ driverGoodsLossRecordMapper.insertBatch(driverGoodsLossRecords);
|
|
|
+
|
|
|
+
|
|
|
+ // 生成司机设备货损记录
|
|
|
+ List<DriverEquipmentLossRecord> driverEquipmentLossRecords = generatorDriverEquipmentLossRecord(statDate,
|
|
|
+ areaStaffIds,
|
|
|
+ areaStaffMap,
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffId(deviceReplenishNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffId(driverDeviceSalesNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffId(deviceInventoryNumVos)
|
|
|
+ );
|
|
|
+ driverEquipmentLossRecordMapper.insertBatch(driverEquipmentLossRecords);
|
|
|
+
|
|
|
+ List<DriverOnRouteDetailLog> driverOnRouteDetailLogs = generatorDriverOnRouteDetailLog(statDate,
|
|
|
+ driverGoodsLossRecords,
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffGoods(pickingBillingQuantityNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffGoods(aggregationBillingQuantityNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffGoods(unOutStockCancelNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffGoods(outStockCancelNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffGoods(driverReplenishNumVos),
|
|
|
+ driverStatisticsMergeLogic.groupByAreaStaffGoods(driverReturnNumVos)
|
|
|
+ );
|
|
|
+
|
|
|
+ driverOnRouteDetailLogMapper.insertBatch(driverOnRouteDetailLogs);
|
|
|
+ log.info(String.format("司机货损统计结束:开始时间[%s], 结束时间[%s]", beginTime, endTime));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取司机设备库存数
|
|
|
+ * @return 司机设备库存数
|
|
|
+ */
|
|
|
+ private List<DriverGoodsOrderNumVo> queryDriverDeviceInventoryNum(LocalDateTime beginTime, LocalDateTime endTime) {
|
|
|
+ DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
|
|
+ String key = String.format("BILLING_QUANTITY_STATISTICS:%s-%s", dateTimeFormatter.format(beginTime), dateTimeFormatter.format(endTime));
|
|
|
+ String driverDeviceInventoryStr = redisComponent.getValue(key);
|
|
|
+
|
|
|
+ if (driverDeviceInventoryStr != null) {
|
|
|
+ return JSONArray.parseArray(driverDeviceInventoryStr, DriverGoodsOrderNumVo.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<DriverDeviceStockSnapshot> driverDeviceStockSnapshots = driverDeviceStockSnapshotMapper.queryDriverDeviceInventoryNum(beginTime, endTime);
|
|
|
+ List<DriverGoodsOrderNumVo> result;
|
|
|
+
|
|
|
+ if (driverDeviceStockSnapshots == null || driverDeviceStockSnapshots.isEmpty()) {
|
|
|
+ result = billingQuantityStatisticsMapper.queryDriverDeviceInventoryNum();
|
|
|
+ // 持久化司机设备库存数
|
|
|
+ driverDeviceStockSnapshotMapper.insertBatch(beginTime, endTime, result);
|
|
|
+ } else {
|
|
|
+ result = driverDeviceStockSnapshots.stream().map(snapshot -> {
|
|
|
+ DriverGoodsOrderNumVo vo = new DriverGoodsOrderNumVo();
|
|
|
+ vo.setAreaStaffId(snapshot.getAreaStaffId());
|
|
|
+ vo.setTotalNum(snapshot.getTotalNum());
|
|
|
+ return vo;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 缓存司机设备库存数
|
|
|
+ redisComponent.cacheValue(key, JSONObject.toJSONString(result));
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成司机货损记录
|
|
|
+ * @param statDate 统计日期
|
|
|
+ * @param areaStaffIds 司机id
|
|
|
+ * @param driverGoodsOrderNumVoMap 拣货单
|
|
|
+ * @param aggregationBillingQuantityNumVoMap 整件单
|
|
|
+ * @param unOutStockCancelNumVoMap 未出库取消
|
|
|
+ * @param outStockCancelNumVoMap 已出库取消
|
|
|
+ * @param driverReplenishNumVoMap 补货
|
|
|
+ * @param driverReturnNumVoMap 回仓
|
|
|
+ * @return 司机货损记录
|
|
|
+ */
|
|
|
+ private List<DriverGoodsLossRecord> generatorDriverGoodsLossRecord(LocalDate statDate,
|
|
|
+ List<Long> areaStaffIds,
|
|
|
+ Map<Long, AreaStaffResponse> areaStaffMap,
|
|
|
+ Map<Long, Long> driverGoodsOrderNumVoMap,
|
|
|
+ Map<Long, Long> aggregationBillingQuantityNumVoMap,
|
|
|
+ Map<Long, Long> unOutStockCancelNumVoMap,
|
|
|
+ Map<Long, Long> outStockCancelNumVoMap,
|
|
|
+ Map<Long, Long> driverReplenishNumVoMap,
|
|
|
+ Map<Long, Long> driverReturnNumVoMap) {
|
|
|
+ List<DriverGoodsLossRecord> yesterdayDriverGoodsLossRecords = driverGoodsLossRecordMapper.searchByStatDate(statDate.minusDays(1));
|
|
|
+ Map<Long, DriverGoodsLossRecord> yesterdayDriverGoodsLossRecordMap;
|
|
|
+ if (null != yesterdayDriverGoodsLossRecords && !yesterdayDriverGoodsLossRecords.isEmpty()) {
|
|
|
+ yesterdayDriverGoodsLossRecordMap = yesterdayDriverGoodsLossRecords.stream().collect(Collectors.toMap(DriverGoodsLossRecord::getAreaStaffId, Function.identity()));
|
|
|
+ } else {
|
|
|
+ yesterdayDriverGoodsLossRecordMap = new HashMap<>();
|
|
|
+ }
|
|
|
+ return areaStaffIds.stream().map(areaStaffId -> {
|
|
|
+ DriverGoodsLossRecord yesterdayDriverGoodsLossRecord = yesterdayDriverGoodsLossRecordMap.get(areaStaffId);
|
|
|
+ Long yesterdayCurrentOnRouteNum = 0L;
|
|
|
+ if (yesterdayDriverGoodsLossRecord != null) {
|
|
|
+ if (BoolEnum.isNo(yesterdayDriverGoodsLossRecord.getUseVerified())) {
|
|
|
+ yesterdayCurrentOnRouteNum = yesterdayDriverGoodsLossRecord.getCurrentOnRouteNum();
|
|
|
+ } else {
|
|
|
+ yesterdayCurrentOnRouteNum = yesterdayDriverGoodsLossRecord.getVerifiedNum();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ DriverGoodsLossRecord driverGoodsLossRecord = new DriverGoodsLossRecord();
|
|
|
+ driverGoodsLossRecord.setStatDate(statDate);
|
|
|
+ driverGoodsLossRecord.setYesterdayOnRouteNum(yesterdayCurrentOnRouteNum);
|
|
|
+ driverGoodsLossRecord.setAreaStaffId(areaStaffId);
|
|
|
+
|
|
|
+ AreaStaffResponse areaStaffResponse = areaStaffMap.get(areaStaffId);
|
|
|
+ if (null != areaStaffResponse) {
|
|
|
+ driverGoodsLossRecord.setOperatorId(areaStaffResponse.getOperatorId());
|
|
|
+ driverGoodsLossRecord.setOperatorChain(areaStaffResponse.getOperatorChain());
|
|
|
+ driverGoodsLossRecord.setAreaStaffId(areaStaffResponse.getId());
|
|
|
+ }
|
|
|
+ driverGoodsLossRecord.setPickingOrderCreateNum(driverStatisticsMergeLogic.getValueOrDefault(driverGoodsOrderNumVoMap, areaStaffId, 0L));
|
|
|
+ driverGoodsLossRecord.setWholeOrderCreateNum(driverStatisticsMergeLogic.getValueOrDefault(aggregationBillingQuantityNumVoMap, areaStaffId, 0L));
|
|
|
+ driverGoodsLossRecord.setUnshippedCancelNum(driverStatisticsMergeLogic.getValueOrDefault(unOutStockCancelNumVoMap, areaStaffId, 0L));
|
|
|
+ driverGoodsLossRecord.setShippedCancelNum(driverStatisticsMergeLogic.getValueOrDefault(outStockCancelNumVoMap, areaStaffId, 0L));
|
|
|
+ driverGoodsLossRecord.setReplenishNum(driverStatisticsMergeLogic.getValueOrDefault(driverReplenishNumVoMap, areaStaffId, 0L));
|
|
|
+ driverGoodsLossRecord.setReturnWarehouseNum(driverStatisticsMergeLogic.getValueOrDefault(driverReturnNumVoMap, areaStaffId, 0L));
|
|
|
+
|
|
|
+ // 当日在途 = 昨日在途 + 拣货单开单数 + 整件单开单数 - 司机补货数 - 司机回仓数 - 未出库取消数
|
|
|
+ Long nowDayCurrentOnRouteNum = yesterdayCurrentOnRouteNum + driverGoodsLossRecord.getPickingOrderCreateNum() + driverGoodsLossRecord.getWholeOrderCreateNum()
|
|
|
+ - driverGoodsLossRecord.getReplenishNum() - driverGoodsLossRecord.getReturnWarehouseNum() - driverGoodsLossRecord.getUnshippedCancelNum();
|
|
|
+ driverGoodsLossRecord.setCurrentOnRouteNum(nowDayCurrentOnRouteNum);
|
|
|
+
|
|
|
+ return driverGoodsLossRecord;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成司机设备货损记录
|
|
|
+ * @param statDate 统计日期
|
|
|
+ * @param areaStaffIds 司机id
|
|
|
+ * @param driverGoodsOrderNumVoMap 设备补货数
|
|
|
+ * @param driverDeviceSalesNumVoMap 设备销售数
|
|
|
+ * @param deviceInventoryNumVoMap 设备库存数
|
|
|
+ * @return 司机设备货损记录
|
|
|
+ */
|
|
|
+ private List<DriverEquipmentLossRecord> generatorDriverEquipmentLossRecord(LocalDate statDate,
|
|
|
+ List<Long> areaStaffIds,
|
|
|
+ Map<Long, AreaStaffResponse> areaStaffMap,
|
|
|
+ Map<Long, Long> driverGoodsOrderNumVoMap,
|
|
|
+ Map<Long, Long> driverDeviceSalesNumVoMap,
|
|
|
+ Map<Long, Long> deviceInventoryNumVoMap
|
|
|
+ ) {
|
|
|
+
|
|
|
+ List<DriverEquipmentLossRecord> yesterdayDriverEquipmentLossRecords = driverEquipmentLossRecordMapper.searchByStatDate(statDate.minusDays(1));
|
|
|
+ Map<Long, DriverEquipmentLossRecord> yesterdayDriverEquipmentLossRecordMap;
|
|
|
+ if (null != yesterdayDriverEquipmentLossRecords && !yesterdayDriverEquipmentLossRecords.isEmpty()) {
|
|
|
+ yesterdayDriverEquipmentLossRecordMap = yesterdayDriverEquipmentLossRecords.stream().collect(Collectors.toMap(DriverEquipmentLossRecord::getAreaStaffId, Function.identity()));
|
|
|
+ } else {
|
|
|
+ yesterdayDriverEquipmentLossRecordMap = new HashMap<>();
|
|
|
+ }
|
|
|
+ return areaStaffIds.stream().map(areaStaffId -> {
|
|
|
+ DriverEquipmentLossRecord driverEquipmentLossRecord = new DriverEquipmentLossRecord();
|
|
|
+ driverEquipmentLossRecord.setStatDate(statDate);
|
|
|
+ AreaStaffResponse areaStaffResponse = areaStaffMap.get(areaStaffId);
|
|
|
+ if (null != areaStaffResponse) {
|
|
|
+ driverEquipmentLossRecord.setOperatorId(areaStaffResponse.getOperatorId());
|
|
|
+ driverEquipmentLossRecord.setOperatorChain(areaStaffResponse.getOperatorChain());
|
|
|
+ driverEquipmentLossRecord.setAreaStaffId(areaStaffResponse.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ DriverEquipmentLossRecord yesterdayDriverEquipmentLossRecord = yesterdayDriverEquipmentLossRecordMap.get(areaStaffId);
|
|
|
+ Long yesterdayEquipmentStockNum = 0L;
|
|
|
+ if (yesterdayDriverEquipmentLossRecord != null) {
|
|
|
+ yesterdayEquipmentStockNum = yesterdayDriverEquipmentLossRecord.getActualEquipmentStockNum();
|
|
|
+ }
|
|
|
+
|
|
|
+ driverEquipmentLossRecord.setEquipmentStockNum(yesterdayEquipmentStockNum);
|
|
|
+ driverEquipmentLossRecord.setEquipmentReplenishNum(driverStatisticsMergeLogic.getValueOrDefault(driverGoodsOrderNumVoMap, areaStaffId, 0L));
|
|
|
+ driverEquipmentLossRecord.setEquipmentSalesNum(driverStatisticsMergeLogic.getValueOrDefault(driverDeviceSalesNumVoMap, areaStaffId, 0L));
|
|
|
+ Long theoreticalEquipmentStockNum = yesterdayEquipmentStockNum + driverEquipmentLossRecord.getEquipmentReplenishNum() - driverEquipmentLossRecord.getEquipmentSalesNum();
|
|
|
+ driverEquipmentLossRecord.setTheoreticalEquipmentStockNum(theoreticalEquipmentStockNum);
|
|
|
+ driverEquipmentLossRecord.setActualEquipmentStockNum(driverStatisticsMergeLogic.getValueOrDefault(deviceInventoryNumVoMap, areaStaffId, 0L));
|
|
|
+ driverEquipmentLossRecord.setProfitLossNum(driverEquipmentLossRecord.getActualEquipmentStockNum() - theoreticalEquipmentStockNum);
|
|
|
+ return driverEquipmentLossRecord;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成司机在途明细日志
|
|
|
+ * @param statDate 统计日期
|
|
|
+ * @param driverGoodsLossRecords 货损记录列表
|
|
|
+ * @param pickingBillingQuantityNumVoMap 拣货
|
|
|
+ * @param aggregationBillingQuantityNumVoMap 整件
|
|
|
+ * @param unOutStockCancelNumVoMap 未出库取消
|
|
|
+ * @param outStockCancelNumVoMap 已出库取消
|
|
|
+ * @param driverReplenishNumVoMap 补货
|
|
|
+ * @param driverReturnNumVoMap 回仓
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<DriverOnRouteDetailLog> generatorDriverOnRouteDetailLog(LocalDate statDate,
|
|
|
+ List<DriverGoodsLossRecord> driverGoodsLossRecords,
|
|
|
+ Map<Long, Map<Integer, Long>> pickingBillingQuantityNumVoMap,
|
|
|
+ Map<Long, Map<Integer, Long>> aggregationBillingQuantityNumVoMap,
|
|
|
+ Map<Long, Map<Integer, Long>> unOutStockCancelNumVoMap,
|
|
|
+ Map<Long, Map<Integer, Long>> outStockCancelNumVoMap,
|
|
|
+ Map<Long, Map<Integer, Long>> driverReplenishNumVoMap,
|
|
|
+ Map<Long, Map<Integer, Long>> driverReturnNumVoMap
|
|
|
+ ) {
|
|
|
+ List<DriverOnRouteDetailLog> yesterdayDriverOnRouteDetailLogs = driverOnRouteDetailLogMapper.searchByStatDate(statDate.minusDays(1));
|
|
|
+ Map<Long, Map<Integer, Long>> yesterdayDriverOnRouteDetailLogMap;
|
|
|
+ if (null != yesterdayDriverOnRouteDetailLogs && !yesterdayDriverOnRouteDetailLogs.isEmpty()) {
|
|
|
+ yesterdayDriverOnRouteDetailLogMap = yesterdayDriverOnRouteDetailLogs.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ DriverOnRouteDetailLog::getAreaStaffId, // 外层key:areaStaffId
|
|
|
+ Collectors.toMap(
|
|
|
+ DriverOnRouteDetailLog::getGoodsId, // 内层key:goodsId
|
|
|
+ DriverOnRouteDetailLog::getTodayStockNum, // 内层value:原对象
|
|
|
+ (existing, replacement) -> replacement // 重复goodsId时覆盖(也可改为existing保留第一个)
|
|
|
+ )
|
|
|
+ ));
|
|
|
+ } else {
|
|
|
+ yesterdayDriverOnRouteDetailLogMap = new HashMap<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<Long, DriverGoodsLossRecord> driverGoodsLossRecordMap = driverGoodsLossRecords.stream().collect(Collectors.toMap(DriverGoodsLossRecord::getAreaStaffId, v -> v));
|
|
|
+
|
|
|
+ List<Map<Long, Map<Integer, Long>>> mapList = new ArrayList<>();
|
|
|
+ mapList.add(pickingBillingQuantityNumVoMap);
|
|
|
+ mapList.add(aggregationBillingQuantityNumVoMap);
|
|
|
+ mapList.add(unOutStockCancelNumVoMap);
|
|
|
+ mapList.add(outStockCancelNumVoMap);
|
|
|
+ mapList.add(driverReplenishNumVoMap);
|
|
|
+ mapList.add(driverReturnNumVoMap);
|
|
|
+
|
|
|
+ List<DriverOnRouteDetailLog> result = new ArrayList<>();
|
|
|
+
|
|
|
+ // 获取司机id及司机对应的商品ids
|
|
|
+ Map<Long, List<Integer>> driverGoodsIdsMap = driverStatisticsMergeLogic.groupByAreaStaffGoodsIds(mapList, driverGoodsLossRecords.size());
|
|
|
+ driverGoodsIdsMap.forEach((areaStaffId, goodsIds) -> {
|
|
|
+
|
|
|
+ Map<Integer, Long> yesterdayDriverDetailLogMap = yesterdayDriverOnRouteDetailLogMap.get(areaStaffId);
|
|
|
+
|
|
|
+ DriverGoodsLossRecord driverGoodsLossRecord = driverGoodsLossRecordMap.get(areaStaffId);
|
|
|
+
|
|
|
+ Map<Integer, Long> pickingBillingQuantityNumMap = pickingBillingQuantityNumVoMap.get(areaStaffId);
|
|
|
+ Map<Integer, Long> aggregationBillingQuantityNumMap = aggregationBillingQuantityNumVoMap.get(areaStaffId);
|
|
|
+ Map<Integer, Long> unOutStockCancelNumMap = unOutStockCancelNumVoMap.get(areaStaffId);
|
|
|
+ Map<Integer, Long> outStockCancelNumMap = outStockCancelNumVoMap.get(areaStaffId);
|
|
|
+ Map<Integer, Long> driverReplenishMap = driverReplenishNumVoMap.get(areaStaffId);
|
|
|
+ Map<Integer, Long> driverReturnNumMap = driverReturnNumVoMap.get(areaStaffId);
|
|
|
+
|
|
|
+ goodsIds.forEach(goodsId -> {
|
|
|
+ Long yesterdayStockNum = driverStatisticsMergeLogic.getValueOrDefault(yesterdayDriverDetailLogMap, goodsId, 0L);
|
|
|
+
|
|
|
+ Long pickingBillingQuantityNum = driverStatisticsMergeLogic.getValueOrDefault(pickingBillingQuantityNumMap, goodsId, 0L);
|
|
|
+ Long aggregationBillingQuantityNum = driverStatisticsMergeLogic.getValueOrDefault(aggregationBillingQuantityNumMap, goodsId, 0L);
|
|
|
+
|
|
|
+ DriverOnRouteDetailLog driverOnRouteDetailLog = new DriverOnRouteDetailLog();
|
|
|
+ driverOnRouteDetailLog.setOperatorId(driverGoodsLossRecord.getOperatorId());
|
|
|
+ driverOnRouteDetailLog.setOperatorChain(driverGoodsLossRecord.getOperatorChain());
|
|
|
+ driverOnRouteDetailLog.setAreaStaffId(areaStaffId);
|
|
|
+ driverOnRouteDetailLog.setStatDate(statDate);
|
|
|
+ driverOnRouteDetailLog.setGoodsLossRecordId(driverGoodsLossRecord.getId());
|
|
|
+ driverOnRouteDetailLog.setGoodsId(goodsId);
|
|
|
+
|
|
|
+ driverOnRouteDetailLog.setCreateNum(pickingBillingQuantityNum + aggregationBillingQuantityNum);
|
|
|
+ driverOnRouteDetailLog.setUnshippedCancelNum(driverStatisticsMergeLogic.getValueOrDefault(unOutStockCancelNumMap, goodsId, 0L));
|
|
|
+ driverOnRouteDetailLog.setShippedCancelNum(driverStatisticsMergeLogic.getValueOrDefault(outStockCancelNumMap, goodsId, 0L));
|
|
|
+ driverOnRouteDetailLog.setReplenishNum(driverStatisticsMergeLogic.getValueOrDefault(driverReplenishMap, goodsId, 0L));
|
|
|
+ driverOnRouteDetailLog.setReturnWarehouseNum(driverStatisticsMergeLogic.getValueOrDefault(driverReturnNumMap, goodsId, 0L));
|
|
|
+ driverOnRouteDetailLog.setYesterdayStockNum(yesterdayStockNum);
|
|
|
+
|
|
|
+ Long todayStockNum = driverOnRouteDetailLog.getYesterdayStockNum() + driverOnRouteDetailLog.getCreateNum() - driverOnRouteDetailLog.getUnshippedCancelNum() - driverOnRouteDetailLog.getReplenishNum() - driverOnRouteDetailLog.getReturnWarehouseNum();
|
|
|
+ driverOnRouteDetailLog.setTodayStockNum(todayStockNum);
|
|
|
+ Long profitLossNum = driverOnRouteDetailLog.getReplenishNum() > 0 ? 0 : -driverOnRouteDetailLog.getReplenishNum();
|
|
|
+ driverOnRouteDetailLog.setProfitLossNum(profitLossNum);
|
|
|
+ result.add(driverOnRouteDetailLog);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+}
|