Java tutorial
/** * *************************************************************************** * Copyright (c) 2010 Qcadoo Limited * Project: Qcadoo MES * Version: 1.3 * * 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; import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.qcadoo.localization.api.TranslationService; import com.qcadoo.mes.technologies.constants.MrpAlgorithm; import com.qcadoo.mes.technologies.constants.OperationFields; import com.qcadoo.mes.technologies.constants.OperationProductInComponentFields; 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.TechnologyOperationComponentType; import com.qcadoo.mes.technologies.states.constants.TechnologyState; 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.search.SearchCriteriaBuilder; import com.qcadoo.model.api.search.SearchQueryBuilder; import com.qcadoo.model.api.search.SearchRestrictions; import com.qcadoo.plugin.api.PluginAccessor; import com.qcadoo.view.api.ComponentState; import com.qcadoo.view.api.ViewDefinitionState; import com.qcadoo.view.api.components.FieldComponent; import com.qcadoo.view.api.components.FormComponent; import com.qcadoo.view.api.components.GridComponent; import com.qcadoo.view.api.components.LookupComponent; import com.qcadoo.view.api.components.TreeComponent; import com.qcadoo.view.api.utils.NumberGeneratorService; @Service public class TechnologyService { private static final String L_FORM = "form"; private static final String L_PRODUCT = "product"; private static final String L_QUANTITY = "quantity"; private static final String L_OPERATION = "operation"; private static final String L_OPERATION_COMPONENT = "operationComponent"; public static final String L_01_COMPONENT = "01component"; public static final String L_02_INTERMEDIATE = "02intermediate"; public static final String L_03_FINAL_PRODUCT = "03finalProduct"; public static final String L_04_WASTE = "04waste"; public static final String L_00_UNRELATED = "00unrelated"; private static final String IS_SYNCHRONIZED_QUERY = String.format( "SELECT t.id as id, t.%s as %s from #%s_%s t where t.id = :technologyId", TechnologyFields.EXTERNAL_SYNCHRONIZED, TechnologyFields.EXTERNAL_SYNCHRONIZED, TechnologiesConstants.PLUGIN_IDENTIFIER, TechnologiesConstants.MODEL_TECHNOLOGY); @Autowired private DataDefinitionService dataDefinitionService; @Autowired private NumberGeneratorService numberGeneratorService; @Autowired private TranslationService translationService; @Autowired private ProductQuantitiesService productQuantitiesService; @Autowired private PluginAccessor pluginAccessor; @Autowired private TechnologyNameAndNumberGenerator technologyNameAndNumberGenerator; public void copyCommentAndAttachmentFromLowerInstance(final Entity technologyOperationComponent, final String belongsToName) { Entity operation = technologyOperationComponent.getBelongsToField(belongsToName); if (operation != null) { technologyOperationComponent.setField(TechnologyOperationComponentFields.COMMENT, operation.getStringField(OperationFields.COMMENT)); technologyOperationComponent.setField(TechnologyOperationComponentFields.ATTACHMENT, operation.getStringField(OperationFields.ATTACHMENT)); } } public boolean checkIfTechnologyStateIsOtherThanCheckedAndAccepted(final Entity technology) { String state = technology.getStringField(TechnologyFields.STATE); return !TechnologyState.ACCEPTED.getStringValue().equals(state) && !TechnologyState.CHECKED.getStringValue().equals(state); } public boolean isTechnologyUsedInActiveOrder(final Entity technology) { if (!ordersPluginIsEnabled()) { return false; } SearchCriteriaBuilder searchCriteria = getOrderDataDefinition().find(); searchCriteria.add(SearchRestrictions.belongsTo("technology", technology)); searchCriteria.add(SearchRestrictions.in("state", Lists.newArrayList("01pending", "02accepted", "03inProgress", "06interrupted"))); searchCriteria.setMaxResults(1); return searchCriteria.uniqueResult() != null; } private boolean ordersPluginIsEnabled() { return pluginAccessor.getPlugin("orders") != null; } private DataDefinition getOrderDataDefinition() { return dataDefinitionService.get("orders", "order"); } private enum ProductDirection { IN, OUT; } public void loadProductsForReferencedTechnology(final ViewDefinitionState viewDefinitionState, final ComponentState state, final String[] args) { if (!(state instanceof TreeComponent)) { return; } TreeComponent tree = (TreeComponent) state; if (tree.getSelectedEntityId() == null) { return; } Entity technologyOperationComponent = dataDefinitionService.get(TechnologiesConstants.PLUGIN_IDENTIFIER, TechnologiesConstants.MODEL_TECHNOLOGY_OPERATION_COMPONENT).get(tree.getSelectedEntityId()); GridComponent outProductsGrid = (GridComponent) viewDefinitionState.getComponentByReference("outProducts"); GridComponent inProductsGrid = (GridComponent) viewDefinitionState.getComponentByReference("inProducts"); if (!TechnologyOperationComponentType.REFERENCE_TECHNOLOGY.getStringValue().equals( technologyOperationComponent.getStringField(TechnologyOperationComponentFields.ENTITY_TYPE))) { inProductsGrid.setEditable(true); outProductsGrid.setEditable(true); return; } Entity technology = technologyOperationComponent .getBelongsToField(TechnologyOperationComponentFields.REFERENCE_TECHNOLOGY); EntityTree operations = technology.getTreeField(TechnologyFields.OPERATION_COMPONENTS); Entity rootOperation = operations.getRoot(); if (rootOperation != null) { outProductsGrid.setEntities(rootOperation .getHasManyField(TechnologyOperationComponentFields.OPERATION_PRODUCT_OUT_COMPONENTS)); } List<Entity> operationProductInComponents = Lists.newArrayList(); Map<Long, BigDecimal> productQuantities = productQuantitiesService.getNeededProductQuantities(technology, BigDecimal.ONE, MrpAlgorithm.ALL_PRODUCTS_IN); for (Entry<Long, BigDecimal> productQuantity : productQuantities.entrySet()) { Entity product = productQuantitiesService.getProduct(productQuantity.getKey()); Entity operationProductInComponent = dataDefinitionService.get(TechnologiesConstants.PLUGIN_IDENTIFIER, TechnologiesConstants.MODEL_OPERATION_PRODUCT_IN_COMPONENT).create(); operationProductInComponent.setField(OperationProductInComponentFields.OPERATION_COMPONENT, rootOperation); operationProductInComponent.setField(OperationProductInComponentFields.PRODUCT, product); operationProductInComponent.setField(OperationProductInComponentFields.QUANTITY, productQuantity.getValue()); operationProductInComponents.add(operationProductInComponent); } inProductsGrid.setEntities(operationProductInComponents); inProductsGrid.setEnabled(false); inProductsGrid.setEditable(false); outProductsGrid.setEnabled(false); outProductsGrid.setEditable(false); } public void generateTechnologyGroupNumber(final ViewDefinitionState viewDefinitionState) { numberGeneratorService.generateAndInsertNumber(viewDefinitionState, TechnologiesConstants.PLUGIN_IDENTIFIER, TechnologiesConstants.MODEL_TECHNOLOGY_GROUP, L_FORM, TechnologyFields.NUMBER); } public void generateTechnologyNumber(final ViewDefinitionState view, final ComponentState state, final String[] args) { if (!(state instanceof FieldComponent)) { throw new IllegalStateException("component is not FieldComponentState"); } FieldComponent numberField = (FieldComponent) view.getComponentByReference(TechnologyFields.NUMBER); LookupComponent productLookup = (LookupComponent) state; Entity product = productLookup.getEntity(); if (product == null || StringUtils.isNotEmpty(Objects.toString(numberField.getFieldValue(), ""))) { return; } numberField.setFieldValue(technologyNameAndNumberGenerator.generateNumber(product)); numberField.requestComponentUpdateState(); } public void generateTechnologyName(final ViewDefinitionState view, final ComponentState state, final String[] args) { if (!(state instanceof FieldComponent)) { throw new IllegalStateException("component is not FieldComponentState"); } FieldComponent nameField = (FieldComponent) view.getComponentByReference(TechnologyFields.NAME); LookupComponent productLookup = (LookupComponent) state; Entity product = productLookup.getEntity(); if (product == null || StringUtils.isNotEmpty(Objects.toString(nameField.getFieldValue(), ""))) { return; } nameField.setFieldValue(technologyNameAndNumberGenerator.generateName(product)); nameField.requestComponentUpdateState(); } public void setLookupDisableInTechnologyOperationComponent(final ViewDefinitionState viewDefinitionState) { FormComponent form = (FormComponent) viewDefinitionState.getComponentByReference(L_FORM); FieldComponent operationLookup = (FieldComponent) viewDefinitionState.getComponentByReference(L_OPERATION); operationLookup.setEnabled(form.getEntityId() == null); } public void toggleDetailsViewEnabled(final ViewDefinitionState view) { view.getComponentByReference(TechnologyFields.STATE).performEvent(view, "toggleEnabled"); } private boolean productComponentsContainProduct(final List<Entity> components, final Entity product) { boolean contains = false; for (Entity entity : components) { if (entity.getBelongsToField(L_PRODUCT).getId().equals(product.getId())) { contains = true; break; } } return contains; } private SearchCriteriaBuilder createSearchCriteria(final Entity product, final Entity technology, final ProductDirection direction) { String model = direction.equals(ProductDirection.IN) ? TechnologiesConstants.MODEL_OPERATION_PRODUCT_IN_COMPONENT : TechnologiesConstants.MODEL_OPERATION_PRODUCT_OUT_COMPONENT; DataDefinition dd = dataDefinitionService.get(TechnologiesConstants.PLUGIN_IDENTIFIER, model); SearchCriteriaBuilder search = dd.find(); search.add(SearchRestrictions.eq("product.id", product.getId())); search.createAlias(L_OPERATION_COMPONENT, L_OPERATION_COMPONENT); search.add(SearchRestrictions.belongsTo("operationComponent.technology", technology)); return search; } public String getProductType(final Entity product, final Entity technology) { SearchCriteriaBuilder searchIns = createSearchCriteria(product, technology, ProductDirection.IN); SearchCriteriaBuilder searchOuts = createSearchCriteria(product, technology, ProductDirection.OUT); SearchCriteriaBuilder searchOutsForRoots = createSearchCriteria(product, technology, ProductDirection.OUT); searchOutsForRoots.add(SearchRestrictions.isNull("operationComponent.parent")); boolean goesIn = productComponentsContainProduct(searchIns.list().getEntities(), product); boolean goesOut = productComponentsContainProduct(searchOuts.list().getEntities(), product); boolean goesOutInAroot = productComponentsContainProduct(searchOutsForRoots.list().getEntities(), product); if (goesOutInAroot) { if (technology.getBelongsToField(L_PRODUCT).getId().equals(product.getId())) { return L_03_FINAL_PRODUCT; } else { return L_04_WASTE; } } if (goesIn && !goesOut) { return L_01_COMPONENT; } if (goesIn && goesOut) { return L_02_INTERMEDIATE; } if (!goesIn && goesOut) { return L_04_WASTE; } return L_00_UNRELATED; } public void addOperationsFromSubtechnologiesToList(final EntityTree entityTree, final List<Entity> technologyOperationComponents) { for (Entity technologyOperationComponent : entityTree) { if (TechnologyOperationComponentType.OPERATION.getStringValue().equals( technologyOperationComponent.getField(TechnologyOperationComponentFields.ENTITY_TYPE))) { technologyOperationComponents.add(technologyOperationComponent); } else { addOperationsFromSubtechnologiesToList( technologyOperationComponent .getBelongsToField(TechnologyOperationComponentFields.REFERENCE_TECHNOLOGY) .getTreeField(TechnologyFields.OPERATION_COMPONENTS), technologyOperationComponents); } } } public boolean invalidateIfAllreadyInTheSameOperation(final DataDefinition operationProductComponentDD, final Entity operationProductComponent) { if (operationProductComponent.getId() == null) { Entity product = operationProductComponent.getBelongsToField(L_PRODUCT); Entity operationComponent = operationProductComponent.getBelongsToField(L_OPERATION_COMPONENT); String fieldName; if (TechnologiesConstants.MODEL_OPERATION_PRODUCT_IN_COMPONENT .equals(operationProductComponentDD.getName())) { fieldName = TechnologyOperationComponentFields.OPERATION_PRODUCT_IN_COMPONENTS; } else { fieldName = TechnologyOperationComponentFields.OPERATION_PRODUCT_OUT_COMPONENTS; } EntityList products = operationComponent.getHasManyField(fieldName); if (product == null || product.getId() == null) { throw new IllegalStateException("Cant get product id"); } if (products != null && listContainsProduct(products, product)) { operationProductComponent.addError(operationProductComponentDD.getField(L_PRODUCT), "technologyOperationComponent.validate.error.productAlreadyExistInTechnologyOperation"); return false; } } return true; } private boolean listContainsProduct(final EntityList list, final Entity product) { for (Entity prod : list) { if (prod.getBelongsToField(L_PRODUCT).getId().equals(product.getId())) { return true; } } return false; } /** * @param technologyOperationComponent * @return productOutComponent. Assuming operation can have only one product/intermediate. */ // TODO dev_team introduce MainTocOutputProductProvider public Entity getMainOutputProductComponent(Entity technologyOperationComponent) { if (TechnologyOperationComponentType.REFERENCE_TECHNOLOGY.getStringValue().equals( technologyOperationComponent.getStringField(TechnologyOperationComponentFields.ENTITY_TYPE))) { technologyOperationComponent = technologyOperationComponent .getBelongsToField(TechnologyOperationComponentFields.REFERENCE_TECHNOLOGY) .getTreeField(TechnologyFields.OPERATION_COMPONENTS).getRoot(); } Entity parentTechnologyOperationComponent = technologyOperationComponent .getBelongsToField(TechnologyOperationComponentFields.PARENT); List<Entity> operationProductOutComponents = technologyOperationComponent .getHasManyField(TechnologyOperationComponentFields.OPERATION_PRODUCT_OUT_COMPONENTS); if (parentTechnologyOperationComponent == null) { Entity technology = technologyOperationComponent .getBelongsToField(TechnologyOperationComponentFields.TECHNOLOGY); Entity product = technology.getBelongsToField(TechnologyFields.PRODUCT); for (Entity operationProductOutComponent : operationProductOutComponents) { if (operationProductOutComponent.getBelongsToField(L_PRODUCT).getId().equals(product.getId())) { return operationProductOutComponent; } } } else { List<Entity> operationProductInComponents = parentTechnologyOperationComponent .getHasManyField(TechnologyOperationComponentFields.OPERATION_PRODUCT_IN_COMPONENTS); for (Entity operationProductOutComponent : operationProductOutComponents) { for (Entity operationProductInComponent : operationProductInComponents) { if (operationProductOutComponent.getBelongsToField(L_PRODUCT).getId() .equals(operationProductInComponent.getBelongsToField(L_PRODUCT).getId())) { return operationProductOutComponent; } } } } throw new IllegalStateException("OperationComponent doesn't have any products nor intermediates, id = " + technologyOperationComponent.getId()); } /** * @param operationComponent * @return Quantity of the output product associated with this operationComponent. Assuming operation can have only one * product/intermediate. */ public BigDecimal getProductCountForOperationComponent(final Entity operationComponent) { return getMainOutputProductComponent(operationComponent).getDecimalField(L_QUANTITY); } /** * Check if technology with given id is external synchronized. * * @param technologyId * identifier of the queried technology * @return true if technology is external synchronized */ public boolean isExternalSynchronized(final Long technologyId) { SearchQueryBuilder sqb = getTechnologyDataDefinition().find(IS_SYNCHRONIZED_QUERY); sqb.setLong("technologyId", technologyId).setMaxResults(1); Entity projection = sqb.uniqueResult(); Preconditions.checkNotNull(projection, String.format("Technology with id = '%s' does not exists.", technologyId)); return projection.getBooleanField(TechnologyFields.EXTERNAL_SYNCHRONIZED); } private DataDefinition getTechnologyDataDefinition() { return dataDefinitionService.get(TechnologiesConstants.PLUGIN_IDENTIFIER, TechnologiesConstants.MODEL_TECHNOLOGY); } public boolean isIntermediateProduct(final Entity opic) { boolean isIntermediate = false; Entity toc = opic.getBelongsToField(OperationProductInComponentFields.OPERATION_COMPONENT); List<Entity> childs = toc.getDataDefinition().find() .add(SearchRestrictions.belongsTo(TechnologyOperationComponentFields.PARENT, toc)).list() .getEntities(); if (childs.isEmpty()) { return isIntermediate; } long productId = opic.getBelongsToField(OperationProductInComponentFields.PRODUCT).getId(); for (Entity child : childs) { for (Entity childOPOC : child .getHasManyField(TechnologyOperationComponentFields.OPERATION_PRODUCT_OUT_COMPONENTS)) { long childProductId = childOPOC.getBelongsToField(OperationProductOutComponentFields.PRODUCT) .getId(); if (productId == childProductId) { isIntermediate = true; return isIntermediate; } } } return isIntermediate; } public boolean isFinalProduct(final Entity opoc) { boolean isFinalProduct = false; Entity toc = opoc.getBelongsToField(OperationProductInComponentFields.OPERATION_COMPONENT); if (toc.getBelongsToField(TechnologyOperationComponentFields.PARENT) != null) { return isFinalProduct; } Entity technology = toc.getBelongsToField(TechnologyOperationComponentFields.TECHNOLOGY); if (technology.getBelongsToField(TechnologyFields.PRODUCT).getId() .equals(opoc.getBelongsToField(OperationProductOutComponentFields.PRODUCT).getId())) { isFinalProduct = true; } return isFinalProduct; } }