Search in sources :

Example 81 with StockMove

use of com.axelor.apps.stock.db.StockMove in project axelor-open-suite by axelor.

the class StockMoveMultiInvoiceServiceImpl method createInvoiceFromMultiOutgoingStockMove.

@Override
@Transactional(rollbackOn = { Exception.class })
public Optional<Invoice> createInvoiceFromMultiOutgoingStockMove(List<StockMove> stockMoveList) throws AxelorException {
    if (stockMoveList == null || stockMoveList.isEmpty()) {
        return Optional.empty();
    }
    Set<Address> deliveryAddressSet = new HashSet<>();
    // create dummy invoice from the first stock move
    Invoice dummyInvoice = createDummyOutInvoice(stockMoveList.get(0));
    // Check if field constraints are respected
    for (StockMove stockMove : stockMoveList) {
        completeInvoiceInMultiOutgoingStockMove(dummyInvoice, stockMove);
        if (stockMove.getToAddressStr() != null) {
            deliveryAddressSet.add(stockMove.getToAddress());
        }
    }
    /*  check if some other fields are different and assign a default value */
    if (dummyInvoice.getAddress() == null) {
        dummyInvoice.setAddress(Beans.get(PartnerService.class).getInvoicingAddress(dummyInvoice.getPartner()));
        dummyInvoice.setAddressStr(Beans.get(AddressService.class).computeAddressStr(dummyInvoice.getAddress()));
    }
    fillReferenceInvoiceFromMultiOutStockMove(stockMoveList, dummyInvoice);
    InvoiceGenerator invoiceGenerator = new InvoiceGenerator(InvoiceRepository.OPERATION_TYPE_CLIENT_SALE, dummyInvoice.getCompany(), dummyInvoice.getPaymentCondition(), dummyInvoice.getPaymentMode(), dummyInvoice.getAddress(), dummyInvoice.getPartner(), dummyInvoice.getContactPartner(), dummyInvoice.getCurrency(), dummyInvoice.getPriceList(), dummyInvoice.getInternalReference(), dummyInvoice.getExternalReference(), dummyInvoice.getInAti(), null, dummyInvoice.getTradingName(), dummyInvoice.getGroupProductsOnPrintings()) {

        @Override
        public Invoice generate() throws AxelorException {
            Invoice invoice = super.createInvoiceHeader();
            invoice.setPartnerTaxNbr(partner.getTaxNbr());
            return invoice;
        }
    };
    Invoice invoice = invoiceGenerator.generate();
    invoice.setAddressStr(dummyInvoice.getAddressStr());
    StringBuilder deliveryAddressStr = new StringBuilder();
    AddressService addressService = Beans.get(AddressService.class);
    for (Address address : deliveryAddressSet) {
        deliveryAddressStr.append(addressService.computeAddressStr(address).replaceAll("\n", ", ") + "\n");
    }
    invoice.setDeliveryAddressStr(deliveryAddressStr.toString());
    List<InvoiceLine> invoiceLineList = new ArrayList<>();
    for (StockMove stockMoveLocal : stockMoveList) {
        stockMoveInvoiceService.checkSplitSalePartiallyInvoicedStockMoveLines(stockMoveLocal, stockMoveLocal.getStockMoveLineList());
        List<InvoiceLine> createdInvoiceLines = stockMoveInvoiceService.createInvoiceLines(invoice, stockMoveLocal, stockMoveLocal.getStockMoveLineList(), null);
        if (stockMoveLocal.getTypeSelect() == StockMoveRepository.TYPE_INCOMING) {
            createdInvoiceLines.forEach(this::negateInvoiceLinePrice);
        }
        invoiceLineList.addAll(createdInvoiceLines);
    }
    invoiceGenerator.populate(invoice, invoiceLineList);
    invoiceRepository.save(invoice);
    invoice = toPositivePriceInvoice(invoice);
    if (invoice.getExTaxTotal().signum() == 0 && stockMoveList.stream().allMatch(StockMove::getIsReversion)) {
        invoice.setOperationTypeSelect(InvoiceRepository.OPERATION_TYPE_CLIENT_REFUND);
    }
    stockMoveList.forEach(invoice::addStockMoveSetItem);
    return Optional.of(invoice);
}
Also used : RefundInvoice(com.axelor.apps.account.service.invoice.generator.invoice.RefundInvoice) Invoice(com.axelor.apps.account.db.Invoice) StockMove(com.axelor.apps.stock.db.StockMove) Address(com.axelor.apps.base.db.Address) AddressService(com.axelor.apps.base.service.AddressService) InvoiceLine(com.axelor.apps.account.db.InvoiceLine) InvoiceGenerator(com.axelor.apps.account.service.invoice.generator.InvoiceGenerator) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Transactional(com.google.inject.persist.Transactional)

