Search in sources :

Example 21 with StockLocation

use of com.axelor.apps.stock.db.StockLocation in project axelor-open-suite by axelor.

the class SaleOrderController method mergeSaleOrder.

@SuppressWarnings({ "rawtypes", "unchecked" })
public void mergeSaleOrder(ActionRequest request, ActionResponse response) {
    List<SaleOrder> saleOrderList = new ArrayList<>();
    List<Long> saleOrderIdList = new ArrayList<>();
    boolean fromPopup = false;
    String lineToMerge;
    if (request.getContext().get("saleQuotationToMerge") != null) {
        lineToMerge = "saleQuotationToMerge";
    } else {
        lineToMerge = "saleOrderToMerge";
    }
    if (request.getContext().get(lineToMerge) != null) {
        if (request.getContext().get(lineToMerge) instanceof List) {
            // No confirmation popup, sale orders are content in a parameter list
            List<Map> saleOrderMap = (List<Map>) request.getContext().get(lineToMerge);
            for (Map map : saleOrderMap) {
                saleOrderIdList.add(new Long((Integer) map.get("id")));
            }
        } else {
            // After confirmation popup, sale order's id are in a string separated by ","
            String saleOrderIdListStr = (String) request.getContext().get(lineToMerge);
            for (String saleOrderId : saleOrderIdListStr.split(",")) {
                saleOrderIdList.add(new Long(saleOrderId));
            }
            fromPopup = true;
        }
    }
    // Check if currency, clientPartner and company are the same for all selected
    // sale orders
    Currency commonCurrency = null;
    Partner commonClientPartner = null;
    Company commonCompany = null;
    Partner commonContactPartner = null;
    Team commonTeam = null;
    // Useful to determine if a difference exists between teams of all sale orders
    boolean existTeamDiff = false;
    // Useful to determine if a difference exists between contact partners of all
    // sale orders
    boolean existContactPartnerDiff = false;
    PriceList commonPriceList = null;
    // Useful to determine if a difference exists between price lists of all sale
    // orders
    boolean existPriceListDiff = false;
    StockLocation commonLocation = null;
    // Useful to determine if a difference exists between stock locations of all
    // sale orders
    boolean existLocationDiff = false;
    SaleOrder saleOrderTemp;
    int count = 1;
    for (Long saleOrderId : saleOrderIdList) {
        saleOrderTemp = JPA.em().find(SaleOrder.class, saleOrderId);
        saleOrderList.add(saleOrderTemp);
        if (count == 1) {
            commonCurrency = saleOrderTemp.getCurrency();
            commonClientPartner = saleOrderTemp.getClientPartner();
            commonCompany = saleOrderTemp.getCompany();
            commonContactPartner = saleOrderTemp.getContactPartner();
            commonTeam = saleOrderTemp.getTeam();
            commonPriceList = saleOrderTemp.getPriceList();
            commonLocation = saleOrderTemp.getStockLocation();
        } else {
            if (commonCurrency != null && !commonCurrency.equals(saleOrderTemp.getCurrency())) {
                commonCurrency = null;
            }
            if (commonClientPartner != null && !commonClientPartner.equals(saleOrderTemp.getClientPartner())) {
                commonClientPartner = null;
            }
            if (commonCompany != null && !commonCompany.equals(saleOrderTemp.getCompany())) {
                commonCompany = null;
            }
            if (commonContactPartner != null && !commonContactPartner.equals(saleOrderTemp.getContactPartner())) {
                commonContactPartner = null;
                existContactPartnerDiff = true;
            }
            if (commonTeam != null && !commonTeam.equals(saleOrderTemp.getTeam())) {
                commonTeam = null;
                existTeamDiff = true;
            }
            if (commonPriceList != null && !commonPriceList.equals(saleOrderTemp.getPriceList())) {
                commonPriceList = null;
                existPriceListDiff = true;
            }
            if (commonLocation != null && !commonLocation.equals(saleOrderTemp.getStockLocation())) {
                commonLocation = null;
                existLocationDiff = true;
            }
        }
        count++;
    }
    StringBuilder fieldErrors = new StringBuilder();
    if (commonCurrency == null) {
        fieldErrors.append(I18n.get(com.axelor.apps.sale.exception.IExceptionMessage.SALE_ORDER_MERGE_ERROR_CURRENCY));
    }
    if (commonClientPartner == null) {
        if (fieldErrors.length() > 0) {
            fieldErrors.append("<br/>");
        }
        fieldErrors.append(I18n.get(com.axelor.apps.sale.exception.IExceptionMessage.SALE_ORDER_MERGE_ERROR_CLIENT_PARTNER));
    }
    if (commonCompany == null) {
        if (fieldErrors.length() > 0) {
            fieldErrors.append("<br/>");
        }
        fieldErrors.append(I18n.get(com.axelor.apps.sale.exception.IExceptionMessage.SALE_ORDER_MERGE_ERROR_COMPANY));
    }
    if (fieldErrors.length() > 0) {
        response.setFlash(fieldErrors.toString());
        return;
    }
    // Check if priceList or contactPartner are content in parameters
    if (request.getContext().get("priceList") != null) {
        commonPriceList = JPA.em().find(PriceList.class, new Long((Integer) ((Map) request.getContext().get("priceList")).get("id")));
    }
    if (request.getContext().get("contactPartner") != null) {
        commonContactPartner = JPA.em().find(Partner.class, new Long((Integer) ((Map) request.getContext().get("contactPartner")).get("id")));
    }
    if (request.getContext().get("team") != null) {
        commonTeam = JPA.em().find(Team.class, new Long((Integer) ((Map) request.getContext().get("team")).get("id")));
    }
    if (request.getContext().get("stockLocation") != null) {
        commonLocation = JPA.em().find(StockLocation.class, new Long((Integer) ((Map) request.getContext().get("stockLocation")).get("id")));
    }
    if (!fromPopup && (existContactPartnerDiff || existPriceListDiff || existTeamDiff)) {
        // Need to display intermediate screen to select some values
        ActionViewBuilder confirmView = ActionView.define("Confirm merge sale order").model(Wizard.class.getName()).add("form", "sale-order-merge-confirm-form").param("popup", "true").param("show-toolbar", "false").param("show-confirm", "false").param("popup-save", "false").param("forceEdit", "true");
        if (existPriceListDiff) {
            confirmView.context("contextPriceListToCheck", "true");
        }
        if (existContactPartnerDiff) {
            confirmView.context("contextContactPartnerToCheck", "true");
            confirmView.context("contextPartnerId", commonClientPartner.getId().toString());
        }
        if (existTeamDiff) {
            confirmView.context("contextTeamToCheck", "true");
        }
        if (existLocationDiff) {
            confirmView.context("contextLocationToCheck", "true");
        }
        confirmView.context(lineToMerge, Joiner.on(",").join(saleOrderIdList));
        response.setView(confirmView.map());
        return;
    }
    try {
        SaleOrder saleOrder = Beans.get(SaleOrderCreateServiceSupplychainImpl.class).mergeSaleOrders(saleOrderList, commonCurrency, commonClientPartner, commonCompany, commonLocation, commonContactPartner, commonPriceList, commonTeam);
        if (saleOrder != null) {
            // Open the generated sale order in a new tab
            response.setView(ActionView.define("Sale order").model(SaleOrder.class.getName()).add("grid", "sale-order-grid").add("form", "sale-order-form").param("search-filters", "sale-order-filters").param("forceEdit", "true").context("_showRecord", String.valueOf(saleOrder.getId())).map());
            response.setCanClose(true);
        }
    } catch (Exception e) {
        response.setFlash(e.getLocalizedMessage());
    }
}
Also used : Company(com.axelor.apps.base.db.Company) StockLocation(com.axelor.apps.stock.db.StockLocation) ArrayList(java.util.ArrayList) SaleOrder(com.axelor.apps.sale.db.SaleOrder) ActionViewBuilder(com.axelor.meta.schema.actions.ActionView.ActionViewBuilder) AxelorException(com.axelor.exception.AxelorException) SaleOrderCreateServiceSupplychainImpl(com.axelor.apps.supplychain.service.SaleOrderCreateServiceSupplychainImpl) Currency(com.axelor.apps.base.db.Currency) List(java.util.List) PriceList(com.axelor.apps.base.db.PriceList) ArrayList(java.util.ArrayList) Team(com.axelor.team.db.Team) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Partner(com.axelor.apps.base.db.Partner) PriceList(com.axelor.apps.base.db.PriceList) Wizard(com.axelor.apps.base.db.Wizard)

Example 22 with StockLocation

use of com.axelor.apps.stock.db.StockLocation in project axelor-open-suite by axelor.

the class BatchComputeWorkInProgressValuation method process.

@Override
protected void process() {
    ProductionBatch productionBatch = batch.getProductionBatch();
    Company company = productionBatch.getCompany();
    StockLocation workshopStockLocation = productionBatch.getWorkshopStockLocation();
    if (productionBatch.getValuationDate() == null) {
        productionBatch.setValuationDate(Beans.get(AppBaseService.class).getTodayDate(company));
    }
    LocalDate valuationDate = productionBatch.getValuationDate();
    List<ManufOrder> manufOrderList;
    Map<String, Object> bindValues = new HashMap<>();
    String domain = "(self.statusSelect = :statusSelectInProgress or self.statusSelect = :statusSelectStandBy " + "or (self.statusSelect = :statusSelectFinished " + "AND self.realEndDateT BETWEEN :valuationDateT AND :todayDateT))";
    bindValues.put("statusSelectInProgress", ManufOrderRepository.STATUS_IN_PROGRESS);
    bindValues.put("statusSelectStandBy", ManufOrderRepository.STATUS_STANDBY);
    bindValues.put("statusSelectFinished", ManufOrderRepository.STATUS_FINISHED);
    bindValues.put("valuationDateT", valuationDate.atStartOfDay());
    bindValues.put("todayDateT", appBaseService.getTodayDateTime().toLocalDateTime());
    if (company != null) {
        domain += " and self.company.id = :companyId";
        bindValues.put("companyId", company.getId());
    }
    if (workshopStockLocation != null) {
        domain += " and self.workshopStockLocation.id = :stockLocationId";
        bindValues.put("stockLocationId", workshopStockLocation.getId());
    }
    Query<ManufOrder> manufOrderQuery = Beans.get(ManufOrderRepository.class).all().filter(domain).bind(bindValues);
    int offset = 0;
    while (!(manufOrderList = manufOrderQuery.order("id").fetch(FETCH_LIMIT, offset)).isEmpty()) {
        for (ManufOrder manufOrder : manufOrderList) {
            ++offset;
            try {
                costSheetService.computeCostPrice(manufOrder, CostSheetRepository.CALCULATION_WORK_IN_PROGRESS, valuationDate);
                incrementDone();
            } catch (Exception e) {
                incrementAnomaly();
                TraceBackService.trace(e, ExceptionOriginRepository.COST_SHEET, batch.getId());
            }
        }
        JPA.clear();
    }
}
Also used : Company(com.axelor.apps.base.db.Company) StockLocation(com.axelor.apps.stock.db.StockLocation) HashMap(java.util.HashMap) ProductionBatch(com.axelor.apps.production.db.ProductionBatch) LocalDate(java.time.LocalDate) ManufOrderRepository(com.axelor.apps.production.db.repo.ManufOrderRepository) ManufOrder(com.axelor.apps.production.db.ManufOrder)

