@Override
  public Errors validateUpdateAttributeValues(
      Long userId, Long inventoryId, List<AttributeValueInstance> attributeValueInstances) {
    Errors errors = applicationContext.getBean(Errors.class);
    User user = userService.findOne(userId);
    if (attributeValueInstances == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Resource invalid"));
      return errors;
    }

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

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

    // </editor-fold>

    if (attributeValueInstances == null) {
      errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid attribute values resource"));
      return errors;
    }

    if (!attributeValueInstances.isEmpty()) {
      for (AttributeValueInstance attributeValueInstance : attributeValueInstances) {
        AttributeValueInstance avi =
            attributeValueInstanceRepository.findOne(
                attributeValueInstance.getAttributeValueInstanceId());
        if (avi == null) {
          errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid attribute value"));
          return errors;
        }
        if (avi.getAttributeSetInstance() != inventory.getAttributeSetInstance()) {
          errors.getErrorObjects().add(new ErrorObject("ERROR", "Invalid attribute"));
          return errors;
        }

        // check if product attribute is active
        if (!avi.getProductAttribute().getActive()) {
          errors
              .getErrorObjects()
              .add(
                  new ErrorObject(
                      "ERROR",
                      avi.getProductAttribute().getCaption() + " product attribute is inactive "));
          return errors;
        }
        // check if attribute value is mandatory
        if (avi.getProductAttribute().getMandatory()) {
          if (avi.getProductAttribute().getIsDate()) {
            if (attributeValueInstance.getDateValue() == null) {
              errors
                  .getErrorObjects()
                  .add(
                      new ErrorObject(
                          "ERROR", avi.getProductAttribute().getCaption() + " can not be empty"));
              return errors;
            }
          } else if (avi.getProductAttribute().getIsNumber()) {
            if (attributeValueInstance.getNumberValue() == null) {
              errors
                  .getErrorObjects()
                  .add(
                      new ErrorObject(
                          "ERROR", avi.getProductAttribute().getCaption() + " can not be empty"));
              return errors;
            }
          } else {
            if (StringUtils.isBlank(attributeValueInstance.getValue())) {
              errors
                  .getErrorObjects()
                  .add(
                      new ErrorObject(
                          "ERROR", avi.getProductAttribute().getCaption() + " can not be empty"));
              return errors;
            }
          }

          // check if attribute value must be unique
          if (avi.getProductAttribute().getUnique()) {
            // check if attribute value already exists
            AttributeValueInstance dbAttributeValueInstance = new AttributeValueInstance();
            if (avi.getProductAttribute().getIsDate()) {
              dbAttributeValueInstance =
                  attributeValueInstanceRepository.findByProductAttributeAndDateValue(
                      avi.getProductAttribute(),
                      attributeValueInstance.getDateValue().withTimeAtStartOfDay());
            } else if (avi.getProductAttribute().getIsNumber()) {
              dbAttributeValueInstance =
                  attributeValueInstanceRepository.findByProductAttributeAndNumberValue(
                      avi.getProductAttribute(), attributeValueInstance.getNumberValue());
            } else {
              dbAttributeValueInstance =
                  attributeValueInstanceRepository.findByProductAttributeAndValue(
                      avi.getProductAttribute(), attributeValueInstance.getValue());
            }
            // check if same as the row being updated
            if (dbAttributeValueInstance != null) {
              if (dbAttributeValueInstance.getAttributeValueInstanceId()
                  != avi.getAttributeValueInstanceId()) {
                // TODO; Validation of unique instances (Tenant level, Business unit level)
                Double count =
                    inventoryService.countByAttributeInstanceAndDocumentTypeAndBusinessUnit(
                        userId,
                        dbAttributeValueInstance
                            .getAttributeSetInstance()
                            .getAttributeSetInstanceId(),
                        DocumentType.GOODS_RECEIPT,
                        inventory.getBusinessUnit().getBusinessUnitId());
                if (count > 0) {
                  errors
                      .getErrorObjects()
                      .add(
                          new ErrorObject(
                              "ERROR",
                              avi.getProductAttribute().getCaption()
                                  + " "
                                  + attributeValueInstance.getValue()
                                  + "  already exists"));
                  return errors;
                }
              }
            }
          }
        }
      }
    }
    return errors;
  }