use of com.axelor.apps.stock.db.StockLocation in project axelor-open-suite by axelor.
the class MrpLineServiceImpl method generatePurchaseProposal.
@Transactional(rollbackOn = { Exception.class })
protected void generatePurchaseProposal(MrpLine mrpLine, Map<Pair<Partner, LocalDate>, PurchaseOrder> purchaseOrders, Map<Partner, PurchaseOrder> purchaseOrdersPerSupplier, boolean isProposalsPerSupplier) throws AxelorException {
Product product = mrpLine.getProduct();
StockLocation stockLocation = mrpLine.getStockLocation();
LocalDate maturityDate = mrpLine.getMaturityDate();
Partner supplierPartner = mrpLine.getSupplierPartner();
if (supplierPartner == null) {
supplierPartner = product.getDefaultSupplierPartner();
if (supplierPartner == null) {
throw new AxelorException(mrpLine, TraceBackRepository.CATEGORY_CONFIGURATION_ERROR, I18n.get(IExceptionMessage.MRP_LINE_1), product.getFullName());
}
}
Company company = stockLocation.getCompany();
Pair<Partner, LocalDate> key = null;
PurchaseOrder purchaseOrder = null;
if (isProposalsPerSupplier) {
if (purchaseOrdersPerSupplier != null) {
purchaseOrder = purchaseOrdersPerSupplier.get(supplierPartner);
}
} else {
if (purchaseOrders != null) {
key = Pair.of(supplierPartner, maturityDate);
purchaseOrder = purchaseOrders.get(key);
}
}
if (purchaseOrder == null) {
purchaseOrder = purchaseOrderRepo.save(purchaseOrderSupplychainService.createPurchaseOrder(AuthUtils.getUser(), company, null, supplierPartner.getCurrency(), maturityDate, this.getPurchaseOrderOrigin(mrpLine), null, stockLocation, appBaseService.getTodayDate(company), Beans.get(PartnerPriceListService.class).getDefaultPriceList(supplierPartner, PriceListRepository.TYPE_PURCHASE), supplierPartner, null));
if (isProposalsPerSupplier) {
if (purchaseOrdersPerSupplier != null) {
purchaseOrdersPerSupplier.put(supplierPartner, purchaseOrder);
}
} else {
if (purchaseOrders != null) {
purchaseOrders.put(key, purchaseOrder);
}
}
if (mrpLine.getMrpLineOriginList().size() == 1) {
if (mrpLine.getMrpLineOriginList().get(0).getRelatedToSelect().equals(MrpLineOriginRepository.RELATED_TO_SALE_ORDER_LINE)) {
purchaseOrder.setGeneratedSaleOrderId(saleOrderLineRepo.find(mrpLine.getMrpLineOriginList().get(0).getRelatedToSelectId()).getSaleOrder().getId());
}
}
}
Unit unit = product.getPurchasesUnit();
BigDecimal qty = mrpLine.getQty();
if (unit == null) {
unit = product.getUnit();
} else {
qty = Beans.get(UnitConversionService.class).convert(product.getUnit(), unit, qty, qty.scale(), product);
}
PurchaseOrderLine poLine = purchaseOrderLineService.createPurchaseOrderLine(purchaseOrder, product, null, null, qty, unit);
poLine.setDesiredDelivDate(maturityDate);
purchaseOrder.addPurchaseOrderLineListItem(poLine);
purchaseOrderService.computePurchaseOrder(purchaseOrder);
linkToOrder(mrpLine, purchaseOrder);
}
use of com.axelor.apps.stock.db.StockLocation in project axelor-open-suite by axelor.
the class MrpServiceImpl method checkInsufficientCumulativeQty.
@Transactional(rollbackOn = { Exception.class })
protected boolean checkInsufficientCumulativeQty(MrpLine mrpLine, Product product, boolean firstPass) throws AxelorException {
BigDecimal cumulativeQty = mrpLine.getCumulativeQty();
MrpLineType mrpLineType = mrpLine.getMrpLineType();
boolean isProposalElement = this.isProposalElement(mrpLineType);
BigDecimal minQty = mrpLine.getMinQty();
if ((((mrpLine.getMrpLineType().getElementSelect() != MrpLineTypeRepository.ELEMENT_AVAILABLE_STOCK) && (!isProposalElement || mrpLineType.getTypeSelect() == MrpLineTypeRepository.TYPE_OUT)) || (mrpLine.getMrpLineType().getElementSelect() == MrpLineTypeRepository.ELEMENT_AVAILABLE_STOCK && firstPass)) && cumulativeQty.compareTo(mrpLine.getMinQty()) < 0) {
Company company = null;
StockLocation stockLocation = mrpLine.getStockLocation();
log.debug("Cumulative qty ({} < {}) is insufficient for product ({}) at the maturity date ({})", cumulativeQty, minQty, product.getFullName(), mrpLine.getMaturityDate());
BigDecimal reorderQty = minQty.subtract(cumulativeQty);
StockRules stockRules = stockRulesService.getStockRules(product, stockLocation, StockRulesRepository.TYPE_FUTURE, StockRulesRepository.USE_CASE_USED_FOR_MRP);
if (stockRules != null) {
reorderQty = reorderQty.max(stockRules.getReOrderQty());
}
if (stockLocation.getCompany() != null) {
company = stockLocation.getCompany();
}
MrpLineType mrpLineTypeProposal = this.getMrpLineTypeForProposal(stockRules, product, company);
if (mrpLineTypeProposal == null) {
return false;
}
long duplicateCount = mrpLineRepository.all().filter("self.mrp.id = ?1 AND self.isEditedByUser = ?2 AND self.product = ?3 AND self.relatedToSelectName = ?4", mrp.getId(), true, product, mrpLine.getRelatedToSelectName()).count();
if (duplicateCount != 0) {
return false;
}
this.createProposalMrpLine(mrpLine.getMrp(), product, mrpLineTypeProposal, reorderQty, stockLocation, mrpLine.getMaturityDate(), mrpLine.getMrpLineOriginList(), mrpLine.getRelatedToSelectName());
return true;
}
return false;
}
use of com.axelor.apps.stock.db.StockLocation in project axelor-open-suite by axelor.
the class PurchaseOrderStockServiceImpl method createStockMove.
protected List<Long> createStockMove(PurchaseOrder purchaseOrder, LocalDate estimatedDeliveryDate, List<PurchaseOrderLine> purchaseOrderLineList) throws AxelorException {
List<Long> stockMoveIdList = new ArrayList<>();
Partner supplierPartner = purchaseOrder.getSupplierPartner();
Company company = purchaseOrder.getCompany();
Address address = Beans.get(PartnerService.class).getDeliveryAddress(supplierPartner);
StockLocation startLocation = getStartStockLocation(purchaseOrder);
StockMove stockMove = stockMoveService.createStockMove(address, null, company, supplierPartner, startLocation, purchaseOrder.getStockLocation(), null, estimatedDeliveryDate, purchaseOrder.getNotes(), purchaseOrder.getShipmentMode(), purchaseOrder.getFreightCarrierMode(), null, null, null, StockMoveRepository.TYPE_INCOMING);
StockMove qualityStockMove = stockMoveService.createStockMove(address, null, company, supplierPartner, startLocation, appBaseService.getAppBase().getEnableTradingNamesManagement() ? purchaseOrder.getTradingName().getQualityControlDefaultStockLocation() : company.getStockConfig().getQualityControlDefaultStockLocation(), null, estimatedDeliveryDate, purchaseOrder.getNotes(), purchaseOrder.getShipmentMode(), purchaseOrder.getFreightCarrierMode(), null, null, null, StockMoveRepository.TYPE_INCOMING);
stockMove.setOriginId(purchaseOrder.getId());
stockMove.setOriginTypeSelect(StockMoveRepository.ORIGIN_PURCHASE_ORDER);
stockMove.setOrigin(purchaseOrder.getPurchaseOrderSeq());
stockMove.setTradingName(purchaseOrder.getTradingName());
stockMove.setGroupProductsOnPrintings(purchaseOrder.getGroupProductsOnPrintings());
qualityStockMove.setOriginId(purchaseOrder.getId());
qualityStockMove.setOriginTypeSelect(StockMoveRepository.ORIGIN_PURCHASE_ORDER);
qualityStockMove.setOrigin(purchaseOrder.getPurchaseOrderSeq());
qualityStockMove.setTradingName(purchaseOrder.getTradingName());
qualityStockMove.setGroupProductsOnPrintings(purchaseOrder.getGroupProductsOnPrintings());
SupplyChainConfig supplychainConfig = Beans.get(SupplyChainConfigService.class).getSupplyChainConfig(purchaseOrder.getCompany());
if (supplychainConfig.getDefaultEstimatedDateForPurchaseOrder() == SupplyChainConfigRepository.CURRENT_DATE && stockMove.getEstimatedDate() == null) {
stockMove.setEstimatedDate(appBaseService.getTodayDate(company));
} else if (supplychainConfig.getDefaultEstimatedDateForPurchaseOrder() == SupplyChainConfigRepository.CURRENT_DATE_PLUS_DAYS && stockMove.getEstimatedDate() == null) {
stockMove.setEstimatedDate(appBaseService.getTodayDate(company).plusDays(supplychainConfig.getNumberOfDaysForPurchaseOrder().longValue()));
}
for (PurchaseOrderLine purchaseOrderLine : purchaseOrderLineList) {
BigDecimal qty = purchaseOrderLineServiceSupplychainImpl.computeUndeliveredQty(purchaseOrderLine);
if (qty.signum() > 0 && !existActiveStockMoveForPurchaseOrderLine(purchaseOrderLine)) {
this.createStockMoveLine(stockMove, qualityStockMove, purchaseOrderLine, qty);
}
}
if (stockMove.getStockMoveLineList() != null && !stockMove.getStockMoveLineList().isEmpty()) {
stockMoveService.plan(stockMove);
stockMoveIdList.add(stockMove.getId());
}
if (qualityStockMove.getStockMoveLineList() != null && !qualityStockMove.getStockMoveLineList().isEmpty()) {
stockMoveService.plan(qualityStockMove);
stockMoveIdList.add(qualityStockMove.getId());
}
return stockMoveIdList;
}
use of com.axelor.apps.stock.db.StockLocation in project axelor-open-suite by axelor.
the class ProjectedStockServiceImpl method createProjectedStock.
@Transactional(rollbackOn = { Exception.class })
@Override
public List<MrpLine> createProjectedStock(Long productId, Long companyId, Long stockLocationId) throws AxelorException {
Product product = Beans.get(ProductRepository.class).find(productId);
Company company = Beans.get(CompanyRepository.class).find(companyId);
StockLocation stockLocation = stockLocationRepository.find(stockLocationId);
Mrp mrp = new Mrp();
mrp.setStockLocation(findStockLocation(company, stockLocation));
// If a company has no stockLocation
if (mrp.getStockLocation() == null) {
return Collections.emptyList();
}
mrp.addProductSetItem(product);
mrp.setMrpTypeSelect(MrpRepository.MRP_TYPE_MRP);
mrp = Beans.get(MrpRepository.class).save(mrp);
mrp = Beans.get(MrpService.class).createProjectedStock(mrp, product, company, stockLocation);
List<MrpLine> mrpLineList = Beans.get(MrpLineRepository.class).all().filter("self.mrp = ?1 AND self.product = ?2 AND self.qty != 0", mrp, product).order("maturityDate").order("mrpLineType.typeSelect").order("mrpLineType.sequence").order("id").fetch();
if (mrpLineList.isEmpty()) {
List<MrpLine> mrpLineListToDelete = Beans.get(MrpLineRepository.class).all().filter("self.mrp = ?1", mrp).fetch();
removeMrpAndMrpLine(mrpLineListToDelete);
return Collections.emptyList();
}
for (MrpLine mrpLine : mrpLineList) {
mrpLine.setCompany(mrpLine.getStockLocation().getCompany());
mrpLine.setUnit(mrpLine.getProduct().getUnit());
}
return mrpLineList;
}
use of com.axelor.apps.stock.db.StockLocation 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;
}
Aggregations