[Bug #930] Impossible to delete work hours type
Added delete button in list of type of work hours. A 'type of work hour' cannot be removed if it's being used by an 'hours cost'. FEA: ItEr74S04BugFixing
This commit is contained in:
parent
6b4bd00be0
commit
e1fcf3af1d
6 changed files with 127 additions and 27 deletions
|
|
@ -21,15 +21,20 @@
|
|||
|
||||
package org.navalplanner.business.costcategories.daos;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.navalplanner.business.common.daos.IntegrationEntityDAO;
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.navalplanner.business.costcategories.entities.HourCost;
|
||||
import org.navalplanner.business.costcategories.entities.TypeOfWorkHours;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*/
|
||||
@Repository
|
||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||
|
|
@ -47,4 +52,14 @@ public class HourCostDAO extends IntegrationEntityDAO<HourCost> implements
|
|||
}
|
||||
super.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Collection<HourCost> hoursCostsByTypeOfWorkHour(
|
||||
TypeOfWorkHours typeOfWorkHours) {
|
||||
return getSession().createCriteria(HourCost.class)
|
||||
.add(Restrictions.eq("type", typeOfWorkHours))
|
||||
.list();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,14 +21,22 @@
|
|||
|
||||
package org.navalplanner.business.costcategories.daos;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.navalplanner.business.common.daos.IIntegrationEntityDAO;
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.navalplanner.business.costcategories.entities.HourCost;
|
||||
import org.navalplanner.business.costcategories.entities.TypeOfWorkHours;
|
||||
|
||||
/**
|
||||
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*/
|
||||
public interface IHourCostDAO extends IIntegrationEntityDAO<HourCost> {
|
||||
|
||||
@Override
|
||||
public void remove(Long id) throws InstanceNotFoundException;
|
||||
}
|
||||
|
||||
public Collection<HourCost> hoursCostsByTypeOfWorkHour(TypeOfWorkHours typeOfWorkHours);
|
||||
|
||||
}
|
||||
|
|
@ -32,21 +32,28 @@ import org.navalplanner.web.common.IIntegrationEntityModel;
|
|||
* Model for UI operations related to {@link TypeOfWorkHours}
|
||||
*
|
||||
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*/
|
||||
public interface ITypeOfWorkHoursModel extends IIntegrationEntityModel {
|
||||
|
||||
/**
|
||||
* Makes some operations needed before edit a {@link TypeOfWorkHours}.
|
||||
*
|
||||
* @param typeOfWorkHours
|
||||
* The object to be edited
|
||||
*/
|
||||
void initEdit(TypeOfWorkHours typeOfWorkHours);
|
||||
void confirmRemove(TypeOfWorkHours typeOfWorkHours);
|
||||
|
||||
/**
|
||||
* Makes some operations needed before create a new {@link TypeOfWorkHours}.
|
||||
* Stores the current {@link WorkReport}.
|
||||
*
|
||||
* @throws ValidationException
|
||||
* If validation fails
|
||||
*/
|
||||
void initCreate();
|
||||
void confirmSave() throws ValidationException;
|
||||
|
||||
boolean existsCostCategoriesUsing(TypeOfWorkHours typeOfWorkHours);
|
||||
|
||||
/**
|
||||
* Gets the current {@link TypeOfWorkHours}.
|
||||
*
|
||||
* @return A {@link TypeOfWorkHours}
|
||||
*/
|
||||
TypeOfWorkHours getTypeOfWorkHours();
|
||||
|
||||
/**
|
||||
* Get all {@link TypeOfWorkHours} elements
|
||||
|
|
@ -56,18 +63,16 @@ public interface ITypeOfWorkHoursModel extends IIntegrationEntityModel {
|
|||
List<TypeOfWorkHours> getTypesOfWorkHours();
|
||||
|
||||
/**
|
||||
* Gets the current {@link TypeOfWorkHours}.
|
||||
*
|
||||
* @return A {@link TypeOfWorkHours}
|
||||
* Makes some operations needed before create a new {@link TypeOfWorkHours}.
|
||||
*/
|
||||
TypeOfWorkHours getTypeOfWorkHours();
|
||||
void initCreate();
|
||||
|
||||
/**
|
||||
* Stores the current {@link WorkReport}.
|
||||
*
|
||||
* @throws ValidationException
|
||||
* If validation fails
|
||||
*/
|
||||
void confirmSave() throws ValidationException;
|
||||
/**
|
||||
* Makes some operations needed before edit a {@link TypeOfWorkHours}.
|
||||
*
|
||||
* @param typeOfWorkHours
|
||||
* The object to be edited
|
||||
*/
|
||||
void initEdit(TypeOfWorkHours typeOfWorkHours);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import static org.navalplanner.web.I18nHelper._;
|
|||
import java.util.ConcurrentModificationException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.navalplanner.business.common.exceptions.ValidationException;
|
||||
import org.navalplanner.business.costcategories.entities.TypeOfWorkHours;
|
||||
import org.navalplanner.web.common.ConstraintChecker;
|
||||
|
|
@ -34,10 +35,12 @@ import org.navalplanner.web.common.Level;
|
|||
import org.navalplanner.web.common.MessagesForUser;
|
||||
import org.navalplanner.web.common.OnlyOneVisible;
|
||||
import org.navalplanner.web.common.Util;
|
||||
import org.navalplanner.web.common.components.NewDataSortableGrid;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.event.CheckEvent;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.util.GenericForwardComposer;
|
||||
import org.zkoss.zul.Messagebox;
|
||||
import org.zkoss.zul.api.Window;
|
||||
|
||||
/**
|
||||
|
|
@ -49,6 +52,9 @@ import org.zkoss.zul.api.Window;
|
|||
public class TypeOfWorkHoursCRUDController extends GenericForwardComposer implements
|
||||
ITypeOfWorkHoursCRUDController {
|
||||
|
||||
private static final org.apache.commons.logging.Log LOG = LogFactory
|
||||
.getLog(TypeOfWorkHoursCRUDController.class);
|
||||
|
||||
private Window createWindow;
|
||||
|
||||
private Window listWindow;
|
||||
|
|
@ -61,11 +67,14 @@ public class TypeOfWorkHoursCRUDController extends GenericForwardComposer implem
|
|||
|
||||
private Component messagesContainer;
|
||||
|
||||
private NewDataSortableGrid listing;
|
||||
|
||||
@Override
|
||||
public void doAfterCompose(Component comp) throws Exception {
|
||||
super.doAfterCompose(comp);
|
||||
comp.setVariable("controller", this, true);
|
||||
messagesForUser = new MessagesForUser(messagesContainer);
|
||||
listing = (NewDataSortableGrid) listWindow.getFellowIfAny("listing");
|
||||
getVisibility().showOnly(listWindow);
|
||||
}
|
||||
|
||||
|
|
@ -149,4 +158,40 @@ public class TypeOfWorkHoursCRUDController extends GenericForwardComposer implem
|
|||
Util.reloadBindings(createWindow);
|
||||
}
|
||||
|
||||
public void confirmDelete(TypeOfWorkHours typeOfWorkHours) {
|
||||
boolean canDelete = existsCostCategoriesUsing(typeOfWorkHours);
|
||||
if (!canDelete) {
|
||||
showCannotDeleteWorkHoursTypeDialog(typeOfWorkHours);
|
||||
return;
|
||||
}
|
||||
int result = showConfirmDeleteWorkHoursType(typeOfWorkHours);
|
||||
if (result == Messagebox.OK) {
|
||||
typeOfWorkHoursModel.confirmRemove(typeOfWorkHours);
|
||||
Util.reloadBindings(listing);
|
||||
}
|
||||
}
|
||||
|
||||
private int showConfirmDeleteWorkHoursType(TypeOfWorkHours typeOfWorkHours) {
|
||||
try {
|
||||
return Messagebox.show(_("Delete item. Are you sure?"), _("Confirm"),
|
||||
Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error(_("Error on removing typeOfWorkHours: ", typeOfWorkHours.getId()), e);
|
||||
}
|
||||
return Messagebox.CANCEL;
|
||||
}
|
||||
|
||||
private boolean existsCostCategoriesUsing(TypeOfWorkHours typeOfWorkHours) {
|
||||
return typeOfWorkHoursModel.existsCostCategoriesUsing(typeOfWorkHours);
|
||||
}
|
||||
|
||||
private void showCannotDeleteWorkHoursTypeDialog(TypeOfWorkHours typeOfWorkHours) {
|
||||
try {
|
||||
Messagebox.show(_("Cannot delete type of work hours. It is being used at this moment in some cost category."),
|
||||
_("Warning"), Messagebox.OK, Messagebox.EXCLAMATION);
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error(_("Error on showing warning message removing typeOfWorkHours: ", typeOfWorkHours.getId()), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import org.navalplanner.business.common.daos.IConfigurationDAO;
|
|||
import org.navalplanner.business.common.entities.EntityNameEnum;
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.navalplanner.business.common.exceptions.ValidationException;
|
||||
import org.navalplanner.business.costcategories.daos.IHourCostDAO;
|
||||
import org.navalplanner.business.costcategories.daos.ITypeOfWorkHoursDAO;
|
||||
import org.navalplanner.business.costcategories.entities.TypeOfWorkHours;
|
||||
import org.navalplanner.web.common.IntegrationEntityModel;
|
||||
|
|
@ -42,7 +43,9 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
|
||||
/**
|
||||
* Model for UI operations related to {@link TypeOfWorkHours}
|
||||
*
|
||||
* @author Jacobo Aragunde Perez <jaragunde@igalia.com>
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*/
|
||||
@Service
|
||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||
|
|
@ -55,6 +58,9 @@ public class TypeOfWorkHoursModel extends IntegrationEntityModel implements
|
|||
@Autowired
|
||||
private ITypeOfWorkHoursDAO typeOfWorkHoursDAO;
|
||||
|
||||
@Autowired
|
||||
private IHourCostDAO hourCostDAO;
|
||||
|
||||
@Autowired
|
||||
private IConfigurationDAO configurationDAO;
|
||||
|
||||
|
|
@ -64,6 +70,16 @@ public class TypeOfWorkHoursModel extends IntegrationEntityModel implements
|
|||
typeOfWorkHoursDAO.save(typeOfWorkHours);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void confirmRemove(TypeOfWorkHours typeOfWorkHours) {
|
||||
try {
|
||||
typeOfWorkHoursDAO.remove(typeOfWorkHours.getId());
|
||||
} catch (InstanceNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeOfWorkHours getTypeOfWorkHours() {
|
||||
return typeOfWorkHours;
|
||||
|
|
@ -115,4 +131,11 @@ public class TypeOfWorkHoursModel extends IntegrationEntityModel implements
|
|||
public IntegrationEntity getCurrentEntity() {
|
||||
return this.typeOfWorkHours;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public boolean existsCostCategoriesUsing(TypeOfWorkHours typeOfWorkHours) {
|
||||
return hourCostDAO.hoursCostsByTypeOfWorkHour(typeOfWorkHours).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -35,18 +35,22 @@
|
|||
<label value="@{typeOfWorkHours.name}" />
|
||||
<label value="@{typeOfWorkHours.defaultPrice}" />
|
||||
<checkbox checked="@{typeOfWorkHours.enabled}" disabled="true" />
|
||||
<!-- Buttons for each row -->
|
||||
<hbox>
|
||||
<button sclass="icono" image="/common/img/ico_editar1.png"
|
||||
hoverImage="/common/img/ico_editar.png"
|
||||
tooltiptext="${i18n:_('Edit')}"
|
||||
onClick="controller.goToEditForm(self.parent.parent.value);">
|
||||
</button>
|
||||
onClick="controller.goToEditForm(self.parent.parent.value);" />
|
||||
|
||||
<button sclass="icono" image="/common/img/ico_borrar1.png"
|
||||
hoverImage="/common/img/ico_borrar.png"
|
||||
tooltiptext="${i18n:_('Delete')}"
|
||||
onClick="controller.confirmDelete(self.parent.parent.value);" />
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</newdatasortablegrid>
|
||||
|
||||
<button id="show_create_form" onClick="controller.goToCreateForm();"
|
||||
label="${i18n:_('Create')}" sclass="create-button global-action" >
|
||||
</button>
|
||||
label="${i18n:_('Create')}" sclass="create-button global-action" />
|
||||
</window>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue