use of com.axelor.apps.stock.db.StockMoveLine in project axelor-open-suite by axelor.
the class StockMoveInvoiceServiceImpl method getStockMoveLinesToInvoice.
@Override
public List<Map<String, Object>> getStockMoveLinesToInvoice(StockMove stockMove) throws AxelorException {
List<Map<String, Object>> stockMoveLines = new ArrayList<>();
for (StockMoveLine stockMoveLine : stockMove.getStockMoveLineList()) {
BigDecimal qty = stockMoveLine.getRealQty().subtract(computeNonCanceledInvoiceQty(stockMoveLine));
if (qty.compareTo(BigDecimal.ZERO) != 0) {
Map<String, Object> stockMoveLineMap = new HashMap<>();
stockMoveLineMap.put("productCode", stockMoveLine.getProduct() != null ? stockMoveLine.getProduct().getCode() : null);
stockMoveLineMap.put("productName", stockMoveLine.getProductName());
stockMoveLineMap.put("remainingQty", qty);
stockMoveLineMap.put("realQty", stockMoveLine.getRealQty());
stockMoveLineMap.put("qtyInvoiced", computeNonCanceledInvoiceQty(stockMoveLine));
stockMoveLineMap.put("qtyToInvoice", BigDecimal.ZERO);
stockMoveLineMap.put("invoiceAll", false);
stockMoveLineMap.put("stockMoveLineId", stockMoveLine.getId());
stockMoveLines.add(stockMoveLineMap);
}
}
return stockMoveLines;
}
use of com.axelor.apps.stock.db.StockMoveLine in project axelor-open-suite by axelor.
the class StockMoveInvoiceServiceImpl method computeStockMoveInvoicingStatus.
@Override
public void computeStockMoveInvoicingStatus(StockMove stockMove) {
int invoicingStatus = StockMoveRepository.STATUS_NOT_INVOICED;
if (stockMove.getStockMoveLineList() != null && stockMove.getInvoiceSet() != null && !stockMove.getInvoiceSet().isEmpty()) {
BigDecimal totalInvoicedQty = stockMove.getStockMoveLineList().stream().map(StockMoveLine::getQtyInvoiced).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
BigDecimal totalRealQty = stockMove.getStockMoveLineList().stream().map(StockMoveLine::getRealQty).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
// realQty is > 0.
if (totalInvoicedQty.signum() == 0 && totalRealQty.signum() == 0) {
// special case where we invoice a stock move line with no quantities.
invoicingStatus = StockMoveRepository.STATUS_INVOICED;
} else if (totalInvoicedQty.signum() > 0 && totalRealQty.compareTo(totalInvoicedQty) > 0) {
invoicingStatus = StockMoveRepository.STATUS_PARTIALLY_INVOICED;
} else if (totalRealQty.compareTo(totalInvoicedQty) == 0) {
invoicingStatus = StockMoveRepository.STATUS_INVOICED;
}
}
stockMove.setInvoicingStatusSelect(invoicingStatus);
}
use of com.axelor.apps.stock.db.StockMoveLine in project axelor-open-suite by axelor.
the class WorkflowVentilationServiceSupplychainImpl method stockMoveProcess.
private void stockMoveProcess(Invoice invoice) throws AxelorException {
// update qty invoiced in stock move line
for (InvoiceLine invoiceLine : invoice.getInvoiceLineList()) {
StockMoveLine stockMoveLine = invoiceLine.getStockMoveLine();
if (stockMoveLine == null) {
continue;
}
if (isStockMoveInvoicingPartiallyActivated(invoice, stockMoveLine)) {
BigDecimal qty = stockMoveLine.getQtyInvoiced();
StockMove stockMove = stockMoveLine.getStockMove();
if (stockMoveInvoiceService.isInvoiceRefundingStockMove(stockMove, invoice)) {
qty = qty.subtract(invoiceLine.getQty());
} else {
qty = qty.add(invoiceLine.getQty());
}
Unit movUnit = stockMoveLine.getUnit(), invUnit = invoiceLine.getUnit();
try {
qty = unitConversionService.convert(invUnit, movUnit, qty, appBaseService.getNbDecimalDigitForQty(), null);
} catch (AxelorException e) {
throw new AxelorException(TraceBackRepository.CATEGORY_INCONSISTENCY, I18n.get(IExceptionMessage.STOCK_MOVE_INVOICE_QTY_INVONVERTIBLE_UNIT) + "\n" + e.getMessage());
}
if (stockMoveLine.getRealQty().compareTo(qty) >= 0) {
stockMoveLine.setQtyInvoiced(qty);
} else {
throw new AxelorException(TraceBackRepository.CATEGORY_INCONSISTENCY, I18n.get(IExceptionMessage.STOCK_MOVE_INVOICE_QTY_MAX));
}
} else {
// set qty invoiced to the maximum (or emptying it if refund) for all stock move lines
boolean invoiceIsRefund = stockMoveInvoiceService.isInvoiceRefundingStockMove(stockMoveLine.getStockMove(), invoice);
stockMoveLine.setQtyInvoiced(invoiceIsRefund ? BigDecimal.ZERO : stockMoveLine.getRealQty());
// search in sale/purchase order lines to set split stock move lines to invoiced.
if (stockMoveLine.getSaleOrderLine() != null) {
stockMoveLineRepository.all().filter("self.saleOrderLine.id = :saleOrderLineId AND self.stockMove.id = :stockMoveId").bind("saleOrderLineId", stockMoveLine.getSaleOrderLine().getId()).bind("stockMoveId", stockMoveLine.getStockMove().getId()).fetch().forEach(stockMvLine -> stockMvLine.setQtyInvoiced(invoiceIsRefund ? BigDecimal.ZERO : stockMvLine.getRealQty()));
}
if (stockMoveLine.getPurchaseOrderLine() != null) {
stockMoveLineRepository.all().filter("self.purchaseOrderLine.id = :purchaseOrderLineId AND self.stockMove.id = :stockMoveId").bind("purchaseOrderLineId", stockMoveLine.getPurchaseOrderLine().getId()).bind("stockMoveId", stockMoveLine.getStockMove().getId()).fetch().forEach(stockMvLine -> stockMvLine.setQtyInvoiced(invoiceIsRefund ? BigDecimal.ZERO : stockMvLine.getRealQty()));
}
}
}
// update stock moves invoicing status
for (StockMove stockMove : invoice.getStockMoveSet()) {
stockMoveInvoiceService.computeStockMoveInvoicingStatus(stockMove);
}
}
use of com.axelor.apps.stock.db.StockMoveLine in project axelor-open-suite by axelor.
the class StockMoveServiceSupplychainImpl method generateReversion.
@Override
@Transactional(rollbackOn = { Exception.class })
public Optional<StockMove> generateReversion(StockMove stockMove) throws AxelorException {
Optional<StockMove> newStockMove = super.generateReversion(stockMove);
List<StockMoveLine> stockMoveLineList = newStockMove.isPresent() ? newStockMove.get().getStockMoveLineList() : null;
if (stockMoveLineList != null && !stockMoveLineList.isEmpty()) {
for (StockMoveLine stockMoveLine : stockMoveLineList) {
stockMoveLine.setQtyInvoiced(BigDecimal.ZERO);
}
}
return newStockMove;
}
use of com.axelor.apps.stock.db.StockMoveLine in project axelor-open-suite by axelor.
the class StockMoveServiceSupplychainImpl method copySplittedStockMoveLine.
/**
* The splitted stock move line needs an allocation and will be planned before the previous stock
* move line is realized. To solve this issue, we deallocate here in the previous stock move line
* the quantity that will be allocated in the generated stock move line. The quantity will be
* reallocated when the generated stock move is planned.
*
* @param stockMoveLine the previous stock move line
* @return the generated stock move line
* @throws AxelorException
*/
@Override
protected StockMoveLine copySplittedStockMoveLine(StockMoveLine stockMoveLine) throws AxelorException {
StockMoveLine newStockMoveLine = super.copySplittedStockMoveLine(stockMoveLine);
AppSupplychainService appSupplychainService = Beans.get(AppSupplychainService.class);
if (appSupplychainService.getAppSupplychain().getManageStockReservation() && appSupplychainService.isApp("supplychain")) {
BigDecimal requestedReservedQty = stockMoveLine.getRequestedReservedQty().subtract(stockMoveLine.getRealQty()).max(BigDecimal.ZERO);
newStockMoveLine.setRequestedReservedQty(requestedReservedQty);
newStockMoveLine.setReservedQty(BigDecimal.ZERO);
reservedQtyService.deallocateStockMoveLineAfterSplit(stockMoveLine, stockMoveLine.getReservedQty());
stockMoveLine.setReservedQty(BigDecimal.ZERO);
}
return newStockMoveLine;
}
Aggregations