@Override
  public Errors validateCreate(Long userId, Long documentId, Inventory inventory) {
    Errors errors = applicationContext.getBean(Errors.class);
    if (inventory == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Resource invalid"));
      return errors;
    }

    User user = userService.findOne(userId);

    // <editor-fold desc="Validate goods receipt resource">

    Document document = documentService.findOne(userId, DocumentType.GOODS_RECEIPT, documentId);
    if (document == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid goods receipt resource"));
      return errors;
    }

    if (user.getTenant() != document.getTenant()) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Access denied to this resource"));
      return errors;
    }

    if (!document.canEdit()) {
      errors
          .getErrorObjects()
          .add(new ErrorObject("ERROR", "Document closed, sorry you can not edit this document."));
      return errors;
    }

    if (!user.getUserSession().getTenantLevel()) {
      if (user.getUserSession().getBusinessUnit() != document.getBusinessUnit()) {
        errors.getErrorObjects().add(new ErrorObject("ERROR", "Access denied to this resource"));
        return errors;
      }
    }

    // </editor-fold>

    // TODO; remove this in future after refactoring how sales orders are posted
    if (!document.getInventoryList().isEmpty()) {
      if (document.getInventoryList().size() + 1 > 200) {
        errors
            .getErrorObjects()
            .add(
                new ErrorObject(
                    "ERROR",
                    "You can only have a maximum of 200 line items in your goods receipt"));
        return errors;
      }
    }

    // <editor-fold desc="Validate product resource">

    Product product = productService.findOne(userId, inventory.getProduct().getProductId());
    if (product == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid product resource"));
      return errors;
    }
    if (!product.getActive()) {
      errors
          .getErrorObjects()
          .add(new ErrorObject("ERROR", "Product inactive, please choose another product."));
      return errors;
    }

    if (product.getProductType() == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid product type"));
      return errors;
    }
    if (!product.getTrackInventory()) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid product type."));
      return errors;
    }

    // </editor-fold>

    // <editor-fold desc="Validate warehouse locator">

    if (inventory.getWarehouseLocator() == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Warehouse storage can not be empty"));
      return errors;
    }

    WarehouseLocator warehouseLocator =
        warehouseLocatorService.findById(
            userId, inventory.getWarehouseLocator().getWarehouseLocatorId());

    if (warehouseLocator == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid warehouse storage"));
      return errors;
    }

    if (document.getWarehouse() != warehouseLocator.getWarehouse()) {
      errors
          .getErrorObjects()
          .add(new ErrorObject("ERROR", "Storage does not belong to this warehouse"));
      return errors;
    }

    if (!warehouseLocator.getActive()) {
      errors
          .getErrorObjects()
          .add(new ErrorObject("ERROR", "Storage inactive, please choose another storage."));
      return errors;
    }

    // </editor-fold>

    return errors;
  }
  @Override
  public Errors validateUpdateStorageAndQuantity(Long userId, Inventory inventory) {
    Errors errors = applicationContext.getBean(Errors.class);
    User user = userService.findOne(userId);
    if (inventory == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Resource invalid"));
      return errors;
    }

    if (inventory.getLineNumber() == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid line number"));
      return errors;
    }

    // <editor-fold desc="Validate goods receipt line resource">

    Inventory dbInventory = inventoryService.findOne(userId, inventory.getInventoryId());
    if (dbInventory == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid goods receipt line resource"));
      return errors;
    }
    if (!dbInventory.getDocument().canEdit()) {
      errors
          .getErrorObjects()
          .add(new ErrorObject("ERROR", "Document closed, sorry you can not edit this document."));
      return errors;
    }
    if (user.getTenant() != dbInventory.getTenant()) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Access to this resource denied"));
      return errors;
    }

    if (!user.getUserSession().getTenantLevel()) {
      if (user.getUserSession().getBusinessUnit() != dbInventory.getDocument().getBusinessUnit()) {
        errors.getErrorObjects().add(new ErrorObject("ERROR", "Access to this resource denied"));
        return errors;
      }
    }

    // </editor-fold>

    // <editor-fold desc="check and update warehouse storage">

    if (inventory.getWarehouseLocator() == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Warehouse storage can not be empty"));
      return errors;
    }

    WarehouseLocator warehouseLocator =
        warehouseLocatorService.findById(
            userId, inventory.getWarehouseLocator().getWarehouseLocatorId());
    if (warehouseLocator == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid warehouse storage resource."));
      return errors;
    }

    if (!dbInventory.getWarehouse().getWarehouseLocators().contains(warehouseLocator)) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid warehouse storage resource."));
      return errors;
    }
    // </editor-fold>

    if (dbInventory.getQuantity() == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Quantity can not be empty"));
      return errors;
    }

    if (dbInventory.getProduct().getUnitOfMeasure() == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid product unit of measure."));
      return errors;
    }

    if (inventory.getQuantity()
        < dbInventory.getProduct().getUnitOfMeasure().getMinimumQuantity()) {
      errors
          .getErrorObjects()
          .add(
              new ErrorObject(
                  "ERROR",
                  "Inventory quantity can not be less than "
                      + dbInventory.getProduct().getUnitOfMeasure().getMinimumQuantity()));
      return errors;
    }
    // <editor-fold desc="check if product has any attribute which is unique; means quantity can
    // only be 1">

    Boolean unique = false;
    if (dbInventory.getAttributeSetInstance() != null) {
      if (dbInventory.getAttributeSetInstance().getAttributeValueInstances() != null) {
        List<AttributeValueInstance> attributeValueInstanceList =
            dbInventory.getAttributeSetInstance().getAttributeValueInstances();
        if (attributeValueInstanceList != null) {
          if (!attributeValueInstanceList.isEmpty()) {
            for (AttributeValueInstance avi : attributeValueInstanceList) {
              if (avi.getProductAttribute().getUnique()) {
                unique = true;
              }
            }
          }
        }
      }
    }

    if (unique) {
      if (inventory.getQuantity() != 1) {
        errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid product quantity."));
        return errors;
      }
    }

    // </editor-fold>

    return errors;
  }