From 4f39e676277d7a66e13d172288032ce16bb18e8c Mon Sep 17 00:00:00 2001
From: zss <zss@example.com>
Date: 星期三, 22 四月 2026 17:05:30 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_河南_鹤壁天沐钢化玻璃厂' into dev_河南_鹤壁天沐钢化玻璃厂
---
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java | 1300 ++++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 1,021 insertions(+), 279 deletions(-)
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index 1a371f9..c9e8734 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -9,11 +9,16 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.service.AccountIncomeService;
+import com.ruoyi.approve.service.IApproveProcessService;
+import com.ruoyi.approve.vo.ApproveProcessVO;
+import com.ruoyi.approve.pojo.ApproveProcess;
+import com.ruoyi.common.enums.ApproveTypeEnum;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.basic.mapper.ProductMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.pojo.CustomerRegions;
+import com.ruoyi.basic.pojo.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.service.ICustomerRegionsService;
import com.ruoyi.common.enums.FileNameType;
@@ -83,6 +88,7 @@
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
@@ -103,6 +109,9 @@
private static final String LOCK_PREFIX = "contract_no_lock:";
private static final long LOCK_WAIT_TIMEOUT = 10; // 閿佺瓑寰呰秴鏃舵椂闂达紙绉掞級
private static final long LOCK_EXPIRE_TIME = 30; // 閿佽嚜鍔ㄨ繃鏈熸椂闂达紙绉掞級
+ private static final int INBOUND_BIZ_TYPE_WEB = 1;
+ private static final int INBOUND_BIZ_TYPE_SCAN_QUALIFIED = 2;
+ private static final int INBOUND_BIZ_TYPE_SCAN_UNQUALIFIED = 3;
private final AccountIncomeService accountIncomeService;
private final SalesLedgerMapper salesLedgerMapper;
private final CustomerMapper customerMapper;
@@ -144,6 +153,8 @@
private final StockInRecordService stockInRecordService;
private final StockOutRecordService stockOutRecordService;
private final StockUtils stockUtils;
+ @Autowired
+ private IApproveProcessService approveProcessService;
@Autowired
private SysDeptMapper sysDeptMapper;
@@ -219,11 +230,7 @@
List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(productWrapper);
Map<Long, ProductModel> productModelMap = Collections.emptyMap();
if (CollectionUtils.isNotEmpty(products)) {
- List<Long> productModelIds = products.stream()
- .map(SalesLedgerProduct::getProductModelId)
- .filter(Objects::nonNull)
- .distinct()
- .collect(Collectors.toList());
+ List<Long> productModelIds = products.stream().map(SalesLedgerProduct::getProductModelId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(productModelIds)) {
List<ProductModel> productModels = productModelMapper.selectBatchIds(productModelIds);
if (CollectionUtils.isNotEmpty(productModels)) {
@@ -239,26 +246,15 @@
product.setRegister(SecurityUtils.getLoginUser().getUser().getNickName());
product.setRegisterDate(LocalDateTime.now());
// 鍙戣揣淇℃伅
- ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
- .eq(ShippingInfo::getSalesLedgerProductId, product.getId())
- .orderByDesc(ShippingInfo::getCreateTime)
- .last("limit 1"));
+ ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>().eq(ShippingInfo::getSalesLedgerProductId, product.getId()).orderByDesc(ShippingInfo::getCreateTime).last("limit 1"));
if (shippingInfo != null) {
product.setShippingStatus(shippingInfo.getStatus());
}
// 鍔犲伐鏄庣粏锛屽厛鏌ind琛ㄨ幏鍙栬浜у搧鍏宠仈鐨勫伐搴忓強鏁伴噺
- List<SalesLedgerProductProcessBind> bindList = salesLedgerProductProcessBindService.list(
- new LambdaQueryWrapper<SalesLedgerProductProcessBind>()
- .eq(SalesLedgerProductProcessBind::getSalesLedgerProductId, product.getId()));
+ List<SalesLedgerProductProcessBind> bindList = salesLedgerProductProcessBindService.list(new LambdaQueryWrapper<SalesLedgerProductProcessBind>().eq(SalesLedgerProductProcessBind::getSalesLedgerProductId, product.getId()));
if (!bindList.isEmpty()) {
- List<Integer> processIds = bindList.stream()
- .map(SalesLedgerProductProcessBind::getSalesLedgerProductProcessId)
- .collect(Collectors.toList());
- Map<Integer, Integer> processQuantityMap = bindList.stream()
- .collect(Collectors.toMap(
- SalesLedgerProductProcessBind::getSalesLedgerProductProcessId,
- SalesLedgerProductProcessBind::getQuantity,
- (a, b) -> a));
+ List<Integer> processIds = bindList.stream().map(SalesLedgerProductProcessBind::getSalesLedgerProductProcessId).collect(Collectors.toList());
+ Map<Integer, Integer> processQuantityMap = bindList.stream().collect(Collectors.toMap(SalesLedgerProductProcessBind::getSalesLedgerProductProcessId, SalesLedgerProductProcessBind::getQuantity, (a, b) -> a));
List<SalesLedgerProductProcess> processList = salesLedgerProductProcessService.listByIds(processIds);
processList.forEach(p -> p.setQuantity(processQuantityMap.get(p.getId())));
product.setSalesProductProcessList(processList);
@@ -282,8 +278,7 @@
// 3.鏌ヨ涓婁紶鏂囦欢
LambdaQueryWrapper<CommonFile> salesLedgerFileWrapper = new LambdaQueryWrapper<>();
- salesLedgerFileWrapper.eq(CommonFile::getCommonId, salesLedger.getId())
- .eq(CommonFile::getType, FileNameType.SALE.getValue());
+ salesLedgerFileWrapper.eq(CommonFile::getCommonId, salesLedger.getId()).eq(CommonFile::getType, FileNameType.SALE.getValue());
List<CommonFile> salesLedgerFiles = commonFileMapper.selectList(salesLedgerFileWrapper);
// 4. 杞崲 DTO
@@ -306,11 +301,7 @@
List<Map<String, Object>> result = salesLedgerMapper.selectMaps(queryWrapper);
// 灏嗕笅鍒掔嚎鍛藉悕杞崲涓洪┘宄板懡鍚�
- return result.stream().map(map -> map.entrySet().stream()
- .collect(Collectors.toMap(
- entry -> underlineToCamel(entry.getKey()),
- Map.Entry::getValue))
- ).collect(Collectors.toList());
+ return result.stream().map(map -> map.entrySet().stream().collect(Collectors.toMap(entry -> underlineToCamel(entry.getKey()), Map.Entry::getValue))).collect(Collectors.toList());
}
@Override
@@ -326,10 +317,7 @@
// 鎵ц鏌ヨ骞惰绠楁�诲拰
List<SalesLedger> salesLedgers = salesLedgerMapper.selectList(queryWrapper);
- BigDecimal totalContractAmount = salesLedgers.stream()
- .map(SalesLedger::getContractAmount)
- .filter(Objects::nonNull)
- .reduce(BigDecimal.ZERO, BigDecimal::add);
+ BigDecimal totalContractAmount = salesLedgers.stream().map(SalesLedger::getContractAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
return totalContractAmount;
}
@@ -338,32 +326,23 @@
public List getTopFiveList() {
// 鏌ヨ鍘熷鏁版嵁
LambdaQueryWrapper<SalesLedger> queryWrapper = Wrappers.lambdaQuery();
- queryWrapper.select(SalesLedger::getCustomerId,
- SalesLedger::getCustomerName,
- SalesLedger::getContractAmount)
- .orderByDesc(SalesLedger::getContractAmount);
+ queryWrapper.select(SalesLedger::getCustomerId, SalesLedger::getCustomerName, SalesLedger::getContractAmount).orderByDesc(SalesLedger::getContractAmount);
List<SalesLedger> records = salesLedgerMapper.selectList(queryWrapper);
// 鎸夊鎴稩D鍒嗙粍骞惰仛鍚堥噾棰�
Map<Long, GroupedCustomer> groupedMap = new LinkedHashMap<>(); // 浣跨敤LinkedHashMap淇濇寔鎺掑簭
for (SalesLedger record : records) {
- groupedMap.computeIfAbsent(record.getCustomerId(),
- k -> new GroupedCustomer(record.getCustomerId(), record.getCustomerName()))
- .addAmount(record.getContractAmount());
+ groupedMap.computeIfAbsent(record.getCustomerId(), k -> new GroupedCustomer(record.getCustomerId(), record.getCustomerName())).addAmount(record.getContractAmount());
}
// 杞崲涓虹粨鏋滃垪琛ㄥ苟鍙栧墠5
- return groupedMap.values().stream()
- .sorted(Comparator.comparing(GroupedCustomer::getTotalAmount).reversed())
- .limit(5)
- .map(customer -> {
- Map<String, Object> result = new HashMap<>();
- result.put("customerId", customer.getCustomerId());
- result.put("customerName", customer.getCustomerName());
- result.put("totalAmount", customer.getTotalAmount());
- return result;
- })
- .collect(Collectors.toList());
+ return groupedMap.values().stream().sorted(Comparator.comparing(GroupedCustomer::getTotalAmount).reversed()).limit(5).map(customer -> {
+ Map<String, Object> result = new HashMap<>();
+ result.put("customerId", customer.getCustomerId());
+ result.put("customerName", customer.getCustomerName());
+ result.put("totalAmount", customer.getTotalAmount());
+ return result;
+ }).collect(Collectors.toList());
}
@Override
@@ -379,31 +358,19 @@
// 鍥炴閲戦
LambdaQueryWrapper<ReceiptPayment> receiptPaymentQuery = new LambdaQueryWrapper<>();
- receiptPaymentQuery
- .ge(ReceiptPayment::getCreateTime, startTime)
- .le(ReceiptPayment::getCreateTime, endTime);
+ receiptPaymentQuery.ge(ReceiptPayment::getCreateTime, startTime).le(ReceiptPayment::getCreateTime, endTime);
- List<ReceiptPayment> receiptPayments =
- receiptPaymentMapper.selectList(receiptPaymentQuery);
+ List<ReceiptPayment> receiptPayments = receiptPaymentMapper.selectList(receiptPaymentQuery);
- BigDecimal receiptAmount = receiptPayments.stream()
- .map(ReceiptPayment::getReceiptPaymentAmount)
- .filter(Objects::nonNull)
- .reduce(BigDecimal.ZERO, BigDecimal::add);
+ BigDecimal receiptAmount = receiptPayments.stream().map(ReceiptPayment::getReceiptPaymentAmount).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
// 寮�绁ㄩ噾棰�
LambdaQueryWrapper<InvoiceLedger> invoiceLedgerQuery = new LambdaQueryWrapper<>();
- invoiceLedgerQuery
- .ge(InvoiceLedger::getCreateTime, startTime)
- .le(InvoiceLedger::getCreateTime, endTime);
+ invoiceLedgerQuery.ge(InvoiceLedger::getCreateTime, startTime).le(InvoiceLedger::getCreateTime, endTime);
- List<InvoiceLedger> invoiceLedgers =
- invoiceLedgerMapper.selectList(invoiceLedgerQuery);
+ List<InvoiceLedger> invoiceLedgers = invoiceLedgerMapper.selectList(invoiceLedgerQuery);
- BigDecimal invoiceAmount = invoiceLedgers.stream()
- .map(InvoiceLedger::getInvoiceTotal)
- .filter(Objects::nonNull)
- .reduce(BigDecimal.ZERO, BigDecimal::add);
+ BigDecimal invoiceAmount = invoiceLedgers.stream().map(InvoiceLedger::getInvoiceTotal).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
MonthlyAmountDto dto = new MonthlyAmountDto();
dto.setMonth(yearMonth.format(DateTimeFormatter.ofPattern("yyyy-MM")));
@@ -418,7 +385,97 @@
@Override
public IPage<SalesLedger> selectSalesLedgerListPage(Page page, SalesLedgerDto salesLedgerDto) {
- return salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto);
+ IPage<SalesLedger> iPage = salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto);
+
+ if (CollectionUtils.isEmpty(iPage.getRecords())) {
+ return iPage;
+ }
+
+ List<Long> salesLedgerIds = iPage.getRecords().stream().map(SalesLedger::getId).collect(Collectors.toList());
+
+ boolean hasWidthHeightFilter = salesLedgerDto.getWidth() != null || salesLedgerDto.getHeight() != null;
+ Map<Long, List<SalesLedgerProduct>> matchedProductsMap = Collections.emptyMap();
+ if (hasWidthHeightFilter) {
+ LambdaQueryWrapper<SalesLedgerProduct> productQueryWrapper = new LambdaQueryWrapper<SalesLedgerProduct>().in(SalesLedgerProduct::getSalesLedgerId, salesLedgerIds).eq(SalesLedgerProduct::getType, 1);
+ if (salesLedgerDto.getWidth() != null) {
+ productQueryWrapper.eq(SalesLedgerProduct::getWidth, salesLedgerDto.getWidth());
+ }
+ if (salesLedgerDto.getHeight() != null) {
+ productQueryWrapper.eq(SalesLedgerProduct::getHeight, salesLedgerDto.getHeight());
+ }
+ List<SalesLedgerProduct> matchedProducts = salesLedgerProductMapper.selectList(productQueryWrapper);
+ matchedProductsMap = CollectionUtils.isEmpty(matchedProducts) ? Collections.emptyMap() : matchedProducts.stream().collect(Collectors.groupingBy(SalesLedgerProduct::getSalesLedgerId));
+ }
+
+ List<SalesLedgerProductTotalsDto> productTotals = salesLedgerProductMapper.selectSalesLedgerProductTotals(salesLedgerIds, 1);
+ Map<Long, SalesLedgerProductTotalsDto> productTotalsMap = CollectionUtils.isEmpty(productTotals) ? Collections.emptyMap() : productTotals.stream().filter(t -> t.getSalesLedgerId() != null).collect(Collectors.toMap(SalesLedgerProductTotalsDto::getSalesLedgerId, Function.identity(), (a, b) -> a));
+
+ List<InvoiceLedgerDto> invoiceLedgerDtoList = invoiceLedgerMapper.invoicedTotal(salesLedgerIds);
+ if (CollectionUtils.isEmpty(invoiceLedgerDtoList)) {
+ invoiceLedgerDtoList = Collections.emptyList();
+ }
+
+ Map<Long, BigDecimal> invoiceTotals = invoiceLedgerDtoList.stream().filter(dto -> dto.getSalesLedgerId() != null && dto.getInvoiceTotal() != null).collect(Collectors.toMap(dto -> dto.getSalesLedgerId().longValue(), InvoiceLedgerDto::getInvoiceTotal, BigDecimal::add));
+
+ List<ReceiptPayment> receiptPayments = Collections.emptyList();
+ if (!CollectionUtils.isEmpty(salesLedgerIds)) {
+ receiptPayments = receiptPaymentMapper.selectList(new LambdaQueryWrapper<ReceiptPayment>().in(ReceiptPayment::getSalesLedgerId, salesLedgerIds));
+ }
+
+ Map<Long, BigDecimal> receiptTotals = new HashMap<>();
+ if (!CollectionUtils.isEmpty(receiptPayments)) {
+ for (ReceiptPayment receiptPayment : receiptPayments) {
+ if (receiptPayment.getSalesLedgerId() != null && receiptPayment.getReceiptPaymentAmount() != null) {
+ receiptTotals.merge(receiptPayment.getSalesLedgerId(), receiptPayment.getReceiptPaymentAmount(), BigDecimal::add);
+ }
+ }
+ }
+
+ for (SalesLedger salesLedger : iPage.getRecords()) {
+ Long ledgerId = salesLedger.getId();
+
+ SalesLedgerProductTotalsDto totals = productTotalsMap.get(ledgerId);
+ if (totals != null) {
+ salesLedger.setProductTotalQuantity(totals.getTotalQuantity() != null ? totals.getTotalQuantity() : BigDecimal.ZERO);
+ salesLedger.setProductTotalArea(totals.getTotalArea() != null ? totals.getTotalArea() : BigDecimal.ZERO);
+ } else {
+ salesLedger.setProductTotalQuantity(BigDecimal.ZERO);
+ salesLedger.setProductTotalArea(BigDecimal.ZERO);
+ }
+ if (hasWidthHeightFilter) {
+ salesLedger.setMatchedProducts(matchedProductsMap.getOrDefault(ledgerId, Collections.emptyList()));
+ }
+
+ BigDecimal contractAmount = salesLedger.getContractAmount() == null ? BigDecimal.ZERO : salesLedger.getContractAmount();
+ BigDecimal invoiceTotal = invoiceTotals.getOrDefault(ledgerId, BigDecimal.ZERO);
+ BigDecimal receiptPaymentAmountTotal = receiptTotals.getOrDefault(ledgerId, BigDecimal.ZERO);
+
+ BigDecimal noInvoiceAmountTotal = contractAmount.subtract(invoiceTotal);
+ if (noInvoiceAmountTotal.compareTo(BigDecimal.ZERO) < 0) {
+ noInvoiceAmountTotal = BigDecimal.ZERO;
+ }
+
+ BigDecimal noReceiptPaymentAmountTotal = invoiceTotal.subtract(receiptPaymentAmountTotal);
+ if (noReceiptPaymentAmountTotal.compareTo(BigDecimal.ZERO) < 0) {
+ noReceiptPaymentAmountTotal = BigDecimal.ZERO;
+ }
+
+ salesLedger.setNoInvoiceAmountTotal(noInvoiceAmountTotal);
+ salesLedger.setInvoiceTotal(invoiceTotal);
+ salesLedger.setReceiptPaymentAmountTotal(receiptPaymentAmountTotal);
+ salesLedger.setNoReceiptAmount(noReceiptPaymentAmountTotal);
+
+ boolean hasInvoiceOperation = invoiceTotal.compareTo(BigDecimal.ZERO) > 0;
+ boolean hasReceiptOperation = receiptPaymentAmountTotal.compareTo(BigDecimal.ZERO) > 0;
+ salesLedger.setIsEdit(!(hasInvoiceOperation || hasReceiptOperation));
+ }
+
+ if (salesLedgerDto.getStatus() != null && salesLedgerDto.getStatus()) {
+ iPage.getRecords().removeIf(salesLedger -> Objects.equals(salesLedger.getNoInvoiceAmountTotal(), new BigDecimal("0.00")));
+ iPage.setTotal(iPage.getRecords().size());
+ }
+
+ return iPage;
}
@Override
@@ -451,16 +508,12 @@
throw new ServiceException("瀵煎叆澶辫触,閿�鍞骇鍝佹暟鎹负绌�");
}
// 瀹㈡埛鏁版嵁
- List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>().in(Customer::getCustomerName,
- salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getCustomerName).collect(Collectors.toList())));
+ List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>().in(Customer::getCustomerName, salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getCustomerName).collect(Collectors.toList())));
List<Map<String, Object>> list = productModelMapper.getProductAndModelList();
// 褰曞叆浜烘暟鎹�
- List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getNickName,
- salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getEntryPerson).collect(Collectors.toList())));
+ List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getNickName, salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getEntryPerson).collect(Collectors.toList())));
for (SalesLedgerImportDto salesLedgerImportDto : salesLedgerImportDtoList) {
- SalesLedger salesLedger1 = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
- .eq(SalesLedger::getSalesContractNo, salesLedgerImportDto.getSalesContractNo())
- .last("LIMIT 1"));
+ SalesLedger salesLedger1 = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>().eq(SalesLedger::getSalesContractNo, salesLedgerImportDto.getSalesContractNo()).last("LIMIT 1"));
if (salesLedger1 != null) {
throw new ServiceException("瀵煎叆澶辫触锛氬悎鍚屽彿 [" + salesLedgerImportDto.getSalesContractNo() + "] 宸插瓨鍦紝璇锋鏌ュ悗閲嶆柊瀵煎叆");
}
@@ -476,35 +529,19 @@
salesLedger.setExecutionDate(DateUtils.toLocalDate(salesLedgerImportDto.getExecutionDate()));
LocalDate expectedDeliveryDate = DateUtils.toLocalDate(salesLedgerImportDto.getEntryDate()).plusDays(7);
- LocalDate importDeliveryDate = salesLedgerImportDto.getDeliveryDate() == null
- ? null
- : DateUtils.toLocalDate(salesLedgerImportDto.getDeliveryDate());
+ LocalDate importDeliveryDate = salesLedgerImportDto.getDeliveryDate() == null ? null : DateUtils.toLocalDate(salesLedgerImportDto.getDeliveryDate());
// 浜や粯鏃ユ湡涓虹┖鍒欓粯璁ゅ彇褰曞叆鏃ユ湡鍚�7澶�
salesLedger.setDeliveryDate(importDeliveryDate == null ? expectedDeliveryDate : importDeliveryDate);
// 閫氳繃瀹㈡埛鍚嶇О鏌ヨ瀹㈡埛ID锛屽鎴峰悎鍚屽彿
- salesLedger.setCustomerId(customers.stream()
- .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName()))
- .findFirst()
- .map(Customer::getId)
- .orElse(null));
- salesLedger.setCustomerContractNo(customers.stream()
- .filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName()))
- .findFirst()
- .map(Customer::getTaxpayerIdentificationNumber)
- .orElse(null));
- Long aLong = sysUsers.stream()
- .filter(sysUser -> sysUser.getNickName().equals(salesLedger.getEntryPerson()))
- .findFirst()
- .map(SysUser::getUserId)
- .orElse(null);
+ salesLedger.setCustomerId(customers.stream().filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName())).findFirst().map(Customer::getId).orElse(null));
+ salesLedger.setCustomerContractNo(customers.stream().filter(customer -> customer.getCustomerName().equals(salesLedger.getCustomerName())).findFirst().map(Customer::getTaxpayerIdentificationNumber).orElse(null));
+ Long aLong = sysUsers.stream().filter(sysUser -> sysUser.getNickName().equals(salesLedger.getEntryPerson())).findFirst().map(SysUser::getUserId).orElse(null);
if (aLong == null) {
throw new ServiceException("褰曞叆浜�:" + salesLedger.getEntryPerson() + ",鏃犲搴旂敤鎴凤紒");
}
salesLedger.setEntryPerson(aLong.toString());
// 閿�鍞骇鍝佹暟鎹粦瀹氾紝閫氳繃閿�鍞崟鍙疯幏鍙栧搴旈攢鍞骇鍝佹暟鎹�
- List<SalesLedgerProductImportDto> salesLedgerProductImportDtos = salesLedgerProductImportDtoList.stream()
- .filter(salesLedgerProductImportDto -> salesLedgerProductImportDto.getSalesContractNo().equals(salesLedger.getSalesContractNo()))
- .collect(Collectors.toList());
+ List<SalesLedgerProductImportDto> salesLedgerProductImportDtos = salesLedgerProductImportDtoList.stream().filter(salesLedgerProductImportDto -> salesLedgerProductImportDto.getSalesContractNo().equals(salesLedger.getSalesContractNo())).collect(Collectors.toList());
if (CollectionUtils.isEmpty(salesLedgerProductImportDtos)) {
throw new ServiceException("閿�鍞崟鍙�:" + salesLedgerImportDto.getSalesContractNo() + ",鏃犲搴斾骇鍝佹暟鎹紒");
}
@@ -545,30 +582,21 @@
salesLedgerProduct.setActualPieceArea(actualPieceArea);
salesLedgerProduct.setActualTotalArea(actualPieceArea.multiply(quantity).setScale(4, RoundingMode.HALF_UP));
- BigDecimal settlePieceArea = salesLedgerProduct.getSettlePieceArea() == null
- ? actualPieceArea
- : salesLedgerProduct.getSettlePieceArea();
+ BigDecimal settlePieceArea = salesLedgerProduct.getSettlePieceArea() == null ? actualPieceArea : salesLedgerProduct.getSettlePieceArea();
salesLedgerProduct.setSettlePieceArea(settlePieceArea);
salesLedgerProduct.setSettleTotalArea(settlePieceArea.multiply(quantity).setScale(4, RoundingMode.HALF_UP));
BigDecimal perimeter = BigDecimal.ZERO;
if (width.compareTo(BigDecimal.ZERO) > 0 && height.compareTo(BigDecimal.ZERO) > 0) {
- perimeter = width.add(height)
- .multiply(new BigDecimal("2"))
- .divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
+ perimeter = width.add(height).multiply(new BigDecimal("2")).divide(new BigDecimal("10"), 2, RoundingMode.HALF_UP);
}
salesLedgerProduct.setPerimeter(perimeter);
BigDecimal extraProcessAmountPerPiece = BigDecimal.ZERO;
- list.stream()
- .filter(Objects::nonNull)
- .filter(map -> Objects.equals(Objects.toString(map.get("productName"), null), salesLedgerProduct.getProductCategory())
- && Objects.equals(Objects.toString(map.get("model"), null), salesLedgerProduct.getSpecificationModel()))
- .findFirst()
- .ifPresent(map -> {
- salesLedgerProduct.setProductModelId(Long.parseLong(map.get("modelId").toString()));
- salesLedgerProduct.setProductId(Long.parseLong(map.get("id").toString()));
- });
+ list.stream().filter(Objects::nonNull).filter(map -> Objects.equals(Objects.toString(map.get("productName"), null), salesLedgerProduct.getProductCategory()) && Objects.equals(Objects.toString(map.get("model"), null), salesLedgerProduct.getSpecificationModel())).findFirst().ifPresent(map -> {
+ salesLedgerProduct.setProductModelId(Long.parseLong(map.get("modelId").toString()));
+ salesLedgerProduct.setProductId(Long.parseLong(map.get("id").toString()));
+ });
salesLedgerProduct.setRegister(loginUser.getNickName());
salesLedgerProduct.setRegisterDate(LocalDateTime.now());
salesLedgerProduct.setApproveStatus(0);
@@ -588,19 +616,13 @@
String qtyStr = parts[1].trim();
try {
BigDecimal processQty = new BigDecimal(qtyStr);
- SalesLedgerProductProcess process = salesLedgerProductProcessService.getOne(
- new LambdaQueryWrapper<SalesLedgerProductProcess>()
- .eq(SalesLedgerProductProcess::getProcessName, processName)
- .last("LIMIT 1")
- );
+ SalesLedgerProductProcess process = salesLedgerProductProcessService.getOne(new LambdaQueryWrapper<SalesLedgerProductProcess>().eq(SalesLedgerProductProcess::getProcessName, processName).last("LIMIT 1"));
if (process != null) {
SalesLedgerProductProcess p = new SalesLedgerProductProcess();
p.setId(process.getId());
p.setQuantity(processQty.intValue());
processList.add(p);
- extraProcessAmountPerPiece = extraProcessAmountPerPiece.add(
- defaultDecimal(process.getUnitPrice()).multiply(processQty)
- );
+ extraProcessAmountPerPiece = extraProcessAmountPerPiece.add(defaultDecimal(process.getUnitPrice()).multiply(processQty));
}
} catch (Exception e) {
log.error("瑙f瀽棰濆鍔犲伐鏁伴噺澶辫触: {}", qtyStr);
@@ -611,18 +633,13 @@
}
// 鍚◣鎬讳环 = 鍗曚环 * 缁撶畻闈㈢Н * 鏁伴噺 + 棰濆鍔犲伐閲戦 * 鏁伴噺
- BigDecimal taxInclusiveTotalPrice = unitPrice.multiply(settlePieceArea)
- .multiply(quantity)
- .add(extraProcessAmountPerPiece.multiply(quantity))
- .setScale(2, RoundingMode.HALF_UP);
+ BigDecimal taxInclusiveTotalPrice = unitPrice.multiply(settlePieceArea).multiply(quantity).add(extraProcessAmountPerPiece.multiply(quantity)).setScale(2, RoundingMode.HALF_UP);
salesLedgerProduct.setTaxInclusiveTotalPrice(taxInclusiveTotalPrice);
assertPositive(taxInclusiveTotalPrice, "鍚◣鎬讳环", locate);
// 绋庣巼鍏佽涓虹┖锛岀┖鍊兼寜0澶勭悊
BigDecimal taxDivisor = BigDecimal.ONE.add(taxRate.divide(new BigDecimal("100"), 6, RoundingMode.HALF_UP));
- salesLedgerProduct.setTaxExclusiveTotalPrice(
- taxInclusiveTotalPrice.divide(taxDivisor, 2, RoundingMode.HALF_UP)
- );
+ salesLedgerProduct.setTaxExclusiveTotalPrice(taxInclusiveTotalPrice.divide(taxDivisor, 2, RoundingMode.HALF_UP));
salesLedgerProduct.setNoInvoiceNum(quantity);
salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxExclusiveTotalPrice());
salesLedgerProduct.setPendingInvoiceTotal(taxInclusiveTotalPrice);
@@ -695,10 +712,7 @@
product.setRegister(SecurityUtils.getLoginUser().getUser().getNickName());
product.setRegisterDate(LocalDateTime.now());
// 鍙戣揣淇℃伅
- ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>()
- .eq(ShippingInfo::getSalesLedgerProductId, product.getId())
- .orderByDesc(ShippingInfo::getCreateTime)
- .last("limit 1"));
+ ShippingInfo shippingInfo = shippingInfoMapper.selectOne(new LambdaQueryWrapper<ShippingInfo>().eq(ShippingInfo::getSalesLedgerProductId, product.getId()).orderByDesc(ShippingInfo::getCreateTime).last("limit 1"));
product.setShippingCarNumber(shippingInfo.getShippingCarNumber());
product.setShippingDate(shippingInfo.getShippingDate());
if (shippingInfo != null) {
@@ -775,21 +789,16 @@
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteSalesLedgerByIds(Long[] ids) {
- List<Long> idList = Arrays.stream(ids)
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
+ List<Long> idList = Arrays.stream(ids).filter(Objects::nonNull).collect(Collectors.toList());
if (CollectionUtils.isEmpty(idList)) {
return 0;
}
// 鍒犻櫎閿�鍞鐞嗘暟鎹�
LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList)
- .select(SalesLedgerProduct::getId);
+ queryWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList).select(SalesLedgerProduct::getId);
List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(queryWrapper);
- List<Long> productIds = products.stream()
- .map(SalesLedgerProduct::getId)
- .collect(Collectors.toList());
+ List<Long> productIds = products.stream().map(SalesLedgerProduct::getId).collect(Collectors.toList());
//鍒犻櫎鐢熶骇鏁版嵁
salesLedgerProductServiceImpl.deleteProductionData(productIds);
@@ -825,27 +834,16 @@
receiptPaymentMapper.delete(wrapperTree);
}
// 鍒犻櫎鍙戣揣鍙拌处璁板綍
- List<ShippingInfo> shippingInfos = shippingInfoMapper.selectList(new LambdaQueryWrapper<ShippingInfo>()
- .in(ShippingInfo::getSalesLedgerId, idList));
+ List<ShippingInfo> shippingInfos = shippingInfoMapper.selectList(new LambdaQueryWrapper<ShippingInfo>().in(ShippingInfo::getSalesLedgerId, idList));
if (CollectionUtils.isNotEmpty(shippingInfos)) {
shippingInfoServiceImpl.delete(shippingInfos.stream().map(ShippingInfo::getId).collect(Collectors.toList()));
}
// 鍒犻櫎鍏宠仈鐨勫叆搴�/鍑哄簱璁板綍锛堣蛋鏈嶅姟灞傚垹闄わ紝瑙﹀彂搴撳瓨鏁伴噺鍥為��锛�
- List<Long> stockInRecordIds = stockInRecordMapper.selectList(new LambdaQueryWrapper<StockInRecord>()
- .in(StockInRecord::getSalesLedgerId, idList)
- .select(StockInRecord::getId))
- .stream()
- .map(StockInRecord::getId)
- .collect(Collectors.toList());
+ List<Long> stockInRecordIds = stockInRecordMapper.selectList(new LambdaQueryWrapper<StockInRecord>().in(StockInRecord::getSalesLedgerId, idList).select(StockInRecord::getId)).stream().map(StockInRecord::getId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(stockInRecordIds)) {
stockInRecordService.batchDelete(stockInRecordIds);
}
- List<Long> stockOutRecordIds = stockOutRecordMapper.selectList(new LambdaQueryWrapper<StockOutRecord>()
- .in(StockOutRecord::getSalesLedgerId, idList)
- .select(StockOutRecord::getId))
- .stream()
- .map(StockOutRecord::getId)
- .collect(Collectors.toList());
+ List<Long> stockOutRecordIds = stockOutRecordMapper.selectList(new LambdaQueryWrapper<StockOutRecord>().in(StockOutRecord::getSalesLedgerId, idList).select(StockOutRecord::getId)).stream().map(StockOutRecord::getId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(stockOutRecordIds)) {
stockOutRecordService.batchDelete(stockOutRecordIds);
}
@@ -896,13 +894,7 @@
List<SalesLedgerProduct> productList = salesLedgerDto.getProductData();
if (productList != null && !productList.isEmpty()) {
handleSalesLedgerProducts(salesLedger.getId(), productList, EnumUtil.fromCode(SaleEnum.class, salesLedgerDto.getType()));
- updateMainContractAmount(
- salesLedger.getId(),
- productList,
- SalesLedgerProduct::getTaxInclusiveTotalPrice,
- salesLedgerMapper,
- SalesLedger.class
- );
+ updateMainContractAmount(salesLedger.getId(), productList, SalesLedgerProduct::getTaxInclusiveTotalPrice, salesLedgerMapper, SalesLedger.class);
}
// 5. 杩佺Щ涓存椂鏂囦欢鍒版寮忕洰褰�
@@ -948,10 +940,7 @@
// 鏋勫缓姝e紡鏂囦欢鍚嶏紙鍖呭惈涓氬姟ID鍜屾椂闂存埑锛岄伩鍏嶅啿绐侊級
String originalFilename = tempFile.getOriginalName();
String fileExtension = FilenameUtils.getExtension(originalFilename);
- String formalFilename = businessId + "_" +
- System.currentTimeMillis() + "_" +
- UUID.randomUUID().toString().substring(0, 8) +
- (StringUtils.hasText(fileExtension) ? "." + fileExtension : "");
+ String formalFilename = businessId + "_" + System.currentTimeMillis() + "_" + UUID.randomUUID().toString().substring(0, 8) + (StringUtils.hasText(fileExtension) ? "." + fileExtension : "");
Path formalFilePath = formalDirPath.resolve(formalFilename);
@@ -995,9 +984,7 @@
@Override
public void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, SaleEnum type) {
// 鎸塈D鍒嗙粍锛屽尯鍒嗘柊澧炲拰鏇存柊鐨勮褰�
- Map<Boolean, List<SalesLedgerProduct>> partitionedProducts = products.stream()
- .peek(p -> p.setSalesLedgerId(salesLedgerId))
- .collect(Collectors.partitioningBy(p -> p.getId() != null));
+ Map<Boolean, List<SalesLedgerProduct>> partitionedProducts = products.stream().peek(p -> p.setSalesLedgerId(salesLedgerId)).collect(Collectors.partitioningBy(p -> p.getId() != null));
List<SalesLedgerProduct> updateList = partitionedProducts.get(true);
List<SalesLedgerProduct> insertList = partitionedProducts.get(false);
@@ -1006,7 +993,15 @@
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);
// 娓呯┖閿�鍞骇鍝佺粦瀹氱殑鍔犲伐
@@ -1020,8 +1015,15 @@
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();
+ ProductModel productModel = productModelMapper.selectById(salesLedgerProduct.getProductModelId());
+ if (productModel == null) {
+ throw new ServiceException("鏂板閿�鍞彴璐﹀け璐�,閿�鍞骇鍝佷笉瀛樺湪");
+ }
+ salesLedgerProduct.setUnit(productModel.getUnit());
salesLedgerProductMapper.insert(salesLedgerProduct);
// 缁戝畾浜у搧棰濆鍔犲伐
// 娓呯┖閿�鍞骇鍝佺粦瀹氱殑鍔犲伐
@@ -1030,6 +1032,38 @@
// 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) {
@@ -1084,11 +1118,7 @@
} finally {
// 3. 閲婃斁閿�
String luaScript = "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end";
- redisTemplate.execute(
- new DefaultRedisScript<>(luaScript, Long.class),
- Collections.singletonList(lockKey),
- lockValue
- );
+ redisTemplate.execute(new DefaultRedisScript<>(luaScript, Long.class), Collections.singletonList(lockKey), lockValue);
}
}
@@ -1145,8 +1175,7 @@
dto.setOrderProcessRequirement(salesLedger.getRemarks());
// 鏌ヨ浜у搧鍒楄〃
- List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(
- new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId));
+ List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId));
BigDecimal totalQuantity = BigDecimal.ZERO;
BigDecimal totalArea = BigDecimal.ZERO;
@@ -1156,8 +1185,7 @@
SalesProcessCardDto.ProcessCardItemDto itemDto = new SalesProcessCardDto.ProcessCardItemDto();
itemDto.setFloorCode(p.getFloorCode());
// 缁勮浜у搧鎻忚堪锛氬ぇ绫� + (瑙勬牸)
- String desc = (p.getProductCategory() != null ? p.getProductCategory() : "") +
- (StringUtils.isNotBlank(p.getSpecificationModel()) ? " " + p.getSpecificationModel() : "");
+ String desc = (p.getProductCategory() != null ? p.getProductCategory() : "") + (StringUtils.isNotBlank(p.getSpecificationModel()) ? " " + p.getSpecificationModel() : "");
itemDto.setProductDescription(desc.trim());
itemDto.setWidth(p.getWidth());
itemDto.setHeight(p.getHeight());
@@ -1184,28 +1212,18 @@
dto.setTotalArea(totalArea.setScale(2, RoundingMode.HALF_UP));
// 宸ヨ壓璺嚎
- List<SalesLedgerProcessRoute> salesLedgerProcessRoutes = salesLedgerProcessRouteService.list(
- new LambdaQueryWrapper<SalesLedgerProcessRoute>()
- .eq(SalesLedgerProcessRoute::getSalesLedgerId, salesLedgerId)
- .orderByAsc(SalesLedgerProcessRoute::getDragSort));
+ List<SalesLedgerProcessRoute> salesLedgerProcessRoutes = salesLedgerProcessRouteService.list(new LambdaQueryWrapper<SalesLedgerProcessRoute>().eq(SalesLedgerProcessRoute::getSalesLedgerId, salesLedgerId).orderByAsc(SalesLedgerProcessRoute::getDragSort));
List<SalesProcessCardDto.ProcessNodeDto> nodeDtos = new ArrayList<>();
if (CollectionUtils.isEmpty(salesLedgerProcessRoutes)) {
// 鏃犺嚜瀹氫箟璺嚎锛氬厛鏌ヨ榛樿宸ヨ壓璺嚎锛涜嫢鏃犻粯璁わ紝鑾峰彇鍒涘缓鏃堕棿鏈�杩戠殑涓�鏉�
- ProcessRoute fallbackRoute = processRouteMapper.selectOne(
- new LambdaQueryWrapper<ProcessRoute>().eq(ProcessRoute::getIsDefault, 1).last("LIMIT 1"));
+ ProcessRoute fallbackRoute = processRouteMapper.selectOne(new LambdaQueryWrapper<ProcessRoute>().eq(ProcessRoute::getIsDefault, 1).last("LIMIT 1"));
if (fallbackRoute == null) {
- fallbackRoute = processRouteMapper.selectOne(
- new LambdaQueryWrapper<ProcessRoute>()
- .orderByDesc(ProcessRoute::getCreateTime)
- .last("LIMIT 1"));
+ fallbackRoute = processRouteMapper.selectOne(new LambdaQueryWrapper<ProcessRoute>().orderByDesc(ProcessRoute::getCreateTime).last("LIMIT 1"));
}
if (fallbackRoute != null) {
- List<ProcessRouteItem> routeItems = processRouteItemMapper.selectList(
- new LambdaQueryWrapper<ProcessRouteItem>()
- .eq(ProcessRouteItem::getRouteId, fallbackRoute.getId())
- .orderByAsc(ProcessRouteItem::getDragSort));
+ List<ProcessRouteItem> routeItems = processRouteItemMapper.selectList(new LambdaQueryWrapper<ProcessRouteItem>().eq(ProcessRouteItem::getRouteId, fallbackRoute.getId()).orderByAsc(ProcessRouteItem::getDragSort));
for (ProcessRouteItem i : routeItems) {
SalesProcessCardDto.ProcessNodeDto node = new SalesProcessCardDto.ProcessNodeDto();
node.setProcessRouteItemId(i.getId());
@@ -1216,12 +1234,9 @@
}
} else {
// 浣跨敤鑷畾涔夎矾绾跨粦瀹氱殑鑺傜偣
- List<Long> itemIds = salesLedgerProcessRoutes.stream()
- .map(SalesLedgerProcessRoute::getProcessRouteItemId)
- .collect(Collectors.toList());
+ List<Long> itemIds = salesLedgerProcessRoutes.stream().map(SalesLedgerProcessRoute::getProcessRouteItemId).collect(Collectors.toList());
List<ProcessRouteItem> rawItems = processRouteItemMapper.selectBatchIds(itemIds);
- Map<Long, ProcessRouteItem> itemMap = rawItems.stream()
- .collect(Collectors.toMap(ProcessRouteItem::getId, i -> i, (a, b) -> a));
+ Map<Long, ProcessRouteItem> itemMap = rawItems.stream().collect(Collectors.toMap(ProcessRouteItem::getId, i -> i, (a, b) -> a));
for (SalesLedgerProcessRoute r : salesLedgerProcessRoutes) {
ProcessRouteItem pi = itemMap.get(r.getProcessRouteItemId());
@@ -1238,14 +1253,9 @@
if (!nodeDtos.isEmpty()) {
// dragSort 杩涜鍗囧簭鎺掑簭
- nodeDtos.sort(Comparator.comparing(
- SalesProcessCardDto.ProcessNodeDto::getDragSort,
- Comparator.nullsLast(Comparator.naturalOrder())
- ));
+ nodeDtos.sort(Comparator.comparing(SalesProcessCardDto.ProcessNodeDto::getDragSort, Comparator.nullsLast(Comparator.naturalOrder())));
// 閲嶆柊鐢熸垚鎺掑簭鍚庣殑璺緞鍚嶇О鍒楄〃
- List<String> sortedPathNames = nodeDtos.stream()
- .map(SalesProcessCardDto.ProcessNodeDto::getProcessRouteItemName)
- .collect(Collectors.toList());
+ List<String> sortedPathNames = nodeDtos.stream().map(SalesProcessCardDto.ProcessNodeDto::getProcessRouteItemName).collect(Collectors.toList());
// 鎷兼帴瀛楃涓�
dto.setProcessPathDisplay(String.join(" -> ", sortedPathNames));
// 璁剧疆椤跺眰鑺傜偣鐨勫伐鑹鸿矾绾�
@@ -1315,8 +1325,7 @@
dto.setPrintTime(LocalDateTime.now());
// 鏌ヨ浜у搧鍒楄〃
- List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(
- new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId));
+ List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId));
if (CollectionUtils.isNotEmpty(products)) {
SalesLedgerProduct firstProduct = products.get(0);
@@ -1331,8 +1340,7 @@
for (SalesLedgerProduct p : products) {
SalesOrdersDto.SalesOrderItemDto itemDto = new SalesOrdersDto.SalesOrderItemDto();
itemDto.setFloorCode(p.getFloorCode());
- String desc = (p.getProductCategory() != null ? p.getProductCategory() : "") +
- (StringUtils.isNotBlank(p.getSpecificationModel()) ? " " + p.getSpecificationModel() : "");
+ String desc = (p.getProductCategory() != null ? p.getProductCategory() : "") + (StringUtils.isNotBlank(p.getSpecificationModel()) ? " " + p.getSpecificationModel() : "");
itemDto.setProductDescription(desc.trim());
itemDto.setWidth(p.getWidth());
itemDto.setHeight(p.getHeight());
@@ -1364,13 +1372,10 @@
List<Long> productIds = products.stream().map(SalesLedgerProduct::getId).collect(Collectors.toList());
BigDecimal otherFeesTotal = BigDecimal.ZERO;
if (CollectionUtils.isNotEmpty(productIds)) {
- List<SalesLedgerProductProcessBind> binds = salesLedgerProductProcessBindService.list(
- new LambdaQueryWrapper<SalesLedgerProductProcessBind>().in(SalesLedgerProductProcessBind::getSalesLedgerProductId, productIds));
+ List<SalesLedgerProductProcessBind> binds = salesLedgerProductProcessBindService.list(new LambdaQueryWrapper<SalesLedgerProductProcessBind>().in(SalesLedgerProductProcessBind::getSalesLedgerProductId, productIds));
if (CollectionUtils.isNotEmpty(binds)) {
- Map<Integer, Integer> processQuantityMap = binds.stream()
- .collect(Collectors.groupingBy(SalesLedgerProductProcessBind::getSalesLedgerProductProcessId,
- Collectors.summingInt(b -> b.getQuantity() != null ? b.getQuantity() : 0)));
+ Map<Integer, Integer> processQuantityMap = binds.stream().collect(Collectors.groupingBy(SalesLedgerProductProcessBind::getSalesLedgerProductProcessId, Collectors.summingInt(b -> b.getQuantity() != null ? b.getQuantity() : 0)));
List<Integer> processIds = new ArrayList<>(processQuantityMap.keySet());
List<SalesLedgerProductProcess> processes = salesLedgerProductProcessService.listByIds(processIds);
@@ -1452,59 +1457,84 @@
// dto.setExternalOrderNo(ledgers.get(0).getCustomerContractNo());
// 鏌ヨ鎵�鏈変骇鍝�
- List<SalesLedgerProduct> allProducts = salesLedgerProductMapper.selectList(
- new LambdaQueryWrapper<SalesLedgerProduct>().in(SalesLedgerProduct::getSalesLedgerId, salesLedgerIds));
+ List<SalesLedgerProduct> allProducts = salesLedgerProductMapper.selectList(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);
- }
+ Map<Long, SalesLedger> ledgerMap = ledgers.stream().collect(Collectors.toMap(SalesLedger::getId, Function.identity()));
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);
+ group.setSpecificationModel(specificationModel);
- 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);
@@ -1537,8 +1567,7 @@
}
// 鏌ヨ浜у搧鍒楄〃
- List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(
- new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId));
+ List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId));
// 鏌ヨ瀹㈡埛鍦板潃
String fullAddress = "";
@@ -1565,12 +1594,10 @@
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") + "*" +
- (p.getHeight() != null ? p.getHeight().stripTrailingZeros().toPlainString() : "0") + "=" +
- (p.getQuantity() != null ? p.getQuantity().stripTrailingZeros().toPlainString() : "0");
+ String specification = (p.getWidth() != null ? p.getWidth().stripTrailingZeros().toPlainString() : "0") + "*" + (p.getHeight() != null ? p.getHeight().stripTrailingZeros().toPlainString() : "0") + "=" + (p.getQuantity() != null ? p.getQuantity().stripTrailingZeros().toPlainString() : "0");
dto.setSpecification(specification);
// 瀹㈡埛鍦板潃 + 妤煎眰缂栧彿
@@ -1599,22 +1626,14 @@
return next;
}
- public <T, S> void updateMainContractAmount(
- Long mainId,
- List<T> subList,
- Function<T, BigDecimal> amountGetter,
- BaseMapper<S> mainMapper,
- Class<S> mainEntityClass) {
+ public <T, S> void updateMainContractAmount(Long mainId, List<T> subList, Function<T, BigDecimal> amountGetter, BaseMapper<S> mainMapper, Class<S> mainEntityClass) {
if (mainId == null || subList == null || subList.isEmpty()) {
return;
}
// 璁$畻瀛愯〃閲戦鎬诲拰
- BigDecimal totalAmount = subList.stream()
- .map(amountGetter)
- .filter(Objects::nonNull)
- .reduce(BigDecimal.ZERO, BigDecimal::add);
+ BigDecimal totalAmount = subList.stream().map(amountGetter).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
// 鏋勯�犱富琛ㄦ洿鏂板璞�
try {
@@ -1677,6 +1696,9 @@
if (ledger.getStockStatus() == null) {
throw new ServiceException("鍏ュ簱澶辫触,閿�鍞鍗曞叆搴撶姸鎬佸紓甯�");
}
+ if (ledger.getStockStatus() == 3) {
+ throw new ServiceException("鍏ュ簱澶辫触,璇ラ攢鍞鍗曟鍦ㄥ叆搴撳鎵逛腑,璇峰嬁閲嶅鎻愪氦");
+ }
if (ledger.getStockStatus() == 2) {
throw new ServiceException("鍏ュ簱澶辫触,璇ラ攢鍞鍗曞凡鍏ュ簱,璇峰嬁閲嶅鍏ュ簱");
}
@@ -1689,6 +1711,42 @@
if (salesLedgerProducts == null || salesLedgerProducts.isEmpty()) {
throw new ServiceException("鍏ュ簱澶辫触,鏈煡璇㈠埌璇ラ攢鍞鍗曠殑閿�鍞骇鍝�");
}
+ String approveUserIds = resolveApproveUserIds(dto.getApproveUserIds(), ledger.getId(), INBOUND_BIZ_TYPE_WEB);
+ if (StringUtils.isEmpty(approveUserIds)) {
+ throw new ServiceException("鍏ュ簱澶辫触,璇烽�夋嫨瀹℃壒浜�");
+ }
+
+ String productIds = products.stream().map(String::valueOf).collect(Collectors.joining(","));
+ LoginUser loginUser = SecurityUtils.getLoginUser();
+ ApproveProcessVO approveProcessVO = new ApproveProcessVO();
+ approveProcessVO.setApproveType(ApproveTypeEnum.STOCK_IN.getCode());
+ approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
+ approveProcessVO.setApproveReason("鍏ュ簱瀹℃壒:" + ledger.getSalesContractNo());
+ approveProcessVO.setApproveRemark("salesStock:" + ledger.getId() + ":" + productIds);
+ approveProcessVO.setApproveUserIds(approveUserIds);
+ approveProcessVO.setApproveUser(loginUser.getUserId());
+ approveProcessVO.setApproveTime(LocalDate.now().toString());
+ try {
+ approveProcessService.addApprove(approveProcessVO);
+ } catch (Exception e) {
+ throw new ServiceException("鍏ュ簱瀹℃壒鍙戣捣澶辫触:" + e.getMessage());
+ }
+ // 瀹℃壒涓�
+ ledger.setStockStatus(3);
+ baseMapper.updateById(ledger);
+ }
+
+ @Override
+ public void executeSalesStockApproved(Long salesLedgerId, List<Long> products) {
+ SalesProductStockDto dto = new SalesProductStockDto();
+ dto.setSalesLedgerId(salesLedgerId);
+ dto.setSalesLedgerProducts(products);
+
+ SalesLedger ledger = baseMapper.selectById(dto.getSalesLedgerId());
+ if (ledger == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,閿�鍞鍗曚笉瀛樺湪");
+ }
+ List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(Wrappers.<SalesLedgerProduct>lambdaQuery().in(SalesLedgerProduct::getId, products));
for (SalesLedgerProduct product : salesLedgerProducts) {
if (!Objects.equals(product.getSalesLedgerId(), ledger.getId())) {
throw new ServiceException("鍏ュ簱澶辫触,瀛樺湪涓嶅睘浜庡綋鍓嶉攢鍞鍗曠殑浜у搧");
@@ -1745,19 +1803,12 @@
@Override
public List<Customer> shippedCustomers() {
- List<SalesLedger> ledgers = list(Wrappers.<SalesLedger>lambdaQuery()
- .eq(SalesLedger::getDeliveryStatus, 5)
- .isNotNull(SalesLedger::getCustomerId)
- .select(SalesLedger::getCustomerId));
+ List<SalesLedger> ledgers = list(Wrappers.<SalesLedger>lambdaQuery().eq(SalesLedger::getDeliveryStatus, 5).isNotNull(SalesLedger::getCustomerId).select(SalesLedger::getCustomerId));
if (CollectionUtils.isEmpty(ledgers)) {
return Collections.emptyList();
}
- Set<Long> customerIds = ledgers.stream()
- .map(SalesLedger::getCustomerId)
- .collect(Collectors.toCollection(LinkedHashSet::new));
- return customerMapper.selectList(Wrappers.<Customer>lambdaQuery()
- .in(Customer::getId, customerIds)
- .orderByAsc(Customer::getCustomerName));
+ Set<Long> customerIds = ledgers.stream().map(SalesLedger::getCustomerId).collect(Collectors.toCollection(LinkedHashSet::new));
+ return customerMapper.selectList(Wrappers.<Customer>lambdaQuery().in(Customer::getId, customerIds).orderByAsc(Customer::getCustomerName));
}
@Override
@@ -1798,11 +1849,63 @@
}
inboundQtyByLineId.merge(inbound.getId(), inboundQty, BigDecimal::add);
}
+ List<SalesLedgerProduct> selectedProducts = salesLedgerProductMapper.selectList(Wrappers.<SalesLedgerProduct>lambdaQuery().in(SalesLedgerProduct::getId, inboundQtyByLineId.keySet()));
+ if (CollectionUtils.isEmpty(selectedProducts)) {
+ throw new ServiceException("鍏ュ簱澶辫触,鏈煡璇㈠埌鍏ュ簱浜у搧");
+ }
+ if (selectedProducts.size() != inboundQtyByLineId.size()) {
+ throw new ServiceException("鍏ュ簱澶辫触,閮ㄥ垎浜у搧涓嶅瓨鍦�");
+ }
+ for (SalesLedgerProduct selectedProduct : selectedProducts) {
+ if (!Objects.equals(selectedProduct.getSalesLedgerId(), salesLedger.getId())) {
+ throw new ServiceException("鍏ュ簱澶辫触,閿�鍞骇鍝佷笌璁㈠崟涓嶅尮閰�");
+ }
+ if (!Objects.equals(selectedProduct.getType(), SaleEnum.SALE.getCode())) {
+ throw new ServiceException("鍏ュ簱澶辫触,浠呮敮鎸侀攢鍞鍗曚骇鍝佽");
+ }
+ if (selectedProduct.getProductModelId() == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍏ュ簱");
+ }
+ }
+ String approveUserIds = resolveApproveUserIds(dto.getApproveUserIds(), salesLedger.getId(), INBOUND_BIZ_TYPE_SCAN_QUALIFIED);
+ if (StringUtils.isEmpty(approveUserIds)) {
+ throw new ServiceException("鍏ュ簱澶辫触,璇烽�夋嫨瀹℃壒浜�");
+ }
+ String lines = inboundQtyByLineId.entrySet().stream().map(e -> e.getKey() + "@" + e.getValue().stripTrailingZeros().toPlainString()).collect(Collectors.joining(","));
+ String reason = "閿�鍞壂鐮佸悎鏍煎叆搴撳鎵�:" + salesLedger.getSalesContractNo();
+ String remark = "scanQualified:" + salesLedger.getId() + ":" + lines;
+ ApproveProcess exist = approveProcessService.getOne(new LambdaQueryWrapper<ApproveProcess>().eq(ApproveProcess::getApproveType, ApproveTypeEnum.STOCK_IN.getCode()).eq(ApproveProcess::getApproveRemark, remark).eq(ApproveProcess::getApproveDelete, 0).orderByDesc(ApproveProcess::getCreateTime).last("limit 1"));
+ if (exist != null && !Objects.equals(exist.getApproveStatus(), 3)) {
+ throw new ServiceException("鍏ュ簱澶辫触,璇ョ敵璇峰凡鎻愪氦瀹℃壒");
+ }
+ LoginUser loginUser = SecurityUtils.getLoginUser();
+ ApproveProcessVO approveProcessVO = new ApproveProcessVO();
+ approveProcessVO.setApproveType(ApproveTypeEnum.STOCK_IN.getCode());
+ approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
+ approveProcessVO.setApproveReason(reason);
+ approveProcessVO.setApproveRemark(remark);
+ approveProcessVO.setApproveUserIds(approveUserIds);
+ approveProcessVO.setApproveUser(loginUser.getUserId());
+ approveProcessVO.setApproveTime(LocalDate.now().toString());
+ try {
+ approveProcessService.addApprove(approveProcessVO);
+ } catch (Exception e) {
+ throw new ServiceException("鍏ュ簱瀹℃壒鍙戣捣澶辫触:" + e.getMessage());
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void executeSalesScanInboundApproved(Long salesLedgerId, Map<Long, BigDecimal> inboundQtyByLineId) {
+ SalesLedger salesLedger = baseMapper.selectById(salesLedgerId);
+ if (salesLedger == null) {
+ throw new ServiceException("鍏ュ簱澶辫触,閿�鍞鍗曚笉瀛樺湪");
+ }
Long ledgerId = salesLedger.getId();
for (Map.Entry<Long, BigDecimal> entry : inboundQtyByLineId.entrySet()) {
Long salesLedgerProductId = entry.getKey();
BigDecimal inboundThisLine = entry.getValue();
- if (inboundThisLine.compareTo(BigDecimal.ZERO) == 0) {
+ if (inboundThisLine == null || inboundThisLine.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(salesLedgerProductId);
@@ -1844,8 +1947,7 @@
dbProduct.fillRemainingQuantity();
salesLedgerProductMapper.updateById(dbProduct);
}
- List<SalesLedgerProduct> ledgerAllProducts = salesLedgerProductMapper.selectList(
- Wrappers.<SalesLedgerProduct>lambdaQuery().eq(SalesLedgerProduct::getSalesLedgerId, ledgerId));
+ List<SalesLedgerProduct> ledgerAllProducts = salesLedgerProductMapper.selectList(Wrappers.<SalesLedgerProduct>lambdaQuery().eq(SalesLedgerProduct::getSalesLedgerId, ledgerId));
boolean anyInbound = ledgerAllProducts.stream().anyMatch(p -> {
BigDecimal sq = p.getStockedQuantity();
return sq != null && sq.compareTo(BigDecimal.ZERO) > 0;
@@ -1885,11 +1987,63 @@
}
inboundQtyByLineId.merge(inbound.getId(), inboundQty, BigDecimal::add);
}
+ List<SalesLedgerProduct> selectedProducts = salesLedgerProductMapper.selectList(Wrappers.<SalesLedgerProduct>lambdaQuery().in(SalesLedgerProduct::getId, inboundQtyByLineId.keySet()));
+ if (CollectionUtils.isEmpty(selectedProducts)) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,鏈煡璇㈠埌鍏ュ簱浜у搧");
+ }
+ if (selectedProducts.size() != inboundQtyByLineId.size()) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,閮ㄥ垎浜у搧涓嶅瓨鍦�");
+ }
+ for (SalesLedgerProduct selectedProduct : selectedProducts) {
+ if (!Objects.equals(selectedProduct.getSalesLedgerId(), salesLedger.getId())) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,閿�鍞骇鍝佷笌璁㈠崟涓嶅尮閰�");
+ }
+ if (!Objects.equals(selectedProduct.getType(), SaleEnum.SALE.getCode())) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,浠呮敮鎸侀攢鍞鍗曚骇鍝佽");
+ }
+ if (selectedProduct.getProductModelId() == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍏ュ簱");
+ }
+ }
+ String approveUserIds = resolveApproveUserIds(dto.getApproveUserIds(), salesLedger.getId(), INBOUND_BIZ_TYPE_SCAN_UNQUALIFIED);
+ if (StringUtils.isEmpty(approveUserIds)) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,璇烽�夋嫨瀹℃壒浜�");
+ }
+ String lines = inboundQtyByLineId.entrySet().stream().map(e -> e.getKey() + "@" + e.getValue().stripTrailingZeros().toPlainString()).collect(Collectors.joining(","));
+ String reason = "閿�鍞壂鐮佷笉鍚堟牸鍏ュ簱瀹℃壒:" + salesLedger.getSalesContractNo();
+ String remark = "scanUnqualified:" + salesLedger.getId() + ":" + lines;
+ ApproveProcess exist = approveProcessService.getOne(new LambdaQueryWrapper<ApproveProcess>().eq(ApproveProcess::getApproveType, ApproveTypeEnum.STOCK_IN.getCode()).eq(ApproveProcess::getApproveRemark, remark).eq(ApproveProcess::getApproveDelete, 0).orderByDesc(ApproveProcess::getCreateTime).last("limit 1"));
+ if (exist != null && !Objects.equals(exist.getApproveStatus(), 3)) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,璇ョ敵璇峰凡鎻愪氦瀹℃壒");
+ }
+ LoginUser loginUser = SecurityUtils.getLoginUser();
+ ApproveProcessVO approveProcessVO = new ApproveProcessVO();
+ approveProcessVO.setApproveType(ApproveTypeEnum.STOCK_IN.getCode());
+ approveProcessVO.setApproveDeptId(loginUser.getCurrentDeptId());
+ approveProcessVO.setApproveReason(reason);
+ approveProcessVO.setApproveRemark(remark);
+ approveProcessVO.setApproveUserIds(approveUserIds);
+ approveProcessVO.setApproveUser(loginUser.getUserId());
+ approveProcessVO.setApproveTime(LocalDate.now().toString());
+ try {
+ approveProcessService.addApprove(approveProcessVO);
+ } catch (Exception e) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳鎵瑰彂璧峰け璐�:" + e.getMessage());
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void executeSalesScanInboundUnqualifiedApproved(Long salesLedgerId, Map<Long, BigDecimal> inboundQtyByLineId) {
+ SalesLedger salesLedger = baseMapper.selectById(salesLedgerId);
+ if (salesLedger == null) {
+ throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,閿�鍞鍗曚笉瀛樺湪");
+ }
Long ledgerId = salesLedger.getId();
for (Map.Entry<Long, BigDecimal> entry : inboundQtyByLineId.entrySet()) {
Long salesLedgerProductId = entry.getKey();
BigDecimal inboundThisLine = entry.getValue();
- if (inboundThisLine.compareTo(BigDecimal.ZERO) == 0) {
+ if (inboundThisLine == null || inboundThisLine.compareTo(BigDecimal.ZERO) <= 0) {
continue;
}
SalesLedgerProduct dbProduct = salesLedgerProductMapper.selectById(salesLedgerProductId);
@@ -1905,14 +2059,30 @@
if (dbProduct.getProductModelId() == null) {
throw new ServiceException("涓嶅悎鏍煎叆搴撳け璐�,浜у搧瑙勬牸鏈淮鎶�,鏃犳硶鍏ュ簱");
}
- stockUtils.addUnStock(ledgerId, dbProduct.getId(), dbProduct.getProductModelId(), inboundThisLine,
- StockInUnQualifiedRecordTypeEnum.SALES_SCAN_UNSTOCK_IN.getCode(), dbProduct.getId());
-
+ 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);
}
+ }
+
+ private String resolveApproveUserIds(String approveUserIds, Long salesLedgerId, Integer bizType) {
+ if (StringUtils.isNotEmpty(approveUserIds)) {
+ return approveUserIds;
+ }
+ LambdaQueryWrapper<ApproveProcess> wrapper = new LambdaQueryWrapper<ApproveProcess>().eq(ApproveProcess::getApproveType, ApproveTypeEnum.STOCK_IN.getCode()).eq(ApproveProcess::getApproveDelete, 0).orderByDesc(ApproveProcess::getCreateTime).last("limit 1");
+ if (Objects.equals(bizType, INBOUND_BIZ_TYPE_WEB)) {
+ wrapper.likeRight(ApproveProcess::getApproveReason, "鍏ュ簱瀹℃壒:").likeRight(ApproveProcess::getApproveRemark, "salesStock:" + salesLedgerId + ":");
+ } else if (Objects.equals(bizType, INBOUND_BIZ_TYPE_SCAN_QUALIFIED)) {
+ wrapper.likeRight(ApproveProcess::getApproveReason, "閿�鍞壂鐮佸悎鏍煎叆搴撳鎵�:").likeRight(ApproveProcess::getApproveRemark, "scanQualified:" + salesLedgerId + ":");
+ } else if (Objects.equals(bizType, INBOUND_BIZ_TYPE_SCAN_UNQUALIFIED)) {
+ wrapper.likeRight(ApproveProcess::getApproveReason, "閿�鍞壂鐮佷笉鍚堟牸鍏ュ簱瀹℃壒:").likeRight(ApproveProcess::getApproveRemark, "scanUnqualified:" + salesLedgerId + ":");
+ } else {
+ return null;
+ }
+ ApproveProcess latest = approveProcessService.getOne(wrapper);
+ return latest == null ? null : latest.getApproveUserIds();
}
@Override
@@ -1979,8 +2149,7 @@
dbProduct.fillRemainingQuantity();
salesLedgerProductMapper.updateById(dbProduct);
}
- List<SalesLedgerProduct> ledgerAllProducts = salesLedgerProductMapper.selectList(
- Wrappers.<SalesLedgerProduct>lambdaQuery().eq(SalesLedgerProduct::getSalesLedgerId, ledgerId));
+ List<SalesLedgerProduct> ledgerAllProducts = salesLedgerProductMapper.selectList(Wrappers.<SalesLedgerProduct>lambdaQuery().eq(SalesLedgerProduct::getSalesLedgerId, ledgerId));
boolean anyInbound = ledgerAllProducts.stream().anyMatch(p -> {
BigDecimal sq = p.getStockedQuantity();
return sq != null && sq.compareTo(BigDecimal.ZERO) > 0;
@@ -2045,12 +2214,585 @@
throw new ServiceException("涓嶅悎鏍煎嚭搴撳け璐�,鍑哄簱鏁伴噺涓嶈兘澶т簬涓嶅悎鏍煎叆搴撴暟閲�");
}
stockUtils.assertUnqualifiedAvailable(dbProduct.getProductModelId(), outboundThisLine);
- stockUtils.subtractUnStock(ledgerId, dbProduct.getId(), dbProduct.getProductModelId(), outboundThisLine,
- StockOutUnQualifiedRecordTypeEnum.SALE_SCAN_UNSTOCK_OUT.getCode(), dbProduct.getId());
+ 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);
}
}
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void shippingImport(MultipartFile file) {
+ if (file == null || file.isEmpty()) {
+ throw new ServiceException("瀵煎叆澶辫触,瀵煎叆鏂囦欢鏁版嵁涓嶈兘涓虹┖");
+ }
+ List<SalesShippingImportDto> list;
+ try {
+ ExcelUtil<SalesShippingImportDto> excelUtil = new ExcelUtil<>(SalesShippingImportDto.class);
+ list = excelUtil.importExcel(file.getInputStream());
+ } catch (Exception e) {
+ log.error("閿�鍞彂璐у巻鍙叉暟鎹鍏�-宸插彂璐у鍏ュけ璐�: {}", e.getMessage());
+ throw new ServiceException("瀵煎叆澶辫触,鏁版嵁璇诲彇寮傚父");
+ }
+ if (CollectionUtils.isEmpty(list)) {
+ throw new ServiceException("瀵煎叆澶辫触,鏂囦欢鏁版嵁涓虹┖");
+ }
+ Map<String, List<SalesShippingImportDto>> groupedByOrderNo = list.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(SalesShippingImportDto::getOrderNo, LinkedHashMap::new, Collectors.toList()));
+
+ for (Map.Entry<String, List<SalesShippingImportDto>> entry : groupedByOrderNo.entrySet()) {
+ String orderNo = entry.getKey();
+ if (!StringUtils.hasText(orderNo)) {
+ throw new ServiceException("瀵煎叆澶辫触,瀛樺湪璁㈠崟缂栧彿涓虹┖鐨勬暟鎹�");
+ }
+ List<SalesShippingImportDto> rowList = entry.getValue();
+ if (CollectionUtils.isEmpty(rowList)) {
+ continue;
+ }
+ SalesLedger ledger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>().eq(SalesLedger::getSalesContractNo, orderNo).last("LIMIT 1"));
+ if (ledger == null) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]涓嶅瓨鍦�,鏃犳硶琛ュ綍宸插彂璐ф暟鎹�");
+ }
+ List<SalesLedgerProduct> dbProducts = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, ledger.getId()).eq(SalesLedgerProduct::getType, SaleEnum.SALE.getCode()));
+ if (CollectionUtils.isEmpty(dbProducts)) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]娌℃湁閿�鍞骇鍝�,鏃犳硶琛ュ綍鍙戣揣");
+ }
+ Map<String, List<SalesLedgerProduct>> productByCategory = dbProducts.stream().collect(Collectors.groupingBy(p -> StringUtils.hasText(p.getProductCategory()) ? p.getProductCategory().trim() : ""));
+ Set<String> importedRowKeys = new HashSet<>();
+
+ for (SalesShippingImportDto row : rowList) {
+ BigDecimal shipQty = defaultDecimal(row.getQuantity());
+ if (shipQty.compareTo(BigDecimal.ZERO) <= 0) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]瀛樺湪鏁伴噺灏忎簬绛変簬0鐨勬暟鎹�");
+ }
+ String rowKey = buildShippingRowKey(ledger.getId(), row);
+ if (!importedRowKeys.add(rowKey)) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]瀛樺湪閲嶅鍙戣揣鏄庣粏琛�");
+ }
+ Map<SalesLedgerProduct, BigDecimal> allocations = allocateShippingProductLines(orderNo, row, productByCategory, dbProducts);
+ for (Map.Entry<SalesLedgerProduct, BigDecimal> alloc : allocations.entrySet()) {
+ SalesLedgerProduct dbProduct = alloc.getKey();
+ BigDecimal allocQty = alloc.getValue();
+ if (dbProduct.getProductModelId() == null) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]浜у搧瑙勬牸鏈淮鎶�,鏃犳硶琛ュ綍鍑哄簱");
+ }
+ BigDecimal oldShipped = defaultDecimal(dbProduct.getShippedQuantity());
+ BigDecimal newShipped = oldShipped.add(allocQty);
+ dbProduct.setStockedQuantity(defaultDecimal(dbProduct.getQuantity()));
+ dbProduct.setShippedQuantity(newShipped);
+ updateProductStockStatus(dbProduct);
+ dbProduct.fillRemainingQuantity();
+ updateProductShipStatus(dbProduct);
+ salesLedgerProductMapper.updateById(dbProduct);
+
+ ShippingInfo shippingInfo = new ShippingInfo();
+ shippingInfo.setSalesLedgerId(ledger.getId());
+ shippingInfo.setSalesLedgerProductId(dbProduct.getId());
+ shippingInfo.setStatus("宸插彂璐�");
+ shippingInfo.setShippingNo(row.getShippingNo());
+ shippingInfo.setType("璐ц溅");
+ shippingInfo.setShippingCarNumber("鏃�");
+ shippingInfo.setShippingDate(row.getReportDate());
+ long existedShippingCount = shippingInfoMapper.selectCount(new LambdaQueryWrapper<ShippingInfo>().eq(ShippingInfo::getSalesLedgerId, ledger.getId()).eq(ShippingInfo::getSalesLedgerProductId, dbProduct.getId()).eq(StringUtils.hasText(row.getShippingNo()), ShippingInfo::getShippingNo, row.getShippingNo()).eq(row.getReportDate() != null, ShippingInfo::getShippingDate, row.getReportDate()));
+ if (existedShippingCount > 0) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]瀛樺湪閲嶅鍙戣揣璁板綍,璇峰嬁閲嶅瀵煎叆");
+ }
+ shippingInfoMapper.insert(shippingInfo);
+ }
+ }
+
+ List<SalesLedgerProduct> latestProducts = salesLedgerProductMapper.selectList(new LambdaQueryWrapper<SalesLedgerProduct>().eq(SalesLedgerProduct::getSalesLedgerId, ledger.getId()).eq(SalesLedgerProduct::getType, SaleEnum.SALE.getCode()));
+ boolean allShipped = CollectionUtils.isNotEmpty(latestProducts) && latestProducts.stream().allMatch(p -> {
+ BigDecimal qty = defaultDecimal(p.getQuantity());
+ BigDecimal shipped = defaultDecimal(p.getShippedQuantity());
+ return shipped.compareTo(qty) >= 0;
+ });
+ if (allShipped && rowList.get(0).getReportDate() != null) {
+ ledger.setDeliveryDate(DateUtils.toLocalDate(rowList.get(0).getReportDate()));
+ }
+ ledger.setDeliveryStatus(allShipped ? 5 : 1);
+ salesLedgerMapper.updateById(ledger);
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void notShippingImport(MultipartFile file) {
+ if (file == null || file.isEmpty()) {
+ throw new ServiceException("瀵煎叆澶辫触,瀵煎叆鏂囦欢鏁版嵁涓嶈兘涓虹┖");
+ }
+ List<SalesNotShippingImportDto> list;
+ try {
+ ExcelUtil<SalesNotShippingImportDto> excelUtil = new ExcelUtil<>(SalesNotShippingImportDto.class);
+ list = excelUtil.importExcel(file.getInputStream());
+ } catch (Exception e) {
+ log.error("閿�鍞彂璐у巻鍙叉暟鎹鍏�-鏈彂璐у鍏ュけ璐�: {}", e.getMessage());
+ throw new ServiceException("瀵煎叆澶辫触,鏁版嵁璇诲彇寮傚父");
+ }
+ if (CollectionUtils.isEmpty(list)) {
+ throw new ServiceException("瀵煎叆澶辫触,鏂囦欢鏁版嵁涓虹┖");
+ }
+ List<SysUser> allUsers = sysUserMapper.selectList(null);
+ Map<String, SysUser> userByNickNameMap = allUsers.stream().filter(Objects::nonNull).filter(u -> StringUtils.hasText(u.getNickName())).collect(Collectors.toMap(SysUser::getNickName, Function.identity(), (a, b) -> a));
+ Map<String, SysUser> userByUserNameMap = allUsers.stream().filter(Objects::nonNull).filter(u -> StringUtils.hasText(u.getUserName())).collect(Collectors.toMap(SysUser::getUserName, Function.identity(), (a, b) -> a));
+
+ Map<String, Customer> customerNameMap = customerMapper.selectList(null).stream().filter(Objects::nonNull).filter(c -> StringUtils.hasText(c.getCustomerName())).collect(Collectors.toMap(Customer::getCustomerName, Function.identity(), (a, b) -> a));
+ List<CustomerRegions> allRegions = customerRegionsService.list();
+ CustomerRegions hebiRegion = allRegions.stream().filter(Objects::nonNull).filter(r -> "楣ゅ".equals(r.getRegionsName())).findFirst().orElseGet(() -> {
+ CustomerRegions region = new CustomerRegions();
+ region.setRegionsName("楣ゅ");
+ region.setParentId(0L);
+ customerRegionsService.save(region);
+ return region;
+ });
+ Map<String, Product> productNameMap = productMapper.selectList(null).stream().filter(Objects::nonNull).filter(p -> StringUtils.hasText(p.getProductName())).collect(Collectors.toMap(Product::getProductName, Function.identity(), (a, b) -> a));
+ Product finishedGoodsParent = productNameMap.get("鎴愬搧");
+ if (finishedGoodsParent == null || finishedGoodsParent.getId() == null) {
+ finishedGoodsParent = new Product();
+ finishedGoodsParent.setProductName("鎴愬搧");
+ finishedGoodsParent.setParentId(null);
+ productMapper.insert(finishedGoodsParent);
+ productNameMap.put("鎴愬搧", finishedGoodsParent);
+ }
+ Map<String, ProductModel> productModelKeyMap = productModelMapper.selectList(null).stream().filter(Objects::nonNull).filter(m -> m.getProductId() != null && StringUtils.hasText(m.getModel())).collect(Collectors.toMap(m -> buildProductModelKey(m.getProductId(), m.getModel()), Function.identity(), (a, b) -> a));
+
+ List<String> extraProcessNames = Arrays.asList("鎵撳瓟", "鎸栫己", "瀹夊叏瑙�", "纾ㄨ竟");
+ Map<String, SalesLedgerProductProcess> processMap = salesLedgerProductProcessService.list(new LambdaQueryWrapper<SalesLedgerProductProcess>().in(SalesLedgerProductProcess::getProcessName, extraProcessNames)).stream().filter(Objects::nonNull).filter(p -> StringUtils.hasText(p.getProcessName())).collect(Collectors.toMap(SalesLedgerProductProcess::getProcessName, Function.identity(), (a, b) -> a));
+ List<ProcessRoute> processRoutes = processRouteMapper.selectList(new LambdaQueryWrapper<ProcessRoute>().eq(ProcessRoute::getProductModelId, 0L));
+ Map<String, ProcessRoute> routeNameMap = processRoutes.stream().filter(Objects::nonNull).filter(r -> StringUtils.hasText(r.getProcessRouteName())).collect(Collectors.toMap(r -> normalizeRouteFlowKey(r.getProcessRouteName()), Function.identity(), this::chooseBetterRoute));
+ Map<Long, List<ProcessRouteItem>> routeItemMap = Collections.emptyMap();
+ List<Long> routeIds = processRoutes.stream().map(ProcessRoute::getId).filter(Objects::nonNull).collect(Collectors.toList());
+ if (CollectionUtils.isNotEmpty(routeIds)) {
+ routeItemMap = processRouteItemMapper.selectList(new LambdaQueryWrapper<ProcessRouteItem>().in(ProcessRouteItem::getRouteId, routeIds).orderByAsc(ProcessRouteItem::getDragSort).orderByAsc(ProcessRouteItem::getId)).stream().filter(Objects::nonNull).collect(Collectors.groupingBy(ProcessRouteItem::getRouteId));
+ }
+
+ Map<String, List<SalesNotShippingImportDto>> groupedByOrderNo = list.stream().filter(Objects::nonNull).collect(Collectors.groupingBy(SalesNotShippingImportDto::getOrderNo, LinkedHashMap::new, Collectors.toList()));
+
+ for (Map.Entry<String, List<SalesNotShippingImportDto>> entry : groupedByOrderNo.entrySet()) {
+ String orderNo = entry.getKey();
+ if (!StringUtils.hasText(orderNo)) {
+ throw new ServiceException("瀵煎叆澶辫触,瀛樺湪璁㈠崟缂栧彿涓虹┖鐨勬暟鎹�");
+ }
+ List<SalesNotShippingImportDto> rowList = entry.getValue();
+ if (CollectionUtils.isEmpty(rowList)) {
+ continue;
+ }
+ SalesNotShippingImportDto first = rowList.get(0);
+ SalesLedger exists = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>().eq(SalesLedger::getSalesContractNo, orderNo).last("LIMIT 1"));
+ if (exists != null) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]宸插瓨鍦�");
+ }
+
+ SalesLedger ledger = new SalesLedger();
+ SysUser creatorUser = resolveImportUser(first.getCreator(), userByNickNameMap, userByUserNameMap, "鍒跺崟鍛�", orderNo);
+ ledger.setSalesContractNo(orderNo);
+ ledger.setCustomerContractNo(first.getContractNo());
+ ledger.setProjectName(first.getProjectName());
+ ledger.setSalesman(first.getSalesman());
+ Customer customer = getOrCreateImportCustomer(first.getCustomerName(), customerNameMap, hebiRegion.getId());
+ ledger.setCustomerName(customer.getCustomerName());
+ ledger.setRemarks(first.getRemark());
+ ledger.setEntryPerson(String.valueOf(creatorUser.getUserId()));
+ ledger.setEntryDate(first.getReportDate());
+ if (first.getReportDate() != null) {
+ ledger.setExecutionDate(DateUtils.toLocalDate(first.getReportDate()));
+ }
+ ledger.setDeliveryDate(first.getDeliveryDeadline() == null ? (first.getReportDate() == null ? LocalDate.now().plusDays(7) : DateUtils.toLocalDate(first.getReportDate()).plusDays(7)) : DateUtils.toLocalDate(first.getDeliveryDeadline()));
+ ledger.setDeliveryStatus(1);
+ ledger.setStockStatus(0);
+
+ ledger.setCustomerId(customer.getId());
+ ledger.setCustomerContractNo(StringUtils.hasText(ledger.getCustomerContractNo()) ? ledger.getCustomerContractNo() : customer.getTaxpayerIdentificationNumber());
+
+ ledger.setContractAmount(BigDecimal.ZERO);
+ salesLedgerMapper.insert(ledger);
+ bindImportProcessRoute(ledger.getId(), rowList, routeNameMap, routeItemMap);
+
+ BigDecimal contractAmount = BigDecimal.ZERO;
+ for (SalesNotShippingImportDto row : rowList) {
+ SalesLedgerProduct product = new SalesLedgerProduct();
+ product.setSalesLedgerId(ledger.getId());
+ product.setType(SaleEnum.SALE.getCode());
+ String specificationModel = buildSpecificationModel(row);
+ Product importProduct = resolveOrCreateImportProduct(row, productNameMap, finishedGoodsParent, orderNo);
+ ProductModel importProductModel = resolveOrCreateImportProductModel(importProduct, specificationModel, row.getGlassThickness(), productModelKeyMap);
+ product.setProductCategory(row.getProductSubCategory());
+ product.setSpecificationModel(specificationModel);
+ product.setProductId(importProduct.getId());
+ product.setProductModelId(importProductModel.getId());
+ product.setFloorCode(row.getFloorNo());
+ product.setWidth(defaultDecimal(row.getWidth()));
+ product.setHeight(defaultDecimal(row.getHeight()));
+ product.setQuantity(defaultDecimal(row.getQuantity()));
+ product.setActualPieceArea(defaultDecimal(row.getActualSingleArea()));
+ product.setActualTotalArea(defaultDecimal(row.getActualTotalArea()));
+ product.setSettlePieceArea(defaultDecimal(row.getSettlementSingleArea()));
+ product.setSettleTotalArea(defaultDecimal(row.getSettlementTotalArea()));
+ product.setTaxInclusiveUnitPrice(defaultDecimal(row.getUnitPrice()));
+ product.setPerimeter(defaultDecimal(row.getPerimeter()));
+ product.setHeavyBox(defaultDecimal(row.getHeavyBox()));
+ product.setProcessRequirement(row.getProcessRequirement());
+ product.setRemark(StringUtils.hasText(row.getAuditRemark()) ? row.getAuditRemark() : row.getRemark());
+ product.setApproveStatus(0);
+ product.setProductStockStatus(0);
+ product.setRegister(creatorUser.getNickName());
+ product.setRegisterDate(row.getReportDate() == null ? LocalDateTime.now() : LocalDateTime.ofInstant(row.getReportDate().toInstant(), ZoneId.systemDefault()));
+
+ BigDecimal qty = defaultDecimal(product.getQuantity());
+ if (qty.compareTo(BigDecimal.ZERO) <= 0) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]瀛樺湪鏁伴噺灏忎簬绛変簬0鐨勬暟鎹�");
+ }
+
+ BigDecimal lineAmount = defaultDecimal(row.getGlassAmount()).add(defaultDecimal(row.getOtherProcessFee()));
+ if (lineAmount.compareTo(BigDecimal.ZERO) <= 0 && product.getTaxInclusiveUnitPrice().compareTo(BigDecimal.ZERO) > 0 && product.getSettleTotalArea().compareTo(BigDecimal.ZERO) > 0) {
+ lineAmount = product.getTaxInclusiveUnitPrice().multiply(product.getSettleTotalArea()).setScale(2, RoundingMode.HALF_UP);
+ }
+ product.setTaxRate(BigDecimal.ZERO);
+ product.setTaxInclusiveTotalPrice(lineAmount);
+ product.setTaxExclusiveTotalPrice(lineAmount);
+ product.setNoInvoiceNum(qty);
+ product.setNoInvoiceAmount(lineAmount);
+ product.setPendingInvoiceTotal(lineAmount);
+ product.fillRemainingQuantity();
+ salesLedgerProductMapper.insert(product);
+
+ List<SalesLedgerProductProcess> bindProcessList = buildImportProcessBinds(row, processMap);
+ if (CollectionUtils.isNotEmpty(bindProcessList)) {
+ salesLedgerProductProcessBindService.updateProductProcessBind(bindProcessList, product.getId());
+ }
+
+ salesLedgerProductServiceImpl.addProductionData(product);
+ contractAmount = contractAmount.add(lineAmount);
+ }
+
+ ledger.setContractAmount(contractAmount);
+ salesLedgerMapper.updateById(ledger);
+ }
+ }
+
+ private List<SalesLedgerProductProcess> buildImportProcessBinds(SalesNotShippingImportDto row, Map<String, SalesLedgerProductProcess> processMap) {
+ LinkedHashMap<String, Integer> processQuantityMap = new LinkedHashMap<>();
+ mergeProcessQuantity(processQuantityMap, "鎵撳瓟", toProcessQuantity(row.getDrilling()));
+ mergeProcessQuantity(processQuantityMap, "鎸栫己", toProcessQuantity(row.getNotching()));
+ mergeProcessQuantity(processQuantityMap, "瀹夊叏瑙�", toProcessQuantity(row.getSafetyCorner()));
+ mergeProcessQuantity(processQuantityMap, "纾ㄨ竟", toProcessQuantity(row.getGrindingIrregular()));
+
+ List<SalesLedgerProductProcess> result = new ArrayList<>();
+ for (Map.Entry<String, Integer> entry : processQuantityMap.entrySet()) {
+ if (entry.getValue() == null || entry.getValue() <= 0) {
+ continue;
+ }
+ SalesLedgerProductProcess process = processMap.get(entry.getKey());
+ if (process == null || process.getId() == null) {
+ log.warn("瀵煎叆宸ヨ壓鏈壘鍒伴厤缃�, processName={}, orderNo={}", entry.getKey(), row.getOrderNo());
+ continue;
+ }
+ SalesLedgerProductProcess bind = new SalesLedgerProductProcess();
+ bind.setId(process.getId());
+ bind.setQuantity(entry.getValue());
+ result.add(bind);
+ }
+ return result;
+ }
+
+ private void bindImportProcessRoute(Long salesLedgerId, List<SalesNotShippingImportDto> rowList, Map<String, ProcessRoute> routeNameMap, Map<Long, List<ProcessRouteItem>> routeItemMap) {
+ String flowKey = rowList.stream().map(SalesNotShippingImportDto::getProcessFlow).filter(StringUtils::hasText).map(this::normalizeRouteFlowKey).filter(StringUtils::hasText).findFirst().orElse("");
+ if (!StringUtils.hasText(flowKey)) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟宸ヨ壓娴佺▼涓嶈兘涓虹┖");
+ }
+ ProcessRoute route = routeNameMap.get(flowKey);
+ if (route == null || route.getId() == null) {
+ route = createImportProcessRoute(flowKey, routeNameMap, routeItemMap);
+ }
+ List<ProcessRouteItem> routeItems = routeItemMap.getOrDefault(route.getId(), Collections.emptyList());
+ if (CollectionUtils.isEmpty(routeItems)) {
+ route = createImportProcessRoute(flowKey, routeNameMap, routeItemMap);
+ routeItems = routeItemMap.getOrDefault(route.getId(), Collections.emptyList());
+ if (CollectionUtils.isEmpty(routeItems)) {
+ throw new ServiceException("瀵煎叆澶辫触,宸ヨ壓璺嚎[" + flowKey + "]鏈厤缃伐鑹鸿妭鐐�");
+ }
+ }
+ List<SalesLedgerProcessRoute> bindList = new ArrayList<>();
+ for (ProcessRouteItem item : routeItems) {
+ SalesLedgerProcessRoute bind = new SalesLedgerProcessRoute();
+ bind.setSalesLedgerId(salesLedgerId);
+ bind.setProcessRouteId(route.getId());
+ bind.setProcessRouteItemId(item.getId());
+ bind.setDragSort(item.getDragSort());
+ bindList.add(bind);
+ }
+ salesLedgerProcessRouteService.saveBatch(bindList);
+ }
+
+ private ProcessRoute createImportProcessRoute(String flowKey, Map<String, ProcessRoute> routeNameMap, Map<Long, List<ProcessRouteItem>> routeItemMap) {
+ List<String> processNames = Arrays.stream(flowKey.split("->")).filter(StringUtils::hasText).map(String::trim).collect(Collectors.toList());
+ if (CollectionUtils.isEmpty(processNames)) {
+ throw new ServiceException("瀵煎叆澶辫触,宸ヨ壓璺嚎[" + flowKey + "]瑙f瀽澶辫触");
+ }
+ ProcessRoute route = new ProcessRoute();
+ route.setProductModelId(0L);
+ route.setProcessRouteName(flowKey);
+ route.setIsDefault(0);
+ route.setDescription("");
+ route.setProcessRouteCode("AUTO_" + System.currentTimeMillis());
+ processRouteMapper.insert(route);
+ List<ProcessRouteItem> routeItems = new ArrayList<>();
+ for (int i = 0; i < processNames.size(); i++) {
+ ProcessRouteItem item = new ProcessRouteItem();
+ item.setRouteId(route.getId());
+ item.setProductModelId(0L);
+ item.setProcessId(0L);
+ item.setProcessName(processNames.get(i));
+ item.setDragSort(i + 1);
+ item.setIsQuality(Boolean.TRUE);
+ processRouteItemMapper.insert(item);
+ routeItems.add(item);
+ }
+ routeNameMap.put(flowKey, route);
+ routeItemMap.put(route.getId(), routeItems);
+ return route;
+ }
+
+ private void mergeProcessQuantity(Map<String, Integer> processQuantityMap, String processName, Integer quantity) {
+ if (!StringUtils.hasText(processName) || quantity == null || quantity <= 0) {
+ return;
+ }
+ Integer old = processQuantityMap.get(processName);
+ if (old == null || old <= 0) {
+ processQuantityMap.put(processName, quantity);
+ }
+ }
+
+ private String normalizeRouteFlowKey(String processFlow) {
+ if (!StringUtils.hasText(processFlow)) {
+ return "";
+ }
+ return Arrays.stream(processFlow.trim().split("\\s*(?:->|鈫抾=>|锛�)\\s*")).filter(StringUtils::hasText).map(String::trim).collect(Collectors.joining("->"));
+ }
+
+ private ProcessRoute chooseBetterRoute(ProcessRoute a, ProcessRoute b) {
+ if (a == null) {
+ return b;
+ }
+ if (b == null) {
+ return a;
+ }
+ boolean aDefault = Objects.equals(a.getIsDefault(), 1);
+ boolean bDefault = Objects.equals(b.getIsDefault(), 1);
+ if (aDefault != bDefault) {
+ return aDefault ? a : b;
+ }
+ LocalDateTime aTime = a.getCreateTime();
+ LocalDateTime bTime = b.getCreateTime();
+ if (aTime == null) {
+ return b;
+ }
+ if (bTime == null) {
+ return a;
+ }
+ return bTime.isAfter(aTime) ? b : a;
+ }
+
+ private Integer toProcessQuantity(BigDecimal value) {
+ if (value == null) {
+ return null;
+ }
+ if (value.compareTo(BigDecimal.ZERO) <= 0) {
+ return 0;
+ }
+ return value.setScale(0, RoundingMode.HALF_UP).intValue();
+ }
+
+ private SysUser resolveImportUser(String rawName, Map<String, SysUser> userByNickNameMap, Map<String, SysUser> userByUserNameMap, String fieldName, String orderNo) {
+ if (!StringUtils.hasText(rawName)) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]鐨刐" + fieldName + "]涓嶈兘涓虹┖");
+ }
+ String key = rawName.trim();
+ SysUser user = userByNickNameMap.get(key);
+ if (user == null) {
+ user = userByUserNameMap.get(key);
+ }
+ if (user == null || user.getUserId() == null) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]鐨刐" + fieldName + ":" + key + "]鏈尮閰嶅埌浜哄憳");
+ }
+ return user;
+ }
+
+ private Customer getOrCreateImportCustomer(String customerName, Map<String, Customer> customerNameMap, Long hebiRegionId) {
+ if (!StringUtils.hasText(customerName)) {
+ throw new ServiceException("瀵煎叆澶辫触,瀹㈡埛鍚嶇О涓嶈兘涓虹┖");
+ }
+ String key = customerName.trim();
+ Customer exists = customerNameMap.get(key);
+ if (exists != null && exists.getId() != null) {
+ return exists;
+ }
+ Customer customer = new Customer();
+ customer.setCustomerName(key);
+ customer.setRegionsId(hebiRegionId);
+ customerMapper.insert(customer);
+ customerNameMap.put(key, customer);
+ return customer;
+ }
+
+ private Product resolveOrCreateImportProduct(SalesNotShippingImportDto row, Map<String, Product> productNameMap, Product finishedGoodsParent, String orderNo) {
+ String productName = row.getProductName();
+ if (StringUtils.hasText(productName)) {
+ Product product = productNameMap.get(productName.trim());
+ if (product != null && product.getId() != null) {
+ return product;
+ }
+ }
+ String productSubCategory = row.getProductSubCategory();
+ if (StringUtils.hasText(productSubCategory)) {
+ Product product = productNameMap.get(productSubCategory.trim());
+ if (product != null && product.getId() != null) {
+ return product;
+ }
+ }
+ String newProductName = buildCategoryProductName(row);
+ if (!StringUtils.hasText(newProductName)) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]浜у搧鍚嶇О鍜屼骇鍝佸垎绫诲潎涓虹┖");
+ }
+ Product created = new Product();
+ created.setParentId(finishedGoodsParent == null ? null : finishedGoodsParent.getId());
+ created.setProductName(newProductName);
+ productMapper.insert(created);
+ productNameMap.put(newProductName, created);
+ return created;
+ }
+
+ private ProductModel resolveOrCreateImportProductModel(Product product, String modelName, BigDecimal thickness, Map<String, ProductModel> productModelKeyMap) {
+ if (product == null || product.getId() == null || !StringUtils.hasText(modelName)) {
+ throw new ServiceException("瀵煎叆澶辫触,浜у搧瑙勬牸鏁版嵁涓嶅畬鏁�");
+ }
+ String key = buildProductModelKey(product.getId(), modelName);
+ ProductModel exists = productModelKeyMap.get(key);
+ if (exists != null && exists.getId() != null) {
+ return exists;
+ }
+ ProductModel created = new ProductModel();
+ created.setProductId(product.getId());
+ created.setModel(modelName.trim());
+ created.setThickness(thickness);
+ productModelMapper.insert(created);
+ productModelKeyMap.put(key, created);
+ return created;
+ }
+
+ private String buildSpecificationModel(SalesNotShippingImportDto row) {
+ if (StringUtils.hasText(row.getProductName())) {
+ return row.getProductName().trim();
+ }
+ if (StringUtils.hasText(row.getProductSubCategory())) {
+ return row.getProductSubCategory().trim();
+ }
+ if (StringUtils.hasText(row.getProductCategory())) {
+ return row.getProductCategory().trim();
+ }
+ return "";
+ }
+
+ private String buildCategoryProductName(SalesNotShippingImportDto row) {
+ String category = row.getProductCategory();
+ String subCategory = row.getProductSubCategory();
+ if (StringUtils.hasText(category) && StringUtils.hasText(subCategory)) {
+ return category.trim() + "-" + subCategory.trim();
+ }
+ if (StringUtils.hasText(subCategory)) {
+ return subCategory.trim();
+ }
+ if (StringUtils.hasText(category)) {
+ return category.trim();
+ }
+ return "";
+ }
+
+ private String buildProductModelKey(Long productId, String modelName) {
+ return productId + "||" + modelName.trim();
+ }
+
+ private String buildCategoryProductName(SalesShippingImportDto row) {
+ String category = row.getProductCategory();
+ String subCategory = row.getProductSubCategory();
+ if (StringUtils.hasText(category) && StringUtils.hasText(subCategory)) {
+ return category.trim() + "-" + subCategory.trim();
+ }
+ if (StringUtils.hasText(subCategory)) {
+ return subCategory.trim();
+ }
+ if (StringUtils.hasText(category)) {
+ return category.trim();
+ }
+ return "";
+ }
+
+ private Integer parseInteger(String value) {
+ if (!StringUtils.hasText(value)) {
+ return 0;
+ }
+ try {
+ return new BigDecimal(value.trim()).setScale(0, RoundingMode.HALF_UP).intValue();
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+
+ private Map<SalesLedgerProduct, BigDecimal> allocateShippingProductLines(String orderNo, SalesShippingImportDto row, Map<String, List<SalesLedgerProduct>> productByCategory, List<SalesLedgerProduct> allProducts) {
+ String subCategory = StringUtils.hasText(row.getProductSubCategory()) ? row.getProductSubCategory().trim() : "";
+ List<SalesLedgerProduct> candidates = productByCategory.getOrDefault(subCategory, Collections.emptyList());
+ if (CollectionUtils.isEmpty(candidates)) {
+ candidates = allProducts;
+ }
+ BigDecimal remaining = defaultDecimal(row.getQuantity());
+ Map<SalesLedgerProduct, BigDecimal> allocations = new LinkedHashMap<>();
+ for (SalesLedgerProduct p : candidates) {
+ BigDecimal qty = defaultDecimal(p.getQuantity());
+ BigDecimal shipped = defaultDecimal(p.getShippedQuantity());
+ BigDecimal canShip = qty.subtract(shipped);
+ if (canShip.compareTo(BigDecimal.ZERO) <= 0) {
+ continue;
+ }
+ BigDecimal alloc = remaining.min(canShip);
+ if (alloc.compareTo(BigDecimal.ZERO) > 0) {
+ allocations.put(p, alloc);
+ remaining = remaining.subtract(alloc);
+ }
+ if (remaining.compareTo(BigDecimal.ZERO) <= 0) {
+ return allocations;
+ }
+ }
+ if (remaining.compareTo(BigDecimal.ZERO) > 0) {
+ throw new ServiceException("瀵煎叆澶辫触,璁㈠崟缂栧彿[" + orderNo + "]浜у搧[" + subCategory + "]鍙戣揣鏁伴噺瓒呭嚭鍓╀綑鍙彂鏁伴噺");
+ }
+ return allocations;
+ }
+
+ private void updateProductShipStatus(SalesLedgerProduct dbProduct) {
+ BigDecimal qty = defaultDecimal(dbProduct.getQuantity());
+ BigDecimal shipped = defaultDecimal(dbProduct.getShippedQuantity());
+ if (shipped.compareTo(BigDecimal.ZERO) <= 0) {
+ dbProduct.setProductStockStatus(0);
+ return;
+ }
+ dbProduct.setProductStockStatus(shipped.compareTo(qty) >= 0 ? 2 : 1);
+ }
+
+ private void updateProductStockStatus(SalesLedgerProduct dbProduct) {
+ BigDecimal qty = defaultDecimal(dbProduct.getQuantity());
+ BigDecimal stocked = defaultDecimal(dbProduct.getStockedQuantity());
+ if (stocked.compareTo(BigDecimal.ZERO) <= 0) {
+ dbProduct.setProductStockStatus(0);
+ return;
+ }
+ dbProduct.setProductStockStatus(stocked.compareTo(qty) >= 0 ? 2 : 1);
+ }
+
+ private String buildShippingRowKey(Long ledgerId, SalesShippingImportDto row) {
+ String shippingNo = StringUtils.hasText(row.getShippingNo()) ? row.getShippingNo().trim() : "";
+ String dateStr = row.getReportDate() == null ? "" : String.valueOf(row.getReportDate().getTime());
+ String subCategory = StringUtils.hasText(row.getProductSubCategory()) ? row.getProductSubCategory().trim() : "";
+ return ledgerId + "|" + subCategory + "|" + shippingNo + "|" + dateStr + "|" + defaultDecimal(row.getQuantity());
+ }
}
--
Gitblit v1.9.3