liding
5 天以前 dce840653b78fc05a732c5c89773c74e15dbed09
src/main/java/com/ruoyi/purchase/service/impl/TicketRegistrationServiceImpl.java
@@ -10,6 +10,7 @@
import com.ruoyi.common.enums.SalesLedgerType;
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.bean.BeanUtils;
import com.ruoyi.other.mapper.TempFileMapper;
@@ -21,6 +22,7 @@
import com.ruoyi.purchase.mapper.ProductRecordMapper;
import com.ruoyi.purchase.mapper.PurchaseLedgerMapper;
import com.ruoyi.purchase.mapper.TicketRegistrationMapper;
import com.ruoyi.purchase.pojo.PaymentRegistration;
import com.ruoyi.purchase.pojo.ProductRecord;
import com.ruoyi.purchase.pojo.PurchaseLedger;
import com.ruoyi.purchase.pojo.TicketRegistration;
@@ -30,7 +32,6 @@
import com.ruoyi.sales.pojo.CommonFile;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.impl.SalesLedgerProductServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
@@ -41,6 +42,7 @@
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -90,6 +92,8 @@
    @Override
    public List<TicketRegistration> selectTicketRegistrationList(TicketRegistration ticketRegistration) {
        LambdaQueryWrapper<TicketRegistration> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TicketRegistration::getTenantId,SecurityUtils.getLoginUser().getTenantId())
                .eq(TicketRegistration::getDeleteFlag,0);
        if (StringUtils.isNotBlank(ticketRegistration.getPurchaseContractNumber())) {
            queryWrapper.like(TicketRegistration::getPurchaseContractNumber, ticketRegistration.getPurchaseContractNumber())
                    .like(TicketRegistration::getSupplierName, ticketRegistration.getSupplierName())
@@ -121,11 +125,39 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addOrUpdateRegistration(TicketRegistrationDto ticketRegistrationDto) throws IOException {
        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
        Long userId = SecurityUtils.getUserId();
        if (ticketRegistrationDto.getPurchaseLedgerId() == null) throw new BaseException("请选择采购单");
        if (StringUtils.isBlank(ticketRegistrationDto.getInvoiceNumber())) throw new BaseException("发票号码不能为空");
        if (ticketRegistrationDto.getIssueDate() == null) throw new BaseException("开票日期不能为空");
        if (ticketRegistrationDto.getInvoiceAmount() == null || ticketRegistrationDto.getInvoiceAmount().compareTo(BigDecimal.ZERO) <= 0) {
            throw new BaseException("发票金额必须大于0");
        }
        // 1. 查询采购台账记录
        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(ticketRegistrationDto.getPurchaseLedgerId());
        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>()
                .eq(PurchaseLedger::getId,ticketRegistrationDto.getPurchaseLedgerId())
                .eq(PurchaseLedger::getTenantId,tenantId));
        if (purchaseLedger == null) {
            // 处理采购台账不存在的情况,例如抛出异常或返回错误
            throw new IllegalArgumentException("采购台账记录不存在,ID: " + ticketRegistrationDto.getPurchaseLedgerId());
        }
        LambdaQueryWrapper<TicketRegistration> duplicate = new LambdaQueryWrapper<TicketRegistration>()
                .eq(TicketRegistration::getTenantId, tenantId)
                .eq(TicketRegistration::getInvoiceNumber, ticketRegistrationDto.getInvoiceNumber())
                .eq(TicketRegistration::getDeleteFlag, 0);
        if (ticketRegistrationDto.getId() != null) duplicate.ne(TicketRegistration::getId, ticketRegistrationDto.getId());
        if (ticketRegistrationMapper.selectCount(duplicate) > 0) throw new BaseException("该发票号码已登记");
        BigDecimal registered = ticketRegistrationMapper.selectList(new LambdaQueryWrapper<TicketRegistration>()
                .eq(TicketRegistration::getTenantId,tenantId)
                .eq(TicketRegistration::getPurchaseLedgerId,purchaseLedger.getId())
                .eq(TicketRegistration::getDeleteFlag,0)
                .ne(ticketRegistrationDto.getId()!=null,TicketRegistration::getId,ticketRegistrationDto.getId()))
                .stream().map(TicketRegistration::getInvoiceAmount).filter(java.util.Objects::nonNull)
                .reduce(BigDecimal.ZERO,BigDecimal::add);
        if (purchaseLedger.getContractAmount()!=null && registered.add(ticketRegistrationDto.getInvoiceAmount()).compareTo(purchaseLedger.getContractAmount())>0) {
            throw new BaseException("来票金额超过采购单剩余可登记金额:" + purchaseLedger.getContractAmount().subtract(registered));
        }
@@ -134,11 +166,23 @@
        TicketRegistration ticketRegistration = new TicketRegistration();
        BeanUtils.copyProperties(ticketRegistrationDto, ticketRegistration);
        ticketRegistration.setPurchaseContractNumber(purchaseLedger.getPurchaseContractNumber());
        ticketRegistration.setTenantId(purchaseLedger.getTenantId());
        ticketRegistration.setTenantId(tenantId);
        ticketRegistration.setSupplierId(purchaseLedger.getSupplierId());
        ticketRegistration.setSupplierName(purchaseLedger.getSupplierName());
        ticketRegistration.setIssueDate(ticketRegistrationDto.getIssueDate());
        ticketRegistration.setContractAmount(purchaseLedger.getContractAmount());
        ticketRegistration.setSalesLedgerId(purchaseLedger.getSalesLedgerId());
        ticketRegistration.setEnterDate(ticketRegistrationDto.getEnterDate());
        ticketRegistration.setCurrency(StringUtils.isBlank(ticketRegistration.getCurrency()) ? "CNY" : ticketRegistration.getCurrency());
        ticketRegistration.setInvoiceStatus(ticketRegistration.getInvoiceStatus()==null?1:ticketRegistration.getInvoiceStatus());
        ticketRegistration.setVerificationStatus(ticketRegistration.getVerificationStatus()==null?0:ticketRegistration.getVerificationStatus());
        ticketRegistration.setDeleteFlag(0);
        ticketRegistration.setUpdateUser(userId);
        ticketRegistration.setUpdateTime(DateUtils.getNowDate());
        if (ticketRegistration.getTaxAmount()==null && ticketRegistration.getTaxRate()!=null) {
            BigDecimal rate=ticketRegistration.getTaxRate().compareTo(BigDecimal.ONE)>0?ticketRegistration.getTaxRate().divide(new BigDecimal("100"),6,RoundingMode.HALF_UP):ticketRegistration.getTaxRate();
            ticketRegistration.setTaxAmount(ticketRegistration.getInvoiceAmount().multiply(rate).divide(BigDecimal.ONE.add(rate),2,RoundingMode.HALF_UP));
        }
        // 4. 处理子表数据
        List<SalesLedgerProduct> productData = ticketRegistrationDto.getProductData();
@@ -147,7 +191,15 @@
        }
        // 5. 执行插入或更新操作
        int rowsAffected = ticketRegistrationMapper.insert(ticketRegistration);
        int rowsAffected;
        if (ticketRegistration.getId()==null) {
            ticketRegistration.setCreateUser(userId);
            rowsAffected=ticketRegistrationMapper.insert(ticketRegistration);
        } else {
            rowsAffected=ticketRegistrationMapper.update(ticketRegistration,new LambdaQueryWrapper<TicketRegistration>()
                    .eq(TicketRegistration::getId,ticketRegistration.getId()).eq(TicketRegistration::getTenantId,tenantId));
            productRecordMapper.delete(new LambdaQueryWrapper<ProductRecord>().eq(ProductRecord::getTicketRegistrationId,ticketRegistration.getId()).eq(ProductRecord::getTenantId,tenantId));
        }
        // 6. 增加采购台账产品开票记录
        List<SalesLedgerProduct> salesLedgerProducts = ticketRegistrationDto.getProductData();
