| | |
| | | package com.ruoyi.sales.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
| | |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | 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.sales.mapper.*; |
| | | import com.ruoyi.sales.pojo.*; |
| | | import com.ruoyi.sales.service.ISalesLedgerService; |
| | | import com.ruoyi.sales.service.ReceiptPaymentService; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.io.FilenameUtils; |
| | |
| | | ; |
| | | @Autowired |
| | | private SysUserMapper sysUserMapper; |
| | | @Autowired |
| | | private ReceiptPaymentService receiptPaymentService; |
| | | |
| | | @Override |
| | | public List<SalesLedger> selectSalesLedgerList(SalesLedgerDto salesLedgerDto) { |
| | |
| | | salesLedgerMapper.insert(salesLedger); |
| | | |
| | | |
| | | List<SalesLedgerProduct> insertedProducts = new ArrayList<>(); |
| | | for (SalesLedgerProductImportDto salesLedgerProductImportDto : salesLedgerProductImportDtos) { |
| | | SalesLedgerProduct salesLedgerProduct = new SalesLedgerProduct(); |
| | | BeanUtils.copyProperties(salesLedgerProductImportDto, salesLedgerProduct); |
| | |
| | | salesLedgerProduct.setApproveStatus(0); |
| | | salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProductImportDto.getTaxInclusiveTotalPrice()); |
| | | salesLedgerProductMapper.insert(salesLedgerProduct); |
| | | insertedProducts.add(salesLedgerProduct); |
| | | // 添加生产数据 |
| | | salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct); |
| | | } |
| | | // 导入时同样自动全额开票、自动全额回款 |
| | | autoInvoiceAndReceiptPayment(salesLedger, insertedProducts); |
| | | } |
| | | |
| | | return AjaxResult.success("导入成功"); |
| | |
| | | if (CollectionUtils.isNotEmpty(invoiceLedgerIds)) { |
| | | LambdaQueryWrapper<ReceiptPayment> wrapperTree = new LambdaQueryWrapper<>(); |
| | | wrapperTree.in(ReceiptPayment::getInvoiceLedgerId, invoiceLedgerIds); |
| | | List<ReceiptPayment> receiptPayments = receiptPaymentMapper.selectList(wrapperTree); |
| | | // 同步删除回款对应的财务收入记录,避免产生孤儿数据 |
| | | if (CollectionUtils.isNotEmpty(receiptPayments)) { |
| | | List<Long> receiptPaymentIds = receiptPayments.stream() |
| | | .map(item -> item.getId().longValue()) |
| | | .collect(Collectors.toList()); |
| | | accountIncomeService.remove(new LambdaQueryWrapper<AccountIncome>() |
| | | .in(AccountIncome::getBusinessId, receiptPaymentIds) |
| | | .eq(AccountIncome::getBusinessType, 1)); |
| | | } |
| | | receiptPaymentMapper.delete(wrapperTree); |
| | | } |
| | | // 删除发货台账记录 |
| | |
| | | salesLedger.setCustomerName(customer.getCustomerName()); |
| | | salesLedger.setTenantId(customer.getTenantId()); |
| | | // 3. 新增或更新主表 |
| | | if (salesLedger.getId() == null) { |
| | | boolean isNew = salesLedger.getId() == null; |
| | | if (isNew) { |
| | | String contractNo = generateSalesContractNo(); |
| | | salesLedger.setSalesContractNo(contractNo); |
| | | salesLedgerMapper.insert(salesLedger); |
| | |
| | | // 5. 迁移临时文件到正式目录 |
| | | if (salesLedgerDto.getTempFileIds() != null && !salesLedgerDto.getTempFileIds().isEmpty()) { |
| | | migrateTempFilesToFormal(salesLedger.getId(), salesLedgerDto.getTempFileIds()); |
| | | } |
| | | |
| | | // 6. 新增台账时自动全额开票、自动全额回款 |
| | | if (isNew && productList != null && !productList.isEmpty()) { |
| | | autoInvoiceAndReceiptPayment(salesLedger, productList); |
| | | } |
| | | return 1; |
| | | } catch (IOException e) { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 新增销售台账时自动全额开票、自动全额回款 |
| | | * <p> |
| | | * 1. 按合同全额自动生成开票登记(invoice_registration + invoice_registration_product + invoice_ledger); |
| | | * 2. 按开票全额自动生成回款登记(receipt_payment)及财务收入记录(account_income)。 |
| | | * |
| | | * @param salesLedger 销售台账主表(已入库) |
| | | * @param products 台账产品列表(已入库,含主键ID) |
| | | */ |
| | | private void autoInvoiceAndReceiptPayment(SalesLedger salesLedger, List<SalesLedgerProduct> products) { |
| | | // 仅处理销售类产品 |
| | | List<SalesLedgerProduct> saleProducts = products.stream() |
| | | .filter(Objects::nonNull) |
| | | .filter(p -> p.getId() != null) |
| | | .filter(p -> SaleEnum.SALE.getCode().equals(p.getType())) |
| | | .collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(saleProducts)) { |
| | | return; |
| | | } |
| | | |
| | | String register = SecurityUtils.getLoginUser().getUser().getNickName(); |
| | | |
| | | // 1. 自动开票:生成一张开票登记主表,覆盖该台账全部产品 |
| | | InvoiceRegistration invoiceRegistration = new InvoiceRegistration(); |
| | | invoiceRegistration.setSalesLedgerId(salesLedger.getId().intValue()); |
| | | invoiceRegistration.setSalesContractNo(salesLedger.getSalesContractNo()); |
| | | invoiceRegistration.setCustomerId(salesLedger.getCustomerId() == null ? null : salesLedger.getCustomerId().intValue()); |
| | | invoiceRegistration.setSalesman(salesLedger.getSalesman()); |
| | | invoiceRegistration.setProjectName(salesLedger.getProjectName()); |
| | | invoiceRegistrationMapper.insert(invoiceRegistration); |
| | | |
| | | List<ReceiptPayment> receiptPaymentList = new ArrayList<>(); |
| | | for (SalesLedgerProduct product : saleProducts) { |
| | | BigDecimal invoiceNum = product.getQuantity(); |
| | | BigDecimal invoiceAmount = product.getTaxInclusiveTotalPrice(); |
| | | // 数量或金额缺失时跳过,不阻断台账新增 |
| | | if (invoiceNum == null || invoiceAmount == null |
| | | || invoiceNum.compareTo(BigDecimal.ZERO) <= 0 |
| | | || invoiceAmount.compareTo(BigDecimal.ZERO) <= 0) { |
| | | continue; |
| | | } |
| | | |
| | | // 1.1 产品未开票数量/金额清零(全额开票) |
| | | salesLedgerProductMapper.update( |
| | | null, |
| | | new LambdaUpdateWrapper<SalesLedgerProduct>() |
| | | .eq(SalesLedgerProduct::getId, product.getId()) |
| | | .set(SalesLedgerProduct::getNoInvoiceNum, BigDecimal.ZERO) |
| | | .set(SalesLedgerProduct::getNoInvoiceAmount, BigDecimal.ZERO) |
| | | ); |
| | | |
| | | // 1.2 开票登记产品 |
| | | InvoiceRegistrationProduct invoiceRegistrationProduct = new InvoiceRegistrationProduct(); |
| | | BeanUtils.copyProperties(product, invoiceRegistrationProduct); |
| | | invoiceRegistrationProduct.setId(null); |
| | | invoiceRegistrationProduct.setSalesLedgerId(salesLedger.getId().intValue()); |
| | | invoiceRegistrationProduct.setInvoiceRegistrationId(invoiceRegistration.getId()); |
| | | invoiceRegistrationProduct.setSalesLedgerProductId(product.getId().intValue()); |
| | | invoiceRegistrationProduct.setInvoiceNum(invoiceNum); |
| | | invoiceRegistrationProduct.setInvoiceAmount(invoiceAmount); |
| | | invoiceRegistrationProduct.setNoInvoiceNum(BigDecimal.ZERO); |
| | | invoiceRegistrationProduct.setNoInvoiceAmount(BigDecimal.ZERO); |
| | | invoiceRegistrationProductMapper.insert(invoiceRegistrationProduct); |
| | | |
| | | // 1.3 开票台账(发票号自动生成) |
| | | InvoiceLedger invoiceLedger = new InvoiceLedger(); |
| | | invoiceLedger.setInvoiceDate(LocalDate.now()); |
| | | invoiceLedger.setInvoiceRegistrationProductId(invoiceRegistrationProduct.getId()); |
| | | invoiceLedger.setInvoiceTotal(invoiceAmount); |
| | | invoiceLedger.setInvoiceNo(generateAutoInvoiceNo(product.getId())); |
| | | invoiceLedger.setCreateUser(SecurityUtils.getUserId().intValue()); |
| | | invoiceLedger.setInvoicePerson(register); |
| | | invoiceLedgerMapper.insert(invoiceLedger); |
| | | |
| | | // 2. 组装自动回款记录(按开票全额回款) |
| | | ReceiptPayment receiptPayment = new ReceiptPayment(); |
| | | receiptPayment.setReceiptPaymentType("0"); |
| | | receiptPayment.setReceiptPaymentAmount(invoiceAmount); |
| | | receiptPayment.setRegistrant(register); |
| | | receiptPayment.setInvoiceLedgerId(invoiceLedger.getId()); |
| | | receiptPayment.setSalesLedgerId(salesLedger.getId()); |
| | | receiptPayment.setSalesLedgerProductId(product.getId()); |
| | | receiptPayment.setReceiptPaymentDate(LocalDate.now()); |
| | | receiptPaymentList.add(receiptPayment); |
| | | } |
| | | |
| | | // 3. 自动回款(内部同步更新产品回款金额并生成财务收入记录) |
| | | if (!receiptPaymentList.isEmpty()) { |
| | | receiptPaymentService.receiptPaymentSaveOrUpdate(receiptPaymentList); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 生成自动开票发票号 |
| | | * |
| | | * @param salesLedgerProductId 销售台账产品ID |
| | | * @return 自动发票号 |
| | | */ |
| | | private String generateAutoInvoiceNo(Long salesLedgerProductId) { |
| | | return "AUTO" + System.currentTimeMillis() + salesLedgerProductId; |
| | | } |
| | | |
| | | private SalesLedger convertToEntity(SalesLedgerDto dto) { |
| | | SalesLedger entity = new SalesLedger(); |
| | | BeanUtils.copyProperties(dto, entity); |