use of com.axelor.apps.stock.db.InventoryLine in project axelor-open-suite by axelor.
the class InventoryService method storeLastInventoryData.
private void storeLastInventoryData(Inventory inventory) {
Map<Pair<Product, TrackingNumber>, BigDecimal> realQties = new HashMap<>();
Map<Product, BigDecimal> consolidatedRealQties = new HashMap<>();
Map<Product, String> realRacks = new HashMap<>();
List<InventoryLine> inventoryLineList = inventory.getInventoryLineList();
if (inventoryLineList != null) {
for (InventoryLine inventoryLine : inventoryLineList) {
Product product = inventoryLine.getProduct();
TrackingNumber trackingNumber = inventoryLine.getTrackingNumber();
realQties.put(Pair.of(product, trackingNumber), inventoryLine.getRealQty());
BigDecimal realQty = consolidatedRealQties.getOrDefault(product, BigDecimal.ZERO);
realQty = realQty.add(inventoryLine.getRealQty());
consolidatedRealQties.put(product, realQty);
realRacks.put(product, inventoryLine.getRack());
}
}
List<StockLocationLine> stockLocationLineList = inventory.getStockLocation().getStockLocationLineList();
if (stockLocationLineList != null) {
for (StockLocationLine stockLocationLine : stockLocationLineList) {
Product product = stockLocationLine.getProduct();
BigDecimal realQty = consolidatedRealQties.get(product);
if (realQty != null) {
stockLocationLine.setLastInventoryRealQty(realQty);
stockLocationLine.setLastInventoryDateT(inventory.getValidatedOn().atStartOfDay().atZone(ZoneOffset.UTC));
}
String rack = realRacks.get(product);
if (rack != null) {
stockLocationLine.setRack(rack);
}
}
}
List<StockLocationLine> detailsStockLocationLineList = inventory.getStockLocation().getDetailsStockLocationLineList();
if (detailsStockLocationLineList != null) {
for (StockLocationLine detailsStockLocationLine : detailsStockLocationLineList) {
Product product = detailsStockLocationLine.getProduct();
TrackingNumber trackingNumber = detailsStockLocationLine.getTrackingNumber();
BigDecimal realQty = realQties.get(Pair.of(product, trackingNumber));
if (realQty != null) {
detailsStockLocationLine.setLastInventoryRealQty(realQty);
detailsStockLocationLine.setLastInventoryDateT(inventory.getValidatedOn().atStartOfDay().atZone(ZoneOffset.UTC));
}
String rack = realRacks.get(product);
if (rack != null) {
detailsStockLocationLine.setRack(rack);
}
}
}
}
use of com.axelor.apps.stock.db.InventoryLine in project axelor-open-suite by axelor.
the class InventoryService method generateStockMove.
/**
* Generate a stock move from an inventory.
*
* @param inventory a realized inventory.
* @param isEnteringStock whether we want to create incoming or upcoming stock move of this
* inventory.
* @return the generated stock move.
* @throws AxelorException
*/
public StockMove generateStockMove(Inventory inventory, boolean isEnteringStock) throws AxelorException {
StockLocation toStockLocation;
StockLocation fromStockLocation;
Company company = inventory.getCompany();
if (isEnteringStock) {
toStockLocation = inventory.getStockLocation();
fromStockLocation = stockConfigService.getInventoryVirtualStockLocation(stockConfigService.getStockConfig(company));
} else {
toStockLocation = stockConfigService.getInventoryVirtualStockLocation(stockConfigService.getStockConfig(company));
fromStockLocation = inventory.getStockLocation();
}
String inventorySeq = inventory.getInventorySeq();
LocalDate inventoryDate = inventory.getPlannedStartDateT().toLocalDate();
LocalDate realDate = inventory.getValidatedOn();
StockMove stockMove = stockMoveService.createStockMove(null, null, company, fromStockLocation, toStockLocation, realDate, inventoryDate, null, StockMoveRepository.TYPE_INTERNAL);
stockMove.setName(inventorySeq);
stockMove.setOriginTypeSelect(StockMoveRepository.ORIGIN_INVENTORY);
stockMove.setOriginId(inventory.getId());
stockMove.setOrigin(inventorySeq);
for (InventoryLine inventoryLine : inventory.getInventoryLineList()) {
generateStockMoveLines(inventoryLine, stockMove, isEnteringStock);
}
if (stockMove.getStockMoveLineList() != null && !stockMove.getStockMoveLineList().isEmpty()) {
stockMoveService.plan(stockMove);
stockMoveService.copyQtyToRealQty(stockMove);
stockMoveService.realize(stockMove, false);
}
return stockMove;
}
use of com.axelor.apps.stock.db.InventoryLine in project axelor-open-suite by axelor.
the class InventoryService method getInventoryLines.
public HashMap<String, InventoryLine> getInventoryLines(Inventory inventory) {
HashMap<String, InventoryLine> inventoryLineMap = new HashMap<>();
for (InventoryLine line : inventory.getInventoryLineList()) {
StringBuilder key = new StringBuilder();
if (line.getProduct() != null) {
key.append(line.getProduct().getCode());
}
if (line.getTrackingNumber() != null) {
key.append(line.getTrackingNumber().getTrackingNumberSeq());
}
inventoryLineMap.put(key.toString(), line);
}
return inventoryLineMap;
}
use of com.axelor.apps.stock.db.InventoryLine in project axelor-open-suite by axelor.
the class ImportInventoryLine method importInventoryLine.
@Transactional(rollbackOn = { Exception.class })
public Object importInventoryLine(Object bean, Map<String, Object> values) throws AxelorException {
assert bean instanceof InventoryLine;
InventoryLine inventoryLine = (InventoryLine) bean;
TrackingNumberConfiguration trackingNumberConfig = inventoryLine.getProduct().getTrackingNumberConfiguration();
BigDecimal qtyByTracking = BigDecimal.ONE;
BigDecimal realQtyRemaning = inventoryLine.getRealQty();
inventoryLineService.compute(inventoryLine, inventoryLine.getInventory());
TrackingNumber trackingNumber;
if (trackingNumberConfig != null) {
if (trackingNumberConfig.getGenerateProductionAutoTrackingNbr()) {
qtyByTracking = trackingNumberConfig.getProductionQtyByTracking();
} else if (trackingNumberConfig.getGeneratePurchaseAutoTrackingNbr()) {
qtyByTracking = trackingNumberConfig.getPurchaseQtyByTracking();
} else {
qtyByTracking = trackingNumberConfig.getSaleQtyByTracking();
}
InventoryLine inventoryLineNew;
for (int i = 0; i < inventoryLine.getRealQty().intValue(); i += qtyByTracking.intValue()) {
trackingNumber = trackingNumberService.createTrackingNumber(inventoryLine.getProduct(), inventoryLine.getInventory().getStockLocation().getCompany(), appBaseService.getTodayDate(inventoryLine.getInventory().getStockLocation().getCompany()), inventoryLine.getInventory().getInventorySeq());
if (realQtyRemaning.compareTo(qtyByTracking) < 0) {
trackingNumber.setCounter(realQtyRemaning);
} else {
trackingNumber.setCounter(qtyByTracking);
}
inventoryLineNew = inventoryLineService.createInventoryLine(inventoryLine.getInventory(), inventoryLine.getProduct(), inventoryLine.getCurrentQty(), inventoryLine.getRack(), trackingNumber);
inventoryLineNew.setUnit(inventoryLine.getProduct().getUnit());
if (realQtyRemaning.compareTo(qtyByTracking) < 0) {
inventoryLineNew.setRealQty(realQtyRemaning);
} else {
inventoryLineNew.setRealQty(qtyByTracking);
realQtyRemaning = realQtyRemaning.subtract(qtyByTracking);
}
inventoryLineRepo.save(inventoryLineNew);
}
return null;
}
return bean;
}
use of com.axelor.apps.stock.db.InventoryLine in project axelor-open-suite by axelor.
the class StockMoveServiceImpl method checkOngoingInventory.
/**
* Check and raise an exception if the provided stock move is involved in an ongoing inventory.
*
* @param stockMove
* @throws AxelorException
*/
private void checkOngoingInventory(StockMove stockMove) throws AxelorException {
List<StockLocation> stockLocationList = new ArrayList<>();
if (stockMove.getFromStockLocation().getTypeSelect() != StockLocationRepository.TYPE_VIRTUAL) {
stockLocationList.add(stockMove.getFromStockLocation());
}
if (stockMove.getToStockLocation().getTypeSelect() != StockLocationRepository.TYPE_VIRTUAL) {
stockLocationList.add(stockMove.getToStockLocation());
}
if (stockLocationList.isEmpty()) {
return;
}
List<Product> productList = stockMove.getStockMoveLineList().stream().map(StockMoveLine::getProduct).filter(Objects::nonNull).collect(Collectors.toList());
if (productList.isEmpty()) {
return;
}
InventoryLineRepository inventoryLineRepo = Beans.get(InventoryLineRepository.class);
InventoryLine inventoryLine = inventoryLineRepo.all().filter("self.inventory.statusSelect BETWEEN :startStatus AND :endStatus\n" + "AND self.inventory.stockLocation IN (:stockLocationList)\n" + "AND self.product IN (:productList)").bind("startStatus", InventoryRepository.STATUS_IN_PROGRESS).bind("endStatus", InventoryRepository.STATUS_COMPLETED).bind("stockLocationList", stockLocationList).bind("productList", productList).fetchOne();
if (inventoryLine != null) {
throw new AxelorException(inventoryLine, TraceBackRepository.CATEGORY_INCONSISTENCY, I18n.get(IExceptionMessage.STOCK_MOVE_19), inventoryLine.getInventory().getInventorySeq());
}
}
Aggregations