@@ -165,6 +217,7 @@
                    productRecord.setSaleLedgerProjectId(salesLedgerProduct.getId());
                    productRecord.setId(null);
                    productRecord.setType("2");
                    productRecord.setTenantId(tenantId);
                     insert = productRecordMapper.insert(productRecord);
                }
                if (insert <= 0) {
@@ -223,12 +276,15 @@
            try {
                // 执行文件迁移(使用原子操作确保安全性)
                Files.move(
                        Paths.get(tempFile.getTempPath()),
                        formalFilePath,
                        StandardCopyOption.REPLACE_EXISTING,
                        StandardCopyOption.ATOMIC_MOVE
                );
//                Files.move(
//                        Paths.get(tempFile.getTempPath()),
//                        formalFilePath,
//                        StandardCopyOption.REPLACE_EXISTING,
//                        StandardCopyOption.ATOMIC_MOVE
//                );
                // 原子移动失败,使用复制+删除
                Files.copy(Paths.get(tempFile.getTempPath()), formalFilePath, StandardCopyOption.REPLACE_EXISTING);
                Files.deleteIfExists(Paths.get(tempFile.getTempPath()));
                log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath);
                // 更新文件记录(关联到业务ID)
@@ -237,7 +293,7 @@
                fileRecord.setName(originalFilename);
                fileRecord.setUrl(formalFilePath.toString());
                fileRecord.setCreateTime(LocalDateTime.now());
                fileRecord.setType(4);
                fileRecord.setType(FileNameType.INVOICE.getValue());
                commonFileMapper.insert(fileRecord);
                log.info("文件迁移成功: {} -> {}", tempFile.getTempPath(), formalFilePath);
@@ -251,55 +307,36 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int delRegistration(Long[] ids) {
        // 删除采购台账产品开票记录对象
        Long tenantId=SecurityUtils.getLoginUser().getTenantId();
        LambdaQueryWrapper<ProductRecord> productRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        productRecordLambdaQueryWrapper.in(ProductRecord::getId, Arrays.asList(ids));
        productRecordLambdaQueryWrapper.in(ProductRecord::getTicketRegistrationId, Arrays.asList(ids)).eq(ProductRecord::getTenantId,tenantId);
        List<ProductRecord> productRecords = productRecordMapper.selectList(productRecordLambdaQueryWrapper);
        if(CollectionUtils.isEmpty(productRecords)){
            return 0;
        }
        LambdaQueryWrapper<TicketRegistration> ticketRegistrationLambdaQueryWrapper = new LambdaQueryWrapper<>();
        ticketRegistrationLambdaQueryWrapper.in(TicketRegistration::getId, productRecords.stream().map(ProductRecord::getTicketRegistrationId).collect(Collectors.toList()));
        List<TicketRegistration> ticketRegistrations = ticketRegistrationMapper.selectList(ticketRegistrationLambdaQueryWrapper);
        // 修改产品信息
        for (ProductRecord productRecord : productRecords) {
            BigDecimal subtract = ticketRegistrations.get(0).getInvoiceAmount().subtract(productRecords.get(0).getTicketsAmount());
            // 小于等于0删除 ,大于0修改
            if(subtract.compareTo(BigDecimal.ZERO) <= 0){
                ticketRegistrationMapper.deleteById(ticketRegistrations.get(0));
            }else if(subtract.compareTo(BigDecimal.ZERO) > 0){
                ticketRegistrations.get(0).setInvoiceAmount(subtract);
                ticketRegistrationMapper.updateById(ticketRegistrations.get(0));
            }
            LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductLambdaQueryWrapper = new LambdaQueryWrapper<>();
            salesLedgerProductLambdaQueryWrapper.eq(SalesLedgerProduct::getId, productRecord.getSaleLedgerProjectId())
                    .eq(SalesLedgerProduct::getType, 2);
            List<SalesLedgerProduct> salesLedgerProducts = salesLedgerProductMapper.selectList(salesLedgerProductLambdaQueryWrapper);
            if(!CollectionUtils.isEmpty(salesLedgerProducts)){
                for (SalesLedgerProduct salesLedgerProduct : salesLedgerProducts) {
                    salesLedgerProduct.setFutureTickets(salesLedgerProduct.getFutureTickets().add(productRecord.getTicketsNum()));
                    salesLedgerProduct.setFutureTicketsAmount(salesLedgerProduct.getFutureTicketsAmount().add(productRecord.getTicketsAmount()));
                    salesLedgerProductMapper.updateById(salesLedgerProduct);
                }
            SalesLedgerProduct product=salesLedgerProductMapper.selectById(productRecord.getSaleLedgerProjectId());
            if(product!=null){
                product.setTicketsNum(nvl(product.getTicketsNum()).subtract(nvl(productRecord.getTicketsNum())).max(BigDecimal.ZERO));
                product.setTicketsAmount(nvl(product.getTicketsAmount()).subtract(nvl(productRecord.getTicketsAmount())).max(BigDecimal.ZERO));
                product.setFutureTickets(nvl(product.getFutureTickets()).add(nvl(productRecord.getTicketsNum())));
                product.setFutureTicketsAmount(nvl(product.getFutureTicketsAmount()).add(nvl(productRecord.getTicketsAmount())));
                salesLedgerProductMapper.updateById(product);
            }
        }
        // 删除采购台账产品开票记录
        productRecordMapper.delete(productRecordLambdaQueryWrapper);
        return 1;
        paymentRegistrationMapper.delete(new LambdaQueryWrapper<PaymentRegistration>().in(PaymentRegistration::getTicketRegistrationId,Arrays.asList(ids)));
        return ticketRegistrationMapper.delete(new LambdaQueryWrapper<TicketRegistration>().in(TicketRegistration::getId,Arrays.asList(ids)).eq(TicketRegistration::getTenantId,tenantId));
    }
    @Override
    public TicketRegistrationDto getRegistrationById(TicketRegistrationDto ticketRegistrationDto) {
        TicketRegistration ticketRegistration = ticketRegistrationMapper.selectById(ticketRegistrationDto.getId());
        TicketRegistration ticketRegistration = ticketRegistrationMapper.selectOne(new LambdaQueryWrapper<TicketRegistration>()
                .eq(TicketRegistration::getId,ticketRegistrationDto.getId()).eq(TicketRegistration::getTenantId,SecurityUtils.getLoginUser().getTenantId()));
        if (ticketRegistration == null) throw new BaseException("来票登记不存在");
        LambdaQueryWrapper<PurchaseLedger> purchaseQueryWrapper = new LambdaQueryWrapper<>();
        purchaseQueryWrapper.eq(PurchaseLedger::getId, ticketRegistration.getPurchaseLedgerId());
        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(purchaseQueryWrapper);
        if (ticketRegistration == null) {
            throw new BaseException("采购台账不存在");
        }
        if (purchaseLedger == null) throw new BaseException("采购台账不存在");
        // 创建并填充DTO
        TicketRegistrationDto resultDto = new TicketRegistrationDto();
        BeanUtils.copyProperties(ticketRegistration, resultDto);
@@ -317,7 +354,9 @@
    public List getTicketNo(TicketRegistrationDto ticketRegistrationDto) {
        LambdaQueryWrapper<TicketRegistration> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(TicketRegistration::getId, TicketRegistration::getInvoiceNumber, TicketRegistration::getInvoiceAmount)
                .eq(TicketRegistration::getPurchaseLedgerId, ticketRegistrationDto.getId());
                .eq(TicketRegistration::getPurchaseLedgerId, ticketRegistrationDto.getId())
                .eq(TicketRegistration::getTenantId,SecurityUtils.getLoginUser().getTenantId())
                .eq(TicketRegistration::getDeleteFlag,0);
        List<Map<String, Object>> result = ticketRegistrationMapper.selectMaps(queryWrapper);
        // 将下划线命名转换为驼峰命名
        return result.stream().map(map -> map.entrySet().stream()
@@ -330,13 +369,19 @@
    @Override
    public IPage<TicketRegistration> selectTicketRegistrationListPage(Page page, TicketRegistration ticketRegistration) {
        LambdaQueryWrapper<TicketRegistration> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(ticketRegistration.getPurchaseContractNumber())) {
            queryWrapper.like(TicketRegistration::getPurchaseContractNumber, ticketRegistration.getPurchaseContractNumber())
                    .like(TicketRegistration::getSupplierName, ticketRegistration.getSupplierName());
        if (StringUtils.isNotBlank(ticketRegistration.getSupplierNameOrContractNo())) {
            queryWrapper.and(wrapper -> wrapper
                    .like(TicketRegistration::getPurchaseContractNumber, ticketRegistration.getSupplierNameOrContractNo())
                    .or()
                    .like(TicketRegistration::getSupplierName, ticketRegistration.getSupplierNameOrContractNo())
                    .or()
                    .like(TicketRegistration::getSalesContractNo, ticketRegistration.getSupplierNameOrContractNo()));
        }
        if (!ObjectUtils.isEmpty(ticketRegistration.getIssueDateStart()) && !ObjectUtils.isEmpty(ticketRegistration.getIssueDateEnd())) {
            queryWrapper.between(TicketRegistration::getIssueDate, LocalDate.parse(ticketRegistration.getIssueDateStart(), DateTimeFormatter.ofPattern("yyyy-MM-dd")), LocalDate.parse(ticketRegistration.getIssueDateEnd(), DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        queryWrapper.eq(TicketRegistration::getTenantId, SecurityUtils.getLoginUser().getTenantId())
                .eq(TicketRegistration::getDeleteFlag,0);
        IPage<TicketRegistration> ticketRegistrationIPage = ticketRegistrationMapper.selectPage(page, queryWrapper);
        // 计算已付款金额
        if (CollectionUtils.isNotEmpty(ticketRegistrationIPage.getRecords())) {
@@ -363,12 +408,18 @@
                ticketRegistrationIPage.setTotal(ticketRegistrationIPage.getRecords().size());
            }
        }
        ticketRegistrationIPage.getRecords().forEach(item -> {
            // 已付款金额 == 待付款金额
            item.setStatusName(item.getPaymentAmountTotal().compareTo(item.getInvoiceAmount()) == 0 ? "已完成付款" : "未完成付款");
        });
        return ticketRegistrationIPage;
    }
    @Override
    public PurchaseLedgerDto getPuargeById(Long id) {
        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectById(id);
        PurchaseLedger purchaseLedger = purchaseLedgerMapper.selectOne(new LambdaQueryWrapper<PurchaseLedger>()
                .eq(PurchaseLedger::getId,id).eq(PurchaseLedger::getTenantId,SecurityUtils.getLoginUser().getTenantId()));
        if(purchaseLedger==null) throw new BaseException("采购台账不存在");
        PurchaseLedgerDto purchaseLedgerDto = new PurchaseLedgerDto();
        BeanUtils.copyProperties(purchaseLedger, purchaseLedgerDto);
        SalesLedgerProduct salesLedgerProduct = new SalesLedgerProduct();
@@ -381,6 +432,12 @@
                .eq(CommonFile::getCommonId, id));
        purchaseLedgerDto.setSalesLedgerFiles(commonFiles);
        return purchaseLedgerDto;
    }
    @Override
    public List<PaymentRegistrationDto> getPaymentRegistrationDtoById(Long id) {
        List<PaymentRegistrationDto> paymentRegistrationDtos =purchaseLedgerMapper.getPaymentRegistrationDtoById(id);
        return paymentRegistrationDtos;
    }
    private void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, Integer type) {
@@ -432,6 +489,8 @@
        }
    }
    private BigDecimal nvl(BigDecimal value) { return value == null ? BigDecimal.ZERO : value; }
    /**
     * 下划线命名转驼峰命名
     */