package com.qcadoo.mes.productionCounting; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.qcadoo.mes.basicProductionCounting.ProductionTrackingUpdateService; import com.qcadoo.mes.productionCounting.constants.*; import com.qcadoo.mes.productionCounting.hooks.helpers.OperationProductsExtractor; import com.qcadoo.model.api.DataDefinitionService; import com.qcadoo.model.api.Entity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @Service public class ProductionTrackingUpdateServiceImpl implements ProductionTrackingUpdateService { @Autowired private DataDefinitionService dataDefinitionService; @Autowired private OperationProductsExtractor operationProductsExtractor; @Override public void updateProductionTracking(final Long productionTrackingId) { Entity productionTracking = dataDefinitionService.get(ProductionCountingConstants.PLUGIN_IDENTIFIER, ProductionCountingConstants.MODEL_PRODUCTION_TRACKING).get(productionTrackingId); Entity order = productionTracking.getBelongsToField(ProductionTrackingFields.ORDER); final boolean registerQuantityInProduct = order.getBooleanField(OrderFieldsPC.REGISTER_QUANTITY_IN_PRODUCT); final boolean registerQuantityOutProduct = order.getBooleanField(OrderFieldsPC.REGISTER_QUANTITY_OUT_PRODUCT); OperationProductsExtractor.TrackingOperationProducts operationProducts = operationProductsExtractor .getProductsByModelName(productionTracking); if (registerQuantityInProduct) { updateInProducts(productionTracking, operationProducts); } if (registerQuantityOutProduct) { updateOutProducts(productionTracking, operationProducts); } productionTracking = productionTracking.getDataDefinition().save(productionTracking); } private void updateOutProducts(final Entity productionTracking, final OperationProductsExtractor.TrackingOperationProducts operationProducts) { List<Entity> outputs = Collections.emptyList(); List<Entity> productionTrackingOutputs = Collections.emptyList(); outputs = operationProducts.getOutputComponents(); productionTrackingOutputs = productionTracking .getHasManyField(ProductionTrackingFields.TRACKING_OPERATION_PRODUCT_OUT_COMPONENTS); Map<Long, Entity> outputsMap = outputs.stream().collect( Collectors.toMap(x -> x.getBelongsToField(TrackingOperationProductOutComponentFields.PRODUCT).getId(), x -> x)); Map<Long, Entity> productionTrackingOutputsMap = productionTrackingOutputs.stream().collect( Collectors.toMap(x -> x.getBelongsToField(TrackingOperationProductOutComponentFields.PRODUCT).getId(), x -> x)); Set<Long> newEntries = Sets.difference(outputsMap.keySet(), productionTrackingOutputsMap.keySet()); Set<Long> removedEntries = Sets.difference(productionTrackingOutputsMap.keySet(), outputsMap.keySet()); Set<Long> toUpdateEntries = Sets.intersection(outputsMap.keySet(), productionTrackingOutputsMap.keySet()); List<Entity> updatedProductionTrackingOutputs = Lists.newArrayList(); for (Long newEntry : newEntries) { updatedProductionTrackingOutputs.add(outputsMap.get(newEntry)); } if (!newEntries.isEmpty() || !removedEntries.isEmpty()) { for (Long e : toUpdateEntries) { Entity toUpdateEntry = productionTrackingOutputsMap.get(e); updatedProductionTrackingOutputs.add(toUpdateEntry); } productionTracking.setField(ProductionTrackingFields.TRACKING_OPERATION_PRODUCT_OUT_COMPONENTS, updatedProductionTrackingOutputs); } } private void updateInProducts(final Entity productionTracking, final OperationProductsExtractor.TrackingOperationProducts operationProducts) { List<Entity> inputs = Collections.emptyList(); List<Entity> productionTrackingInputs = Collections.emptyList(); inputs = operationProducts.getInputComponents(); productionTrackingInputs = productionTracking .getHasManyField(ProductionTrackingFields.TRACKING_OPERATION_PRODUCT_IN_COMPONENTS); Map<Long, Entity> inputsMap = inputs.stream().collect( Collectors.toMap(x -> x.getBelongsToField(TrackingOperationProductInComponentFields.PRODUCT).getId(), x -> x)); Map<Long, Entity> productionTrackingInputsMap = productionTrackingInputs.stream().collect( Collectors.toMap(x -> x.getBelongsToField(TrackingOperationProductOutComponentFields.PRODUCT).getId(), x -> x)); Set<Long> newEntries = Sets.difference(inputsMap.keySet(), productionTrackingInputsMap.keySet()); Set<Long> toUpdateEntries = Sets.intersection(inputsMap.keySet(), productionTrackingInputsMap.keySet()); Set<Long> removedEntries = Sets.difference(productionTrackingInputsMap.keySet(), inputsMap.keySet()); List<Entity> updatedProductionTrackingInputs = Lists.newArrayList(); for (Long newEntry : newEntries) { updatedProductionTrackingInputs.add(inputsMap.get(newEntry)); } if (!newEntries.isEmpty() || !removedEntries.isEmpty()) { for (Long e : toUpdateEntries) { Entity toUpdateEntry = productionTrackingInputsMap.get(e); updatedProductionTrackingInputs.add(toUpdateEntry); } productionTracking.setField(ProductionTrackingFields.TRACKING_OPERATION_PRODUCT_IN_COMPONENTS, updatedProductionTrackingInputs); } } }