Example 82 with StockMove

use of com.axelor.apps.stock.db.StockMove in project axelor-open-suite by axelor.

the class StockMoveMultiInvoiceServiceImpl method generateMultipleInvoices.

@Override
public Entry<List<Long>, String> generateMultipleInvoices(List<Long> stockMoveIdList) {
    StockMoveRepository stockMoveRepository = Beans.get(StockMoveRepository.class);
    List<Long> invoiceIdList = new ArrayList<>();
    StringBuilder stockMovesInError = new StringBuilder();
    List<StockMove> stockMoveList;
    Query<StockMove> stockMoveQuery = stockMoveRepository.all().filter("self.id IN :stockMoveIdList").bind("stockMoveIdList", stockMoveIdList).order("id");
    int offset = 0;
    while (!(stockMoveList = stockMoveQuery.fetch(AbstractBatch.FETCH_LIMIT, offset)).isEmpty()) {
        for (StockMove stockMove : stockMoveList) {
            offset++;
            try {
                Invoice invoice = stockMoveInvoiceService.createInvoice(stockMove, 0, null);
                if (invoice != null) {
                    invoiceIdList.add(invoice.getId());
                }
            } catch (Exception e) {
                if (stockMovesInError.length() > 0) {
                    stockMovesInError.append("<br/>");
                }
                stockMovesInError.append(String.format(I18n.get(IExceptionMessage.STOCK_MOVE_GENERATE_INVOICE), stockMove.getName(), e.getLocalizedMessage()));
                break;
            }
        }
        JPA.clear();
    }
    return new SimpleImmutableEntry<>(invoiceIdList, stockMovesInError.toString());
}
Also used : StockMove(com.axelor.apps.stock.db.StockMove) RefundInvoice(com.axelor.apps.account.service.invoice.generator.invoice.RefundInvoice) Invoice(com.axelor.apps.account.db.Invoice) SimpleImmutableEntry(java.util.AbstractMap.SimpleImmutableEntry) ArrayList(java.util.ArrayList) StockMoveRepository(com.axelor.apps.stock.db.repo.StockMoveRepository) AxelorException(com.axelor.exception.AxelorException)

Example 83 with StockMove

use of com.axelor.apps.stock.db.StockMove in project axelor-open-suite by axelor.

the class StockMoveInvoiceServiceImpl method createInvoiceFromPurchaseOrder.

@Override
@Transactional(rollbackOn = { Exception.class })
public Invoice createInvoiceFromPurchaseOrder(StockMove stockMove, PurchaseOrder purchaseOrder, Map<Long, BigDecimal> qtyToInvoiceMap) throws AxelorException {
    if (!supplyChainConfigService.getSupplyChainConfig(stockMove.getCompany()).getActivateIncStockMovePartialInvoicing() && computeNonCanceledInvoiceQty(stockMove).signum() > 0) {
        throw new AxelorException(TraceBackRepository.CATEGORY_INCONSISTENCY, I18n.get(IExceptionMessage.STOCK_MOVE_PARTIAL_INVOICE_ERROR));
    }
    InvoiceGenerator invoiceGenerator = purchaseOrderInvoiceService.createInvoiceGenerator(purchaseOrder, stockMove.getIsReversion());
    Invoice invoice = invoiceGenerator.generate();
    invoiceGenerator.populate(invoice, this.createInvoiceLines(invoice, stockMove, stockMove.getStockMoveLineList(), qtyToInvoiceMap));
    if (invoice != null) {
        // do not create empty invoices
        if (invoice.getInvoiceLineList() == null || invoice.getInvoiceLineList().isEmpty()) {
            return null;
        }
        this.extendInternalReference(stockMove, invoice);
        invoice.setAddressStr(Beans.get(AddressService.class).computeAddressStr(invoice.getAddress()));
        if (invoice != null) {
            Set<StockMove> stockMoveSet = invoice.getStockMoveSet();
            if (stockMoveSet == null) {
                stockMoveSet = new HashSet<>();
                invoice.setStockMoveSet(stockMoveSet);
            }
            stockMoveSet.add(stockMove);
        }
        invoiceRepository.save(invoice);
    }
    return invoice;
}
Also used : AxelorException(com.axelor.exception.AxelorException) Invoice(com.axelor.apps.account.db.Invoice) StockMove(com.axelor.apps.stock.db.StockMove) InvoiceGenerator(com.axelor.apps.account.service.invoice.generator.InvoiceGenerator) Transactional(com.google.inject.persist.Transactional)

Example 84 with StockMove