Example 23 with StockLocation

use of com.axelor.apps.stock.db.StockLocation in project axelor-open-suite by axelor.

the class ProductionProductStockLocationServiceImpl method computeIndicators.

@Override
public Map<String, Object> computeIndicators(Long productId, Long companyId, Long stockLocationId) throws AxelorException {
    Map<String, Object> map = super.computeIndicators(productId, companyId, stockLocationId);
    Product product = productRepository.find(productId);
    Company company = companyRepository.find(companyId);
    StockLocation stockLocation = stockLocationRepository.find(stockLocationId);
    int scale = appBaseService.getNbDecimalDigitForQty();
    BigDecimal consumeManufOrderQty = this.getConsumeManufOrderQty(product, company, stockLocation).setScale(scale, RoundingMode.HALF_UP);
    BigDecimal availableQty = (BigDecimal) map.getOrDefault("$availableQty", BigDecimal.ZERO.setScale(scale, RoundingMode.HALF_UP));
    map.put("$buildingQty", this.getBuildingQty(product, company, stockLocation).setScale(scale, RoundingMode.HALF_UP));
    map.put("$consumeManufOrderQty", consumeManufOrderQty);
    map.put("$missingManufOrderQty", BigDecimal.ZERO.max(consumeManufOrderQty.subtract(availableQty)).setScale(scale, RoundingMode.HALF_UP));
    return map;
}
Also used : Company(com.axelor.apps.base.db.Company) StockLocation(com.axelor.apps.stock.db.StockLocation) Product(com.axelor.apps.base.db.Product) BigDecimal(java.math.BigDecimal)

