package com.qcadoo.mes.materialFlowResources.service; import java.math.BigDecimal; import java.util.Map; import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.stereotype.Service; import com.qcadoo.mes.materialFlowResources.constants.DocumentFields; import com.qcadoo.mes.materialFlowResources.constants.MaterialFlowResourcesConstants; import com.qcadoo.mes.materialFlowResources.constants.PositionFields; import com.qcadoo.mes.materialFlowResources.constants.ResourceFields; import com.qcadoo.mes.materialFlowResources.constants.ResourceStockFields; import com.qcadoo.model.api.DataDefinition; import com.qcadoo.model.api.DataDefinitionService; import com.qcadoo.model.api.Entity; import com.qcadoo.model.api.search.SearchRestrictions; @Service public class ResourceStockServiceImpl implements ResourceStockService { @Autowired private DataDefinitionService dataDefinitionService; @Autowired private NamedParameterJdbcTemplate jdbcTemplate; @Override public void addResourceStock(final Entity resource) { Entity product = resource.getBelongsToField(ResourceFields.PRODUCT); Entity location = resource.getBelongsToField(ResourceFields.LOCATION); BigDecimal quantity = resource.getDecimalField(ResourceFields.QUANTITY); addResourceStock(product, location, quantity); } @Override public void addResourceStock(Entity product, Entity location, BigDecimal quantity) { Entity resourceStock; Optional<Entity> maybeStock = getResourceStockForProductAndLocation(product, location); if (maybeStock.isPresent()) { resourceStock = maybeStock.get(); BigDecimal oldQuantity = resourceStock.getDecimalField(ResourceStockFields.QUANTITY); BigDecimal oldAvailableQuantity = resourceStock.getDecimalField(ResourceStockFields.AVAILABLE_QUANTITY); resourceStock.setField(ResourceStockFields.QUANTITY, oldQuantity.add(quantity)); resourceStock.setField(ResourceStockFields.AVAILABLE_QUANTITY, oldAvailableQuantity.add(quantity)); } else { resourceStock = createResourceStock(product, location, quantity); } getResourceStockDataDefinition().save(resourceStock); } @Override public void removeResourceStock(Entity resource) { Entity product = resource.getBelongsToField(ResourceFields.PRODUCT); Entity location = resource.getBelongsToField(ResourceFields.LOCATION); BigDecimal quantity = resource.getDecimalField(ResourceFields.QUANTITY); removeResourceStock(product, location, quantity); } @Override public void removeResourceStock(Entity product, Entity location, BigDecimal quantity) { Optional<Entity> maybeStock = getResourceStockForProductAndLocation(product, location); if (maybeStock.isPresent()) { Entity resourceStock = maybeStock.get(); BigDecimal oldQuantity = resourceStock.getDecimalField(ResourceStockFields.QUANTITY); BigDecimal oldAvailableQuantity = resourceStock.getDecimalField(ResourceStockFields.AVAILABLE_QUANTITY); BigDecimal newQuantity = oldQuantity.subtract(quantity); BigDecimal newAvailableQuantity = oldAvailableQuantity.subtract(quantity); if (newQuantity.compareTo(BigDecimal.ZERO) <= 0) { newQuantity = BigDecimal.ZERO; newAvailableQuantity = BigDecimal.ZERO; } resourceStock.setField(ResourceStockFields.QUANTITY, newQuantity); resourceStock.setField(ResourceStockFields.AVAILABLE_QUANTITY, newAvailableQuantity); getResourceStockDataDefinition().save(resourceStock); } } @Override public Optional<Entity> getResourceStockForProductAndLocation(Entity product, Entity location) { Entity existingResourceStock = getResourceStockDataDefinition().find() .add(SearchRestrictions.belongsTo(ResourceStockFields.LOCATION, location)) .add(SearchRestrictions.belongsTo(ResourceStockFields.PRODUCT, product)).setMaxResults(1).uniqueResult(); return Optional.ofNullable(existingResourceStock); } private Entity createResourceStock(final Entity product, final Entity location, final BigDecimal quantity) { Entity stock = getResourceStockDataDefinition().create(); stock.setField(ResourceStockFields.LOCATION, location); stock.setField(ResourceStockFields.PRODUCT, product); stock.setField(ResourceStockFields.QUANTITY, quantity); stock.setField(ResourceStockFields.AVAILABLE_QUANTITY, quantity); stock.setField(ResourceStockFields.RESERVED_QUANTITY, BigDecimal.ZERO); return stock; } private DataDefinition getResourceStockDataDefinition() { return dataDefinitionService.get(MaterialFlowResourcesConstants.PLUGIN_IDENTIFIER, MaterialFlowResourcesConstants.MODEL_RESOURCE_STOCK); } public void updateResourceStock(Map<String, Object> params, BigDecimal quantityToAdd) { params.put("quantity_to_add", quantityToAdd); String query = "UPDATE materialflowresources_resourcestock SET reservedquantity = reservedquantity + :quantity_to_add, " + "availablequantity = availablequantity - :quantity_to_add WHERE product_id = :product_id AND " + "location_id = (SELECT locationfrom_id FROM materialflowresources_document WHERE id=:document_id)"; jdbcTemplate.update(query, params); } public void updateResourceStock(Entity position, BigDecimal quantityToAdd) { updateResourceStock(position.getBelongsToField(PositionFields.PRODUCT), position.getBelongsToField(PositionFields.DOCUMENT).getBelongsToField(DocumentFields.LOCATION_FROM), quantityToAdd); } public void updateResourceStock(Entity product, Entity location, BigDecimal quantityToAdd) { Optional<Entity> maybeResourceStock = getResourceStockForProductAndLocation(product, location); if (maybeResourceStock.isPresent()) { Entity resourceStock = maybeResourceStock.get(); BigDecimal reservedQuantity = resourceStock.getDecimalField(ResourceStockFields.RESERVED_QUANTITY); BigDecimal availableQuantity = resourceStock.getDecimalField(ResourceStockFields.AVAILABLE_QUANTITY); BigDecimal quantity = resourceStock.getDecimalField(ResourceStockFields.QUANTITY); if (quantity.compareTo(BigDecimal.ZERO) == 0) { reservedQuantity = BigDecimal.ZERO; availableQuantity = BigDecimal.ZERO; } else { availableQuantity = availableQuantity.subtract(quantityToAdd); reservedQuantity = reservedQuantity.add(quantityToAdd); } resourceStock.setField(ResourceStockFields.AVAILABLE_QUANTITY, availableQuantity); resourceStock.setField(ResourceStockFields.RESERVED_QUANTITY, reservedQuantity); resourceStock.getDataDefinition().save(resourceStock); } } }