maven
13 小时以前 95c61d927e361592eec441c293acde5bff0fd494
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -12,26 +12,34 @@
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountIncomeService;
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.Product;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.security.LoginUser;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.sales.dto.MonthlyAmountDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.dto.*;
import com.ruoyi.sales.mapper.*;
import com.ruoyi.sales.pojo.*;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ISalesLedgerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -43,10 +51,13 @@
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -77,6 +88,7 @@
    private final CustomerMapper customerMapper;
    private final SalesLedgerProductMapper salesLedgerProductMapper;
    private final SalesLedgerProductServiceImpl salesLedgerProductServiceImpl;
    private final CommonFileMapper commonFileMapper;
@@ -84,13 +96,19 @@
    private final ReceiptPaymentMapper receiptPaymentMapper;
    private final ShippingInfoServiceImpl shippingInfoServiceImpl;
    private final CommonFileServiceImpl commonFileService;
    private final ShippingInfoMapper shippingInfoMapper;
    private final InvoiceLedgerMapper invoiceLedgerMapper;
    private final SalesLedgerSchedulingMapper salesLedgerSchedulingMapper;
    private final SalesLedgerWorkMapper salesLedgerWorkMapper;
    private final SalesLedgerProductionAccountingMapper  salesLedgerProductionAccountingMapper;
    private final SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
    private final InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
@@ -128,6 +146,9 @@
    private final RedisTemplate<String, String> redisTemplate;
    @Autowired
    private ProductModelMapper productModelMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ProductStructureMapper productStructureMapper;
@@ -323,6 +344,129 @@
        return salesLedgerMapper.selectSalesLedgerListPage(page, salesLedgerDto);
    }
    @Autowired
    private SysUserMapper sysUserMapper;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult importData(MultipartFile file) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        try {
            InputStream inputStream = file.getInputStream();
            ExcelUtil<SalesLedgerImportDto> salesLedgerImportDtoExcelUtil = new ExcelUtil<>(SalesLedgerImportDto.class);
            Map<String, List<SalesLedgerImportDto>> stringListMap = salesLedgerImportDtoExcelUtil.importExcelMultiSheet(Arrays.asList("销售台账数据", "销售产品数据"), inputStream, 0);
            if (CollectionUtils.isEmpty(stringListMap)) return AjaxResult.error("销售表格为空!");
            // 业务层合并
            List<SalesLedgerImportDto> salesLedgerImportDtoList = stringListMap.get("销售台账数据");
            if (CollectionUtils.isEmpty(salesLedgerImportDtoList)) return AjaxResult.error("销售台账数据为空!");
            List<SalesLedgerImportDto> salesLedgerProductImportDtoList = stringListMap.get("销售产品数据");
            if (CollectionUtils.isEmpty(salesLedgerProductImportDtoList)) return AjaxResult.error("销售产品数据为空!");
            // 客户数据
            List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>().in(Customer::getCustomerName,
                    salesLedgerImportDtoList.stream().map(SalesLedgerImportDto::getCustomerName).collect(Collectors.toList())));