Example 24 with StockLocation

use of com.axelor.apps.stock.db.StockLocation in project axelor-open-suite by axelor.

the class StockLocationServiceSupplychainImpl method getReservedQty.

@Override
public BigDecimal getReservedQty(Long productId, Long locationId, Long companyId) throws AxelorException {
    if (productId != null) {
        Product product = productRepo.find(productId);
        Unit productUnit = product.getUnit();
        UnitConversionService unitConversionService = Beans.get(UnitConversionService.class);
        if (locationId == null || locationId == 0L) {
            List<StockLocation> stockLocations = getNonVirtualStockLocations(companyId);
            if (!stockLocations.isEmpty()) {
                BigDecimal reservedQty = BigDecimal.ZERO;
                for (StockLocation stockLocation : stockLocations) {
                    StockLocationLine stockLocationLine = stockLocationLineService.getOrCreateStockLocationLine(stockLocationRepo.find(stockLocation.getId()), productRepo.find(productId));
                    if (stockLocationLine != null) {
                        Unit stockLocationLineUnit = stockLocationLine.getUnit();
                        reservedQty = reservedQty.add(stockLocationLine.getReservedQty());
                        if (productUnit != null && !productUnit.equals(stockLocationLineUnit)) {
                            reservedQty = unitConversionService.convert(stockLocationLineUnit, productUnit, reservedQty, reservedQty.scale(), product);
                        }
                    }
                }
                return reservedQty;
            }
        } else {
            StockLocationLine stockLocationLine = stockLocationLineService.getOrCreateStockLocationLine(stockLocationRepo.find(locationId), productRepo.find(productId));
            if (stockLocationLine != null) {
                Unit stockLocationLineUnit = stockLocationLine.getUnit();
                if (productUnit != null && !productUnit.equals(stockLocationLineUnit)) {
                    return unitConversionService.convert(stockLocationLineUnit, productUnit, stockLocationLine.getReservedQty(), stockLocationLine.getReservedQty().scale(), product);
                }
                return stockLocationLine.getReservedQty();
            }
        }
    }
    return BigDecimal.ZERO;
}
Also used : UnitConversionService(com.axelor.apps.base.service.UnitConversionService) StockLocation(com.axelor.apps.stock.db.StockLocation) Product(com.axelor.apps.base.db.Product) StockLocationLine(com.axelor.apps.stock.db.StockLocationLine) Unit(com.axelor.apps.base.db.Unit) BigDecimal(java.math.BigDecimal)

Example 25 with StockLocation

use of com.axelor.apps.stock.db.StockLocation in project axelor-open-suite by axelor.

the class StockRulesServiceSupplychainImpl method generatePurchaseOrder.

