public boolean checkIfCustomTranslationIsUnique(
      final DataDefinition customTranslationDD, final Entity customTranslation) {
    String pluginIdentifier = customTranslation.getStringField(PLUGIN_IDENTIFIER);
    String locale = customTranslation.getStringField(LOCALE);
    String key = customTranslation.getStringField(KEY);

    SearchCriteriaBuilder searchCriteriaBuilder =
        customTranslationDD
            .find()
            .add(SearchRestrictions.eq(PLUGIN_IDENTIFIER, pluginIdentifier))
            .add(SearchRestrictions.eq(LOCALE, locale))
            .add(SearchRestrictions.eq(KEY, key));

    if (customTranslation.getId() != null) {
      searchCriteriaBuilder.add(SearchRestrictions.ne("id", customTranslation.getId()));
    }

    SearchResult searchResult = searchCriteriaBuilder.list();

    if (!searchResult.getEntities().isEmpty()) {
      customTranslation.addError(
          customTranslationDD.getField(KEY),
          "customTranslation.customTranslation.error.customTranslationIsntUnique");

      return false;
    }

    return true;
  }
 public boolean validateDates(
     final DataDefinition deliveredProductDD, final Entity deliveredProduct) {
   Date productionDate = deliveredProduct.getDateField(DeliveredProductFieldsDTMF.PRODUCTION_DATE);
   Date expirationDate = deliveredProduct.getDateField(DeliveredProductFieldsDTMF.EXPIRATION_DATE);
   if (productionDate != null && expirationDate != null) {
     if (productionDate.after(expirationDate)) {
       deliveredProduct.addError(
           deliveredProductDD.getField(DeliveredProductFieldsDTMF.EXPIRATION_DATE),
           "materialFlow.error.position.expirationDate.lessThenProductionDate");
       return false;
     }
   }
   return true;
 }
  public boolean checkIfLocationIsWarehouse(
      final DataDefinition resourceDD, final Entity resource) {
    Entity location = resource.getBelongsToField(LOCATION);

    if (location != null) {
      String type = location.getStringField(TYPE);

      if (!"02warehouse".equals(type)) {
        resource.addError(
            resourceDD.getField(LOCATION),
            "materialFlowResources.validate.global.error.locationIsNotWarehouse");

        return false;
      }
    }

    return true;
  }
  private void checkIfProductionLineFilled(
      DataDefinition multiAssignmentToShiftDD, Entity multiAssignmentToShift) {
    if (multiAssignmentToShift.getId() != null) {
      String occupationType =
          multiAssignmentToShift.getStringField(MultiAssignmentToShiftFields.OCCUPATION_TYPE);

      Entity dictionaryItem = findDictionaryItemByName(occupationType);

      String technicalCode = dictionaryItem.getStringField(TECHNICAL_CODE);

      if (technicalCode != null && technicalCode.equals(WORK_ON_LINE.getStringValue())) {
        if (multiAssignmentToShift.getBelongsToField(MultiAssignmentToShiftFields.PRODUCTION_LINE)
            == null) {
          multiAssignmentToShift.addError(
              multiAssignmentToShiftDD.getField(MultiAssignmentToShiftFields.PRODUCTION_LINE),
              "assignmentToShift.staffAssignmentToShift.productionLine.isEmpty");
        }
      }
    }
  }
  private void moveResources(
      Entity warehouseFrom,
      Entity warehouseTo,
      Entity position,
      Object date,
      WarehouseAlgorithm warehouseAlgorithm) {
    Entity product = position.getBelongsToField(PositionFields.PRODUCT);

    List<Entity> resources =
        getResourcesForWarehouseProductAndAlgorithm(
            warehouseFrom, product, position, warehouseAlgorithm);

    BigDecimal quantity = position.getDecimalField(PositionFields.QUANTITY);

    resourceStockService.removeResourceStock(product, warehouseFrom, quantity);
    for (Entity resource : resources) {
      BigDecimal resourceQuantity = resource.getDecimalField(QUANTITY);

      BigDecimal resourceAvailableQuantity =
          resource.getDecimalField(ResourceFields.AVAILABLE_QUANTITY);
      if (quantity.compareTo(resourceAvailableQuantity) >= 0) {
        quantity = quantity.subtract(resourceAvailableQuantity, numberService.getMathContext());
        if (resourceQuantity.compareTo(resourceAvailableQuantity) <= 0) {
          resource.getDataDefinition().delete(resource.getId());
        } else {
          BigDecimal newResourceQuantity = resourceQuantity.subtract(resourceAvailableQuantity);
          BigDecimal resourceConversion = resource.getDecimalField(ResourceFields.CONVERSION);
          BigDecimal quantityInAdditionalUnit = newResourceQuantity.multiply(resourceConversion);
          resource.setField(ResourceFields.AVAILABLE_QUANTITY, BigDecimal.ZERO);
          resource.setField(ResourceFields.QUANTITY, newResourceQuantity);
          resource.setField(
              ResourceFields.QUANTITY_IN_ADDITIONAL_UNIT,
              numberService.setScale(quantityInAdditionalUnit));
          resource.getDataDefinition().save(resource);
        }

        createResource(position, warehouseTo, resource, resourceAvailableQuantity, date);

        if (BigDecimal.ZERO.compareTo(quantity) == 0) {
          return;
        }
      } else {
        resourceQuantity = resourceQuantity.subtract(quantity, numberService.getMathContext());
        resourceAvailableQuantity =
            resourceAvailableQuantity.subtract(quantity, numberService.getMathContext());
        String givenUnit = resource.getStringField(ResourceFields.GIVEN_UNIT);
        BigDecimal quantityInAdditionalUnit =
            convertToGivenUnit(resourceQuantity, product, givenUnit);

        resource.setField(
            ResourceFields.QUANTITY_IN_ADDITIONAL_UNIT,
            numberService.setScale(quantityInAdditionalUnit));
        resource.setField(ResourceFields.QUANTITY, numberService.setScale(resourceQuantity));
        resource.setField(ResourceFields.AVAILABLE_QUANTITY, resourceAvailableQuantity);

        resource.getDataDefinition().save(resource);

        createResource(position, warehouseTo, resource, quantity, date);

        return;
      }
    }

    position.addError(
        position.getDataDefinition().getField(PositionFields.QUANTITY),
        "materialFlow.error.position.quantity.notEnough");
  }
  private List<Entity> updateResources(
      Entity warehouse, Entity position, WarehouseAlgorithm warehouseAlgorithm) {
    DataDefinition positionDD =
        dataDefinitionService.get(
            MaterialFlowResourcesConstants.PLUGIN_IDENTIFIER,
            MaterialFlowResourcesConstants.MODEL_POSITION);

    List<Entity> newPositions = Lists.newArrayList();

    Entity product = position.getBelongsToField(PositionFields.PRODUCT);

    List<Entity> resources =
        getResourcesForWarehouseProductAndAlgorithm(
            warehouse, product, position, warehouseAlgorithm);

    BigDecimal quantity = position.getDecimalField(PositionFields.QUANTITY);

    resourceStockService.removeResourceStock(product, warehouse, quantity);
    for (Entity resource : resources) {
      BigDecimal resourceQuantity = resource.getDecimalField(ResourceFields.QUANTITY);
      BigDecimal resourceAvailableQuantity =
          resource.getDecimalField(ResourceFields.AVAILABLE_QUANTITY);

      Entity newPosition = positionDD.create();

      newPosition.setField(
          PositionFields.PRODUCT, position.getBelongsToField(PositionFields.PRODUCT));
      newPosition.setField(
          PositionFields.GIVEN_QUANTITY, position.getDecimalField(PositionFields.GIVEN_QUANTITY));
      newPosition.setField(
          PositionFields.GIVEN_UNIT, position.getStringField(PositionFields.GIVEN_UNIT));
      newPosition.setField(PositionFields.PRICE, resource.getField(ResourceFields.PRICE));
      newPosition.setField(PositionFields.BATCH, resource.getField(ResourceFields.BATCH));
      newPosition.setField(
          PositionFields.PRODUCTION_DATE, resource.getField(ResourceFields.PRODUCTION_DATE));
      newPosition.setField(
          PositionFields.EXPIRATION_DATE, resource.getField(ResourceFields.EXPIRATION_DATE));
      newPosition.setField(PositionFields.RESOURCE, resource);
      newPosition.setField(
          PositionFields.STORAGE_LOCATION, resource.getField(ResourceFields.STORAGE_LOCATION));
      newPosition.setField(
          PositionFields.ADDITIONAL_CODE, resource.getField(ResourceFields.ADDITIONAL_CODE));
      newPosition.setField(PositionFields.CONVERSION, position.getField(PositionFields.CONVERSION));
      newPosition.setField(
          PositionFields.PALLET_NUMBER, resource.getField(ResourceFields.PALLET_NUMBER));
      newPosition.setField(
          PositionFields.TYPE_OF_PALLET, resource.getField(ResourceFields.TYPE_OF_PALLET));
      // newPosition.setField(PositionFields.GIVEN_UNIT,
      // resource.getField(ResourceFields.GIVEN_UNIT));

      setPositionAttributesFromResource(newPosition, resource);

      if (quantity.compareTo(resourceAvailableQuantity) >= 0) {
        quantity = quantity.subtract(resourceAvailableQuantity, numberService.getMathContext());
        if (resourceQuantity.compareTo(resourceAvailableQuantity) <= 0) {
          resource.getDataDefinition().delete(resource.getId());
        } else {
          BigDecimal newResourceQuantity = resourceQuantity.subtract(resourceAvailableQuantity);
          BigDecimal resourceConversion = resource.getDecimalField(ResourceFields.CONVERSION);
          BigDecimal quantityInAdditionalUnit = newResourceQuantity.multiply(resourceConversion);
          resource.setField(ResourceFields.AVAILABLE_QUANTITY, BigDecimal.ZERO);
          resource.setField(ResourceFields.QUANTITY, newResourceQuantity);
          resource.setField(
              ResourceFields.QUANTITY_IN_ADDITIONAL_UNIT,
              numberService.setScale(quantityInAdditionalUnit));
          resource.getDataDefinition().save(resource);
        }

        newPosition.setField(
            PositionFields.QUANTITY, numberService.setScale(resourceAvailableQuantity));

        BigDecimal givenResourceQuantity = convertToGivenUnit(resourceAvailableQuantity, position);

        newPosition.setField(
            PositionFields.GIVEN_QUANTITY, numberService.setScale(givenResourceQuantity));

        newPositions.add(newPosition);

        if (BigDecimal.ZERO.compareTo(quantity) == 0) {
          return newPositions;
        }
      } else {
        resourceQuantity = resourceQuantity.subtract(quantity, numberService.getMathContext());
        resourceAvailableQuantity =
            resourceAvailableQuantity.subtract(quantity, numberService.getMathContext());
        if (position.getBelongsToField(PositionFields.RESOURCE) != null
            && reservationsService.reservationsEnabledForDocumentPositions()) {
          BigDecimal reservedQuantity =
              resource
                  .getDecimalField(ResourceFields.RESERVED_QUANTITY)
                  .subtract(quantity, numberService.getMathContext());
          resource.setField(ResourceFields.RESERVED_QUANTITY, reservedQuantity);
        }
        BigDecimal resourceConversion = resource.getDecimalField(ResourceFields.CONVERSION);
        BigDecimal quantityInAdditionalUnit = resourceQuantity.multiply(resourceConversion);

        resource.setField(
            ResourceFields.QUANTITY_IN_ADDITIONAL_UNIT,
            numberService.setScale(quantityInAdditionalUnit));
        resource.setField(ResourceFields.QUANTITY, numberService.setScale(resourceQuantity));
        resource.setField(ResourceFields.AVAILABLE_QUANTITY, resourceAvailableQuantity);

        resource.getDataDefinition().save(resource);
        newPosition.setField(PositionFields.QUANTITY, numberService.setScale(quantity));

        BigDecimal givenQuantity = convertToGivenUnit(quantity, position);

        newPosition.setField(PositionFields.GIVEN_QUANTITY, numberService.setScale(givenQuantity));
        newPositions.add(newPosition);

        return newPositions;
      }
    }

    position.addError(
        position.getDataDefinition().getField(PositionFields.QUANTITY),
        "materialFlow.error.position.quantity.notEnough");

    return Lists.newArrayList(position);
  }