use of com.axelor.apps.stock.db.StockMove in project axelor-open-suite by axelor.
the class StockMoveMultiInvoiceServiceImpl method createInvoiceFromMultiIncomingStockMove.
@Override
@Transactional(rollbackOn = { Exception.class })
public Optional<Invoice> createInvoiceFromMultiIncomingStockMove(List<StockMove> stockMoveList) throws AxelorException {
if (stockMoveList == null || stockMoveList.isEmpty()) {
return Optional.empty();
}
// create dummy invoice from the first stock move
Invoice dummyInvoice = createDummyInInvoice(stockMoveList.get(0));
// Check if field constraints are respected
for (StockMove stockMove : stockMoveList) {
completeInvoiceInMultiIncomingStockMove(dummyInvoice, stockMove);
}
/* 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()));
}
fillReferenceInvoiceFromMultiInStockMove(stockMoveList, dummyInvoice);
InvoiceGenerator invoiceGenerator = new InvoiceGenerator(InvoiceRepository.OPERATION_TYPE_SUPPLIER_PURCHASE, 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(), null) {
@Override
public Invoice generate() throws AxelorException {
return super.createInvoiceHeader();
}
};
Invoice invoice = invoiceGenerator.generate();
invoice.setAddressStr(dummyInvoice.getAddressStr());
List<InvoiceLine> invoiceLineList = new ArrayList<>();
for (StockMove stockMoveLocal : stockMoveList) {
List<InvoiceLine> createdInvoiceLines = stockMoveInvoiceService.createInvoiceLines(invoice, stockMoveLocal, stockMoveLocal.getStockMoveLineList(), null);
if (stockMoveLocal.getTypeSelect() == StockMoveRepository.TYPE_OUTGOING) {
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_SUPPLIER_REFUND);
}
stockMoveList.forEach(invoice::addStockMoveSetItem);
return Optional.of(invoice);
}
use of com.axelor.apps.stock.db.StockMove in project axelor-open-suite by axelor.
the class StockMoveInvoiceServiceImpl method createInvoiceFromSaleOrder.
@Override
@Transactional(rollbackOn = { Exception.class })
public Invoice createInvoiceFromSaleOrder(StockMove stockMove, SaleOrder saleOrder, Map<Long, BigDecimal> qtyToInvoiceMap) throws AxelorException {
// we block if we are trying to invoice partially if config is deactivated
if (!supplyChainConfigService.getSupplyChainConfig(stockMove.getCompany()).getActivateOutStockMovePartialInvoicing() && computeNonCanceledInvoiceQty(stockMove).signum() > 0) {
throw new AxelorException(TraceBackRepository.CATEGORY_INCONSISTENCY, I18n.get(IExceptionMessage.STOCK_MOVE_PARTIAL_INVOICE_ERROR), stockMove.getStockMoveSeq());
}
InvoiceGenerator invoiceGenerator = saleOrderInvoiceService.createInvoiceGenerator(saleOrder, stockMove.getIsReversion());
Invoice invoice = invoiceGenerator.generate();
checkSplitSalePartiallyInvoicedStockMoveLines(stockMove, stockMove.getStockMoveLineList());
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;
}
invoice.setSaleOrder(saleOrder);
this.extendInternalReference(stockMove, invoice);
invoice.setDeliveryAddress(stockMove.getToAddress());
invoice.setDeliveryAddressStr(stockMove.getToAddressStr());
invoice.setAddressStr(saleOrder.getMainInvoicingAddressStr());
// fill default advance payment invoice
if (invoice.getOperationSubTypeSelect() != InvoiceRepository.OPERATION_SUB_TYPE_ADVANCE) {
invoice.setAdvancePaymentInvoiceSet(Beans.get(InvoiceService.class).getDefaultAdvancePaymentInvoice(invoice));
}
invoice.setPartnerTaxNbr(saleOrder.getClientPartner().getTaxNbr());
if (!Strings.isNullOrEmpty(saleOrder.getInvoiceComments())) {
invoice.setNote(saleOrder.getInvoiceComments());
}
if (ObjectUtils.isEmpty(invoice.getProformaComments()) && !Strings.isNullOrEmpty(saleOrder.getProformaComments())) {
invoice.setProformaComments(saleOrder.getProformaComments());
}
Set<StockMove> stockMoveSet = invoice.getStockMoveSet();
if (stockMoveSet == null) {
stockMoveSet = new HashSet<>();
invoice.setStockMoveSet(stockMoveSet);
}
stockMoveSet.add(stockMove);
invoiceRepository.save(invoice);
}
return invoice;
}
use of com.axelor.apps.stock.db.StockMove 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.StockMove 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.StockMove in project axelor-open-suite by axelor.
the class StockMoveServiceSupplychainImpl method splitInto2.
@Override
@Transactional(rollbackOn = { Exception.class })
public StockMove splitInto2(StockMove originalStockMove, List<StockMoveLine> modifiedStockMoveLines) throws AxelorException {
StockMove newStockMove = super.splitInto2(originalStockMove, modifiedStockMoveLines);
newStockMove.setOrigin(originalStockMove.getOrigin());
newStockMove.setOriginTypeSelect(originalStockMove.getOriginTypeSelect());
newStockMove.setOriginId(originalStockMove.getOriginId());
return newStockMove;
}
Aggregations