Adds the generated code sequence to resource calendars .

Replaces the generated code by the code sequence
for each resource calendar and add the generated code
to the base calendar children (CalendarException,
CalendarData, CalendarAvailability).

FEA :ItEr61S04NavalPlanEntities
This commit is contained in:
Susana Montes Pedreira 2010-10-27 10:09:51 +02:00 committed by Javier Moran Rua
parent 1be0b8f262
commit a43fe366d3
11 changed files with 292 additions and 43 deletions

View file

@ -32,12 +32,14 @@ import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.hibernate.validator.AssertTrue;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
import org.hibernate.validator.Valid;
import org.joda.time.DateTimeConstants;
import org.joda.time.LocalDate;
import org.navalplanner.business.calendars.daos.IBaseCalendarDAO;
import org.navalplanner.business.calendars.entities.CalendarData.Days;
import org.navalplanner.business.common.IntegrationEntity;
import org.navalplanner.business.common.entities.EntitySequence;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.ResourcesPerDay;
@ -113,6 +115,8 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar {
@Valid
private List<CalendarAvailability> calendarAvailabilities = new ArrayList<CalendarAvailability>();
private Integer lastSequenceCode = 0;
public enum DayType {
NORMAL, ZERO_HOURS, OWN_EXCEPTION, ANCESTOR_EXCEPTION
}
@ -504,6 +508,7 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar {
private void copyFields(BaseCalendar copy) {
copy.name = this.name;
copy.setCodeAutogenerated(this.isCodeAutogenerated());
copy.calendarDataVersions = new ArrayList<CalendarData>();
for (CalendarData calendarData : this.calendarDataVersions) {
copy.calendarDataVersions.add(calendarData.copy());
@ -1085,4 +1090,55 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar {
}
public void generateCalendarExceptionCodes(int numberOfDigits) {
for (CalendarException exception : this.getExceptions()) {
if ((exception.getCode() == null)
|| (exception.getCode().isEmpty())
|| (!exception.getCode().startsWith(this.getCode()))) {
this.incrementLastSequenceCode();
String exceptionCode = EntitySequence.formatValue(
numberOfDigits, this.getLastSequenceCode());
exception.setCode(this.getCode()
+ EntitySequence.CODE_SEPARATOR_CHILDREN
+ exceptionCode);
}
}
for (CalendarData data : this.getCalendarDataVersions()) {
if ((data.getCode() == null) || (data.getCode().isEmpty())
|| (!data.getCode().startsWith(this.getCode()))) {
this.incrementLastSequenceCode();
String dataCode = EntitySequence.formatValue(numberOfDigits,
this.getLastSequenceCode());
data.setCode(this.getCode()
+ EntitySequence.CODE_SEPARATOR_CHILDREN + dataCode);
}
}
for (CalendarAvailability availability : this
.getCalendarAvailabilities()) {
if ((availability.getCode() == null)
|| (availability.getCode().isEmpty())
|| (!availability.getCode().startsWith(this.getCode()))) {
this.incrementLastSequenceCode();
String availabilityCode = EntitySequence.formatValue(
numberOfDigits, this.getLastSequenceCode());
availability.setCode(this.getCode()
+ EntitySequence.CODE_SEPARATOR_CHILDREN
+ availabilityCode);
}
}
}
public void incrementLastSequenceCode() {
if (lastSequenceCode == null) {
lastSequenceCode = 0;
}
lastSequenceCode++;
}
@NotNull(message = "last sequence code not specified")
public Integer getLastSequenceCode() {
return lastSequenceCode;
}
}

View file

@ -41,9 +41,9 @@ import org.navalplanner.business.workreports.entities.WorkReport;
public enum EntityNameEnum {
ORDER("Order"), CRITERION("Criterion"), LABEL("Label"), MACHINE("Machine"), WORKER(
"Worker"), UNIT_TYPE("Unit type"), CALENDAR("Calendar"), WORK_HOURS_TYPE(
"Worker"), UNIT_TYPE("Unit type"), CALENDAR("Calendar"), WORK_HOURS_TYPE(
"Type of work hours"), MATERIAL_CATEGORY("Material category"), WORK_REPORT(
"Work report");
"Work report"), RESOURCE_CALENDAR("Resource calendar");
private String description;
@ -72,6 +72,7 @@ public enum EntityNameEnum {
case UNIT_TYPE:
return (IIntegrationEntityDAO<UnitType>) Registry.getUnitTypeDAO();
case CALENDAR:
case RESOURCE_CALENDAR:
return (IIntegrationEntityDAO<CalendarData>) Registry
.getCalendarDataDAO();
case WORK_HOURS_TYPE:

View file

@ -19,6 +19,8 @@
<property name="codeAutogenerated" access="field"/>
<property name="lastSequenceCode" access="field"/>
<!-- Index created in a database-object section -->
<set name="exceptions" access="field" cascade="all-delete-orphan">
<key column="BASE_CALENDAR_ID" />
@ -121,6 +123,8 @@
</id>
<version name="version" access="property" type="long" />
<property name="code" access="property" not-null="true" unique="true"/>
<property name="startDate" access="field"
type="org.joda.time.contrib.hibernate.PersistentLocalDate" />
<property name="endDate" access="field"

View file

@ -22,7 +22,6 @@ package org.navalplanner.web.calendars;
import static org.navalplanner.web.I18nHelper._;
import java.util.ConcurrentModificationException;
import java.util.Date;
import org.navalplanner.business.calendars.entities.BaseCalendar;
@ -34,12 +33,12 @@ import org.navalplanner.web.common.OnlyOneVisible;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.common.components.CalendarHighlightedDays;
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.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Label;
import org.zkoss.zul.SimpleTreeNode;
import org.zkoss.zul.Treecell;
@ -67,6 +66,8 @@ public class BaseCalendarCRUDController extends GenericForwardComposer {
private Window createNewVersion;
private Grid gridCalendarInformation;
private boolean confirmingRemove = false;
private OnlyOneVisible visibility;
@ -124,6 +125,8 @@ public class BaseCalendarCRUDController extends GenericForwardComposer {
public void save() {
try {
validateCalendarExceptionCodes();
baseCalendarModel.generateCalendarCodes();
baseCalendarModel.confirmSave();
messagesForUser.showMessage(Level.INFO, _(
"Base calendar \"{0}\" saved", baseCalendarModel
@ -207,7 +210,8 @@ public class BaseCalendarCRUDController extends GenericForwardComposer {
private void assignEditionController() {
editionController = new BaseCalendarEditionController(
baseCalendarModel, editWindow, createNewVersion) {
baseCalendarModel, editWindow, createNewVersion,
messagesForUser) {
@Override
public void goToList() {
@ -235,7 +239,7 @@ public class BaseCalendarCRUDController extends GenericForwardComposer {
private void assignCreateController() {
createController = new BaseCalendarEditionController(baseCalendarModel,
createWindow, createNewVersion) {
createWindow, createNewVersion, messagesForUser) {
@Override
public void goToList() {
@ -414,24 +418,11 @@ public class BaseCalendarCRUDController extends GenericForwardComposer {
}
}
public void onCheckGenerateCode(Event e) {
CheckEvent ce = (CheckEvent) e;
if (ce.isChecked()) {
try {
baseCalendarModel.setCodeAutogenerated(ce.isChecked());
} catch (ConcurrentModificationException err) {
messagesForUser.showMessage(Level.ERROR, err.getMessage());
}
}
reloadCodeInformation();
}
private void reloadCodeInformation() {
private void validateCalendarExceptionCodes() {
if (baseCalendarModel.isEditing()) {
Util.reloadBindings(editWindow.getFellow("txtCode"));
this.editionController.validateCalendarExceptionCodes();
} else {
Util.reloadBindings(createWindow.getFellow("txtCode"));
this.createController.validateCalendarExceptionCodes();
}
}
}

View file

@ -45,6 +45,7 @@ import org.navalplanner.business.calendars.entities.BaseCalendar.DayType;
import org.navalplanner.business.calendars.entities.CalendarData.Days;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.business.workingday.EffortDuration.Granularity;
import org.navalplanner.web.common.IMessagesForUser;
import org.navalplanner.web.common.Level;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.common.components.CalendarHighlightedDays;
@ -65,9 +66,11 @@ import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Label;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.api.Window;
/**
@ -114,11 +117,15 @@ public abstract class BaseCalendarEditionController extends
private EffortDurationPicker exceptionDurationPicker;
private IMessagesForUser messagesForUser;
public BaseCalendarEditionController(IBaseCalendarModel baseCalendarModel,
Window window, Window createNewVersionWindow) {
Window window, Window createNewVersionWindow,
IMessagesForUser messagesForUser) {
this.baseCalendarModel = baseCalendarModel;
this.window = window;
this.createNewVersionWindow = createNewVersionWindow;
this.messagesForUser = messagesForUser;
}
public abstract void goToList();
@ -845,23 +852,25 @@ public abstract class BaseCalendarEditionController extends
appendDayListcell(item, calendarException);
appendExceptionTypeListcell(item, calendarException);
appendDurationListcell(item, calendarException);
appendCodeListcell(item, calendarException);
appendOperationsListcell(item, calendarException);
markAsSelected(item, calendarException);
addEventListener(item);
}
private void addEventListener(Listitem item) {
private void addEventListener(final Listitem item) {
item.addEventListener(Events.ON_CLICK, new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
Listitem item = (Listitem) event.getTarget();
CalendarException calendarException = (CalendarException) item
if (!item.isSelected()) {
Listitem item = (Listitem) event.getTarget();
CalendarException calendarException = (CalendarException) item
.getValue();
setSelectedDay(calendarException
setSelectedDay(calendarException
.getDate().toDateTimeAtStartOfDay().toDate());
reloadDayInformation();
reloadDayInformation();
}
}
});
}
@ -904,6 +913,40 @@ public abstract class BaseCalendarEditionController extends
item.appendChild(listcell);
}
private void appendCodeListcell(final Listitem item,
final CalendarException calendarException) {
item.setValue(calendarException);
Listcell listcell = new Listcell();
final Textbox code = new Textbox();
if (getBaseCalendar() != null) {
code.setDisabled(getBaseCalendar().isCodeAutogenerated());
}
Util.bind(code, new Util.Getter<String>() {
@Override
public String get() {
return calendarException.getCode();
}
}, new Util.Setter<String>() {
@Override
public void set(String value) {
try {
calendarException.setCode(value);
} catch (IllegalArgumentException e) {
throw new WrongValueException(code, e.getMessage());
}
}
});
code.setConstraint("no empty:" + _("cannot be null or empty"));
listcell.appendChild(code);
item.appendChild(listcell);
}
private void appendOperationsListcell(Listitem item, CalendarException calendarException) {
Listcell listcell = new Listcell();
listcell.appendChild(createRemoveButton(calendarException));
@ -1015,6 +1058,7 @@ public abstract class BaseCalendarEditionController extends
appendValidFromListcell(item, calendarAvailability);
appendExpirationDateListcell(item, calendarAvailability);
appendAvailabilityCodeListcell(item, calendarAvailability);
appendOperationsListcell(item, calendarAvailability);
}
@ -1096,6 +1140,40 @@ public abstract class BaseCalendarEditionController extends
item.appendChild(listcell);
}
private void appendAvailabilityCodeListcell(Listitem item,
final CalendarAvailability availability) {
item.setValue(availability);
Listcell listcell = new Listcell();
final Textbox code = new Textbox();
if (getBaseCalendar() != null) {
code.setDisabled(getBaseCalendar().isCodeAutogenerated());
}
Util.bind(code, new Util.Getter<String>() {
@Override
public String get() {
return availability.getCode();
}
}, new Util.Setter<String>() {
@Override
public void set(String value) {
try {
availability.setCode(value);
} catch (IllegalArgumentException e) {
throw new WrongValueException(code, e.getMessage());
}
}
});
code.setConstraint("no empty:" + _("cannot be null or empty"));
listcell.appendChild(code);
item.appendChild(listcell);
}
private void appendOperationsListcell(Listitem item,
CalendarAvailability calendarAvailability) {
Listcell listcell = new Listcell();
@ -1142,6 +1220,10 @@ public abstract class BaseCalendarEditionController extends
Util.reloadBindings(window.getFellow("calendarAvailabilities"));
}
public void reloadExceptionsList() {
Util.reloadBindings(window.getFellow("exceptionsList"));
}
public boolean isNotResourceCalendar() {
BaseCalendar baseCalendar = baseCalendarModel.getBaseCalendar();
if ((baseCalendar == null)
@ -1150,4 +1232,52 @@ public abstract class BaseCalendarEditionController extends
}
return true;
}
public void validateCalendarExceptionCodes(){
Listbox listbox = (Listbox) window.getFellow("exceptionsList");
if (listbox != null) {
for (int i = 0; i < listbox.getItemCount(); i++) {
Listitem item = (Listitem) listbox.getItems().get(i);
if (item.getChildren().size() == 5) {
Textbox code = (Textbox) ((Listcell) item.getChildren()
.get(3)).getFirstChild();
if (code != null && !code.isDisabled()
&& code.getValue().isEmpty()) {
throw new WrongValueException(code,
_("It can not be empty"));
}
}
}
}
}
public void onCheckGenerateCode(Event e) {
CheckEvent ce = (CheckEvent) e;
if (ce.isChecked()) {
try {
baseCalendarModel.setCodeAutogenerated(ce.isChecked());
} catch (ConcurrentModificationException err) {
messagesForUser.showMessage(Level.ERROR, err.getMessage());
}
}
reloadCodeInformation();
}
private void reloadCodeInformation() {
Util.reloadBindings(window.getFellow("txtCode"));
reloadExceptionsList();
reloadActivationPeriods();
}
public void onSelectException(Event event) {
Listbox listBox = (Listbox) event.getTarget();
Listitem item = (Listitem) listBox.getSelectedItem();
if (item != null) {
CalendarException calendarException = (CalendarException) item
.getValue();
setSelectedDay(calendarException.getDate().toDateTimeAtStartOfDay()
.toDate());
reloadDayInformation();
}
}
}

View file

@ -136,6 +136,14 @@ public class BaseCalendarModel extends IntegrationEntityModel implements
this.baseCalendar = getFromDB(baseCalendar).newDerivedCalendar();
forceLoad(this.baseCalendar);
this.baseCalendar.setCode("");
boolean codeGenerated = configurationDAO.getConfiguration()
.getGenerateCodeForBaseCalendars();
if (codeGenerated) {
setDefaultCode();
}
this.baseCalendar.setCodeAutogenerated(codeGenerated);
}
@Override
@ -146,6 +154,11 @@ public class BaseCalendarModel extends IntegrationEntityModel implements
this.baseCalendar = getFromDB(baseCalendar).newCopy();
forceLoad(this.baseCalendar);
this.baseCalendar.setCode("");
if (this.baseCalendar.isCodeAutogenerated()) {
setDefaultCode();
}
}
@Override
@ -274,7 +287,7 @@ public class BaseCalendarModel extends IntegrationEntityModel implements
if (getTypeOfDay(date).equals(DayType.OWN_EXCEPTION)) {
getBaseCalendar().updateExceptionDay(date, duration, type);
} else {
CalendarException day = CalendarException.create(date,
CalendarException day = CalendarException.create("", date,
duration,
type);
getBaseCalendar().addExceptionDay(day);
@ -492,6 +505,14 @@ public class BaseCalendarModel extends IntegrationEntityModel implements
}
}
@Transactional
public void generateCalendarCodes() {
if (getBaseCalendar().isCodeAutogenerated()) {
baseCalendar
.generateCalendarExceptionCodes(getNumberOfDigitsCode());
}
}
@Override
@Transactional
public void confirmRemove() {
@ -659,6 +680,7 @@ public class BaseCalendarModel extends IntegrationEntityModel implements
CalendarAvailability calendarAvailability = CalendarAvailability
.create(startDate, null);
calendarAvailability.setCode("");
getBaseCalendar().addNewCalendarAvailability(calendarAvailability);
}
}
@ -686,7 +708,13 @@ public class BaseCalendarModel extends IntegrationEntityModel implements
@Override
public Set<IntegrationEntity> getChildren() {
return new HashSet<IntegrationEntity>();
Set<IntegrationEntity> children = new HashSet<IntegrationEntity>();
if (baseCalendar != null) {
children.addAll(baseCalendar.getExceptions());
children.addAll(baseCalendar.getCalendarDataVersions());
children.addAll(baseCalendar.getCalendarAvailabilities());
}
return children;
}
@Override

View file

@ -199,4 +199,6 @@ public interface IBaseCalendarModel extends IIntegrationEntityModel {
void setDurationAt(Days day, EffortDuration value);
void generateCalendarCodes();
}

View file

@ -23,6 +23,9 @@ package org.navalplanner.web.calendars;
import org.apache.commons.lang.Validate;
import org.navalplanner.business.calendars.entities.BaseCalendar;
import org.navalplanner.business.calendars.entities.ResourceCalendar;
import org.navalplanner.business.common.daos.IConfigurationDAO;
import org.navalplanner.business.common.entities.EntityNameEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
@ -44,17 +47,30 @@ public class ResourceCalendarModel extends BaseCalendarModel implements
public void initCreate() {
editing = false;
this.baseCalendar = ResourceCalendar.create();
this.baseCalendar.setCode("");
}
@Autowired
private IConfigurationDAO configurationDAO;
@Override
@Transactional(readOnly = true)
public void initCreateDerived(BaseCalendar baseCalendar) {
editing = false;
Validate.notNull(baseCalendar);
// the code always is autogenerated when it is created.
boolean codeGenerated = true;
this.baseCalendar = getFromDB(baseCalendar)
.newDerivedResourceCalendar();
forceLoad(this.baseCalendar);
this.baseCalendar.setCode("");
if (codeGenerated) {
setDefaultCode();
}
this.baseCalendar.setCodeAutogenerated(codeGenerated);
}
@Override
@ -65,6 +81,15 @@ public class ResourceCalendarModel extends BaseCalendarModel implements
this.baseCalendar = getFromDB(baseCalendar).newCopyResourceCalendar();
forceLoad(this.baseCalendar);
this.baseCalendar.setCode("");
if (this.baseCalendar.isCodeAutogenerated()) {
setDefaultCode();
}
}
@Override
public EntityNameEnum getEntityName() {
return EntityNameEnum.RESOURCE_CALENDAR;
}
}

View file

@ -355,7 +355,10 @@ public class MachineCRUDController extends GenericForwardComposer {
parentCalendar = machineModel.getDefaultCalendar();
}
machineModel.setCalendar(parentCalendar.newDerivedResourceCalendar());
resourceCalendarModel.initCreateDerived(parentCalendar);
resourceCalendarModel.generateCalendarCodes();
machineModel.setCalendar((ResourceCalendar) resourceCalendarModel
.getBaseCalendar());
}
private Window editCalendarWindow;
@ -375,7 +378,7 @@ public class MachineCRUDController extends GenericForwardComposer {
baseCalendarEditionController = new BaseCalendarEditionController(
resourceCalendarModel, editCalendarWindow,
createNewVersionWindow) {
createNewVersionWindow, messagesForUser) {
@Override
public void goToList() {
@ -394,9 +397,11 @@ public class MachineCRUDController extends GenericForwardComposer {
@Override
public void save() {
validateCalendarExceptionCodes();
ResourceCalendar calendar = (ResourceCalendar) resourceCalendarModel
.getBaseCalendar();
if (calendar != null) {
resourceCalendarModel.generateCalendarCodes();
machineModel.setCalendarOfMachine(calendar);
}
reloadWindow();

View file

@ -398,7 +398,11 @@ public class WorkerCRUDController extends GenericForwardComposer implements
if (parentCalendar == null) {
parentCalendar = workerModel.getDefaultCalendar();
}
workerModel.setCalendar(parentCalendar.newDerivedResourceCalendar());
resourceCalendarModel.initCreateDerived(parentCalendar);
resourceCalendarModel.generateCalendarCodes();
workerModel.setCalendar((ResourceCalendar) resourceCalendarModel
.getBaseCalendar());
}
public void editCalendar() {
@ -438,7 +442,7 @@ public class WorkerCRUDController extends GenericForwardComposer implements
baseCalendarEditionController = new BaseCalendarEditionController(
resourceCalendarModel, editCalendarWindow,
createNewVersionWindow) {
createNewVersionWindow, messages) {
@Override
public void goToList() {
@ -457,10 +461,12 @@ public class WorkerCRUDController extends GenericForwardComposer implements
@Override
public void save() {
validateCalendarExceptionCodes();
Integer capacity = workerModel.getCapacity();
ResourceCalendar calendar = (ResourceCalendar) resourceCalendarModel
.getBaseCalendar();
if (calendar != null) {
resourceCalendarModel.generateCalendarCodes();
workerModel.setCalendar(calendar);
}
reloadCurrentWindow();

View file

@ -45,7 +45,7 @@
<label value="@{calendarController.editionController.nameParentCalendar}" visible="@{calendarController.editionController.isDerived}" />
</vbox>
</row>
<row>
<row visible="@{calendarController.editionController.notResourceCalendar}">
<label value="${i18n:_('Code')}" />
<hbox>
<textbox id="txtCode" value="@{calendarController.editionController.baseCalendar.code}" width="250px"
@ -135,11 +135,13 @@
<listbox id="exceptionsList"
model="@{calendarController.editionController.calendarExceptions}"
itemRenderer="@{calendarController.editionController.calendarExceptionRenderer}"
rows="4" width="100%">
onSelect="calendarController.editionController.onSelectException(event)"
rows="4" width="100%" >
<listhead>
<listheader label="${i18n:_('Day')}" />
<listheader label="${i18n:_('Exception Type')}" />
<listheader label="${i18n:_('Workable Time')}" />
<listheader label="${i18n:_('Code')}" visible="@{calendarController.editionController.notResourceCalendar}"/>
<listheader label="${i18n:_('Operations')}" />
</listhead>
</listbox>
@ -191,14 +193,12 @@
<hbox>
<label value="${i18n:_('Type')}" />
<vbox>
<label value="@{calendarController.editionController.calendarType}" />
<combobox id="parentCalendars"
<label value="@{calendarController.editionController.calendarType}" />
<combobox id="parentCalendars"
visible="@{calendarController.editionController.isDerived}">
<comboitem self="@{each='baseCalnedar'}" value="@{baseCalnedar}"
label="@{baseCalnedar.name}" />
</combobox>
</vbox>
</combobox>
</hbox>
<hbox visible="@{calendarController.editionController.isEditing}">
@ -228,7 +228,8 @@
<listhead>
<listheader label="${i18n:_('Valid from')}" />
<listheader label="${i18n:_('Expiry date')}" />
<listheader label="${i18n:_('Operations')}" />
<listheader label="${i18n:_('Code')}" visible="@{calendarController.editionController.notResourceCalendar}"/>
<listheader label="${i18n:_('Operations')}"/>
</listhead>
</listbox>
<button label="${i18n:_('Create activation period')}"