/** * *************************************************************************** * Copyright (c) 2010 Qcadoo Limited * Project: Qcadoo MES * Version: 1.4 * * This file is part of Qcadoo. * * Qcadoo is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation; either version 3 of the License, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *************************************************************************** */ package com.qcadoo.mes.technologies.hooks; import java.util.List; import java.util.Map.Entry; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.qcadoo.mes.technologies.TechnologyService; import com.qcadoo.mes.technologies.constants.AssignedToOperation; import com.qcadoo.mes.technologies.constants.OperationFields; import com.qcadoo.mes.technologies.constants.OperationProductOutComponentFields; import com.qcadoo.mes.technologies.constants.TechnologiesConstants; import com.qcadoo.mes.technologies.constants.TechnologyFields; import com.qcadoo.mes.technologies.constants.TechnologyOperationComponentFields; import com.qcadoo.mes.technologies.constants.TechnologyOperationComponentReferenceMode; import com.qcadoo.mes.technologies.constants.TechnologyOperationComponentType; import com.qcadoo.model.api.DataDefinition; import com.qcadoo.model.api.DataDefinitionService; import com.qcadoo.model.api.Entity; import com.qcadoo.model.api.EntityList; import com.qcadoo.model.api.EntityTree; import com.qcadoo.model.api.EntityTreeNode; @Service public class TechnologyOperationComponentHooks { @Autowired private TechnologyService technologyService; @Autowired private DataDefinitionService dataDefinitionService; public void onCreate(final DataDefinition technologyOperationComponentDD, final Entity technologyOperationComponent) { copyCommentAndAttachmentFromOperation(technologyOperationComponent); setParentIfRootNodeAlreadyExists(technologyOperationComponent); copyReferencedTechnology(technologyOperationComponentDD, technologyOperationComponent); copyWorkstationsSettingsFromOperation(technologyOperationComponent); } private void copyWorkstationsSettingsFromOperation(final Entity technologyOperationComponent) { Entity operation = technologyOperationComponent.getBelongsToField(TechnologyOperationComponentFields.OPERATION); if (operation != null) { technologyOperationComponent.setField(TechnologyOperationComponentFields.QUANTITY_OF_WORKSTATIONS, operation.getIntegerField(OperationFields.QUANTITY_OF_WORKSTATIONS)); technologyOperationComponent.setField(TechnologyOperationComponentFields.ASSIGNED_TO_OPERATION, operation.getField(OperationFields.ASSIGNED_TO_OPERATION)); technologyOperationComponent.setField(TechnologyOperationComponentFields.WORKSTATION_TYPE, operation.getBelongsToField(OperationFields.WORKSTATION_TYPE)); technologyOperationComponent.setField(TechnologyOperationComponentFields.WORKSTATIONS, operation.getManyToManyField(OperationFields.WORKSTATIONS)); technologyOperationComponent.setField(TechnologyOperationComponentFields.DIVISION, operation.getBelongsToField(OperationFields.DIVISION)); technologyOperationComponent.setField(TechnologyOperationComponentFields.PRODUCTION_LINE, operation.getBelongsToField(OperationFields.PRODUCTION_LINE)); } } private void copyCommentAndAttachmentFromOperation(final Entity technologyOperationComponent) { technologyService.copyCommentAndAttachmentFromLowerInstance(technologyOperationComponent, TechnologyOperationComponentFields.OPERATION); } private void setParentIfRootNodeAlreadyExists(final Entity technologyOperationComponent) { Entity technology = technologyOperationComponent.getBelongsToField(TechnologyOperationComponentFields.TECHNOLOGY); EntityTree tree = technology.getTreeField(TechnologyFields.OPERATION_COMPONENTS); if (tree == null) { return; } if (tree.isEmpty()) { return; } EntityTreeNode rootNode = tree.getRoot(); if ((rootNode == null) || (technologyOperationComponent.getBelongsToField(TechnologyOperationComponentFields.PARENT) != null)) { return; } technologyOperationComponent.setField(TechnologyOperationComponentFields.PARENT, rootNode); } private void copyReferencedTechnology(final DataDefinition technologyOperationComponentDD, final Entity technologyOperationComponent) { if (!TechnologyOperationComponentFields.REFERENCE_TECHNOLOGY .equals(technologyOperationComponent.getField(TechnologyOperationComponentFields.ENTITY_TYPE)) && (technologyOperationComponent.getField(TechnologyOperationComponentFields.REFERENCE_TECHNOLOGY) == null)) { return; } boolean isCopy = TechnologyOperationComponentReferenceMode.COPY.getStringValue() .equals(technologyOperationComponent.getStringField(TechnologyOperationComponentFields.REFERENCE_MODE)); Entity technology = technologyOperationComponent.getBelongsToField(TechnologyOperationComponentFields.TECHNOLOGY); Entity referencedTechnology = technologyOperationComponent .getBelongsToField(TechnologyOperationComponentFields.REFERENCE_TECHNOLOGY); Set<Long> technologies = Sets.newHashSet(); technologies.add(technology.getId()); boolean isCyclic = checkForCyclicReferences(technologies, referencedTechnology, isCopy); if (isCyclic) { technologyOperationComponent.addError( technologyOperationComponentDD.getField(TechnologyOperationComponentFields.REFERENCE_TECHNOLOGY), "technologies.technologyReferenceTechnologyComponent.error.cyclicDependency"); return; } if (isCopy) { EntityTreeNode root = referencedTechnology.getTreeField(TechnologyFields.OPERATION_COMPONENTS).getRoot(); if (root == null) { technologyOperationComponent.addError( technologyOperationComponentDD.getField(TechnologyOperationComponentFields.REFERENCE_TECHNOLOGY), "technologies.technologyReferenceTechnologyComponent.error.operationComponentsEmpty"); return; } Entity copiedRoot = copyReferencedTechnologyOperations(root, technologyOperationComponent.getBelongsToField(TechnologyOperationComponentFields.TECHNOLOGY)); for (Entry<String, Object> entry : copiedRoot.getFields().entrySet()) { if (!(entry.getKey().equals("id") || entry.getKey().equals(TechnologyOperationComponentFields.PARENT))) { technologyOperationComponent.setField(entry.getKey(), entry.getValue()); } } technologyOperationComponent.setField(TechnologyOperationComponentFields.ENTITY_TYPE, TechnologyOperationComponentType.OPERATION.getStringValue()); technologyOperationComponent.setField(TechnologyOperationComponentFields.REFERENCE_TECHNOLOGY, null); } } private Entity copyReferencedTechnologyOperations(final Entity node, final Entity technology) { Entity copy = node.copy(); copy.setId(null); copy.setField(TechnologyOperationComponentFields.PARENT, null); copy.setField(TechnologyOperationComponentFields.TECHNOLOGY, technology); for (Entry<String, Object> entry : node.getFields().entrySet()) { Object value = entry.getValue(); if (value instanceof EntityList) { EntityList entities = (EntityList) value; List<Entity> copies = Lists.newArrayList(); for (Entity entity : entities) { copies.add(copyReferencedTechnologyOperations(entity, technology)); } copy.setField(entry.getKey(), copies); } } return copy; } private boolean checkForCyclicReferences(final Set<Long> technologies, final Entity referencedTechnology, final boolean copy) { if (!copy && technologies.contains(referencedTechnology.getId())) { return true; } technologies.add(referencedTechnology.getId()); for (Entity technologyOperationComponent : referencedTechnology.getTreeField(TechnologyFields.OPERATION_COMPONENTS)) { if (TechnologyOperationComponentType.REFERENCE_TECHNOLOGY.getStringValue() .equals(technologyOperationComponent.getStringField(TechnologyOperationComponentFields.ENTITY_TYPE))) { boolean isCyclic = checkForCyclicReferences(technologies, technologyOperationComponent.getBelongsToField(TechnologyOperationComponentFields.REFERENCE_TECHNOLOGY), false); if (isCyclic) { return true; } } } return false; } public void onSave(final DataDefinition technologyOperationComponentDD, final Entity technologyOperationComponent) { clearField(technologyOperationComponent); if (technologyOperationComponent.getId() != null) { DataDefinition opocDD = dataDefinitionService.get(TechnologiesConstants.PLUGIN_IDENTIFIER, TechnologiesConstants.MODEL_OPERATION_PRODUCT_OUT_COMPONENT); List<Entity> opocs = technologyOperationComponent .getHasManyField(TechnologyOperationComponentFields.OPERATION_PRODUCT_OUT_COMPONENTS); for (Entity opoc : opocs) { clearSet(opocDD, opoc, technologyOperationComponent); } } } private void clearSet(final DataDefinition dataDefinition, final Entity opoc, final Entity toc) { Boolean set = (Boolean) opoc.getField(OperationProductOutComponentFields.SET); if (set == null || (set && toc.getBelongsToField(TechnologyOperationComponentFields.PARENT) != null)) { opoc.setField(OperationProductOutComponentFields.SET, false); dataDefinition.save(opoc); } } private void clearField(final Entity technologyOperationComponent) { String assignedToOperation = technologyOperationComponent .getStringField(TechnologyOperationComponentFields.ASSIGNED_TO_OPERATION); if (AssignedToOperation.WORKSTATIONS_TYPE.getStringValue().equals(assignedToOperation)) { technologyOperationComponent.setField(TechnologyOperationComponentFields.WORKSTATIONS, null); } } }