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);
  }