[Bug #931] Added explicit check hour cost in 'Cost category' don't overlap for the same type of hours

FEA: ItEr74S04BugFixing
This commit is contained in:
Diego Pino Garcia 2011-04-06 18:04:39 +02:00
parent 145b6b70f9
commit e281fab21b
5 changed files with 100 additions and 40 deletions

View file

@ -28,6 +28,7 @@ import org.navalplanner.business.common.BaseEntity;
/**
* Encapsulates some validation failure <br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
public class ValidationException extends RuntimeException {
@ -63,6 +64,12 @@ public class ValidationException extends RuntimeException {
return bean.toString();
}
public static ValidationException invalidValue(String message, Object value) {
InvalidValue invalidValue = new InvalidValue(message, null, "", value,
null);
return new ValidationException(invalidValue);
}
private InvalidValue[] invalidValues;
public InvalidValue[] getInvalidValues() {

View file

@ -45,6 +45,7 @@ import org.navalplanner.business.costcategories.daos.ICostCategoryDAO;
/**
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
public class CostCategory extends IntegrationEntity {
@ -91,6 +92,58 @@ public class CostCategory extends IntegrationEntity {
return (CostCategory) create(new CostCategory(name));
}
public static void validateHourCostsOverlap(Set<HourCost> hoursCosts)
throws ValidationException {
List<HourCost> listHourCosts = new ArrayList<HourCost>(hoursCosts);
for (int i = 0; i < listHourCosts.size(); i++) {
LocalDate initDate = listHourCosts.get(i).getInitDate();
LocalDate endDate = listHourCosts.get(i).getEndDate();
for (int j = i + 1; j < listHourCosts.size(); j++) {
HourCost listElement = listHourCosts.get(j);
if (listElement.getType() == null
|| listHourCosts.get(i).getType() == null) {
// this is not exactly an overlapping but a
// problem with missing compulsory fields
throw ValidationException.invalidValue(
_("Hours cost type cannot be empty or null"),
listElement);
}
if (listElement.getType().getId()
.equals(listHourCosts.get(i).getType().getId())) {
if (initDate == null || listElement.getInitDate() == null) {
// this is not exactly an overlapping but a
// problem with missing compulsory fields
throw ValidationException.invalidValue(
_("Init date cannot be empty or null"),
listElement);
}
if (endDate == null && listElement.getEndDate() == null) {
throw ValidationException.invalidValue(
_("End date cannot be empty or null"),
listElement);
} else if ((endDate == null && listElement.getEndDate()
.compareTo(initDate) >= 0)
|| (listElement.getEndDate() == null && listElement
.getInitDate().compareTo(endDate) <= 0)) {
throw ValidationException
.invalidValue(
_("Two hour costs with the same type overlap in time"),
listElement);
} else if ((endDate != null && listElement.getEndDate() != null)
&& ((listElement.getEndDate().compareTo(initDate) >= 0 && listElement
.getEndDate().compareTo(endDate) <= 0) || (listElement
.getInitDate().compareTo(initDate) >= 0 && listElement
.getInitDate().compareTo(endDate) <= 0))) {
throw ValidationException
.invalidValue(
_("Two hour costs with the same type overlap in time"),
listElement);
}
}
}
}
}
protected CostCategory(String name) {
this.name = name;
}
@ -173,42 +226,12 @@ public class CostCategory extends IntegrationEntity {
@AssertFalse(message="Two hour costs with the same type overlap in time")
public boolean checkHourCostsOverlap() {
List<HourCost> listHourCosts = new ArrayList<HourCost>();
listHourCosts.addAll(getHourCosts());
for(int i=0; i<listHourCosts.size(); i++) {
LocalDate initDate = listHourCosts.get(i).getInitDate();
LocalDate endDate = listHourCosts.get(i).getEndDate();
for(int j=i+1; j<listHourCosts.size(); j++) {
HourCost listElement = listHourCosts.get(j);
if (listElement.getType() == null || listHourCosts.get(i).getType() == null) {
//this is not exactly an overlapping but a
//problem with missing compulsory fields
return true;
}
if(listElement.getType().getId().equals(listHourCosts.get(i).getType().getId())) {
if (initDate == null || listElement.getInitDate() == null) {
//this is not exactly an overlapping but a
//problem with missing compulsory fields
return true;
}
if (endDate == null && listElement.getEndDate() == null) {
return true;
}
else if((endDate == null && listElement.getEndDate().compareTo(initDate)>=0) ||
(listElement.getEndDate() == null && listElement.getInitDate().compareTo(endDate)<=0)) {
return true;
}
else if((endDate != null && listElement.getEndDate() != null) &&
((listElement.getEndDate().compareTo(initDate)>=0 &&
listElement.getEndDate().compareTo(endDate)<=0) ||
(listElement.getInitDate().compareTo(initDate)>=0 &&
listElement.getInitDate().compareTo(endDate)<=0))) {
return true;
}
}
}
try {
validateHourCostsOverlap(getHourCosts());
return false;
} catch (ValidationException e) {
return true;
}
return false;
}
@Override

View file

@ -31,6 +31,7 @@ import java.util.List;
import java.util.Set;
import org.apache.commons.logging.LogFactory;
import org.hibernate.validator.InvalidValue;
import org.joda.time.LocalDate;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
@ -45,7 +46,9 @@ import org.navalplanner.web.common.OnlyOneVisible;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.common.components.Autocomplete;
import org.navalplanner.web.workreports.WorkReportCRUDController;
import org.zkoss.ganttz.util.ComponentsFinder;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.CheckEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
@ -68,6 +71,7 @@ import org.zkoss.zul.api.Window;
* Controller for CRUD actions over a {@link CostCategory}
*
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
@SuppressWarnings("serial")
public class CostCategoryCRUDController extends GenericForwardComposer
@ -164,20 +168,36 @@ public class CostCategoryCRUDController extends GenericForwardComposer
}
public boolean save() {
if(!ConstraintChecker.isValid(createWindow)) {
if (!ConstraintChecker.isValid(createWindow)) {
return false;
}
try {
costCategoryModel.validateHourCostsOverlap();
} catch (ValidationException e) {
showHoursCostsOverlapValidationException(e);
}
try {
costCategoryModel.confirmSave();
messagesForUser.showMessage(Level.INFO,
_("Cost category saved"));
messagesForUser.showMessage(Level.INFO, _("Cost category saved"));
return true;
} catch (ValidationException e) {
e.getInvalidValue().getValue();
messagesForUser.showInvalidValues(e);
}
return false;
}
private void showHoursCostsOverlapValidationException(ValidationException e) {
InvalidValue invalid = e.getInvalidValue();
Row comp = ComponentsFinder.findRowByValue(listHourCosts,
invalid.getValue());
if (comp != null) {
throw new WrongValueException(comp, invalid.getMessage());
}
}
public CostCategory getCostCategory() {
return costCategoryModel.getCostCategory();
}

View file

@ -47,6 +47,7 @@ import org.springframework.transaction.annotation.Transactional;
* Model for UI operations related to {@link CostCategory}
*
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -181,4 +182,9 @@ public class CostCategoryModel extends IntegrationEntityModel implements
public IntegrationEntity getCurrentEntity() {
return this.costCategory;
}
}
@Override
public void validateHourCostsOverlap() throws ValidationException {
CostCategory.validateHourCostsOverlap(getCostCategory().getHourCosts());
}
}

View file

@ -34,6 +34,7 @@ import org.navalplanner.web.common.IIntegrationEntityModel;
* Model for UI operations related to {@link CostCategory}
*
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*/
public interface ICostCategoryModel extends IIntegrationEntityModel {
@ -62,4 +63,7 @@ public interface ICostCategoryModel extends IIntegrationEntityModel {
throws InstanceNotFoundException;
boolean canRemoveCostCategory(CostCategory category);
}
void validateHourCostsOverlap() throws ValidationException;
}