use of com.axelor.apps.stock.db.StockMove in project axelor-open-suite by axelor.

the class StockMoveInvoiceServiceImpl method createInvoiceLine.

@Override
public InvoiceLine createInvoiceLine(Invoice invoice, StockMoveLine stockMoveLine, BigDecimal qty) throws AxelorException {
    Product product = stockMoveLine.getProduct();
    boolean isTitleLine = false;
    int sequence = InvoiceLineGenerator.DEFAULT_SEQUENCE;
    SaleOrderLine saleOrderLine = stockMoveLine.getSaleOrderLine();
    PurchaseOrderLine purchaseOrderLine = stockMoveLine.getPurchaseOrderLine();
    if (saleOrderLine != null) {
        sequence = saleOrderLine.getSequence();
    } else if (purchaseOrderLine != null) {
        if (purchaseOrderLine.getIsTitleLine()) {
            isTitleLine = true;
        }
        sequence = purchaseOrderLine.getSequence();
    }
    // do not create lines with no qties
    if ((qty == null || qty.signum() == 0 || stockMoveLine.getRealQty().signum() == 0) && !isTitleLine) {
        return null;
    }
    if (product == null && !isTitleLine) {
        throw new AxelorException(TraceBackRepository.CATEGORY_CONFIGURATION_ERROR, I18n.get(IExceptionMessage.STOCK_MOVE_INVOICE_1), stockMoveLine.getStockMove().getStockMoveSeq());
    }
    InvoiceLineGenerator invoiceLineGenerator = new InvoiceLineGeneratorSupplyChain(invoice, product, stockMoveLine.getProductName(), stockMoveLine.getDescription(), qty, stockMoveLine.getUnit(), sequence, false, stockMoveLine.getSaleOrderLine(), stockMoveLine.getPurchaseOrderLine(), stockMoveLine) {

        @Override
        public List<InvoiceLine> creates() throws AxelorException {
            InvoiceLine invoiceLine = this.createInvoiceLine();
            List<InvoiceLine> invoiceLines = new ArrayList<>();
            invoiceLines.add(invoiceLine);
            return invoiceLines;
        }
    };
    List<InvoiceLine> invoiceLines = invoiceLineGenerator.creates();
    InvoiceLine invoiceLine = null;
    if (invoiceLines != null && !invoiceLines.isEmpty()) {
        invoiceLine = invoiceLines.get(0);
        if (!stockMoveLine.getIsMergedStockMoveLine()) {
            // not a consolidated line so we can set the reference.
            invoiceLine.setStockMoveLine(stockMoveLine);
        } else {
            // set the reference to a correct stock move line by following either the sale order line or
            // purchase order line. We cannot have a consolidated line without purchase order line or
            // sale order line reference
            StockMoveLine nonConsolidatedStockMoveLine = null;
            StockMove stockMove = stockMoveLine.getStockMove();
            if (saleOrderLine != null) {
                nonConsolidatedStockMoveLine = stockMoveLineRepository.all().filter("self.saleOrderLine.id = :saleOrderLineId " + "AND self.stockMove.id = :stockMoveId " + "AND self.id != :stockMoveLineId").bind("saleOrderLineId", saleOrderLine.getId()).bind("stockMoveId", stockMove.getId()).bind("stockMoveLineId", stockMoveLine.getId()).order("id").fetchOne();
            } else if (purchaseOrderLine != null) {
                nonConsolidatedStockMoveLine = stockMoveLineRepository.all().filter("self.purchaseOrderLine.id = :purchaseOrderLineId " + "AND self.stockMove.id = :stockMoveId " + "AND self.id != :stockMoveLineId").bind("purchaseOrderLineId", purchaseOrderLine.getId()).bind("stockMoveId", stockMove.getId()).bind("stockMoveLineId", stockMoveLine.getId()).order("id").fetchOne();
            }
            invoiceLine.setStockMoveLine(nonConsolidatedStockMoveLine);
            deleteConsolidatedStockMoveLine(stockMoveLine);
        }
    }
    return invoiceLine;
}
Also used : AxelorException(com.axelor.exception.AxelorException) StockMove(com.axelor.apps.stock.db.StockMove) InvoiceLine(com.axelor.apps.account.db.InvoiceLine) ArrayList(java.util.ArrayList) Product(com.axelor.apps.base.db.Product) SaleOrderLine(com.axelor.apps.sale.db.SaleOrderLine) InvoiceLineGenerator(com.axelor.apps.account.service.invoice.generator.InvoiceLineGenerator) PurchaseOrderLine(com.axelor.apps.purchase.db.PurchaseOrderLine) InvoiceLineGeneratorSupplyChain(com.axelor.apps.supplychain.service.invoice.generator.InvoiceLineGeneratorSupplyChain) StockMoveLine(com.axelor.apps.stock.db.StockMoveLine)

