|
@@ -0,0 +1,151 @@
|
|
|
+package com.sd.business.service.order.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.ruoyi.common.core.domain.BaseIdPo;
|
|
|
+import com.ruoyi.common.utils.wrapper.IWrapper;
|
|
|
+import com.sd.business.entity.board.vo.TurnoverRateStatisticsVo;
|
|
|
+import com.sd.business.entity.department.constant.DepartmentConstant;
|
|
|
+import com.sd.business.entity.inventory.po.InventoryBackup;
|
|
|
+import com.sd.business.entity.order.enums.OrderClassifyEnum;
|
|
|
+import com.sd.business.entity.order.enums.OrderStatusEnum;
|
|
|
+import com.sd.business.entity.order.po.OrderInfo;
|
|
|
+import com.sd.business.entity.order.po.OrderSalesShipmentStatistics;
|
|
|
+import com.sd.business.entity.order.po.OrderSku;
|
|
|
+import com.sd.business.entity.order.vo.OrderSalesShipmentStatisticsVo;
|
|
|
+import com.sd.business.entity.warehouse.constant.WarehouseConstant;
|
|
|
+import com.sd.business.mapper.order.OrderSalesShipmentStatisticsMapper;
|
|
|
+import com.sd.business.service.inventory.InventoryBackupService;
|
|
|
+import com.sd.business.service.order.OrderSalesShipmentStatisticsService;
|
|
|
+import com.sd.business.service.order.OrderService;
|
|
|
+import com.sd.business.service.order.OrderSkuService;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * <p>
|
|
|
+ * 订单销售出库统计 服务实现类
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @author
|
|
|
+ * @since 2023-10-20
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class OrderSalesShipmentStatisticsServiceImpl extends ServiceImpl<OrderSalesShipmentStatisticsMapper, OrderSalesShipmentStatistics> implements OrderSalesShipmentStatisticsService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private OrderService orderService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private OrderSkuService orderSkuService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private InventoryBackupService inventoryBackupService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<OrderSalesShipmentStatisticsVo> getSalesShipmentStatisticsByDate(Date beginDate, Date endDate) {
|
|
|
+ IWrapper<OrderSalesShipmentStatistics> wrapper = getWrapper();
|
|
|
+ wrapper.orderByDesc("osss", OrderSalesShipmentStatistics::getId);
|
|
|
+ wrapper.between("osss", OrderSalesShipmentStatistics::getTotalDate, beginDate, endDate);
|
|
|
+ wrapper.groupBy("osss.bom_spec_id");
|
|
|
+ return this.baseMapper.getSalesShipmentStatisticsList(wrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<TurnoverRateStatisticsVo> getTurnoverRateStatisticsList() {
|
|
|
+ // 查询90天的周转率
|
|
|
+ Date date = new Date();
|
|
|
+ Date beginDate = DateUtil.beginOfDay(DateUtil.offsetDay(date, -90));
|
|
|
+ Date endDate = DateUtil.beginOfDay(DateUtil.offsetDay(date, -1));
|
|
|
+ List<OrderSalesShipmentStatisticsVo> statisticsVoList = this.getSalesShipmentStatisticsByDate(beginDate, date);
|
|
|
+ if (ObjectUtil.isEmpty(statisticsVoList)) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ List<Long> bomSpecIds = statisticsVoList.stream().map(OrderSalesShipmentStatistics::getBomSpecId).collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 期初库存数据
|
|
|
+ Map<Long, InventoryBackup> beginBackupMap = inventoryBackupService.mapKEntity(InventoryBackup::getBomSpecId, q -> q
|
|
|
+ .eq(InventoryBackup::getBackupDate, beginDate)
|
|
|
+ .eq(InventoryBackup::getDepartmentId, DepartmentConstant.SD_SPORTS)
|
|
|
+ .eq(InventoryBackup::getWarehouseId, WarehouseConstant.SEMI_FINISHED_PRODUCT)
|
|
|
+ .in(InventoryBackup::getBomSpecId, bomSpecIds));
|
|
|
+
|
|
|
+ // 期末库存数据
|
|
|
+ Map<Long, InventoryBackup> endBackupMap = inventoryBackupService.mapKEntity(InventoryBackup::getBomSpecId, q -> q
|
|
|
+ .eq(InventoryBackup::getBackupDate, endDate)
|
|
|
+ .eq(InventoryBackup::getDepartmentId, DepartmentConstant.SD_SPORTS)
|
|
|
+ .eq(InventoryBackup::getWarehouseId, WarehouseConstant.SEMI_FINISHED_PRODUCT)
|
|
|
+ .in(InventoryBackup::getBomSpecId, bomSpecIds));
|
|
|
+
|
|
|
+ List<TurnoverRateStatisticsVo> list = statisticsVoList.stream().map(item -> {
|
|
|
+ // 计算周转率
|
|
|
+ // 时间段库存周转天数 = 时间段天数 * (1 / 2) * (期初库存数量+期末库存数量) / 时间段销售量;
|
|
|
+ // 库存周转率 = 时间段天数 / 库存周转天数。
|
|
|
+ // 获取期初和期末数据
|
|
|
+ InventoryBackup beginBackup = beginBackupMap.get(item.getBomSpecId());
|
|
|
+ InventoryBackup endBackup = endBackupMap.get(item.getBomSpecId());
|
|
|
+ BigDecimal beginQuantity;
|
|
|
+ BigDecimal endQuantity;
|
|
|
+ if (beginBackup == null) {
|
|
|
+ beginQuantity = BigDecimal.ZERO;
|
|
|
+ } else {
|
|
|
+ beginQuantity = beginBackup.getQuantity().add(beginBackup.getLockQuantity() == null ? BigDecimal.ZERO : beginBackup.getLockQuantity());
|
|
|
+ }
|
|
|
+ if (endBackup == null) {
|
|
|
+ endQuantity = BigDecimal.ZERO;
|
|
|
+ } else {
|
|
|
+ endQuantity = endBackup.getQuantity().add(endBackup.getLockQuantity() == null ? BigDecimal.ZERO : endBackup.getLockQuantity());
|
|
|
+ }
|
|
|
+ BigDecimal days = new BigDecimal(90);
|
|
|
+ BigDecimal turnoverRate;
|
|
|
+ if (ObjectUtil.equals(item.getQuantity(), BigDecimal.ZERO)
|
|
|
+ || ObjectUtil.equals(beginQuantity.add(endQuantity), BigDecimal.ZERO)) {
|
|
|
+ turnoverRate = BigDecimal.ZERO;
|
|
|
+ } else {
|
|
|
+ turnoverRate = days
|
|
|
+ .divide(days.multiply(new BigDecimal("0.5"))
|
|
|
+ .multiply(beginQuantity.add(endQuantity))
|
|
|
+ .divide(item.getQuantity(), 4, RoundingMode.HALF_UP),
|
|
|
+ 4, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+ TurnoverRateStatisticsVo vo = new TurnoverRateStatisticsVo();
|
|
|
+ vo.setBomSpecCode(item.getBomSpecCode());
|
|
|
+ vo.setBomSpecName(item.getBomSpecName());
|
|
|
+ vo.setTurnoverRate(turnoverRate);
|
|
|
+ return vo;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void salesShipmentStatistics() {
|
|
|
+ Date yesterday = DateUtil.yesterday();
|
|
|
+ String date = DateUtil.formatDate(yesterday);
|
|
|
+ List<OrderInfo> list = orderService.list(q -> q
|
|
|
+ .eq(OrderInfo::getStatus, OrderStatusEnum.COMPLETION_PRODUCTION.getKey())
|
|
|
+ .ne(OrderInfo::getClassify, OrderClassifyEnum.OUTSOURCE_ORDER.getKey())
|
|
|
+ .likeLeft(OrderInfo::getShippingTime, date)
|
|
|
+ .select(BaseIdPo::getId));
|
|
|
+ if (list.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<Long> orderIds = list.stream().map(BaseIdPo::getId).collect(Collectors.toList());
|
|
|
+ Map<Long, BigDecimal> map = orderSkuService.mapKV(OrderSku::getBomSpecId,
|
|
|
+ OrderSku::getQuantity,
|
|
|
+ q -> q.in(OrderSku::getOrderId, orderIds));
|
|
|
+ List<OrderSalesShipmentStatistics> statisticsDtoList = map.keySet().stream().map(item -> {
|
|
|
+ OrderSalesShipmentStatistics dto = new OrderSalesShipmentStatistics();
|
|
|
+ dto.setTotalDate(yesterday);
|
|
|
+ dto.setBomSpecId(item);
|
|
|
+ dto.setQuantity(map.get(item));
|
|
|
+ return dto;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ this.saveBatch(statisticsDtoList);
|
|
|
+ }
|
|
|
+}
|