| | |
| | | throw new ServiceException("下发失败,未选择生产计划"); |
| | | } |
| | | |
| | | List<ProductionPlanDto> plans = productionPlanMapper.selectWithMaterialByIds(planIds); |
| | | if (plans == null || plans.isEmpty() || plans.size() != planIds.size()) { |
| | | List<ProductionPlanDto> planLists = productionPlanMapper.selectWithMaterialByIds(planIds); |
| | | if (planLists == null || planLists.isEmpty() || planLists.size() != planIds.size()) { |
| | | throw new ServiceException("下发失败,生产计划不存在或已被删除"); |
| | | } |
| | | |
| | | ProductionPlanDto firstPlan = plans.getFirst(); |
| | | ProductionPlanDto firstPlan = planLists.getFirst(); |
| | | if (firstPlan.getProductModelId() == null) { |
| | | throw new ServiceException("下发失败,生产计划缺少产品型号"); |
| | | } |
| | | |
| | | boolean hasDifferentModel = plans.stream() |
| | | boolean hasDifferentModel = planLists.stream() |
| | | .anyMatch(item -> !Objects.equals(item.getProductModelId(), firstPlan.getProductModelId())); |
| | | if (hasDifferentModel) { |
| | | throw new BaseException("合并失败,所选生产计划的产品型号不一致"); |
| | | } |
| | | |
| | | boolean hasIssuedPlan = plans.stream() |
| | | .anyMatch(item -> item.getStatus() != null && item.getStatus() != PLAN_STATUS_WAIT); |
| | | boolean hasIssuedPlan = planLists.stream() |
| | | .anyMatch(item -> item.getStatus() != null && item.getStatus() == PLAN_STATUS_ISSUED); |
| | | if (hasIssuedPlan) { |
| | | throw new BaseException("合并失败,所选生产计划存在已下发或部分下发数据"); |
| | | } |
| | | |
| | | BigDecimal totalRequiredQuantity = plans.stream() |
| | | .map(ProductionPlan::getQtyRequired) |
| | | .filter(Objects::nonNull) |
| | | BigDecimal totalRequiredQuantity = planLists.stream() |
| | | .map(this::resolveRemainingQuantity) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | if (totalRequiredQuantity.compareTo(BigDecimal.ZERO) <= 0) { |
| | | throw new ServiceException("下发失败,所选生产计划需求总量必须大于0"); |
| | |
| | | throw new ServiceException("下发失败,下发数量不能大于计划需求总量"); |
| | | } |
| | | |
| | | BigDecimal remainingForOrderBind = assignedQuantity; |
| | | List<Long> issuedPlanIds = new ArrayList<>(); |
| | | for (ProductionPlanDto plan : planLists) { |
| | | BigDecimal remainingQuantity = resolveRemainingQuantity(plan); |
| | | if (remainingForOrderBind.compareTo(BigDecimal.ZERO) <= 0 || remainingQuantity.compareTo(BigDecimal.ZERO) <= 0) { |
| | | continue; |
| | | } |
| | | BigDecimal issueForThisPlan = remainingForOrderBind.min(remainingQuantity); |
| | | remainingForOrderBind = remainingForOrderBind.subtract(issueForThisPlan); |
| | | if (issueForThisPlan.compareTo(BigDecimal.ZERO) > 0) { |
| | | issuedPlanIds.add(plan.getId()); |
| | | } |
| | | } |
| | | if (issuedPlanIds.isEmpty()) { |
| | | throw new ServiceException("Issue failed, no quantity available for dispatch"); |
| | | } |
| | | |
| | | ProductionOrder productionOrder = new ProductionOrder(); |
| | | productionOrder.setProductionPlanIds(formatPlanIds(planIds)); |
| | | productionOrder.setProductionPlanIds(formatPlanIds(issuedPlanIds)); |
| | | productionOrder.setProductModelId(firstPlan.getProductModelId()); |
| | | productionOrder.setQuantity(assignedQuantity); |
| | | productionOrder.setPlanCompleteTime(productionPlanDto.getPlanCompleteTime()); |
| | |
| | | throw new ServiceException("下发失败,生产订单保存失败"); |
| | | } |
| | | |
| | | int targetStatus = assignedQuantity.compareTo(totalRequiredQuantity) < 0 ? PLAN_STATUS_PARTIAL : PLAN_STATUS_ISSUED; |
| | | List<ProductionPlan> updates = planIds.stream().map(id -> { |
| | | //已下发数量 |
| | | BigDecimal remainingAssignedQuantity = assignedQuantity; |
| | | List<ProductionPlan> updates = new ArrayList<>(); |
| | | for (ProductionPlanDto plan : planLists) { |
| | | BigDecimal requiredQuantity = Optional.ofNullable(plan.getQtyRequired()).orElse(BigDecimal.ZERO); |
| | | if (requiredQuantity.compareTo(BigDecimal.ZERO) < 0) { |
| | | requiredQuantity = BigDecimal.ZERO; |
| | | } |
| | | BigDecimal remainingQuantity = resolveRemainingQuantity(plan); |
| | | BigDecimal historicalIssuedQuantity = requiredQuantity.subtract(remainingQuantity); |
| | | BigDecimal issuedQuantity = BigDecimal.ZERO; |
| | | if (remainingAssignedQuantity.compareTo(BigDecimal.ZERO) > 0 && remainingQuantity.compareTo(BigDecimal.ZERO) > 0) { |
| | | issuedQuantity = remainingAssignedQuantity.min(remainingQuantity); |
| | | remainingAssignedQuantity = remainingAssignedQuantity.subtract(issuedQuantity); |
| | | } |
| | | |
| | | BigDecimal totalIssuedQuantity = historicalIssuedQuantity.add(issuedQuantity); |
| | | int planStatus = resolvePlanStatus(requiredQuantity, totalIssuedQuantity); |
| | | ProductionPlan update = new ProductionPlan(); |
| | | update.setId(id); |
| | | update.setStatus(targetStatus); |
| | | return update; |
| | | }).collect(Collectors.toList()); |
| | | update.setId(plan.getId()); |
| | | update.setStatus(planStatus); |
| | | update.setQuantityIssued(totalIssuedQuantity); |
| | | update.setIssued(planStatus == PLAN_STATUS_ISSUED); |
| | | updates.add(update); |
| | | } |
| | | if (!updates.isEmpty()) { |
| | | this.updateBatchById(updates); |
| | | } |
| | |
| | | util.exportExcel(response, exportList, "主生产计划"); |
| | | } |
| | | |
| | | private BigDecimal resolveRemainingQuantity(ProductionPlan plan) { |
| | | if (plan == null) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | BigDecimal requiredQuantity = Optional.ofNullable(plan.getQtyRequired()).orElse(BigDecimal.ZERO); |
| | | if (requiredQuantity.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | BigDecimal issuedQuantity = Optional.ofNullable(plan.getQuantityIssued()).orElse(BigDecimal.ZERO); |
| | | if (issuedQuantity.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return requiredQuantity; |
| | | } |
| | | if (issuedQuantity.compareTo(requiredQuantity) >= 0) { |
| | | return BigDecimal.ZERO; |
| | | } |
| | | return requiredQuantity.subtract(issuedQuantity); |
| | | } |
| | | |
| | | private int resolvePlanStatus(BigDecimal requiredQuantity, BigDecimal issuedQuantity) { |
| | | if (requiredQuantity == null || requiredQuantity.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return PLAN_STATUS_WAIT; |
| | | } |
| | | if (issuedQuantity == null || issuedQuantity.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return PLAN_STATUS_WAIT; |
| | | } |
| | | return issuedQuantity.compareTo(requiredQuantity) < 0 ? PLAN_STATUS_PARTIAL : PLAN_STATUS_ISSUED; |
| | | } |
| | | |
| | | private String formatPlanIds(List<Long> planIds) { |
| | | return planIds.stream() |
| | | .filter(Objects::nonNull) |