//            // 规格型号数据
//            List<ProductModel> productModels = productModelMapper.selectList(new LambdaQueryWrapper<ProductModel>().in(ProductModel::getModel,
//                    salesLedgerProductImportDtoList.stream().map(SalesLedgerImportDto::getSpecificationModel).collect(Collectors.toList())));
//            // 产品大类数据
//            List<Product> productList = productMapper.selectList(new LambdaQueryWrapper<Product>().in(Product::getProductName,
//                    salesLedgerProductImportDtoList.stream().map(SalesLedgerImportDto::getProductCategory).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())));
            for (SalesLedgerImportDto salesLedgerImportDto : salesLedgerImportDtoList) {
                SalesLedger salesLedger1 = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
                        .eq(SalesLedger::getSalesContractNo, salesLedgerImportDto.getSalesContractNo())
                        .last("LIMIT 1"));
                if(salesLedger1 != null){
                    continue;
                }
                SalesLedger salesLedger = new SalesLedger();
                BeanUtils.copyProperties(salesLedgerImportDto, salesLedger);
                salesLedger.setExecutionDate(DateUtils.toLocalDate(salesLedgerImportDto.getExecutionDate()));
                // 通过客户名称查询客户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);
                if (aLong == null)
                    throw new RuntimeException("录入人:" + salesLedger.getEntryPerson() + ",无对应用户!");
                salesLedger.setEntryPerson(aLong.toString());
                // 销售产品数据绑定,通过销售单号获取对应销售产品数据
                List<SalesLedgerProductImportDto> salesLedgerProductImportDtos = salesLedgerProductImportDtoList.stream()
                        .filter(salesLedgerProductImportDto -> salesLedgerProductImportDto.getSalesContractNo().equals(salesLedger.getSalesContractNo()))
                        .collect(Collectors.toList());
                if (CollectionUtils.isEmpty(salesLedgerProductImportDtos))
                    throw new RuntimeException("销售单号:" + salesLedgerImportDto.getSalesContractNo() + ",无对应产品数据!");
                salesLedger.setContractAmount(salesLedgerProductImportDtos.stream()
                        .map(SalesLedgerProductImportDto::getTaxInclusiveTotalPrice)
                        .reduce(BigDecimal.ZERO,BigDecimal::add));
                salesLedgerMapper.insert(salesLedger);
                for (SalesLedgerProductImportDto salesLedgerProductImportDto : salesLedgerProductImportDtos) {
                    SalesLedgerProduct salesLedgerProduct = new SalesLedgerProduct();
                    BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct);
                    salesLedgerProduct.setSalesLedgerId(salesLedger.getId());
                    salesLedgerProduct.setType(1);
                    // 计算不含税总价
                    salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice().divide(new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP));
                    salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
                    salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxExclusiveTotalPrice());
                    list.stream()
                            .filter(map -> map.get("productName").equals(salesLedgerProduct.getProductCategory()) && map.get("model").equals(salesLedgerProduct.getSpecificationModel()))
                            .findFirst()
                            .ifPresent(map -> {
                                salesLedgerProduct.setProductModelId(Long.parseLong(map.get("modelId").toString()));
                                salesLedgerProduct.setProductId(Long.parseLong(map.get("id").toString()));
                            });
