|
@@ -1,15 +1,25 @@
|
|
|
package com.fjhx.stock.service.impl;
|
|
|
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.fjhx.constants.StatusConstant;
|
|
|
+import com.fjhx.entity.scheduling.entity.Scheduling;
|
|
|
import com.fjhx.entity.stock.StockDetail;
|
|
|
+import com.fjhx.params.stock.PickingTrackingNumStatisticsResult;
|
|
|
+import com.fjhx.scheduling.service.ISchedulingService;
|
|
|
import com.fjhx.stock.mapper.StockDetailMapper;
|
|
|
import com.fjhx.stock.service.StockDetailService;
|
|
|
import com.fjhx.utils.Assert;
|
|
|
+import com.fjhx.utils.BigDecimalUtil;
|
|
|
import org.springblade.core.tenant.annotation.TenantIgnore;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* <p>
|
|
@@ -23,6 +33,9 @@ import java.util.Map;
|
|
|
@TenantIgnore
|
|
|
public class StockDetailServiceImpl extends ServiceImpl<StockDetailMapper, StockDetail> implements StockDetailService {
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private ISchedulingService schedulingService;
|
|
|
+
|
|
|
@Override
|
|
|
public Map<String, Object> getMaterialInfoByQrCode(Map<String, String> condition) {
|
|
|
String qrCode = condition.get("qrCode");
|
|
@@ -40,5 +53,275 @@ public class StockDetailServiceImpl extends ServiceImpl<StockDetailMapper, Stock
|
|
|
updateBatchById(stockDetail);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public List<Map<String, Object>> restrictedPicking(Map<String, String> condition) {
|
|
|
+
|
|
|
+ String jobNo = condition.get("jobNo");
|
|
|
+
|
|
|
+ QueryWrapper<Object> wrapper = Wrappers.query()
|
|
|
+ .eq("ss.is_delete", StatusConstant.No)
|
|
|
+ .and(q -> q.eq("ss.printer", jobNo).or().eq("ss.paper_man", jobNo))
|
|
|
+ .and(q -> q.eq("ss.material_status", StatusConstant.No).or().eq("ss.paper_status", StatusConstant.No));
|
|
|
+
|
|
|
+ List<Map<String, Object>> list = baseMapper.restrictedPicking(wrapper, jobNo);
|
|
|
+
|
|
|
+ if (list.size() == 0) {
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取物料编码集合
|
|
|
+ List<String> materialCodeList = list.stream().map(item -> item.get("materialCode").toString()).collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 查询实时库存长度和现场库存长度
|
|
|
+ Map<String, Map<String, BigDecimal>> map = baseMapper.getMaterialQuantity(Wrappers.query().in("s.MaterialCode", materialCodeList));
|
|
|
+
|
|
|
+ for (Map<String, Object> item : list) {
|
|
|
+ String materialCode = item.get("materialCode").toString(); // 物料编码
|
|
|
+ float materialWidth = (float) item.get("materialWidth"); // 门幅
|
|
|
+ BigDecimal availableQuantity = (BigDecimal) item.get("availableQuantity"); // 排班数量
|
|
|
+
|
|
|
+ // 门幅保留0位小数
|
|
|
+ item.put("availableQuantity", BigDecimalUtil.keepDecimals(availableQuantity, 0));
|
|
|
+
|
|
|
+ // 计算排班面积
|
|
|
+ BigDecimal availableArea = BigDecimalUtil.init(availableQuantity).multiply(materialWidth)
|
|
|
+ .divide(100, 1).getValue();
|
|
|
+ item.put("availableArea", availableArea);
|
|
|
+
|
|
|
+ Map<String, BigDecimal> materialCodeQuantityMap = map.get(materialCode);
|
|
|
+ if (materialCodeQuantityMap == null) {
|
|
|
+ item.put("totalArea", BigDecimal.ZERO);
|
|
|
+ item.put("userArea", BigDecimal.ZERO);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算实时库存面积
|
|
|
+ BigDecimal bigDecimal = materialCodeQuantityMap.get("totalQuantity"); // 实时库存长度
|
|
|
+ if (bigDecimal == null) {
|
|
|
+ item.put("totalArea", BigDecimal.ZERO);
|
|
|
+ } else {
|
|
|
+ BigDecimal totalArea = BigDecimalUtil.init(bigDecimal).multiply(materialWidth)
|
|
|
+ .divide(100, 1).getValue();
|
|
|
+ item.put("totalArea", totalArea);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算现场库存面积
|
|
|
+ BigDecimal userQuantity = materialCodeQuantityMap.get("userQuantity");
|
|
|
+ if (userQuantity == null) {
|
|
|
+ item.put("userArea", BigDecimal.ZERO);
|
|
|
+ } else {
|
|
|
+ BigDecimal userArea = BigDecimalUtil.init(userQuantity).multiply(materialWidth)
|
|
|
+ .divide(100, 1).getValue();
|
|
|
+ item.put("userArea", userArea);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询推荐物料
|
|
|
+ Map<String, Object> recommendMaterial = baseMapper.selectRecommendMaterial(materialCode, availableQuantity);
|
|
|
+
|
|
|
+ item.putAll(recommendMaterial);
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void submitRestrictedPicking(List<Map<String, String>> condition) {
|
|
|
+
|
|
|
+ List<Scheduling> schedulingList = condition.stream().map(item -> {
|
|
|
+ String id = item.get("id");
|
|
|
+ String type = item.get("type");
|
|
|
+ String rfidCode = item.get("rfidCode");
|
|
|
+
|
|
|
+ Scheduling scheduling = new Scheduling();
|
|
|
+ scheduling.setId(id);
|
|
|
+ if (type.equals("1")) {
|
|
|
+ scheduling.setMaterialStatus(1);
|
|
|
+ scheduling.setMaterialRfid(rfidCode);
|
|
|
+ } else {
|
|
|
+ scheduling.setPaperStatus(1);
|
|
|
+ scheduling.setPaperRfid(rfidCode);
|
|
|
+ }
|
|
|
+ return scheduling;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+
|
|
|
+ schedulingService.updateBatchById(schedulingList);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<HashMap<String, Object>> pickingTrackingUserStatistics(Map<String, String> condition) {
|
|
|
+
|
|
|
+ // 获取查询条件
|
|
|
+ QueryWrapper<Object> wrapper = pickingTrackingStatisticsGetWrapper("ss.plan_date", condition);
|
|
|
+
|
|
|
+ List<Map<String, Object>> list = baseMapper.getPlanList(wrapper);
|
|
|
+
|
|
|
+ if (list.size() == 0) {
|
|
|
+ HashMap<String, Object> countUserMap = new HashMap<>();
|
|
|
+ countUserMap.put("sum", 0);
|
|
|
+ countUserMap.put("userName", "全部");
|
|
|
+ return Collections.singletonList(countUserMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 用户统计
|
|
|
+ return pickingTrackingUserStatistics(list);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public PickingTrackingNumStatisticsResult pickingTrackingNumStatistics(Map<String, String> condition) {
|
|
|
+
|
|
|
+ PickingTrackingNumStatisticsResult result = new PickingTrackingNumStatisticsResult();
|
|
|
+
|
|
|
+ // 获取查询条件
|
|
|
+ QueryWrapper<Object> wrapper = pickingTrackingStatisticsGetWrapper("ss.plan_date", condition);
|
|
|
+
|
|
|
+ String jobNo = condition.get("jobNo");
|
|
|
+
|
|
|
+ List<Map<String, Object>> list = baseMapper.getPlanListByUser(wrapper, jobNo);
|
|
|
+
|
|
|
+ if (list.size() == 0) {
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 指定领料卷数
|
|
|
+ result.setAppointNum(list.size());
|
|
|
+
|
|
|
+ // 物料编码去重集合
|
|
|
+ List<String> code = list.stream().map(item -> item.get("code").toString()).distinct().collect(Collectors.toList());
|
|
|
+ // 获取物料门幅键值对
|
|
|
+ Map<String, Float> codeWidthMap = getCodeWidthMap(code);
|
|
|
+
|
|
|
+ // 赋值实际领料
|
|
|
+ setActual(result, condition, code, codeWidthMap);
|
|
|
+
|
|
|
+ // 赋值排班领料
|
|
|
+ setPlan(result, list, codeWidthMap);
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 赋值实际领料
|
|
|
+ */
|
|
|
+ private void setActual(PickingTrackingNumStatisticsResult result, Map<String, String> condition, List<String> code, Map<String, Float> codeWidthMap) {
|
|
|
+
|
|
|
+ // 指定物料出库物料集合
|
|
|
+ List<Map<String, Object>> outputList = baseMapper.getOutputList(
|
|
|
+ pickingTrackingStatisticsGetWrapper("sw.CreatedTime", condition)
|
|
|
+ .in("sw.MaterialCode", code)
|
|
|
+ .eq("sw.StockChangeType", 20));
|
|
|
+
|
|
|
+ // 实际领料卷数
|
|
|
+ result.setActualNum(outputList.size());
|
|
|
+
|
|
|
+ // 实际领料米数
|
|
|
+ BigDecimal actualMeter = outputList.stream().map(item -> (BigDecimal) item.get("changeNum")).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ result.setActualMeter(actualMeter);
|
|
|
+
|
|
|
+ // 实际领料面积
|
|
|
+ BigDecimal actualArea = outputList.stream().map(
|
|
|
+ item -> BigDecimalUtil.init(item.get("quantity")).multiply(codeWidthMap.get(item.get("code").toString())).getValue(2)
|
|
|
+ ).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ result.setActualArea(actualArea);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 赋值排班领料
|
|
|
+ */
|
|
|
+ private void setPlan(PickingTrackingNumStatisticsResult result, List<Map<String, Object>> list, Map<String, Float> codeWidthMap) {
|
|
|
+ // 排班米数
|
|
|
+ BigDecimal planMeter = list.stream().map(item -> (BigDecimal) item.get("quantity")).reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ result.setPlanMeter(planMeter);
|
|
|
+
|
|
|
+ // 排班面积
|
|
|
+ BigDecimal planArea = list.stream()
|
|
|
+ .map(item -> BigDecimalUtil.init(item.get("quantity")).multiply(codeWidthMap.get(item.get("code").toString())).getValue(2))
|
|
|
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
+ result.setPlanArea(planArea);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取物料门幅键值对
|
|
|
+ */
|
|
|
+ private Map<String, Float> getCodeWidthMap(List<String> codeList) {
|
|
|
+ // 查询物料门幅
|
|
|
+ List<Map<String, Object>> list = baseMapper.getMaterialWidthByCode(Wrappers.query().in("m.Code", codeList));
|
|
|
+ return list.stream().collect(Collectors.toMap(
|
|
|
+ item -> item.get("code").toString(),
|
|
|
+ item -> (Float) item.get("width")
|
|
|
+ ));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 领料追踪统计获取wrapper
|
|
|
+ */
|
|
|
+ private QueryWrapper<Object> pickingTrackingStatisticsGetWrapper(String param, Map<String, String> condition) {
|
|
|
+ String type = condition.get("type");
|
|
|
+ Assert.notEmpty(type, "时间类型不能为空");
|
|
|
+ Date beginTime;
|
|
|
+ Date endTime;
|
|
|
+ Date date = new Date();
|
|
|
+ switch (type) {
|
|
|
+ case "1":
|
|
|
+ beginTime = DateUtil.beginOfDay(date);
|
|
|
+ endTime = DateUtil.endOfDay(date);
|
|
|
+ break;
|
|
|
+ case "2":
|
|
|
+ beginTime = DateUtil.beginOfWeek(date);
|
|
|
+ endTime = DateUtil.endOfWeek(date);
|
|
|
+ break;
|
|
|
+ case "3":
|
|
|
+ beginTime = DateUtil.beginOfMonth(date);
|
|
|
+ endTime = DateUtil.endOfMonth(date);
|
|
|
+ break;
|
|
|
+ case "4":
|
|
|
+ beginTime = DateUtil.beginOfYear(date);
|
|
|
+ endTime = DateUtil.endOfYear(date);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ beginTime = DateUtil.parse(condition.get("beginTime"));
|
|
|
+ endTime = DateUtil.parse(condition.get("endTime"));
|
|
|
+ }
|
|
|
+
|
|
|
+ return Wrappers.query().between(param, beginTime, endTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 领料追踪统计:用户统计
|
|
|
+ */
|
|
|
+ private List<HashMap<String, Object>> pickingTrackingUserStatistics(List<Map<String, Object>> list) {
|
|
|
+ // 统计用户
|
|
|
+ List<String> jobNoList = list.stream().map(item -> item.get("jobNo").toString()).distinct().collect(Collectors.toList());
|
|
|
+
|
|
|
+ Map<String, Map<String, String>> JobNoMap = baseMapper.selectUserByJobNoList(Wrappers.query().in("JobNo", jobNoList));
|
|
|
+ List<HashMap<String, Object>> userList = new ArrayList<>(
|
|
|
+ list.stream().collect(Collectors.toMap(
|
|
|
+ item -> item.get("jobNo").toString(),
|
|
|
+ item -> {
|
|
|
+ HashMap<String, Object> map = new HashMap<>();
|
|
|
+ String jobNo = item.get("jobNo").toString();
|
|
|
+ map.put("jobNo", jobNo);
|
|
|
+ map.put("userName", JobNoMap.get(jobNo).get("userName"));
|
|
|
+ map.put("sum", 1);
|
|
|
+ return map;
|
|
|
+ },
|
|
|
+ (v1, v2) -> {
|
|
|
+ v1.put("sum", (Integer) v1.get("sum") + 1);
|
|
|
+ return v1;
|
|
|
+ }
|
|
|
+ )).values());
|
|
|
+
|
|
|
+ int sum = userList.stream().mapToInt(item -> (Integer) item.get("sum")).sum();
|
|
|
+ HashMap<String, Object> countUserMap = new HashMap<>();
|
|
|
+ countUserMap.put("sum", sum);
|
|
|
+ countUserMap.put("userName", "全部");
|
|
|
+ userList.add(0, countUserMap);
|
|
|
+
|
|
|
+ return userList;
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
}
|