Example 85 with StockMove

use of com.axelor.apps.stock.db.StockMove in project axelor-open-suite by axelor.

the class StockMoveInvoiceServiceImpl method createInvoiceFromOrderlessStockMove.

@Override
@Transactional(rollbackOn = { Exception.class })
public Invoice createInvoiceFromOrderlessStockMove(StockMove stockMove, Map<Long, BigDecimal> qtyToInvoiceMap) throws AxelorException {
    int stockMoveType = stockMove.getTypeSelect();
    int invoiceOperationType;
    if (stockMove.getIsReversion()) {
        if (stockMoveType == StockMoveRepository.TYPE_INCOMING) {
            invoiceOperationType = InvoiceRepository.OPERATION_TYPE_CLIENT_REFUND;
        } else if (stockMoveType == StockMoveRepository.TYPE_OUTGOING) {
            invoiceOperationType = InvoiceRepository.OPERATION_TYPE_SUPPLIER_REFUND;
        } else {
            return null;
        }
    } else {
        if (stockMoveType == StockMoveRepository.TYPE_INCOMING) {
            invoiceOperationType = InvoiceRepository.OPERATION_TYPE_SUPPLIER_PURCHASE;
        } else if (stockMoveType == StockMoveRepository.TYPE_OUTGOING) {
            invoiceOperationType = InvoiceRepository.OPERATION_TYPE_CLIENT_SALE;
        } else {
            return null;
        }
    }
    // do not use invoiced partner if the option is disabled
    if (!appSupplychainService.getAppSupplychain().getActivatePartnerRelations()) {
        stockMove.setInvoicedPartner(null);
    }
    InvoiceGenerator invoiceGenerator = new InvoiceGeneratorSupplyChain(stockMove, invoiceOperationType) {

        @Override
        public Invoice generate() throws AxelorException {
            return super.createInvoiceHeader();
        }
    };
    Invoice invoice = invoiceGenerator.generate();
    invoiceGenerator.populate(invoice, this.createInvoiceLines(invoice, stockMove, stockMove.getStockMoveLineList(), qtyToInvoiceMap));
    if (invoice != null) {
        this.extendInternalReference(stockMove, invoice);
        invoice.setAddressStr(Beans.get(AddressService.class).computeAddressStr(invoice.getAddress()));
        if (stockMoveType == StockMoveRepository.TYPE_OUTGOING) {
            invoice.setHeadOfficeAddress(stockMove.getPartner().getHeadOfficeAddress());
        }
        invoiceRepository.save(invoice);
        if (invoice != null) {
            Set<StockMove> stockMoveSet = invoice.getStockMoveSet();
            if (stockMoveSet == null) {
                stockMoveSet = new HashSet<>();
                invoice.setStockMoveSet(stockMoveSet);
            }
            stockMoveSet.add(stockMove);
        }
        invoiceRepository.save(invoice);
    }
    return invoice;
}
Also used : Invoice(com.axelor.apps.account.db.Invoice) StockMove(com.axelor.apps.stock.db.StockMove) InvoiceGenerator(com.axelor.apps.account.service.invoice.generator.InvoiceGenerator) InvoiceGeneratorSupplyChain(com.axelor.apps.supplychain.service.invoice.generator.InvoiceGeneratorSupplyChain) Transactional(com.google.inject.persist.Transactional)

Aggregations

StockMove (com.axelor.apps.stock.db.StockMove)129 AxelorException (com.axelor.exception.AxelorException)57 StockMoveLine (com.axelor.apps.stock.db.StockMoveLine)50 ArrayList (java.util.ArrayList)36 StockMoveRepository (com.axelor.apps.stock.db.repo.StockMoveRepository)33 Transactional (com.google.inject.persist.Transactional)32 StockMoveService (com.axelor.apps.stock.service.StockMoveService)31 BigDecimal (java.math.BigDecimal)30 List (java.util.List)25 Company (com.axelor.apps.base.db.Company)23 Map (java.util.Map)21 Product (com.axelor.apps.base.db.Product)19 Invoice (com.axelor.apps.account.db.Invoice)18 StockLocation (com.axelor.apps.stock.db.StockLocation)18 Beans (com.axelor.inject.Beans)17 Optional (java.util.Optional)16 StockMoveLineService (com.axelor.apps.stock.service.StockMoveLineService)15 I18n (com.axelor.i18n.I18n)15 Inject (com.google.inject.Inject)14 HashMap (java.util.HashMap)14