| | |
| | | if (!updateList.isEmpty()) { |
| | | for (SalesLedgerProduct product : updateList) { |
| | | product.setType(type.getCode()); |
| | | product.setProductStockStatus(0); |
| | | SalesLedgerProduct db = salesLedgerProductMapper.selectById(product.getId()); |
| | | if (db != null) { |
| | | BigDecimal stockedQty = product.getStockedQuantity() != null ? product.getStockedQuantity() : db.getStockedQuantity(); |
| | | BigDecimal orderQty = product.getQuantity() != null ? product.getQuantity() : db.getQuantity(); |
| | | product.setStockedQuantity(stockedQty); |
| | | product.setProductStockStatus(calculateProductStockStatus(stockedQty, orderQty)); |
| | | } else { |
| | | product.setProductStockStatus(0); |
| | | } |
| | | product.fillRemainingQuantity(); |
| | | salesLedgerProductMapper.updateById(product); |
| | | // 清空销售产品绑定的加工 |
| | |
| | | salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity()); |
| | | salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice()); |
| | | salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProduct.getTaxInclusiveTotalPrice()); |
| | | salesLedgerProduct.setProductStockStatus(0); |
| | | BigDecimal stockedQty = salesLedgerProduct.getStockedQuantity(); |
| | | BigDecimal orderQty = salesLedgerProduct.getQuantity(); |
| | | salesLedgerProduct.setProductStockStatus(calculateProductStockStatus(stockedQty, orderQty)); |
| | | salesLedgerProduct.fillRemainingQuantity(); |
| | | salesLedgerProductMapper.insert(salesLedgerProduct); |
| | | // 绑定产品额外加工 |
| | |
| | | // salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct); |
| | | } |
| | | } |
| | | refreshSalesLedgerStockStatus(salesLedgerId); |
| | | } |
| | | |
| | | private int calculateProductStockStatus(BigDecimal stockedQty, BigDecimal orderQty) { |
| | | BigDecimal stocked = stockedQty == null ? BigDecimal.ZERO : stockedQty; |
| | | BigDecimal order = orderQty == null ? BigDecimal.ZERO : orderQty; |
| | | if (stocked.compareTo(BigDecimal.ZERO) <= 0) { |
| | | return 0; |
| | | } |
| | | if (order.compareTo(BigDecimal.ZERO) > 0 && stocked.compareTo(order) < 0) { |
| | | return 1; |
| | | } |
| | | return 2; |
| | | } |
| | | |
| | | private void refreshSalesLedgerStockStatus(Long salesLedgerId) { |
| | | if (salesLedgerId == null) return; |
| | | SalesLedger ledger = baseMapper.selectById(salesLedgerId); |
| | | if (ledger == null) return; |
| | | List<SalesLedgerProduct> allProducts = salesLedgerProductMapper.selectList( |
| | | Wrappers.<SalesLedgerProduct>lambdaQuery() |
| | | .eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId) |
| | | .eq(SalesLedgerProduct::getType, SaleEnum.SALE.getCode())); |
| | | if (CollectionUtils.isEmpty(allProducts)) { |
| | | ledger.setStockStatus(0); |
| | | baseMapper.updateById(ledger); |
| | | return; |
| | | } |
| | | boolean anyInbound = allProducts.stream().anyMatch(p -> { |
| | | BigDecimal sq = p.getStockedQuantity(); |
| | | return sq != null && sq.compareTo(BigDecimal.ZERO) > 0; |
| | | }); |
| | | boolean allFull = allProducts.stream().allMatch(p -> Objects.equals(p.getProductStockStatus(), 2)); |
| | | ledger.setStockStatus(allFull ? 2 : (anyInbound ? 1 : 0)); |
| | | baseMapper.updateById(ledger); |
| | | } |
| | | |
| | | private SalesLedger convertToEntity(SalesLedgerDto dto) { |
| | |
| | | |
| | | // 查询所有产品 |
| | | List<SalesLedgerProduct> allProducts = salesLedgerProductMapper.selectList( |
| | | new LambdaQueryWrapper<SalesLedgerProduct>().in(SalesLedgerProduct::getSalesLedgerId, salesLedgerIds)); |
| | | new LambdaQueryWrapper<SalesLedgerProduct>() |
| | | .in(SalesLedgerProduct::getSalesLedgerId, salesLedgerIds) |
| | | .eq(SalesLedgerProduct::getType, 1)); |
| | | |
| | | if (CollectionUtils.isNotEmpty(allProducts)) { |
| | | Map<Long, SalesLedger> ledgerMap = ledgers.stream() |
| | | .collect(Collectors.toMap(SalesLedger::getId, Function.identity())); |
| | | |
| | | Map<Long, List<SalesLedgerProduct>> groupedData = new LinkedHashMap<>(); |
| | | for (SalesLedgerProduct p : allProducts) { |
| | | groupedData.computeIfAbsent(p.getSalesLedgerId(), k -> new ArrayList<>()).add(p); |
| | | } |
| | | |
| | | List<SalesInvoicesDto.InvoiceOrderGroupDto> groups = new ArrayList<>(); |
| | | BigDecimal totalQty = BigDecimal.ZERO; |
| | | BigDecimal totalArea = BigDecimal.ZERO; |
| | | |
| | | for (Map.Entry<Long, List<SalesLedgerProduct>> ledgerEntry : groupedData.entrySet()) { |
| | | SalesLedger ledger = ledgerMap.get(ledgerEntry.getKey()); |
| | | String orderNo = ledger != null ? ledger.getSalesContractNo() : ""; |
| | | List<SalesLedgerProduct> products = ledgerEntry.getValue(); |
| | | Map<String, List<SalesLedgerProduct>> groupedData = new LinkedHashMap<>(); |
| | | Map<String, Set<String>> groupOrderNos = new LinkedHashMap<>(); |
| | | for (SalesLedgerProduct p : allProducts) { |
| | | String productCategory = StringUtils.defaultString(p.getProductCategory(), ""); |
| | | String specificationModel = StringUtils.defaultString(p.getSpecificationModel(), ""); |
| | | String groupKey = productCategory + "||" + specificationModel; |
| | | groupedData.computeIfAbsent(groupKey, k -> new ArrayList<>()).add(p); |
| | | |
| | | SalesLedger ledger = ledgerMap.get(p.getSalesLedgerId()); |
| | | String orderNo = ledger != null ? StringUtils.defaultString(ledger.getSalesContractNo(), "") : ""; |
| | | if (StringUtils.isNotEmpty(orderNo)) { |
| | | groupOrderNos.computeIfAbsent(groupKey, k -> new LinkedHashSet<>()).add(orderNo); |
| | | } |
| | | } |
| | | |
| | | for (Map.Entry<String, List<SalesLedgerProduct>> productEntry : groupedData.entrySet()) { |
| | | String key = productEntry.getKey(); |
| | | String[] parts = key.split("\\|\\|", -1); |
| | | String productName = parts.length > 0 ? parts[0] : ""; |
| | | String specificationModel = parts.length > 1 ? parts[1] : ""; |
| | | List<SalesLedgerProduct> products = productEntry.getValue(); |
| | | |
| | | SalesInvoicesDto.InvoiceOrderGroupDto group = new SalesInvoicesDto.InvoiceOrderGroupDto(); |
| | | group.setSalesContractNo(orderNo); |
| | | if (CollectionUtils.isNotEmpty(products)) { |
| | | group.setProductName(products.get(0).getProductCategory()); |
| | | } |
| | | Set<String> orderNos = groupOrderNos.getOrDefault(key, Collections.emptySet()); |
| | | group.setSalesContractNo(String.join(",", orderNos)); |
| | | group.setProductName(productName); |
| | | |
| | | List<SalesInvoicesDto.InvoiceItemDto> itemDtos = new ArrayList<>(); |
| | | Map<String, SalesInvoicesDto.InvoiceItemDto> mergedItems = new LinkedHashMap<>(); |
| | | BigDecimal groupQty = BigDecimal.ZERO; |
| | | BigDecimal groupArea = BigDecimal.ZERO; |
| | | |
| | | for (SalesLedgerProduct p : products) { |
| | | SalesInvoicesDto.InvoiceItemDto item = new SalesInvoicesDto.InvoiceItemDto(); |
| | | item.setFloorCode(p.getFloorCode()); |
| | | item.setWidthHeight((p.getWidth() != null ? p.getWidth().stripTrailingZeros().toPlainString() : "0") + |
| | | " * " + (p.getHeight() != null ? p.getHeight().stripTrailingZeros().toPlainString() : "0")); |
| | | item.setQuantity(p.getQuantity()); |
| | | String widthHeight = (p.getWidth() != null ? p.getWidth().stripTrailingZeros().toPlainString() : "0") + |
| | | " * " + (p.getHeight() != null ? p.getHeight().stripTrailingZeros().toPlainString() : "0"); |
| | | String floorCode = StringUtils.defaultString(p.getFloorCode(), ""); |
| | | String remark = StringUtils.defaultString(p.getRemark(), ""); |
| | | String processReq = StringUtils.defaultString(p.getProcessRequirement(), ""); |
| | | String itemKey = floorCode + "||" + widthHeight + "||" + remark + "||" + processReq; |
| | | |
| | | BigDecimal qty = p.getQuantity() != null ? p.getQuantity() : BigDecimal.ZERO; |
| | | |
| | | // 面积 |
| | | BigDecimal area = p.getSettleTotalArea() != null ? p.getSettleTotalArea() : p.getActualTotalArea(); |
| | | if (area == null && p.getWidth() != null && p.getHeight() != null && p.getQuantity() != null) { |
| | | area = p.getWidth().multiply(p.getHeight()).multiply(p.getQuantity()).divide(new BigDecimal(1000000), 2, RoundingMode.HALF_UP); |
| | | } |
| | | item.setArea(area); |
| | | item.setRemark(p.getRemark()); |
| | | item.setProcessRequirement(p.getProcessRequirement()); |
| | | area = area != null ? area : BigDecimal.ZERO; |
| | | |
| | | itemDtos.add(item); |
| | | groupQty = groupQty.add(p.getQuantity() != null ? p.getQuantity() : BigDecimal.ZERO); |
| | | groupArea = groupArea.add(area != null ? area : BigDecimal.ZERO); |
| | | SalesInvoicesDto.InvoiceItemDto item = mergedItems.get(itemKey); |
| | | if (item == null) { |
| | | item = new SalesInvoicesDto.InvoiceItemDto(); |
| | | item.setFloorCode(floorCode); |
| | | item.setWidthHeight(widthHeight); |
| | | item.setSpecificationModel(p.getSpecificationModel()); |
| | | item.setQuantity(qty); |
| | | item.setArea(area); |
| | | item.setRemark(remark); |
| | | item.setProcessRequirement(processReq); |
| | | mergedItems.put(itemKey, item); |
| | | } else { |
| | | item.setQuantity((item.getQuantity() != null ? item.getQuantity() : BigDecimal.ZERO).add(qty)); |
| | | item.setArea((item.getArea() != null ? item.getArea() : BigDecimal.ZERO).add(area)); |
| | | } |
| | | |
| | | groupQty = groupQty.add(qty); |
| | | groupArea = groupArea.add(area); |
| | | } |
| | | |
| | | group.setItems(itemDtos); |
| | | group.setItems(new ArrayList<>(mergedItems.values())); |
| | | group.setGroupTotalQuantity(groupQty); |
| | | group.setGroupTotalArea(groupArea.setScale(2, RoundingMode.HALF_UP)); |
| | | groups.add(group); |
| | |
| | | SalesLabelDto dto = new SalesLabelDto(); |
| | | dto.setCustomerName(salesLedger.getCustomerName()); |
| | | dto.setSalesContractNo(salesLedger.getSalesContractNo()); |
| | | dto.setProductName(p.getProductCategory()); |
| | | dto.setProductName(p.getSpecificationModel()); |
| | | |
| | | // 宽*高=数量 |
| | | String specification = (p.getWidth() != null ? p.getWidth().stripTrailingZeros().toPlainString() : "0") + "*" + |
| | |
| | | throw new ServiceException("入库失败,未查询到该销售订单的销售产品"); |
| | | } |
| | | for (SalesLedgerProduct product : salesLedgerProducts) { |
| | | if (!Objects.equals(product.getSalesLedgerId(), ledger.getId())) { |
| | | throw new ServiceException("入库失败,存在不属于当前销售订单的产品"); |
| | | } |
| | | if (product.getProductModelId() == null) { |
| | | continue; |
| | | } |
| | | BigDecimal orderQty = product.getQuantity() == null ? BigDecimal.ZERO : product.getQuantity(); |
| | | BigDecimal oldStocked = product.getStockedQuantity() == null ? BigDecimal.ZERO : product.getStockedQuantity(); |
| | | BigDecimal inboundQty = orderQty.subtract(oldStocked); |
| | | if (inboundQty.compareTo(BigDecimal.ZERO) < 0) { |
| | | inboundQty = BigDecimal.ZERO; |
| | | } |
| | | if (inboundQty.compareTo(BigDecimal.ZERO) <= 0) { |
| | | continue; |
| | | } |
| | | StockInventoryDto stockInventoryDto = new StockInventoryDto(); |
| | | stockInventoryDto.setRecordId(product.getId()); |
| | | stockInventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.SALE_STOCK_IN.getCode()); |
| | | stockInventoryDto.setQualitity(product.getQuantity()); |
| | | stockInventoryDto.setQualitity(inboundQty); |
| | | stockInventoryDto.setProductModelId(product.getProductModelId()); |
| | | stockInventoryDto.setSalesLedgerId(ledger.getId()); |
| | | stockInventoryDto.setSalesLedgerProductId(product.getId()); |
| | | stockInventoryService.addstockInventory(stockInventoryDto); |
| | | |
| | | BigDecimal newStocked = oldStocked.add(inboundQty); |
| | | int lineStockStatus; |
| | | if (newStocked.compareTo(BigDecimal.ZERO) <= 0) { |
| | | lineStockStatus = 0; |
| | | } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) { |
| | | lineStockStatus = 1; |
| | | } else { |
| | | lineStockStatus = 2; |
| | | } |
| | | product.setStockedQuantity(newStocked); |
| | | product.setProductStockStatus(lineStockStatus); |
| | | product.fillRemainingQuantity(); |
| | | salesLedgerProductMapper.updateById(product); |
| | | } |
| | | // 按销售订单产品入库情况更新主单入库状态:1-部分入库,2-已入库 |
| | | List<SalesLedgerProduct> ledgerAllProducts = salesLedgerProductMapper.selectList(Wrappers.<SalesLedgerProduct>lambdaQuery().eq(SalesLedgerProduct::getSalesLedgerId, ledger.getId())); |
| | | boolean hasStocked = CollectionUtils.isNotEmpty(ledgerAllProducts) && ledgerAllProducts.stream().anyMatch(item -> Objects.equals(item.getProductStockStatus(), 1)); |
| | | boolean allStocked = CollectionUtils.isNotEmpty(ledgerAllProducts) && ledgerAllProducts.stream().allMatch(item -> Objects.equals(item.getProductStockStatus(), 1)); |
| | | boolean hasStocked = CollectionUtils.isNotEmpty(ledgerAllProducts) && ledgerAllProducts.stream().anyMatch(item -> { |
| | | BigDecimal sq = item.getStockedQuantity(); |
| | | return sq != null && sq.compareTo(BigDecimal.ZERO) > 0; |
| | | }); |
| | | boolean allStocked = CollectionUtils.isNotEmpty(ledgerAllProducts) && ledgerAllProducts.stream().allMatch(item -> { |
| | | BigDecimal orderQty = item.getQuantity() == null ? BigDecimal.ZERO : item.getQuantity(); |
| | | BigDecimal stockedQty = item.getStockedQuantity() == null ? BigDecimal.ZERO : item.getStockedQuantity(); |
| | | return orderQty.compareTo(BigDecimal.ZERO) <= 0 || stockedQty.compareTo(orderQty) >= 0; |
| | | }); |
| | | ledger.setStockStatus(allStocked ? 2 : (hasStocked ? 1 : 0)); |
| | | baseMapper.updateById(ledger); |
| | | } |
| | |
| | | } |
| | | stockUtils.addUnStock(ledgerId, dbProduct.getId(), dbProduct.getProductModelId(), inboundThisLine, |
| | | StockInUnQualifiedRecordTypeEnum.SALES_SCAN_UNSTOCK_IN.getCode(), dbProduct.getId()); |
| | | |
| | | BigDecimal oldUnStocked = dbProduct.getUnqualifiedStockedQuantity() == null ? BigDecimal.ZERO : dbProduct.getUnqualifiedStockedQuantity(); |
| | | dbProduct.setUnqualifiedStockedQuantity(oldUnStocked.add(inboundThisLine)); |
| | | dbProduct.fillRemainingQuantity(); |
| | | salesLedgerProductMapper.updateById(dbProduct); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | stockUtils.assertQualifiedAvailable(dbProduct.getProductModelId(), outboundThisLine); |
| | | |
| | | BigDecimal oldStocked = dbProduct.getStockedQuantity() == null ? BigDecimal.ZERO : dbProduct.getStockedQuantity(); |
| | | BigDecimal newStocked = oldStocked.subtract(outboundThisLine); |
| | | if (newStocked.compareTo(BigDecimal.ZERO) < 0) { |
| | | newStocked = BigDecimal.ZERO; |
| | | } |
| | | |
| | | StockInventoryDto stockInventoryDto = new StockInventoryDto(); |
| | | stockInventoryDto.setRecordId(dbProduct.getId()); |
| | | stockInventoryDto.setRecordType(StockOutQualifiedRecordTypeEnum.SALE_SCAN_STOCK_OUT.getCode()); |
| | |
| | | stockInventoryDto.setSalesLedgerProductId(dbProduct.getId()); |
| | | stockInventoryService.subtractStockInventory(stockInventoryDto); |
| | | |
| | | BigDecimal orderQty = dbProduct.getQuantity() == null ? BigDecimal.ZERO : dbProduct.getQuantity(); |
| | | int lineStockStatus; |
| | | if (newStocked.compareTo(BigDecimal.ZERO) <= 0) { |
| | | lineStockStatus = 0; |
| | | } else if (orderQty.compareTo(BigDecimal.ZERO) > 0 && newStocked.compareTo(orderQty) < 0) { |
| | | lineStockStatus = 1; |
| | | } else { |
| | | lineStockStatus = 2; |
| | | } |
| | | dbProduct.setStockedQuantity(newStocked); |
| | | dbProduct.setProductStockStatus(lineStockStatus); |
| | | BigDecimal oldShipped = dbProduct.getShippedQuantity() == null ? BigDecimal.ZERO : dbProduct.getShippedQuantity(); |
| | | dbProduct.setShippedQuantity(oldShipped.add(outboundThisLine)); |
| | | dbProduct.fillRemainingQuantity(); |
| | | salesLedgerProductMapper.updateById(dbProduct); |
| | | } |
| | |
| | | if (dbProduct.getProductModelId() == null) { |
| | | throw new ServiceException("不合格出库失败,产品规格未维护,无法出库"); |
| | | } |
| | | BigDecimal unStocked = dbProduct.getUnqualifiedStockedQuantity() == null ? BigDecimal.ZERO : dbProduct.getUnqualifiedStockedQuantity(); |
| | | BigDecimal unShipped = dbProduct.getUnqualifiedShippedQuantity() == null ? BigDecimal.ZERO : dbProduct.getUnqualifiedShippedQuantity(); |
| | | BigDecimal canUnShip = unStocked.subtract(unShipped); |
| | | if (outboundThisLine.compareTo(canUnShip) > 0) { |
| | | throw new ServiceException("不合格出库失败,出库数量不能大于不合格入库数量"); |
| | | } |
| | | stockUtils.assertUnqualifiedAvailable(dbProduct.getProductModelId(), outboundThisLine); |
| | | stockUtils.subtractUnStock(ledgerId, dbProduct.getId(), dbProduct.getProductModelId(), outboundThisLine, |
| | | StockOutUnQualifiedRecordTypeEnum.SALE_SCAN_UNSTOCK_OUT.getCode(), dbProduct.getId()); |
| | | |
| | | dbProduct.setUnqualifiedShippedQuantity(unShipped.add(outboundThisLine)); |
| | | dbProduct.fillRemainingQuantity(); |
| | | salesLedgerProductMapper.updateById(dbProduct); |
| | | } |
| | | } |
| | | } |