diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java
index fb7bc2370..939dfa5ac 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/Criterion.java
@@ -174,7 +174,7 @@ public class Criterion extends IntegrationEntity implements ICriterion {
}
public static Criterion create(CriterionType type) {
- return create(new Criterion(type));
+ return create(new Criterion(type),"");
}
public static Criterion create(String name, CriterionType type) {
diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionType.java b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionType.java
index 31624a352..3fde4afa3 100644
--- a/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionType.java
+++ b/navalplanner-business/src/main/java/org/navalplanner/business/resources/entities/CriterionType.java
@@ -27,11 +27,16 @@ import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotEmpty;
+import org.hibernate.validator.NotNull;
import org.hibernate.validator.Valid;
import org.navalplanner.business.advance.entities.AdvanceAssignment;
import org.navalplanner.business.common.IntegrationEntity;
import org.navalplanner.business.common.Registry;
+import org.navalplanner.business.common.entities.EntitySequence;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
+import org.navalplanner.business.orders.entities.HoursGroup;
+import org.navalplanner.business.orders.entities.OrderElement;
+import org.navalplanner.business.orders.entities.OrderLine;
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
import org.springframework.stereotype.Component;
/**
@@ -151,6 +156,7 @@ public class CriterionType extends IntegrationEntity implements
private Boolean generateCode = false;
+ private Integer lastCriterionSequenceCode = 0;
/**
* Constructor for hibernate. Do not use!
*/
@@ -498,6 +504,10 @@ public class CriterionType extends IntegrationEntity implements
this.generateCode = generateCode;
}
+ public boolean isCodeAutogenerated() {
+ return getGenerateCode() != null && getGenerateCode();
+ }
+
/**
* It checks there are no {@link AdvanceAssignment} any criteria of this
* {@link CriterionType} has been assigned to any {@link Resource}
@@ -520,4 +530,16 @@ public class CriterionType extends IntegrationEntity implements
.checkChildrenAssignedToAnyResource(this)));
}
+ @NotNull(message = "last criterion sequence code not specified")
+ public Integer getLastCriterionSequenceCode() {
+ return lastCriterionSequenceCode;
+ }
+
+ public void incrementLastCriterionSequenceCode() {
+ if (this.lastCriterionSequenceCode == null) {
+ this.lastCriterionSequenceCode = 0;
+ }
+ this.lastCriterionSequenceCode++;
+ }
+
}
diff --git a/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml b/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml
index 9e0b28e47..9d73618cd 100644
--- a/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml
+++ b/navalplanner-business/src/main/resources/org/navalplanner/business/resources/entities/Resources.hbm.xml
@@ -168,6 +168,7 @@
+
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionAdminController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionAdminController.java
index d7e0065b2..e7e2fff08 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionAdminController.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionAdminController.java
@@ -22,6 +22,7 @@ package org.navalplanner.web.resources.criterion;
import static org.navalplanner.web.I18nHelper._;
+import java.util.ConcurrentModificationException;
import java.util.List;
import org.apache.commons.logging.Log;
@@ -342,13 +343,14 @@ public class CriterionAdminController extends GenericForwardComposer {
public void onCheckGenerateCode(Event e) {
CheckEvent ce = (CheckEvent) e;
- if(ce.isChecked()) {
- //we have to auto-generate the code for new objects
- if(((CriterionType)criterionsModel_V2.getCriterionType()).isNewObject()) {
- ((CriterionType)criterionsModel_V2.getCriterionType()).setCodeAutogenerated();
- Util.reloadBindings(createComponent);
+ if (ce.isChecked()) {
+ try {
+ // we have to auto-generate the code for new objects
+ criterionsModel_V2.setCodeAutogenerated(ce.isChecked());
+ } catch (ConcurrentModificationException err) {
+ messagesForUser.showMessage(Level.ERROR, err.getMessage());
}
- editionTree.regenerateCodeForUnsavedCriteria();
+ Util.reloadBindings(createComponent);
}
//disable code field in criterion tree controller
editionTree.setCriterionCodeEditionDisabled(ce.isChecked());
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionTreeController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionTreeController.java
index fa8271c88..565efd268 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionTreeController.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionTreeController.java
@@ -396,8 +396,8 @@ public class CriterionTreeController extends GenericForwardComposer {
codeEditionDisabled = disabled;
}
- public void regenerateCodeForUnsavedCriteria() {
- getModel().regenerateCodeForUnsavedCriteria();
+ public void regenerateCodeForUnsavedCriteria(int numberOfDigits) {
+ getModel().regenerateCodeForUnsavedCriteria(numberOfDigits);
}
public void reloadTree(){
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionTreeModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionTreeModel.java
index cb1e0f421..43ff0d010 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionTreeModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionTreeModel.java
@@ -34,6 +34,7 @@ import java.util.List;
import java.util.Set;
import org.hibernate.validator.InvalidValue;
+import org.navalplanner.business.common.entities.EntitySequence;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.resources.entities.CriterionType;
@@ -436,17 +437,33 @@ public class CriterionTreeModel implements ICriterionTreeModel {
return false;
}
- public void regenerateCodeForUnsavedCriteria() {
- regenerateCodeForUnsavedCriteria(criterionRootDTO.getChildren());
+ public void regenerateCodeForUnsavedCriteria(int numberOfDigits) {
+ regenerateCodeForUnsavedCriteria(criterionRootDTO.getChildren(),
+ numberOfDigits);
}
private void regenerateCodeForUnsavedCriteria(
- List criterionDTOs) {
- for(CriterionDTO criterionDTO : criterionDTOs){
- if(criterionDTO.getCriterion().isNewObject()) {
- criterionDTO.getCriterion().setCodeAutogenerated();
+ List criterionDTOs, int numberOfDigits) {
+ for (CriterionDTO criterionDTO : criterionDTOs) {
+ Criterion criterion = criterionDTO.getCriterion();
+ if ((criterion.getCode() == null)
+ || (criterion.getCode().isEmpty())
+ || (!criterion.getCode()
+ .startsWith(criterionType.getCode()))) {
+ setGenerateCode(criterion, numberOfDigits);
}
- regenerateCodeForUnsavedCriteria(criterionDTO.getChildren());
+ regenerateCodeForUnsavedCriteria(criterionDTO.getChildren(),
+ numberOfDigits);
+ }
+ }
+
+ private void setGenerateCode(Criterion criterion, int numberOfDigits) {
+ if ((criterion.getCode() == null) || (criterion.getCode().isEmpty())
+ || (!criterion.getCode().startsWith(criterionType.getCode()))) {
+ criterionType.incrementLastCriterionSequenceCode();
+ String criterionCode = EntitySequence.formatValue(numberOfDigits,
+ criterionType.getLastCriterionSequenceCode());
+ criterion.setCode(criterionType.getCode() + criterionCode);
}
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionsModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionsModel.java
index 8fd96df97..b803e6977 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionsModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/CriterionsModel.java
@@ -24,12 +24,19 @@ import static org.navalplanner.web.I18nHelper._;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.hibernate.NonUniqueResultException;
import org.navalplanner.business.common.daos.IConfigurationDAO;
+import org.navalplanner.business.common.daos.IEntitySequenceDAO;
+import org.navalplanner.business.common.entities.EntityNameEnum;
+import org.navalplanner.business.common.entities.EntitySequence;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.resources.daos.ICriterionDAO;
@@ -70,12 +77,21 @@ public class CriterionsModel implements ICriterionsModel {
@Autowired
private IConfigurationDAO configurationDAO;
+ @Autowired
+ private IEntitySequenceDAO entitySequenceDAO;
+
private CriterionType criterionType;
private Criterion criterion;
private ICriterionTreeModel criterionTreeModel;
+ private String oldCodeCriterionType;
+
+ private Map oldCriterionTypeCodeChildren = new HashMap();
+
+ private Boolean generateCodeOldCriterionType;
+
@Override
@Transactional(readOnly = true)
public List getTypes() {
@@ -106,15 +122,63 @@ public class CriterionsModel implements ICriterionsModel {
@Override
@Transactional(readOnly=true)
public void prepareForCreate() {
- boolean generateCode = configurationDAO.getConfiguration().getGenerateCodeForCriterion();
- if(generateCode) {
- this.criterionType = CriterionType.create();
- }
- else {
- this.criterionType = CriterionType.create("");
+ this.criterionType = CriterionType.create("");
+ initializeCriterionTypeCode();
+ this.criterionTreeModel = new CriterionTreeModel(criterionType);
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public void initializeCriterionTypeCode() {
+ boolean generateCode = configurationDAO.getConfiguration()
+ .getGenerateCodeForCriterion();
+ if (generateCode) {
+ setDefaultCriterionTypeCode();
}
this.criterionType.setGenerateCode(generateCode);
- this.criterionTreeModel = new CriterionTreeModel(criterionType);
+ }
+
+ @Override
+ public void setCodeAutogenerated(boolean codeAutogenerated)
+ throws ConcurrentModificationException {
+ if (criterionType != null) {
+ if (criterionType.isNewObject()) {
+ setDefaultCriterionTypeCode();
+ } else {
+ if (isGenerateCodeOldCriterionType()) {
+ restoreOldCodes();
+ } else {
+ setDefaultCriterionTypeCode();
+ }
+ }
+ criterionType.setGenerateCode(codeAutogenerated);
+ }
+ }
+
+ private void setDefaultCriterionTypeCode()
+ throws ConcurrentModificationException {
+ String code = entitySequenceDAO
+ .getNextEntityCode(EntityNameEnum.CRITERION);
+ if (code == null) {
+ throw new ConcurrentModificationException(
+ _("Could not get criterion type code, please try again later"));
+ }
+ this.criterionType.setCode(code);
+ }
+
+ private void generateCriterionCodes() {
+ int numberOfDigits = 5;
+ try {
+ EntitySequence entitySequence = entitySequenceDAO
+ .getActiveEntitySequence(EntityNameEnum.CRITERION);
+ numberOfDigits = entitySequence.getNumberOfDigits();
+ } catch (InstanceNotFoundException e) {
+ throw new RuntimeException(e);
+ } catch (NonUniqueResultException e) {
+ throw new RuntimeException(e);
+ }
+
+ criterionTreeModel.regenerateCodeForUnsavedCriteria(numberOfDigits);
}
@Override
@@ -138,6 +202,25 @@ public class CriterionsModel implements ICriterionsModel {
Validate.notNull(criterionType);
this.criterionType = getFromDB(criterionType);
this.criterionTreeModel = new CriterionTreeModel(this.criterionType);
+ initOldCodes();
+ }
+
+ private void initOldCodes() {
+ if (criterionType != null) {
+ setOldCodeCriterionType(criterionType.getCode());
+ for (Criterion criterion : criterionType.getCriterions()) {
+ oldCriterionTypeCodeChildren
+ .put(criterion, criterion.getCode());
+ }
+ setGenerateCodeOldCriterionType(criterionType.isCodeAutogenerated());
+ }
+ }
+
+ private void restoreOldCodes() {
+ criterionType.setCode(getOldCodeCriterionType());
+ for (Criterion criterion : oldCriterionTypeCodeChildren.keySet()) {
+ criterion.setCode(oldCriterionTypeCodeChildren.get(criterion));
+ }
}
@Override
@@ -147,7 +230,7 @@ public class CriterionsModel implements ICriterionsModel {
criterionTypeDAO.remove(criterionType.getId());
} catch (InstanceNotFoundException e) {
throw new RuntimeException(e);
- }
+ }
}
@Transactional(readOnly = true)
@@ -173,6 +256,9 @@ public class CriterionsModel implements ICriterionsModel {
@Override
@Transactional
public void saveCriterionType() throws ValidationException {
+ if (criterionType.isCodeAutogenerated()) {
+ generateCriterionCodes();
+ }
criterionTreeModel.saveCriterions(criterionType);
criterionTypeDAO.save(criterionType);
}
@@ -228,6 +314,7 @@ public class CriterionsModel implements ICriterionsModel {
public void reloadCriterionType() {
this.criterionType = getFromDB(criterionType);
this.criterionTreeModel = new CriterionTreeModel(this.criterionType);
+ this.initOldCodes();
}
@Override
@@ -247,7 +334,6 @@ public class CriterionsModel implements ICriterionsModel {
|| (criterion.getChildren().isEmpty() && (numberOfRelatedEntities(criterion) == 0));
}
-
@Override
public void addForRemoval(Criterion criterion) {
criterionType.getCriterions().remove(criterion);
@@ -264,4 +350,21 @@ public class CriterionsModel implements ICriterionsModel {
return true;
}
+ private void setOldCodeCriterionType(String oldCodeCriterionType) {
+ this.oldCodeCriterionType = oldCodeCriterionType;
+ }
+
+ private String getOldCodeCriterionType() {
+ return oldCodeCriterionType;
+ }
+
+ private void setGenerateCodeOldCriterionType(Boolean generatedCode) {
+ this.generateCodeOldCriterionType = generatedCode;
+ }
+
+ private Boolean isGenerateCodeOldCriterionType() {
+ return (generateCodeOldCriterionType != null) ? generateCodeOldCriterionType
+ : false;
+ }
+
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionTreeModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionTreeModel.java
index 9d38dc99e..910e017ba 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionTreeModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionTreeModel.java
@@ -30,7 +30,6 @@ import org.navalplanner.business.resources.entities.CriterionType;
import org.zkoss.zul.TreeModel;
/**
- *
* @author Susana Montes Pedreira
*/
public interface ICriterionTreeModel {
@@ -69,5 +68,5 @@ public interface ICriterionTreeModel {
void unindent(CriterionDTO nodeToIndent);
- void regenerateCodeForUnsavedCriteria();
+ void regenerateCodeForUnsavedCriteria(int numberOfDigits);
}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionsModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionsModel.java
index 5e1d48104..7c93abcec 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionsModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/criterion/ICriterionsModel.java
@@ -21,6 +21,7 @@
package org.navalplanner.web.resources.criterion;
import java.util.Collection;
+import java.util.ConcurrentModificationException;
import java.util.List;
import org.navalplanner.business.common.exceptions.ValidationException;
@@ -69,10 +70,8 @@ public interface ICriterionsModel {
/**
* Reloads {@link CriterionType} from DB and all its criterions
- *
* This method should be call after saveAndContinue() from controller to
* synchronize what has been committed to DB after saving and the model
- *
*/
void reloadCriterionType();
@@ -87,4 +86,9 @@ public interface ICriterionsModel {
boolean isDeletable(CriterionType criterionType);
void addForRemoval(Criterion criterion);
+
+ void initializeCriterionTypeCode();
+
+ void setCodeAutogenerated(boolean codeAutogenerated)
+ throws ConcurrentModificationException;
}