//                    salesLedgerProduct.setProductId(productList.stream()
//                            .filter(product -> product.getProductName().equals(salesLedgerProduct.getProductCategory()))
//                            .findFirst()
//                            .map(Product::getId)
//                            .orElse(null));
//                    salesLedgerProduct.setProductModelId(productModels.stream()
//                            .filter(productModel -> productModel.getModel().equals(salesLedgerProduct.getSpecificationModel()))
//                            .findFirst()
//                            .map(ProductModel::getId)
//                            .orElse(null));
                    salesLedgerProduct.setRegister(loginUser.getNickName());
                    salesLedgerProduct.setRegisterDate(LocalDateTime.now());
                    salesLedgerProduct.setApproveStatus(0);
                    salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProductImportDto.getTaxInclusiveTotalPrice());
                    salesLedgerProductMapper.insert(salesLedgerProduct);
                }
            }
            return AjaxResult.success("导入成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.success("导入失败");
    }
    @Override
    public List<LossProductModelDto> getSalesLedgerWithProductsLoss(Long salesLedgerId) {
        List<LossProductModelDto> lossProductModelDtos = salesLedgerProductMapper.selectProductBomStructure(salesLedgerId);
        return lossProductModelDtos;
    }
    // 内部类用于存储聚合结果
    private static class GroupedCustomer {
        private final Long customerId;
@@ -393,86 +537,8 @@
        List<Long> productIds = products.stream()
                .map(SalesLedgerProduct::getId)
                .collect(Collectors.toList());
        //批量查询productOrder
        List<ProductOrder> productOrders = productOrderMapper.selectList(
                new LambdaQueryWrapper<ProductOrder>()
                        .in(ProductOrder::getProductModelId, productIds)
        );
        if (!org.springframework.util.CollectionUtils.isEmpty(productOrders)) {
            List<Long> orderIds = productOrders.stream()
                    .map(ProductOrder::getId)
                    .collect(Collectors.toList());
            // 批量查询processRouteItems
            List<ProductProcessRouteItem> allRouteItems = productProcessRouteItemMapper.selectList(
                    new LambdaQueryWrapper<ProductProcessRouteItem>()
                            .in(ProductProcessRouteItem::getProductOrderId, orderIds)
            );
            if (!CollectionUtils.isEmpty(allRouteItems)) {
                // 获取要删除的工序项ID
                List<Long> routeItemIds = allRouteItems.stream()
                        .map(ProductProcessRouteItem::getId)
                        .collect(Collectors.toList());
                // 查询关联的工单ID
                List<ProductWorkOrder> workOrders = productWorkOrderMapper.selectList(
                        new LambdaQueryWrapper<ProductWorkOrder>()
                                .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds)
                );
                if (!CollectionUtils.isEmpty(workOrders)) {
                    List<Long> workOrderIds = workOrders.stream()
                            .map(ProductWorkOrder::getId)
                            .collect(Collectors.toList());
                    // 查询关联的生产主表ID
                    List<ProductionProductMain> productMains = productionProductMainMapper.selectList(
                            new LambdaQueryWrapper<ProductionProductMain>()
                                    .in(ProductionProductMain::getWorkOrderId, workOrderIds)
                    );
                    List<Long> productMainIds = productMains.stream()
                            .map(ProductionProductMain::getId)
                            .collect(Collectors.toList());
                    // 删除产出表、投入表数据
                    if (!CollectionUtils.isEmpty(productMainIds)) {
                        productionProductOutputMapper.deleteByProductMainIds(productMainIds);
                        productionProductInputMapper.deleteByProductMainIds(productMainIds);
                        List<QualityInspect> qualityInspects = qualityInspectMapper.selectList(
                                new LambdaQueryWrapper<QualityInspect>()
                                        .in(QualityInspect::getProductMainId, productMainIds)
                        );
                        qualityInspects.forEach(qualityInspect -> {
                            //inspectState=1 已提交 不能删除
                            if(qualityInspect.getInspectState() == 1){
                                throw new RuntimeException("已提交的检验单不能删除");
                            }
                        });
                        qualityInspectMapper.deleteByProductMainIds(productMainIds);
                    }
                    // 删除生产主表数据
                    productionProductMainMapper.deleteByWorkOrderIds(workOrderIds);
                    // 删除工单数据
                    productWorkOrderMapper.delete(new LambdaQueryWrapper<ProductWorkOrder>()
                            .in(ProductWorkOrder::getProductProcessRouteItemId, routeItemIds));
                }
            }
            // 批量删除processRouteItem
            productProcessRouteItemMapper.delete(new LambdaQueryWrapper<ProductProcessRouteItem>()
                    .in(ProductProcessRouteItem::getProductOrderId, orderIds));
            // 批量删除productProcessRoute
            productProcessRouteMapper.delete(new LambdaQueryWrapper<ProductProcessRoute>()
                    .in(ProductProcessRoute::getProductOrderId, orderIds));
            // 批量删除productOrder
            productOrderMapper.delete(new LambdaQueryWrapper<ProductOrder>()
                    .in(ProductOrder::getProductModelId, productIds));
        }
        //删除生产数据
        salesLedgerProductServiceImpl.deleteProductionData(productIds);
        // 批量删除产品子表
        if (!productIds.isEmpty()) {
@@ -483,11 +549,11 @@
        wrapper.in(InvoiceRegistrationProduct::getSalesLedgerId, idList);
        List<InvoiceRegistrationProduct> invoiceRegistrationProducts = invoiceRegistrationProductMapper.selectList(wrapper);
        List<Integer> invoiceLedgerIds = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(invoiceRegistrationProducts)){
        if (CollectionUtils.isNotEmpty(invoiceRegistrationProducts)) {
            LambdaQueryWrapper<InvoiceLedger> wrapperOne = new LambdaQueryWrapper<>();
            wrapperOne.in(InvoiceLedger::getInvoiceRegistrationProductId, invoiceRegistrationProducts.stream().map(InvoiceRegistrationProduct::getId).collect(Collectors.toList()));
            List<InvoiceLedger> invoiceLedgers = invoiceLedgerMapper.selectList(wrapperOne);
            if(CollectionUtils.isNotEmpty(invoiceLedgers)){
            if (CollectionUtils.isNotEmpty(invoiceLedgers)) {
                invoiceLedgerIds = invoiceLedgers.stream().map(InvoiceLedger::getId).collect(Collectors.toList());
            }
            invoiceLedgerMapper.delete(wrapperOne);
@@ -497,11 +563,19 @@
        wrapperTwo.in(InvoiceRegistration::getSalesLedgerId, idList);
        invoiceRegistrationMapper.delete(wrapperTwo);
        if(CollectionUtils.isNotEmpty(invoiceLedgerIds)){
        if (CollectionUtils.isNotEmpty(invoiceLedgerIds)) {
            LambdaQueryWrapper<ReceiptPayment> wrapperTree = new LambdaQueryWrapper<>();
            wrapperTree.in(ReceiptPayment::getInvoiceLedgerId, invoiceLedgerIds);
            receiptPaymentMapper.delete(wrapperTree);
        }
        // 删除发货台账记录
        List<ShippingInfo> shippingInfos = shippingInfoMapper.selectList(new LambdaQueryWrapper<ShippingInfo>()
                .eq(ShippingInfo::getSalesLedgerId, idList));
        if(CollectionUtils.isNotEmpty(shippingInfos)){
            shippingInfoServiceImpl.delete(shippingInfos.stream().map(ShippingInfo::getId).collect(Collectors.toList()));
        }
        // 删除附件表
        commonFileService.deleteByBusinessIds(idList, FileNameType.SALE.getValue());
        // 删除生产管控数据
        // 删除生产订单数据
@@ -512,7 +586,7 @@
        LambdaQueryWrapper<SalesLedgerWork> workOrderWrapper = new LambdaQueryWrapper<>();
        workOrderWrapper.in(SalesLedgerWork::getSalesLedgerId, idList);
        salesLedgerWorkMapper.delete(workOrderWrapper);
        // 删除生产报工数据
        // 删除生产核算数据
        LambdaQueryWrapper<SalesLedgerProductionAccounting> reportWrapper = new LambdaQueryWrapper<>();
        reportWrapper.in(SalesLedgerProductionAccounting::getSalesLedgerId, idList);
        salesLedgerProductionAccountingMapper.delete(reportWrapper);
@@ -668,79 +742,8 @@
                salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
                salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProduct.getTaxInclusiveTotalPrice());
                salesLedgerProductMapper.insert(salesLedgerProduct);
                ProductOrder productOrder = new ProductOrder();
                productOrder.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId());
                productOrder.setProductModelId(salesLedgerProduct.getId());
                productOrder.setNpsNo("SC" + String.format("%08d", salesLedgerProduct.getId()));
                productOrder.setQuantity(salesLedgerProduct.getQuantity());//需求数量
                productOrder.setCompleteQuantity(BigDecimal.ZERO);//完成数量
                productOrderMapper.insert(productOrder);
                ProcessRoute processRoute = processRouteMapper.selectOne(new QueryWrapper<ProcessRoute>().lambda().eq(ProcessRoute::getProductModelId, salesLedgerProduct.getProductModelId()));
                List<ProductStructureDto> productStructureDtos = productStructureMapper.listBybomId(processRoute.getBomId());
                if (processRoute != null) {
                    //新增生产订单工艺路线主表
                    ProductProcessRoute productProcessRoute = new ProductProcessRoute();
                    productProcessRoute.setProductModelId(processRoute.getProductModelId());
                    productProcessRoute.setProcessRouteCode(processRoute.getProcessRouteCode());
                    productProcessRoute.setProductOrderId(productOrder.getId());
                    productProcessRoute.setBomId(processRoute.getBomId());
                    productProcessRouteMapper.insert(productProcessRoute);
                    //新增生产订单工艺路线子表
                    List<ProcessRouteItem> processRouteItems = processRouteItemMapper.selectList(new QueryWrapper<ProcessRouteItem>().lambda().eq(ProcessRouteItem::getRouteId, processRoute.getId()));
                    // 生成当前日期的前缀:年月日
                    String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                    for (ProcessRouteItem processRouteItem : processRouteItems) {
                        ProductProcessRouteItem productProcessRouteItem = new ProductProcessRouteItem();
                        productProcessRouteItem.setProductModelId(processRouteItem.getProductModelId());
                        productProcessRouteItem.setProcessId(processRouteItem.getProcessId());
                        productProcessRouteItem.setProductOrderId(productOrder.getId());
                        productProcessRouteItem.setProductRouteId(productProcessRoute.getId());
                        productProcessRouteItem.setDragSort(processRouteItem.getDragSort());
                        int insert = productProcessRouteItemMapper.insert(productProcessRouteItem);
                        if (insert > 0) {
                            // 查询今日已存在的最大工单号
                            QueryWrapper<ProductWorkOrder> queryWrapper = new QueryWrapper<>();
                            queryWrapper.likeRight("work_order_no", datePrefix)
                                    .orderByDesc("work_order_no")
                                    .last("LIMIT 1");
                            ProductWorkOrder lastWorkOrder = productWorkOrderMapper.selectOne(queryWrapper);
                            int sequenceNumber = 1; // 默认序号
                            if (lastWorkOrder != null && lastWorkOrder.getWorkOrderNo() != null) {
                                String lastNo = lastWorkOrder.getWorkOrderNo().toString();
                                if (lastNo.startsWith(datePrefix)) {
                                    String seqStr = lastNo.substring(datePrefix.length());
                                    try {
                                        sequenceNumber = Integer.parseInt(seqStr) + 1;
                                    } catch (NumberFormatException e) {
                                        sequenceNumber = 1;
                                    }
                                }
                            }
                            // 生成完整的工单号
                            String workOrderNoStr = String.format("%s%03d", datePrefix, sequenceNumber);
                            ProductWorkOrder productWorkOrder = new ProductWorkOrder();
                            productStructureDtos.stream().forEach(productStructureDto -> {
                                if (productStructureDto.getProductModelId().equals(productProcessRouteItem.getProductModelId())){
                                    productWorkOrder.setPlanQuantity(productWorkOrder.getPlanQuantity());
                                }
                            });
                            if (Objects.equals(productProcessRouteItem.getProductModelId(), salesLedgerProduct.getProductModelId())) {
                                productWorkOrder.setPlanQuantity(salesLedgerProduct.getQuantity());
                            }
                            productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId());
                            productWorkOrder.setProductOrderId(productOrder.getId());
                            productWorkOrder.setWorkOrderNo(workOrderNoStr);
                            productWorkOrder.setStatus(1);
                            productWorkOrderMapper.insert(productWorkOrder);
                        }
                    }
                    productOrder.setRouteId(processRoute.getId());
                    productOrderMapper.updateById(productOrder);
                }
                // 添加生产数据
                salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct);
            }
        }
    }