It Changes configuration interface to include the creation of the code sequences for each entity.

FEA :ItEr61S04NavalPlanEntities
This commit is contained in:
Susana Montes Pedreira 2010-10-13 19:09:21 +02:00 committed by Javier Moran Rua
parent fe60ae5511
commit 4302177cde
5 changed files with 425 additions and 17 deletions

View file

@ -23,14 +23,18 @@ package org.navalplanner.web.common;
import static org.navalplanner.web.I18nHelper._;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.List;
import org.navalplanner.business.calendars.entities.BaseCalendar;
import org.navalplanner.business.common.entities.Configuration;
import org.navalplanner.business.common.entities.EntityNameEnum;
import org.navalplanner.business.common.entities.EntitySequence;
import org.navalplanner.business.common.entities.OrderSequence;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
@ -39,16 +43,20 @@ import org.zkoss.zk.ui.event.SelectEvent;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Intbox;
import org.zkoss.zul.Radio;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.Tabpanel;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.api.Listitem;
import org.zkoss.zul.api.Panel;
import org.zkoss.zul.api.Window;
/**
* Controller for {@link Configuration} entity.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public class ConfigurationController extends GenericForwardComposer {
@ -62,6 +70,8 @@ public class ConfigurationController extends GenericForwardComposer {
private Component messagesContainer;
private Tabpanel panelConfiguration;
private OrderSequenceRowRenderer orderSequenceRowRenderer = new OrderSequenceRowRenderer();
@Override
@ -75,14 +85,61 @@ public class ConfigurationController extends GenericForwardComposer {
@Override
public void onEvent(Event event) throws Exception {
Listitem selectedItem = (Listitem) ((SelectEvent) event)
.getSelectedItems()
.iterator().next();
.getSelectedItems().iterator().next();
setDefaultCalendar((BaseCalendar) selectedItem
.getValue());
}
});
messages = new MessagesForUser(messagesContainer);
createPanelEntityComponents();
}
private void createPanelEntityComponents() {
for (final EntityNameEnum entityName : EntityNameEnum.values()) {
Component entitySequenceComponent = Executions.createComponents(
"components/panelEntitySequence.zul", panelConfiguration,
new HashMap<String, String>());
initPanelTitle((Panel) entitySequenceComponent, entityName);
initButtonInPanelSequence(entitySequenceComponent, entityName);
initGridInPanelSequence(entitySequenceComponent, entityName);
reloadEntitySequenceList(entityName);
}
}
private void initPanelTitle(Panel panel, final EntityNameEnum entityName) {
panel.setTitle(_("{0} sequences", entityName.getDescription()));
}
private void initButtonInPanelSequence(Component component,
final EntityNameEnum entityName) {
String name = entityName.getDescription();
try {
Button button = (Button) component.getFirstChild().getFirstChild()
.getFirstChild();
button.setLabel(_("New {0} sequence", name));
button.addEventListener(Events.ON_CLICK, new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
addEntitySequence(entityName);
}
});
} catch (ClassCastException e) {
}
}
private void initGridInPanelSequence(Component component,
EntityNameEnum entityName) {
String name = entityName.getDescription();
String id = name + "SequenceList";
try {
Grid grid = (Grid) component.getFirstChild().getLastChild()
.getFirstChild();
grid.setId(id);
} catch (ClassCastException e) {
}
}
public List<BaseCalendar> getCalendars() {
@ -101,6 +158,7 @@ public class ConfigurationController extends GenericForwardComposer {
if (ConstraintChecker.isValid(configurationWindow)) {
try {
configurationModel.confirm();
configurationModel.init();
messages.showMessage(Level.INFO, _("Changes saved"));
reloadWindow();
} catch (ValidationException e) {
@ -121,6 +179,9 @@ public class ConfigurationController extends GenericForwardComposer {
private void reloadWindow() {
Util.reloadBindings(configurationWindow);
for (EntityNameEnum sequence : EntityNameEnum.values()) {
reloadEntitySequenceList(sequence);
}
}
public String getCompanyCode() {
@ -183,6 +244,10 @@ public class ConfigurationController extends GenericForwardComposer {
generateCodeForMaterialCategories);
}
public void reloadGeneralConfiguration() {
reloadWindow();
}
public Boolean getGenerateCodeForUnitTypes() {
return configurationModel.getGenerateCodeForUnitTypes();
}
@ -211,6 +276,15 @@ public class ConfigurationController extends GenericForwardComposer {
reloadOrderSequencesList();
}
public void removeEntitySequence(EntitySequence entitySequence) {
try {
configurationModel.removeEntitySequence(entitySequence);
} catch (IllegalArgumentException e) {
messages.showMessage(Level.ERROR, e.getMessage());
}
reloadEntitySequenceList(entitySequence.getEntityName());
}
private void reloadOrderSequencesList() {
Util
.reloadBindings(configurationWindow
@ -386,4 +460,170 @@ public class ConfigurationController extends GenericForwardComposer {
return configurationModel.isMonteCarloMethodTabVisible();
}
private void reloadEntitySequenceList(EntityNameEnum entityNameEnum) {
String nameList = entityNameEnum.getDescription();
Grid grid = (Grid) configurationWindow.getFellow(nameList
+ "SequenceList");
grid.setModel(new SimpleListModel(getEntitySequences(entityNameEnum)));
grid.invalidate();
}
public EntitySequenceRowRenderer getEntitySequenceRowRenderer() {
return new EntitySequenceRowRenderer();
}
private class EntitySequenceRowRenderer implements RowRenderer {
@Override
public void render(Row row, Object data) throws Exception {
EntitySequence entitySequence = (EntitySequence) data;
row.setValue(entitySequence);
appendActiveRadiobox(row, entitySequence);
appendPrefixTextbox(row, entitySequence);
appendNumberOfDigitsInbox(row, entitySequence);
appendLastValueInbox(row, entitySequence);
appendOperations(row, entitySequence);
}
private void appendActiveRadiobox(final Row row,
final EntitySequence entitySequence) {
final Radio radiobox = Util.bind(new Radio(),
new Util.Getter<Boolean>() {
@Override
public Boolean get() {
return entitySequence.isActive();
}
}, new Util.Setter<Boolean>() {
@Override
public void set(Boolean value) {
entitySequence.setActive(value);
updateOtherSequences(entitySequence);
}
});
row.appendChild(radiobox);
if (entitySequence.isActive()) {
radiobox.getRadiogroup().setSelectedItem(radiobox);
radiobox.getRadiogroup().invalidate();
}
}
private void updateOtherSequences(final EntitySequence activeSequence) {
for (EntitySequence sequence : getEntitySequences(activeSequence
.getEntityName())) {
if (sequence.getId() != activeSequence.getId()) {
sequence.setActive(false);
}
}
}
private void appendPrefixTextbox(Row row,
final EntitySequence entitySequence) {
final Textbox tempTextbox = new Textbox();
Textbox textbox = Util.bind(tempTextbox, new Util.Getter<String>() {
@Override
public String get() {
return entitySequence.getPrefix();
}
}, new Util.Setter<String>() {
@Override
public void set(String value) {
try {
entitySequence.setPrefix(value);
} catch (IllegalArgumentException e) {
throw new WrongValueException(tempTextbox, e
.getMessage());
}
}
});
textbox.setConstraint("no empty:" + _("cannot be null or empty"));
if (entitySequence.isAlreadyInUse()) {
textbox.setDisabled(true);
}
row.appendChild(textbox);
}
private void appendNumberOfDigitsInbox(Row row,
final EntitySequence entitySequence) {
final Intbox tempIntbox = new Intbox();
Intbox intbox = Util.bind(tempIntbox, new Util.Getter<Integer>() {
@Override
public Integer get() {
return entitySequence.getNumberOfDigits();
}
}, new Util.Setter<Integer>() {
@Override
public void set(Integer value) {
try {
entitySequence.setNumberOfDigits(value);
} catch (IllegalArgumentException e) {
throw new WrongValueException(tempIntbox, e
.getMessage());
}
}
});
intbox.setConstraint("no empty:" + _("cannot be null or empty"));
if (entitySequence.isAlreadyInUse()) {
intbox.setDisabled(true);
}
row.appendChild(intbox);
}
private void appendLastValueInbox(Row row,
final EntitySequence entitySequence) {
Textbox textbox = Util.bind(new Textbox(),
new Util.Getter<String>() {
@Override
public String get() {
return EntitySequence.formatValue(entitySequence
.getNumberOfDigits(), entitySequence
.getLastValue());
}
});
row.appendChild(textbox);
}
private void appendOperations(Row row,
final EntitySequence entitySequence) {
final Button removeButton = Util
.createRemoveButton(new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
removeEntitySequence(entitySequence);
}
});
if (entitySequence.isAlreadyInUse()) {
removeButton.setDisabled(true);
}
row.appendChild(removeButton);
}
}
public void addEntitySequence(EntityNameEnum entityName) {
configurationModel.addEntitySequence(entityName);
reloadEntitySequenceList(entityName);
}
public List<EntitySequence> getEntitySequences(EntityNameEnum entityName) {
return configurationModel.getEntitySequences(entityName);
}
}

View file

@ -22,17 +22,24 @@ package org.navalplanner.web.common;
import static org.navalplanner.web.I18nHelper._;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.navalplanner.business.calendars.daos.IBaseCalendarDAO;
import org.navalplanner.business.calendars.entities.BaseCalendar;
import org.navalplanner.business.common.daos.IConfigurationDAO;
import org.navalplanner.business.common.daos.IEntitySequenceDAO;
import org.navalplanner.business.common.daos.IOrderSequenceDAO;
import org.navalplanner.business.common.entities.Configuration;
import org.navalplanner.business.common.entities.EntityNameEnum;
import org.navalplanner.business.common.entities.EntitySequence;
import org.navalplanner.business.common.entities.OrderSequence;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
@ -60,6 +67,8 @@ public class ConfigurationModel implements IConfigurationModel {
private List<OrderSequence> orderSequences;
private Map<EntityNameEnum, List<EntitySequence>> entitySequences = new HashMap<EntityNameEnum, List<EntitySequence>>();
@Autowired
private IConfigurationDAO configurationDAO;
@ -69,6 +78,9 @@ public class ConfigurationModel implements IConfigurationModel {
@Autowired
private IOrderSequenceDAO orderSequenceDAO;
@Autowired
private IEntitySequenceDAO entitySequenceDAO;
@Override
@Transactional(readOnly = true)
public List<BaseCalendar> getCalendars() {
@ -88,6 +100,18 @@ public class ConfigurationModel implements IConfigurationModel {
public void init() {
this.configuration = getCurrentConfiguration();
this.orderSequences = orderSequenceDAO.getAll();
initEntitySequences();
}
private void initEntitySequences() {
this.entitySequences.clear();
for (EntityNameEnum entityName : EntityNameEnum.values()) {
entitySequences.put(entityName, new ArrayList<EntitySequence>());
}
for (EntitySequence entitySequence : entitySequenceDAO.getAll()) {
entitySequences.get(entitySequence.getEntityName()).add(
entitySequence);
}
}
private Configuration getCurrentConfiguration() {
@ -119,6 +143,9 @@ public class ConfigurationModel implements IConfigurationModel {
@Override
@Transactional
public void confirm() {
checkEntitySequences();
if (orderSequences.isEmpty()) {
throw new ValidationException(
_("At least one order sequence is needed"));
@ -137,11 +164,37 @@ public class ConfigurationModel implements IConfigurationModel {
try {
configurationDAO.save(configuration);
storeAndRemoveOrderSequences();
storeAndRemoveEntitySequences();
} catch (HibernateOptimisticLockingFailureException e) {
throw new ConcurrentModificationException(
_("Some order was created during the configuration process, it is impossible to update order sequence table. Please, try again later"));
}
}
private void checkEntitySequences() {
// check if exist at least one sequence for each entity
for (EntityNameEnum entityName : EntityNameEnum.values()) {
String entity = entityName.getDescription();
List<EntitySequence> sequences = entitySequences.get(entityName);
if (sequences.isEmpty()) {
throw new ValidationException(_(
"At least one {0} sequence is needed", entity));
}
if (!isAnyActive(sequences)) {
throw new ValidationException(_(
"At least one {0} sequence must be active", entity));
}
}
}
private boolean isAnyActive(List<EntitySequence> sequences) {
for (EntitySequence entitySequence : sequences) {
if (entitySequence.isActive()) {
return true;
}
}
return false;
}
private boolean checkConstraintPrefixNotRepeated() {
@ -174,6 +227,48 @@ public class ConfigurationModel implements IConfigurationModel {
}
}
private void storeAndRemoveEntitySequences() {
Collection<List<EntitySequence>> col_sequences = entitySequences
.values();
List<EntitySequence> sequences = new ArrayList<EntitySequence>();
for (List<EntitySequence> list : col_sequences) {
sequences.addAll(list);
}
removeEntitySequences(sequences);
storeEntitySequences(sequences);
}
public void removeEntitySequences(final List<EntitySequence> sequences) {
// first one is necessary to remove the deleted sequences.
List<EntitySequence> toRemove = entitySequenceDAO
.findEntitySquencesNotIn(sequences);
for (final EntitySequence entitySequence : toRemove) {
try {
entitySequenceDAO.remove(entitySequence);
} catch (InstanceNotFoundException e) {
throw new ValidationException(
_("Some sequences to remove not existed"));
} catch (IllegalArgumentException e) {
throw new ValidationException(e.getMessage());
}
}
}
public void storeEntitySequences(List<EntitySequence> sequences) {
// it updates the sequences that are not active first
List<EntitySequence> toSaveAfter = new ArrayList<EntitySequence>();
for (EntitySequence entitySequence : sequences) {
if (entitySequence.isActive()) {
toSaveAfter.add(entitySequence);
} else {
entitySequenceDAO.save(entitySequence);
}
}
for (EntitySequence entitySequence : toSaveAfter) {
entitySequenceDAO.save(entitySequence);
}
}
private boolean checkConstraintJustOneOrderSequenceActive() {
boolean someoneActive = false;
for (OrderSequence orderSequence : orderSequences) {
@ -390,7 +485,6 @@ public class ConfigurationModel implements IConfigurationModel {
return configuration.isExpandOrderPlanningViewCharts();
}
@Override
public void setExpandResourceLoadViewCharts(
Boolean expandResourceLoadViewCharts) {
@ -408,4 +502,23 @@ public class ConfigurationModel implements IConfigurationModel {
return configuration.isExpandResourceLoadViewCharts();
}
public List<EntitySequence> getEntitySequences(EntityNameEnum entityName) {
return entitySequences.get(entityName);
}
public void addEntitySequence(EntityNameEnum entityName) {
List<EntitySequence> sequences = entitySequences.get(entityName);
EntitySequence entitySequence = EntitySequence.create("", entityName);
if (sequences.isEmpty()) {
entitySequence.setActive(true);
}
sequences.add(entitySequence);
}
public void removeEntitySequence(EntitySequence entitySequence)
throws IllegalArgumentException {
entitySequences.get(entitySequence.getEntityName()).remove(
entitySequence);
}
}

View file

@ -20,10 +20,15 @@
package org.navalplanner.web.common;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.navalplanner.business.calendars.entities.BaseCalendar;
import org.navalplanner.business.common.entities.EntityNameEnum;
import org.navalplanner.business.common.entities.EntitySequence;
import org.navalplanner.business.common.entities.OrderSequence;
import org.springframework.transaction.annotation.Transactional;
/**
* Contract for {@link ConfigurationModel}.
@ -76,6 +81,11 @@ public interface IConfigurationModel {
void removeOrderSequence(OrderSequence orderSequence)
throws IllegalArgumentException;
List<EntitySequence> getEntitySequences(EntityNameEnum entityName);
void addEntitySequence(EntityNameEnum entityName);
void removeEntitySequence(EntitySequence entitySequence)
throws IllegalArgumentException;
void setExpandCompanyPlanningViewCharts(
Boolean expandCompanyPlanningViewCharts);
@ -102,5 +112,4 @@ public interface IConfigurationModel {
Boolean getGenerateCodeForUnitTypes();
void setGenerateCodeForUnitTypes(Boolean generateCodeForUnitTypes);
}

View file

@ -0,0 +1,37 @@
<!--
This file is part of NavalPlan
Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
Desenvolvemento Tecnolóxico de Galicia
This program 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, see <http://www.gnu.org/licenses/>.
-->
<panel border="normal">
<panelchildren>
<hbox valign="center">
<button />
</hbox>
<radiogroup>
<grid fixedLayout="true" rowRenderer="@{configurationController.entitySequenceRowRenderer}" >
<columns sizable="true">
<column label="${i18n:_('Active')}" />
<column label="${i18n:_('Prefix')}" />
<column label="${i18n:_('Number of digits')}"/>
<column label="${i18n:_('Last value')}" />
<column label="${i18n:_('Operations')}" />
</columns>
</grid>
</radiogroup>
</panelchildren>
</panel>

View file

@ -40,7 +40,7 @@
<tab label="${i18n:_('Main preferences')}" />
</tabs>
<tabpanels>
<tabpanel>
<tabpanel id="panelConfiguration">
<grid fixedLayout="true" id="configurationVariables">
<columns>
<column width="200px" />
@ -71,25 +71,32 @@
<rows>
<row>
<checkbox label="${i18n:_('Criterion')}"
checked="@{configurationController.generateCodeForCriterion}" />
checked="@{configurationController.generateCodeForCriterion}"
onCheck="configurationController.reloadGeneralConfiguration();" />
<checkbox label="${i18n:_('Label')}"
checked="@{configurationController.generateCodeForLabel}" />
checked="@{configurationController.generateCodeForLabel}"
onCheck="configurationController.reloadGeneralConfiguration();" />
</row>
<row>
<checkbox label="${i18n:_('Work report')}"
checked="@{configurationController.generateCodeForWorkReport}" />
checked="@{configurationController.generateCodeForWorkReport}"
onCheck="configurationController.reloadGeneralConfiguration();" />
<checkbox label="${i18n:_('Resources')}"
checked="@{configurationController.generateCodeForResources}" />
checked="@{configurationController.generateCodeForResources}"
onCheck="configurationController.reloadGeneralConfiguration();" />
</row>
<row>
<checkbox label="${i18n:_('Types of work hours')}"
checked="@{configurationController.generateCodeForTypesOfWorkHours}" />
checked="@{configurationController.generateCodeForTypesOfWorkHours}"
onCheck="configurationController.reloadGeneralConfiguration();" />
<checkbox label="${i18n:_('Material categories')}"
checked="@{configurationController.generateCodeForMaterialCategories}" />
checked="@{configurationController.generateCodeForMaterialCategories}"
onCheck="configurationController.reloadGeneralConfiguration();" />
</row>
<row>
<checkbox label="${i18n:_('Unit Measures')}"
checked="@{configurationController.generateCodeForUnitTypes}" />
checked="@{configurationController.generateCodeForUnitTypes}"
onCheck="configurationController.reloadGeneralConfiguration();" />
</row>
</rows>
</grid>
@ -104,13 +111,16 @@
<rows>
<row>
<checkbox label="${i18n:_('Company view')}"
checked="@{configurationController.expandCompanyPlanningViewCharts}" />
checked="@{configurationController.expandCompanyPlanningViewCharts}"
onCheck="configurationController.reloadGeneralConfiguration();" />
<checkbox label="${i18n:_('Order view')}"
checked="@{configurationController.expandOrderPlanningViewCharts}" />
checked="@{configurationController.expandOrderPlanningViewCharts}"
onCheck="configurationController.reloadGeneralConfiguration();" />
</row>
<row>
<checkbox label="${i18n:_('Resource load view')}"
checked="@{configurationController.expandResourceLoadViewCharts}" />
checked="@{configurationController.expandResourceLoadViewCharts}"
onCheck="configurationController.reloadGeneralConfiguration();" />
</row>
</rows>
</grid>
@ -155,7 +165,6 @@
</grid>
</panelchildren>
</panel>
</tabpanel>
</tabpanels>
</tabbox>