use of com.axelor.apps.base.db.Product in project axelor-open-suite by axelor.
the class ExpenseServiceImpl method createInvoiceLine.
@Override
public List<InvoiceLine> createInvoiceLine(Invoice invoice, ExpenseLine expenseLine, int priority) throws AxelorException {
Product product = expenseLine.getExpenseProduct();
InvoiceLineGenerator invoiceLineGenerator = null;
Integer atiChoice = invoice.getCompany().getAccountConfig().getInvoiceInAtiSelect();
if (atiChoice == AccountConfigRepository.INVOICE_WT_ALWAYS || atiChoice == AccountConfigRepository.INVOICE_WT_DEFAULT) {
invoiceLineGenerator = new InvoiceLineGenerator(invoice, product, product.getName(), expenseLine.getUntaxedAmount(), expenseLine.getTotalAmount(), expenseLine.getUntaxedAmount(), expenseLine.getComments(), BigDecimal.ONE, product.getUnit(), null, priority, BigDecimal.ZERO, PriceListLineRepository.AMOUNT_TYPE_NONE, expenseLine.getUntaxedAmount(), expenseLine.getTotalAmount(), false) {
@Override
public List<InvoiceLine> creates() throws AxelorException {
InvoiceLine invoiceLine = this.createInvoiceLine();
List<InvoiceLine> invoiceLines = new ArrayList<>();
invoiceLines.add(invoiceLine);
return invoiceLines;
}
};
} else {
invoiceLineGenerator = new InvoiceLineGenerator(invoice, product, product.getName(), expenseLine.getUntaxedAmount(), expenseLine.getTotalAmount(), expenseLine.getTotalAmount(), expenseLine.getComments(), BigDecimal.ONE, product.getUnit(), null, priority, BigDecimal.ZERO, PriceListLineRepository.AMOUNT_TYPE_NONE, expenseLine.getUntaxedAmount(), expenseLine.getTotalAmount(), false) {
@Override
public List<InvoiceLine> creates() throws AxelorException {
InvoiceLine invoiceLine = this.createInvoiceLine();
List<InvoiceLine> invoiceLines = new ArrayList<>();
invoiceLines.add(invoiceLine);
return invoiceLines;
}
};
}
return invoiceLineGenerator.creates();
}
use of com.axelor.apps.base.db.Product in project axelor-open-suite by axelor.
the class ReservedQtyServiceImpl method allocateReservedQuantityInSaleOrderLines.
/**
* The new parameter allocated stock move line is used if we are allocating a stock move line.
* This method will reallocate the lines with the same stock move (and the same product) before
* other stock move lines.
*
* <p>We are using an optional because in the basic use of the method, the argument is empty.
*/
protected BigDecimal allocateReservedQuantityInSaleOrderLines(BigDecimal qtyToAllocate, StockLocation stockLocation, Product product, Unit stockLocationLineUnit, Optional<StockMoveLine> allocatedStockMoveLine) throws AxelorException {
List<StockMoveLine> stockMoveLineListToAllocate = stockMoveLineRepository.all().filter("self.stockMove.fromStockLocation.id = :stockLocationId " + "AND self.product.id = :productId " + "AND self.stockMove.statusSelect = :planned " + "AND self.reservationDateTime IS NOT NULL " + "AND self.reservedQty < self.requestedReservedQty").bind("stockLocationId", stockLocation.getId()).bind("productId", product.getId()).bind("planned", StockMoveRepository.STATUS_PLANNED).order("reservationDateTime").order("stockMove.estimatedDate").fetch();
// put stock move lines with the same stock move on the beginning of the list.
allocatedStockMoveLine.ifPresent(stockMoveLine -> stockMoveLineListToAllocate.sort(// Note: this comparator imposes orderings that are inconsistent with equals.
(sml1, sml2) -> {
if (sml1.getStockMove().equals(sml2.getStockMove())) {
return 0;
} else if (sml1.getStockMove().equals(stockMoveLine.getStockMove())) {
return -1;
} else if (sml2.getStockMove().equals(stockMoveLine.getStockMove())) {
return 1;
} else {
return 0;
}
}));
BigDecimal leftQtyToAllocate = qtyToAllocate;
for (StockMoveLine stockMoveLine : stockMoveLineListToAllocate) {
BigDecimal leftQtyToAllocateStockMove = convertUnitWithProduct(stockLocationLineUnit, stockMoveLine.getUnit(), leftQtyToAllocate, product);
BigDecimal neededQtyToAllocate = stockMoveLine.getRequestedReservedQty().subtract(stockMoveLine.getReservedQty());
BigDecimal allocatedStockMoveQty = leftQtyToAllocateStockMove.min(neededQtyToAllocate);
BigDecimal allocatedQty = convertUnitWithProduct(stockMoveLine.getUnit(), stockLocationLineUnit, allocatedStockMoveQty, product);
// update reserved qty in stock move line and sale order line
updateReservedQuantityFromStockMoveLine(stockMoveLine, product, allocatedStockMoveQty);
// update left qty to allocate
leftQtyToAllocate = leftQtyToAllocate.subtract(allocatedQty);
}
return qtyToAllocate.subtract(leftQtyToAllocate);
}
use of com.axelor.apps.base.db.Product in project axelor-open-suite by axelor.
the class ReservedQtyServiceImpl method changeRequestedQtyLowerThanQty.
/**
* On planning, we want the requested quantity to be equal or lower to the quantity of the line.
* So, if the requested quantity is greater than the quantity, we change it to be equal.
*
* @param stockMoveLine
* @throws AxelorException
*/
protected void changeRequestedQtyLowerThanQty(StockMoveLine stockMoveLine) throws AxelorException {
BigDecimal qty = stockMoveLine.getRealQty().max(BigDecimal.ZERO);
BigDecimal requestedReservedQty = stockMoveLine.getRequestedReservedQty();
if (requestedReservedQty.compareTo(qty) > 0) {
Product product = stockMoveLine.getProduct();
BigDecimal diffRequestedQty = requestedReservedQty.subtract(qty);
stockMoveLine.setRequestedReservedQty(qty);
// update in stock location line
StockLocationLine stockLocationLine = stockLocationLineService.getOrCreateStockLocationLine(stockMoveLine.getStockMove().getFromStockLocation(), product);
BigDecimal diffRequestedQuantityLocation = convertUnitWithProduct(stockMoveLine.getUnit(), stockLocationLine.getUnit(), diffRequestedQty, product);
stockLocationLine.setRequestedReservedQty(stockLocationLine.getRequestedReservedQty().add(diffRequestedQuantityLocation));
}
}
use of com.axelor.apps.base.db.Product in project axelor-open-suite by axelor.
the class SaleOrderInvoiceServiceImpl method generateAdvancePayment.
@Override
@Transactional(rollbackOn = { Exception.class })
public Invoice generateAdvancePayment(SaleOrder saleOrder, BigDecimal amountToInvoice, boolean isPercent) throws AxelorException {
List<SaleOrderLineTax> taxLineList = saleOrder.getSaleOrderLineTaxList();
AccountConfigService accountConfigService = Beans.get(AccountConfigService.class);
BigDecimal percentToInvoice = computeAmountToInvoicePercent(saleOrder, amountToInvoice, isPercent);
Product invoicingProduct = accountConfigService.getAccountConfig(saleOrder.getCompany()).getAdvancePaymentProduct();
Account advancePaymentAccount = accountConfigService.getAccountConfig(saleOrder.getCompany()).getAdvancePaymentAccount();
if (invoicingProduct == null) {
throw new AxelorException(saleOrder, TraceBackRepository.CATEGORY_CONFIGURATION_ERROR, I18n.get(IExceptionMessage.SO_INVOICE_MISSING_ADVANCE_PAYMENT_PRODUCT));
}
if (advancePaymentAccount == null) {
throw new AxelorException(saleOrder, TraceBackRepository.CATEGORY_CONFIGURATION_ERROR, I18n.get(IExceptionMessage.SO_INVOICE_MISSING_ADVANCE_PAYMENT_ACCOUNT), saleOrder.getCompany().getName());
}
Invoice invoice = createInvoiceAndLines(saleOrder, taxLineList, invoicingProduct, percentToInvoice, InvoiceRepository.OPERATION_SUB_TYPE_ADVANCE, advancePaymentAccount);
// no need for link to sale order lines for an advance payment
if (invoice.getInvoiceLineList() != null) {
invoice.getInvoiceLineList().forEach(invoiceLine -> invoiceLine.setSaleOrderLine(null));
}
return invoiceRepo.save(invoice);
}
use of com.axelor.apps.base.db.Product in project axelor-open-suite by axelor.
the class MrpServiceImpl method computeMultipleProductsPurchaseReorderQty.
protected BigDecimal computeMultipleProductsPurchaseReorderQty(Product product, BigDecimal reorderQty) {
List<ProductMultipleQty> productMultipleQtyList = product.getPurchaseProductMultipleQtyList();
if (productMultipleQtyList == null || reorderQty == null || reorderQty.signum() == 0) {
return reorderQty;
}
BigDecimal diff = productMultipleQtyList.stream().map(ProductMultipleQty::getMultipleQty).filter(bigDecimal -> bigDecimal.signum() != 0).map(bigDecimal -> {
BigDecimal remainder = reorderQty.remainder(bigDecimal);
return remainder.signum() == 0 ? BigDecimal.ZERO : bigDecimal.subtract(remainder);
}).min(Comparator.naturalOrder()).orElse(BigDecimal.ZERO);
return reorderQty.add(diff);
}
Aggregations