@Override
@Transactional(rollbackOn = { Exception.class })
public void generatePurchaseOrder(Product product, BigDecimal qty, StockLocationLine stockLocationLine, int type) throws AxelorException {
    if (!Beans.get(AppSupplychainService.class).isApp("supplychain")) {
        super.generatePurchaseOrder(product, qty, stockLocationLine, type);
        return;
    }
    StockLocation stockLocation = stockLocationLine.getStockLocation();
    // TODO à supprimer après suppression des variantes
    if (stockLocation == null) {
        return;
    }
    StockRules stockRules = this.getStockRules(product, stockLocation, type, StockRulesRepository.USE_CASE_STOCK_CONTROL);
    if (stockRules == null) {
        return;
    }
    if (this.useMinStockRules(stockLocationLine, stockRules, qty, type)) {
        if (stockRules.getOrderAlertSelect().equals(StockRulesRepository.ORDER_ALERT_ALERT)) {
            this.generateAndSendMessage(stockRules);
        } else if (stockRules.getOrderAlertSelect().equals(StockRulesRepository.ORDER_ALERT_PURCHASE_ORDER)) {
            BigDecimal minReorderQty = getDefaultSupplierMinQty(product);
            BigDecimal qtyToOrder = this.getQtyToOrder(qty, stockLocationLine, type, stockRules, minReorderQty);
            Partner supplierPartner = product.getDefaultSupplierPartner();
            if (supplierPartner != null) {
                Company company = stockLocation.getCompany();
                LocalDate today = Beans.get(AppBaseService.class).getTodayDate(company);
                PurchaseOrderSupplychainService purchaseOrderSupplychainService = Beans.get(PurchaseOrderSupplychainService.class);
                PurchaseOrder purchaseOrder = purchaseOrderRepo.save(purchaseOrderSupplychainService.createPurchaseOrder(AuthUtils.getUser(), company, null, supplierPartner.getCurrency(), today.plusDays(supplierPartner.getDeliveryDelay()), stockRules.getName(), null, stockLocation, today, Beans.get(PartnerPriceListService.class).getDefaultPriceList(supplierPartner, PriceListRepository.TYPE_PURCHASE), supplierPartner, null));
                purchaseOrder.addPurchaseOrderLineListItem(purchaseOrderLineService.createPurchaseOrderLine(purchaseOrder, product, null, null, qtyToOrder, product.getUnit()));
                Beans.get(PurchaseOrderService.class).computePurchaseOrder(purchaseOrder);
                purchaseOrderRepo.save(purchaseOrder);
                if (stockRules.getAlert()) {
                    this.generateAndSendMessage(stockRules);
                }
            }
        }
    }
}
Also used : Company(com.axelor.apps.base.db.Company) StockLocation(com.axelor.apps.stock.db.StockLocation) PurchaseOrder(com.axelor.apps.purchase.db.PurchaseOrder) Partner(com.axelor.apps.base.db.Partner) LocalDate(java.time.LocalDate) BigDecimal(java.math.BigDecimal) StockRules(com.axelor.apps.stock.db.StockRules) Transactional(com.google.inject.persist.Transactional)

Aggregations

StockLocation (com.axelor.apps.stock.db.StockLocation)56 Company (com.axelor.apps.base.db.Company)19 BigDecimal (java.math.BigDecimal)18 Product (com.axelor.apps.base.db.Product)15 AxelorException (com.axelor.exception.AxelorException)13 Transactional (com.google.inject.persist.Transactional)13 StockMove (com.axelor.apps.stock.db.StockMove)12 StockLocationRepository (com.axelor.apps.stock.db.repo.StockLocationRepository)12 ArrayList (java.util.ArrayList)12 StockConfig (com.axelor.apps.stock.db.StockConfig)10 StockConfigProductionService (com.axelor.apps.production.service.config.StockConfigProductionService)9 StockMoveLine (com.axelor.apps.stock.db.StockMoveLine)8 StockLocationService (com.axelor.apps.stock.service.StockLocationService)8 List (java.util.List)8 Partner (com.axelor.apps.base.db.Partner)6 Unit (com.axelor.apps.base.db.Unit)6 StockLocationLine (com.axelor.apps.stock.db.StockLocationLine)6 LocalDate (java.time.LocalDate)6 UnitConversionService (com.axelor.apps.base.service.UnitConversionService)5 AppBaseService (com.axelor.apps.base.service.app.AppBaseService)5