Merge branch 'master' into work-reports-effort-duration

This commit is contained in:
Manuel Rego Casasnovas 2011-09-08 13:52:32 +02:00
commit b80793565b
130 changed files with 10946 additions and 565 deletions

View file

@ -0,0 +1,243 @@
# Russian translations for NavalPlan - GanttZK module.
# Copyright (C) 2011 Pavel Rudensky <prudensky@gmail.com>
# This file is distributed under the same license as the NavalPlan package.
# Pavel Rudensky <prudensky@gmail.com>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: 1.1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2011-05-11 18:16+0200\n"
"PO-Revision-Date: 2011-08-30 16:46+0400\n"
"Last-Translator: Pavel Rudensky <prudensky@gmail.com>\n"
"Language-Team: Russian\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:215
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:234
msgid "Erase"
msgstr "Стереть"
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:319
msgid "Add Dependency"
msgstr "Добавить зависимости"
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
msgid "Worker"
msgstr "Работник"
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
msgid "Start"
msgstr "Начало"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:592
msgid "Show reported hours"
msgstr "Показать затраченные часы"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:78
msgid "Show/Hide Progress"
msgstr "Показать/Убрать "
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:92
msgid "by criteria"
msgstr "по критериям"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:70
msgid "Show/Hide reported hours"
msgstr "Показать/Скрыть сообщенные часы"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:45
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:36
msgid "Zoom"
msgstr "Масштаб"
#: ganttzk/src/main/java/org/zkoss/ganttz/TabsRegistry.java:121
msgid "Limiting resources"
msgstr "Ограничение ресурсов"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:68
msgid "The specified dependency is not allowed"
msgstr "Указанные зависимости не допускаются"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:254
msgid "Set End-End"
msgstr "Установить Конец-Конец"
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
msgid "Task"
msgstr "Задача"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:91
msgid "by resources"
msgstr "по ресурсам"
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:64
msgid "Criterion"
msgstr "Критерий"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:40
msgid "Print"
msgstr "Печать"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java:190
msgid "total work hours: {0}, assigned hours: {1}"
msgstr "Общее количество часов: {0}, назначенные часы: {1}"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:71
msgid "Week"
msgstr "Неделя"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java:111
msgid "See scheduling"
msgstr "Просмотр планирования"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:489
msgid "filtering by name"
msgstr "фильтрация по имени"
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:30
msgid "End"
msgstr "Конец"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java:243
msgid "changing zoom"
msgstr "изменение масштаба"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
msgid "Quarter"
msgstr "Квартал"
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
msgid "None"
msgstr "Ничто"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:44
msgid "Filter"
msgstr "Фильтр"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:67
msgid "Flatten/Unflatten tree"
msgstr "Развернуть/Свернуть дерево"
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
msgid "Project"
msgstr "Проект"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:51
msgid "Name filter"
msgstr "Наименование фильтра"
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:28
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:69
msgid "Name"
msgstr "Наименование"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:572
msgid "Show progress"
msgstr "Показать шкалу развития"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:64
msgid "Expand/Collapse all"
msgstr "Развернуть/Свернуть все"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:36
msgid "Create Project"
msgstr "Создать проект"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Год"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:145
msgid "showing criteria"
msgstr "показаны критерии"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:58
msgid "Month"
msgstr "Месяц"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:61
msgid "Show/Hide resources"
msgstr "Показать/Скрыть ресурсы"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:246
msgid "Set End-Start"
msgstr "Установить Конец-Начало"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:302
msgid "decreasing zoom"
msgstr "уменьшить масштаб"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:559
msgid "Hide critical path"
msgstr "Скрыть критическую часть"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:599
msgid "Hide reported hours"
msgstr "Скрыть затраченные часы"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:84
msgid "Day"
msgstr "День"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:55
msgid "Show/Hide Critical path"
msgstr "Показать/Скрыть критическую часть"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:142
msgid "showing resources"
msgstr "Показать ресурсы"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java:184
msgid "Load: {0}%"
msgstr "Загрузка: {0}%"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:58
msgid "Show/Hide labels"
msgstr "Показать/Скрыть метки"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:97
msgid "Hour"
msgstr "Час"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:114
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:92
msgid "Graphics"
msgstr "Графика"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:250
msgid "Set Start-Start"
msgstr "Установить Начало-Начало"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java:143
msgid "See resource allocation"
msgstr "Просмотр распределения ресурсов"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:285
msgid "increasing zoom"
msgstr "увеличить масштаб"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:455
msgid "Show all elements"
msgstr "Посмотреть все элементы"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:454
msgid "All"
msgstr "Все"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:38
msgid "Refresh"
msgstr "Обновить"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:577
msgid "Hide progress"
msgstr "Спрятать шкалу развития"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:554
msgid "Show critical path"
msgstr "Показать критическую часть"

View file

@ -43,6 +43,7 @@ planner = self;
<separator/>
<!-- Visualization modes -->
<space bar="true" />
<label>${ganttzk_i18n:_('Zoom')}:</label>
<listbox id="listZoomLevels" mold="select" rows="1"
model="${planner.zoomLevels}">

View file

@ -35,4 +35,4 @@ ADVANCE_ALLOCATIONS.listenToScroll = function() {
if (timeTracker != undefined ) innerScrollableArea.width(timeTracker.realWidth());
};
};

View file

@ -8,6 +8,8 @@
<script src="../yui/2.7.0/resize/resize-min.js"/>
<script src="../yui/2.7.0/logger/logger-min.js"/>
<script src="advanceAllocations.js"/>
<widget name="GanttPanel"/>
<widget name="TaskRow"/>
<widget name="TaskComponent"/>

View file

@ -240,6 +240,11 @@ public class DirectAdvanceAssignment extends AdvanceAssignment {
return true;
}
@AssertTrue(message = "max value must be greater than zero")
public boolean checkConstraintMaxValueMustBeGreaterThanZero() {
return maxValue.compareTo(BigDecimal.ZERO) > 0;
}
public void setNonCalculatedConsolidation(
Set<NonCalculatedConsolidation> nonCalculatedConsolidation) {
this.nonCalculatedConsolidations = nonCalculatedConsolidation;

View file

@ -77,6 +77,12 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar,
return calendar;
}
public static BaseCalendar createBasicCalendar(String code) {
BaseCalendar calendar = create(code);
resetDefaultCapacities(calendar);
return calendar;
}
public static List<BaseCalendar> sortByName(List<BaseCalendar> baseCalendars) {
Collections.sort(baseCalendars, new Comparator<BaseCalendar>() {
@ -140,7 +146,6 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar,
}
@NotEmpty
private String name;
@Valid
@ -170,6 +175,7 @@ public class BaseCalendar extends IntegrationEntity implements ICalendar,
this.name = name;
}
@NotEmpty(message = "name not specified")
public String getName() {
return name;
}

View file

@ -150,8 +150,7 @@ public class CalendarExceptionType extends IntegrationEntity implements
EnumMap<Granularity, Integer> values = duration.decompose();
Integer hours = values.get(Granularity.HOURS);
Integer minutes = values.get(Granularity.MINUTES);
Integer seconds = values.get(Granularity.SECONDS);
return hours + ":" + minutes + ":" + seconds ;
return hours + ":" + minutes;
}
public void setDuration(EffortDuration duration) {

View file

@ -28,9 +28,15 @@ import static org.navalplanner.business.i18n.I18nHelper._;
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public enum CalendarExceptionTypeColor {
DEFAULT(_("red (default)"), "red", "lightcoral"),
GREEN(_("green"), "green", "lightgreen"),
BLUE(_("blue"), "blue", "lightblue");
DEFAULT(_("red (default)"), "#FF3333", "#FF9999"),
GREEN(_("green"),"#2ee62e", "#8ae68a"),
BLUE(_("blue"), "#3333FF", "#9999FF"),
CYAN(_("cyan"), "#33FFFF", "#99FFFF"),
MAGENTA(_("magenta"), "#FF33FF", "#FF99FF"),
YELLOW(_("yellow"), "#e6e62e", "#e6e6a1"),
BLACK(_("black"), "#333333", "#999999"),
ORANGE(_("orange"), "#ffb733", "#ffdb99"),
PURPLE(_("purple"), "#801a80", "#b38eb3");
private final String name;
private final String colorOwnException;

View file

@ -181,8 +181,7 @@ public class Capacity {
EnumMap<Granularity, Integer> values = duration.decompose();
Integer hours = values.get(Granularity.HOURS);
Integer minutes = values.get(Granularity.MINUTES);
Integer seconds = values.get(Granularity.SECONDS);
return hours + ":" + minutes + ":" + seconds;
return hours + ":" + minutes;
}
@Override
@ -267,4 +266,4 @@ public class Capacity {
+ "]";
}
}
}

View file

@ -24,6 +24,7 @@ package org.navalplanner.business.materials.entities;
import java.math.BigDecimal;
import org.apache.commons.lang.StringUtils;
import org.hibernate.validator.NotEmpty;
import org.hibernate.validator.NotNull;
import org.navalplanner.business.common.IntegrationEntity;
import org.navalplanner.business.common.Registry;
@ -101,6 +102,7 @@ public class Material extends IntegrationEntity implements Comparable {
this.category = category;
}
@NotEmpty(message = "description is not specified")
public String getDescription() {
return description;
}

View file

@ -97,4 +97,6 @@ public interface IOrderDAO extends IIntegrationEntityDAO<Order> {
public List<Order> loadOrdersAvoidingProxyFor(
List<OrderElement> orderElement);
boolean existsByNameAnotherTransaction(String name);
}

View file

@ -401,4 +401,15 @@ public class OrderDAO extends IntegrationEntityDAO<Order> implements
return result;
}
@Override
@Transactional(readOnly = true, propagation = Propagation.REQUIRES_NEW)
public boolean existsByNameAnotherTransaction(String name) {
try {
Order order = findByName(name);
return order.getName().equals(name);
} catch (InstanceNotFoundException e) {
return false;
}
}
}

View file

@ -38,8 +38,11 @@ import org.navalplanner.business.advance.bootstrap.PredefinedAdvancedTypes;
import org.navalplanner.business.advance.entities.AdvanceType;
import org.navalplanner.business.advance.entities.DirectAdvanceAssignment;
import org.navalplanner.business.calendars.entities.BaseCalendar;
import org.navalplanner.business.common.Registry;
import org.navalplanner.business.common.entities.EntitySequence;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.externalcompanies.entities.ExternalCompany;
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.planner.entities.DayAssignment;
import org.navalplanner.business.planner.entities.Task;
import org.navalplanner.business.planner.entities.TaskElement;
@ -538,4 +541,23 @@ public class Order extends OrderLineGroup {
return getAdvanceAssignmentByType(advanceType);
}
@AssertTrue(message = "project name is already being used")
public boolean checkConstraintProjectUniqueName() {
IOrderDAO orderDAO = Registry.getOrderDAO();
if (isNewObject()) {
return !orderDAO.existsByNameAnotherTransaction(getName());
} else {
try {
Order o = orderDAO.findByNameAnotherTransaction(getName());
return o.getId().equals(getId());
} catch (InstanceNotFoundException e) {
return true;
}
}
}
}

View file

@ -159,17 +159,34 @@ public abstract class OrderElement extends IntegrationEntity implements
public SchedulingState getSchedulingState() {
if (schedulingState == null) {
schedulingState = SchedulingState.createSchedulingState(
getSchedulingStateType(), getChildrenStates(),
getCurrentSchedulingData().onTypeChangeListener());
ensureSchedulingStateInitializedFromTop();
initializeSchedulingState(); // maybe this order element was added
// later
}
return schedulingState;
}
private void ensureSchedulingStateInitializedFromTop() {
OrderElement current = this;
while (current.getParent() != null) {
current = current.getParent();
}
current.initializeSchedulingState();
}
private SchedulingState initializeSchedulingState() {
if (schedulingState != null) {
return schedulingState;
}
return schedulingState = SchedulingState.createSchedulingState(
getSchedulingStateType(), getChildrenStates(),
getCurrentSchedulingData().onTypeChangeListener());
}
private List<SchedulingState> getChildrenStates() {
List<SchedulingState> result = new ArrayList<SchedulingState>();
for (OrderElement each : getChildren()) {
result.add(each.getSchedulingState());
result.add(each.initializeSchedulingState());
}
return result;
}

View file

@ -32,16 +32,16 @@ import org.navalplanner.business.common.BaseEntity;
* @author Diego Pino García <dpino@igalia.com>
*
*/
public class AssignmentFunction extends BaseEntity {
public static AssignmentFunction create() {
return create(new AssignmentFunction());
}
public abstract class AssignmentFunction extends BaseEntity {
/**
* This method goes over the {@link ResourceAllocation} list and apply the
* assignment function if it is defined.
*
* As this is called at the end of {@link Task#doAllocation} and a flat
* allocation was already applied before. If assignment function was set to
* manual it is reseted to flat again.
*
* @param resourceAllocations
* List of {@link ResourceAllocation}
*/
@ -51,38 +51,37 @@ public class AssignmentFunction extends BaseEntity {
AssignmentFunction assignmentFunction = resourceAllocation
.getAssignmentFunction();
if (assignmentFunction != null) {
assignmentFunction.applyTo(resourceAllocation);
if (assignmentFunction.isManual()) {
// reset to flat
resourceAllocation.setAssignmentFunctionWithoutApply(null);
} else {
assignmentFunction.applyTo(resourceAllocation);
}
}
}
}
public AssignmentFunction() {
}
/**
* This method applies the function to the received resourceAllocation
* <i>This method is intended to be overridden by subclasses</i>
* @param resourceAllocation
*/
public void applyTo(ResourceAllocation<?> resourceAllocation) {
// override at subclasses
}
public abstract void applyTo(ResourceAllocation<?> resourceAllocation);
public String getName() {
// override at subclasses
return null;
}
public abstract String getName();
public enum ASSIGNMENT_FUNCTION_NAME {
public abstract boolean isManual();
public enum AssignmentFunctionName {
FLAT(_("Flat")),
MANUAL(_("Manual")),
STRETCHES(_("Stretches")),
INTERPOLATION(_("Interporlation")),
SIGMOID(_("Sigmoid"));
private String name;
private ASSIGNMENT_FUNCTION_NAME(String name) {
private AssignmentFunctionName(String name) {
this.name = name;
}

View file

@ -1,66 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
package org.navalplanner.business.planner.entities;
import java.util.Arrays;
import java.util.List;
import org.navalplanner.business.planner.entities.allocationalgorithms.ResourcesPerDayModification;
import org.navalplanner.business.workingday.EffortDuration;
/**
* Calculate hours per day for resource based on total amount of hours to be
* done and number of resources per day using a flat allocation
*
* @author Diego Pino García <dpino@igalia.com>
*/
public class FlatFunction extends AssignmentFunction {
public static FlatFunction create() {
return create(new FlatFunction());
}
protected FlatFunction() {
}
public String getName() {
return ASSIGNMENT_FUNCTION_NAME.FLAT.toString();
}
public void applyTo(ResourceAllocation<?> resourceAllocation) {
apply(resourceAllocation);
}
private void apply(ResourceAllocation<?> resourceAllocation) {
int hours = resourceAllocation.getAssignedHours();
List<ResourcesPerDayModification> resourcesPerDayModification = Arrays.asList(resourceAllocation
.asResourcesPerDayModification());
ResourceAllocation
.allocating(resourcesPerDayModification)
.untilAllocating(EffortDuration.hours(hours));
}
}

View file

@ -0,0 +1,49 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 Igalia, S.L.
*
* 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/>.
*/
package org.navalplanner.business.planner.entities;
/**
* Manual allocation function, it used to represent when user has done a manual
* allocation.
*
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public class ManualFunction extends AssignmentFunction {
public static ManualFunction create() {
return create(new ManualFunction());
}
@Override
public String getName() {
return AssignmentFunctionName.MANUAL.toString();
}
@Override
public void applyTo(ResourceAllocation<?> resourceAllocation) {
// Do nothing
}
@Override
public boolean isManual() {
return true;
}
}

View file

@ -87,8 +87,6 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
private static final Log LOG = LogFactory.getLog(ResourceAllocation.class);
private static final FlatFunction FLAT_FUNCTION = FlatFunction.create();
public static <T extends ResourceAllocation<?>> List<T> getSatisfied(
Collection<T> resourceAllocations) {
Validate.notNull(resourceAllocations);
@ -1418,18 +1416,20 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
return assignmentFunction;
}
public void setAssignmentFunction(AssignmentFunction assignmentFunction) {
// If the assignment function is empty, avoid creating an association
// between the resource allocation and the assignment function
if (assignmentFunction == null) {
FLAT_FUNCTION.applyTo(this);
return;
}
/**
* If {@link AssignmentFunction} is null, it's just set and nothing is
* applied
*
* @param assignmentFunction
*/
public void setAssignmentFunctionAndApplyIfNotFlat(AssignmentFunction assignmentFunction) {
this.assignmentFunction = assignmentFunction;
this.assignmentFunction.applyTo(this);
if (this.assignmentFunction != null) {
this.assignmentFunction.applyTo(this);
}
}
private void setWithoutApply(AssignmentFunction assignmentFunction) {
public void setAssignmentFunctionWithoutApply(AssignmentFunction assignmentFunction) {
this.assignmentFunction = assignmentFunction;
}
@ -2071,7 +2071,7 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
updateOriginalTotalAssigment();
updateResourcesPerDay();
}
setWithoutApply(modifications.getAssignmentFunction());
setAssignmentFunctionWithoutApply(modifications.getAssignmentFunction());
mergeDerivedAllocations(scenario, modifications.getDerivedAllocations());
}

View file

@ -52,7 +52,7 @@ public class SigmoidFunction extends AssignmentFunction {
@Override
public String getName() {
return ASSIGNMENT_FUNCTION_NAME.SIGMOID.toString();
return AssignmentFunctionName.SIGMOID.toString();
}
@Override
@ -266,4 +266,9 @@ public class SigmoidFunction extends AssignmentFunction {
PRECISSION, ROUND_MODE);
}
@Override
public boolean isManual() {
return false;
}
}

View file

@ -387,9 +387,9 @@ public class StretchesFunction extends AssignmentFunction {
@Override
public String getName() {
if (StretchesFunctionTypeEnum.INTERPOLATED.equals(type)) {
return ASSIGNMENT_FUNCTION_NAME.INTERPOLATION.toString();
return AssignmentFunctionName.INTERPOLATION.toString();
} else {
return ASSIGNMENT_FUNCTION_NAME.STRETCHES.toString();
return AssignmentFunctionName.STRETCHES.toString();
}
}
@ -476,4 +476,9 @@ public class StretchesFunction extends AssignmentFunction {
}
}
@Override
public boolean isManual() {
return false;
}
}

View file

@ -26,6 +26,7 @@ import java.util.List;
import org.hibernate.NonUniqueResultException;
import org.navalplanner.business.common.daos.IGenericDAO;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.qualityforms.entities.QualityForm;
import org.navalplanner.business.qualityforms.entities.QualityFormType;
@ -52,4 +53,6 @@ public interface IQualityFormDAO extends IGenericDAO<QualityForm, Long> {
boolean existsOtherWorkReportTypeByName(QualityForm qualityForm);
boolean existsByNameAnotherTransaction(QualityForm qualityForm);
void checkHasTasks(QualityForm qualityForm) throws ValidationException;
}

View file

@ -22,11 +22,13 @@
package org.navalplanner.business.qualityforms.daos;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.hibernate.Criteria;
import org.hibernate.NonUniqueResultException;
import org.hibernate.Query;
import org.hibernate.criterion.Restrictions;
import org.navalplanner.business.advance.daos.IAdvanceTypeDAO;
import org.navalplanner.business.advance.entities.AdvanceType;
@ -150,4 +152,16 @@ public class QualityFormDAO extends GenericDAOHibernate<QualityForm, Long>
super.save(entity);
}
@Override
public void checkHasTasks(QualityForm qualityForm) throws ValidationException {
Query query = getSession().createQuery(
"FROM TaskQualityForm taskQualityForm JOIN taskQualityForm.qualityForm tq WHERE tq IN (:qualityForms)");
query.setParameterList("qualityForms", Collections.singleton(qualityForm));
if (!query.list().isEmpty()) {
throw ValidationException
.invalidValue(
"Cannot delete quality form. It is being used at this moment by some task.",
qualityForm);
}
}
}

View file

@ -34,7 +34,8 @@ public enum Language {
BROWSER_LANGUAGE(_("Use browser language configuration"), null),
GALICIAN_LANGUAGE(_("Galician"), new Locale("gl")),
SPANISH_LANGUAGE(_("Spanish"), new Locale("es")),
ENGLISH_LANGUAGE(_("English"), Locale.ENGLISH);
ENGLISH_LANGUAGE(_("English"), Locale.ENGLISH),
RUSSIAN_LANGUAGE(_("Russian"), new Locale("ru"));
private final String displayName;

View file

@ -365,7 +365,7 @@ public class EffortDuration implements Comparable<EffortDuration> {
Integer hours = valuesForEachUnit.get(Granularity.HOURS);
Integer minutes = valuesForEachUnit.get(Granularity.MINUTES);
Integer seconds = valuesForEachUnit.get(Granularity.SECONDS);
return hours + ":" + minutes + ":" + seconds;
return String.format("%d:%02d:%02d", hours, minutes, seconds);
}
public String toFormattedString() {
@ -374,9 +374,9 @@ public class EffortDuration implements Comparable<EffortDuration> {
int hours = byGranularity.get(Granularity.HOURS);
int minutes = byGranularity.get(Granularity.MINUTES);
if (minutes == 0) {
return String.format("%s", hours);
return String.format("%d", hours);
} else {
return String.format("%s:%s", hours, minutes);
return String.format("%d:%02d", hours, minutes);
}
}

View file

@ -0,0 +1,58 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 - ComtecSF S.L.
*
* 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/>.
*/
package org.navalplanner.business.workreports.entities;
import java.util.Date;
import java.util.Set;
import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.workreports.valueobjects.DescriptionValue;
/**
* Interface which must be implemented by {@link WorkReport} and
* {@link WorkReportLine}
*
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
*
*/
public interface IWorkReportsElements {
Date getDate();
void setDate(Date date);
Resource getResource();
void setResource(Resource resource);
Set<Label> getLabels();
void setLabels(Set<Label> labels);
Set<DescriptionValue> getDescriptionValues();
void setDescriptionValues(Set<DescriptionValue> descriptionValues);
OrderElement getOrderElement();
void setOrderElement(OrderElement orderElement);
}

View file

@ -47,7 +47,8 @@ import org.navalplanner.business.workreports.valueobjects.DescriptionValue;
* @author Diego Pino García <dpino@igalia.com>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
public class WorkReport extends IntegrationEntity {
public class WorkReport extends IntegrationEntity implements
IWorkReportsElements {
public static final String DATE = "date";
public static final String RESOURCE = "resource";
@ -105,10 +106,12 @@ public class WorkReport extends IntegrationEntity {
this.orderElement = orderElement;
}
@Override
public Date getDate() {
return date != null ? new Date(date.getTime()) : null;
}
@Override
public void setDate(Date date) {
this.date = date != null ? new Date(date.getTime()) : null;
if (workReportType != null) {
@ -154,27 +157,33 @@ public class WorkReport extends IntegrationEntity {
workReportLines.remove(workReportLine);
}
@Override
@Valid
public Set<DescriptionValue> getDescriptionValues() {
return Collections.unmodifiableSet(descriptionValues);
}
@Override
public void setDescriptionValues(Set<DescriptionValue> descriptionValues) {
this.descriptionValues = descriptionValues;
}
@Override
public Set<Label> getLabels() {
return labels;
}
@Override
public void setLabels(Set<Label> labels) {
this.labels = labels;
}
@Override
public Resource getResource() {
return resource;
}
@Override
public void setResource(Resource resource) {
this.resource = resource;
if (workReportType != null) {
@ -186,10 +195,12 @@ public class WorkReport extends IntegrationEntity {
}
}
@Override
public OrderElement getOrderElement() {
return orderElement;
}
@Override
public void setOrderElement(OrderElement orderElement) {
this.orderElement = orderElement;
if (workReportType != null) {

View file

@ -51,7 +51,8 @@ import org.navalplanner.business.workreports.valueobjects.DescriptionValue;
* @author Diego Pino García <dpino@igalia.com>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
public class WorkReportLine extends IntegrationEntity implements Comparable {
public class WorkReportLine extends IntegrationEntity implements Comparable,
IWorkReportsElements {
public static WorkReportLine create(WorkReport workReport) {
return create(new WorkReportLine(workReport));
@ -132,6 +133,7 @@ public class WorkReportLine extends IntegrationEntity implements Comparable {
updateEffort();
}
@Override
@NotNull(message = "date not specified")
public Date getDate() {
return date;
@ -144,6 +146,7 @@ public class WorkReportLine extends IntegrationEntity implements Comparable {
return LocalDate.fromDateFields(getDate());
}
@Override
public void setDate(Date date) {
this.date = date;
if ((workReport != null) && (workReport.getWorkReportType() != null)) {
@ -153,11 +156,13 @@ public class WorkReportLine extends IntegrationEntity implements Comparable {
}
}
@Override
@NotNull(message = "resource not specified")
public Resource getResource() {
return resource;
}
@Override
public void setResource(Resource resource) {
this.resource = resource;
if ((workReport != null) && (workReport.getWorkReportType() != null)) {
@ -167,11 +172,13 @@ public class WorkReportLine extends IntegrationEntity implements Comparable {
}
}
@Override
@NotNull(message = "order element not specified")
public OrderElement getOrderElement() {
return orderElement;
}
@Override
public void setOrderElement(OrderElement orderElement) {
this.orderElement = orderElement;
if ((workReport != null) && (workReport.getWorkReportType() != null)) {
@ -181,10 +188,12 @@ public class WorkReportLine extends IntegrationEntity implements Comparable {
}
}
@Override
public Set<Label> getLabels() {
return labels;
}
@Override
public void setLabels(Set<Label> labels) {
this.labels = labels;
}
@ -207,11 +216,13 @@ public class WorkReportLine extends IntegrationEntity implements Comparable {
updateEffort();
}
@Override
@Valid
public Set<DescriptionValue> getDescriptionValues() {
return descriptionValues;
}
@Override
public void setDescriptionValues(Set<DescriptionValue> descriptionValues) {
this.descriptionValues = descriptionValues;
}

View file

@ -230,6 +230,24 @@
</update>
</changeSet>
<changeSet author="mrego" id="create-table-manual_function">
<createTable tableName="manual_function">
<column name="assignment_function_id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="manual_function_pkey" />
</column>
</createTable>
<addForeignKeyConstraint baseColumnNames="assignment_function_id"
baseTableName="manual_function"
constraintName="mnual_function_assignment_function_fkey"
deferrable="false"
initiallyDeferred="false"
onDelete="NO ACTION"
onUpdate="NO ACTION"
referencedColumnNames="id"
referencedTableName="assignment_function"
referencesUniqueColumn="false" />
</changeSet>
<changeSet id="change-numhours-to-effort-in-work-report-lines" author="idiazt">
<comment>Changing work_report_line numHours to effort</comment>
<renameColumn tableName="work_report_line" oldColumnName="num_hours" newColumnName="effort"/>
@ -274,5 +292,4 @@
newColumnName="sum_charged_effort_id" />
</changeSet>
</databaseChangeLog>

View file

@ -327,6 +327,9 @@
<joined-subclass name="SigmoidFunction" table="sigmoid_function">
<key column="assignment_function_id" />
</joined-subclass>
<joined-subclass name="ManualFunction" table="manual_function">
<key column="assignment_function_id" />
</joined-subclass>
</class>
<class name="DerivedAllocation" table="derived_allocation">

View file

@ -0,0 +1,94 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 Igalia, S.L.
*
* 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/>.
*/
package org.navalplanner.business.test.advance.daos;
import static org.junit.Assert.assertTrue;
import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE;
import java.math.BigDecimal;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.advance.daos.IAdvanceAssignmentDAO;
import org.navalplanner.business.advance.daos.IAdvanceTypeDAO;
import org.navalplanner.business.advance.entities.AdvanceAssignment;
import org.navalplanner.business.advance.entities.AdvanceType;
import org.navalplanner.business.advance.entities.DirectAdvanceAssignment;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
BUSINESS_SPRING_CONFIG_TEST_FILE })
/**
* Test for {@link AdvanceAssignmentDAO}
*
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
@Transactional
public class AdvanceAssignmentDAOTest {
@Autowired
private IAdvanceAssignmentDAO advanceAssignmentDAO;
@Autowired
private IAdvanceTypeDAO advanceTypeDAO;
private AdvanceType givenAdvanceType() {
BigDecimal value = new BigDecimal(100);
BigDecimal precision = BigDecimal.ONE;
AdvanceType advanceType = AdvanceType.create("advance-type", value,
true, precision, true, false);
advanceTypeDAO.save(advanceType);
return advanceType;
}
@Test
public void saveValidAdvanceAssignment() {
AdvanceAssignment advance = DirectAdvanceAssignment.create(false,
BigDecimal.TEN);
advance.setAdvanceType(givenAdvanceType());
advanceAssignmentDAO.save(advance);
assertTrue(advance.getId() != null);
}
@Test(expected = ValidationException.class)
public void saveAdvanceAssignmentWithZeroAsMaxValue() {
AdvanceAssignment advance = DirectAdvanceAssignment.create(false,
BigDecimal.ZERO);
advance.setAdvanceType(givenAdvanceType());
advanceAssignmentDAO.save(advance);
assertTrue(advance.getId() != null);
}
@Test(expected = ValidationException.class)
public void saveAdvanceAssignmentWithNegativeNumberAsMaxValue() {
AdvanceAssignment advance = DirectAdvanceAssignment.create(false,
BigDecimal.valueOf(-10));
advance.setAdvanceType(givenAdvanceType());
advanceAssignmentDAO.save(advance);
assertTrue(advance.getId() != null);
}
}

View file

@ -32,6 +32,7 @@ import static org.navalplanner.business.workingday.EffortDuration.zero;
import static org.navalplanner.business.workingday.IntraDayDate.PartialDay.wholeDay;
import java.util.Set;
import java.util.UUID;
import org.joda.time.LocalDate;
import org.junit.Test;
@ -82,7 +83,7 @@ public class BaseCalendarTest {
public static BaseCalendar createBasicCalendar() {
BaseCalendar calendar = BaseCalendar.create();
calendar.setName("Test");
calendar.setName("test-" + UUID.randomUUID());
Capacity eightHours = withNormalDuration(hours(8));
calendar.setCapacityAt(Days.MONDAY, eightHours);

View file

@ -73,6 +73,7 @@ public class MaterialAssignmentDAOTest {
UnitType unitType = UnitType.create("m");
unitTypeDAO.save(unitType);
Material material = Material.create(UUID.randomUUID().toString());
material.setDescription("material");
material.setCategory(materialCategory);
material.setUnitType(unitType);
materialDAO.save(material);

View file

@ -38,6 +38,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.IDataBootstrap;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.materials.daos.IMaterialCategoryDAO;
import org.navalplanner.business.materials.daos.IMaterialDAO;
import org.navalplanner.business.materials.entities.Material;
@ -93,6 +94,7 @@ public class MaterialDAOTest {
MaterialCategory materialCategory = MaterialCategory.create(UUID.randomUUID().toString());
materialCategoryDAO.save(materialCategory);
Material material = Material.create(UUID.randomUUID().toString());
material.setDescription("material");
material.setCategory(materialCategory);
return material;
}
@ -104,6 +106,13 @@ public class MaterialDAOTest {
assertTrue(material.getId() != null);
}
@Test(expected = ValidationException.class)
public void testSaveMaterialWithoutDescription() {
Material material = createValidMaterial();
material.setDescription(null);
materialDAO.save(material);
}
@Test
public void testRemoveMaterial() throws InstanceNotFoundException {
Material material = createValidMaterial();

View file

@ -0,0 +1,151 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 Igalia, S.L.
*
* 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/>.
*/
package org.navalplanner.business.test.orders.daos;
import static junit.framework.Assert.assertNotNull;
import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE;
import java.util.Date;
import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.navalplanner.business.calendars.daos.IBaseCalendarDAO;
import org.navalplanner.business.calendars.entities.BaseCalendar;
import org.navalplanner.business.common.IAdHocTransactionService;
import org.navalplanner.business.common.IOnTransaction;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.orders.daos.IOrderDAO;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.scenarios.IScenarioManager;
import org.navalplanner.business.scenarios.bootstrap.IScenariosBootstrap;
import org.navalplanner.business.scenarios.entities.OrderVersion;
import org.navalplanner.business.test.calendars.entities.BaseCalendarTest;
import org.navalplanner.business.test.planner.daos.ResourceAllocationDAOTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
/**
* Test for {@link IOrderDAO}
*
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
BUSINESS_SPRING_CONFIG_TEST_FILE })
@Transactional
public class OrderDAOTest {
@Before
public void loadRequiredaData() {
transactionService.runOnAnotherTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
scenariosBootstrap.loadRequiredData();
return null;
}
});
}
@Autowired
private IOrderDAO orderDAO;
@Autowired
private IBaseCalendarDAO calendarDAO;
@Autowired
private IScenariosBootstrap scenariosBootstrap;
@Autowired
private IScenarioManager scenarioManager;
@Autowired
private IAdHocTransactionService transactionService;
@Test
public void testInSpringContainer() {
assertNotNull(orderDAO);
}
private Order createValidOrder(String name) {
Order order = Order.create();
order.setName(name);
order.setCode(UUID.randomUUID().toString());
order.setInitDate(new Date());
BaseCalendar basicCalendar = BaseCalendarTest.createBasicCalendar();
calendarDAO.save(basicCalendar);
order.setCalendar(basicCalendar);
OrderVersion orderVersion = ResourceAllocationDAOTest
.setupVersionUsing(scenarioManager, order);
order.useSchedulingDataFor(orderVersion);
return order;
}
@Test
public void testSaveTwoOrdersWithDifferentNames() {
transactionService.runOnAnotherTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
Order order = createValidOrder("test");
orderDAO.save(order);
orderDAO.flush();
return null;
}
});
transactionService.runOnAnotherTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
Order order = createValidOrder("test2");
orderDAO.save(order);
orderDAO.flush();
return null;
}
});
}
@Test(expected = ValidationException.class)
public void testSaveTwoOrdersWithSameNames() {
transactionService.runOnAnotherTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
Order order = createValidOrder("test");
orderDAO.save(order);
orderDAO.flush();
return null;
}
});
transactionService.runOnAnotherTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
Order order = createValidOrder("test");
orderDAO.save(order);
orderDAO.flush();
return null;
}
});
}
}

View file

@ -153,7 +153,7 @@ public class AddAdvanceAssignmentsToOrderElementTest {
private DirectAdvanceAssignment createValidAdvanceAssignment(
boolean reportGlobalAdvance) {
DirectAdvanceAssignment advanceAssignment = DirectAdvanceAssignment
.create(reportGlobalAdvance, new BigDecimal(0));
.create(reportGlobalAdvance, BigDecimal.TEN);
return advanceAssignment;
}

View file

@ -34,6 +34,7 @@ import org.junit.runner.RunWith;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.planner.daos.IAssignmentFunctionDAO;
import org.navalplanner.business.planner.entities.AssignmentFunction;
import org.navalplanner.business.planner.entities.ManualFunction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@ -57,7 +58,7 @@ public class AssignmentFunctionDAOTest {
}
private AssignmentFunction createValidAssignmentFunction() {
return AssignmentFunction.create();
return ManualFunction.create();
}
@Test

View file

@ -172,7 +172,7 @@ public class TaskElementDAOTest {
Order order = Order.create();
OrderVersion orderVersion = ResourceAllocationDAOTest
.setupVersionUsing(scenarioManager, order);
order.setName("bla");
order.setName("bla-" + UUID.randomUUID());
order.setInitDate(new Date());
order.setCode("code-" + UUID.randomUUID());
order.useSchedulingDataFor(orderVersion);

View file

@ -111,6 +111,9 @@
<copy todir="src/main/webapp/help/en" failonerror="false">
<fileset dir="../doc/src/user/en/html"/>
</copy>
<copy todir="src/main/webapp/help/ru" failonerror="false">
<fileset dir="../doc/src/user/en/html"/>
</copy>
</tasks>
</configuration>
</execution>

View file

@ -32,6 +32,7 @@ import org.navalplanner.business.calendars.entities.BaseCalendar;
import org.navalplanner.business.calendars.entities.CalendarData;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.web.common.BaseCRUDController.CRUDControllerState;
import org.navalplanner.web.common.ConstraintChecker;
import org.navalplanner.web.common.IMessagesForUser;
import org.navalplanner.web.common.Level;
import org.navalplanner.web.common.MessagesForUser;
@ -127,6 +128,7 @@ public class BaseCalendarCRUDController extends GenericForwardComposer {
public void save() {
try {
ConstraintChecker.isValid(editWindow);
validateCalendarExceptionCodes();
baseCalendarModel.generateCalendarCodes();
baseCalendarModel.confirmSave();
@ -141,6 +143,7 @@ public class BaseCalendarCRUDController extends GenericForwardComposer {
public void saveAndContinue() {
try {
ConstraintChecker.isValid(editWindow);
validateCalendarExceptionCodes();
baseCalendarModel.generateCalendarCodes();
baseCalendarModel.confirmSaveAndContinue();

View file

@ -122,7 +122,7 @@ public class BaseCalendarModel extends IntegrationEntityModel implements
.getConfiguration().getGenerateCodeForBaseCalendars()
: false;
this.baseCalendar = BaseCalendar.createBasicCalendar();
this.baseCalendar = BaseCalendar.createBasicCalendar("");
if (codeGenerated) {
setDefaultCode();

View file

@ -267,7 +267,7 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
globalView.goToCompanyScheduling();
}
}, "01-introducion.html"),
subItem(_("Projects"), new ICapture() {
subItem(_("Projects List"), new ICapture() {
@Override
public void capture() {
globalView.goToOrdersList();

View file

@ -49,6 +49,7 @@ import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Hbox;
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;
@ -75,6 +76,8 @@ public class CalendarExceptionTypeCRUDController extends
private EffortDurationPicker extraEffort;
private Listbox colorsListbox;
private static ListitemRenderer calendarExceptionTypeColorRenderer = new ListitemRenderer() {
@Override
public void render(Listitem item, Object data) throws Exception {
@ -265,4 +268,19 @@ public class CalendarExceptionTypeCRUDController extends
return exceptionDayTypeRenderer;
}
public String getStyleColorOwnException() {
return (getExceptionDayType() == null) ? "" : "background-color: "
+ getExceptionDayType().getColor().getColorOwnException();
}
public String getStyleColorDerivedException() {
return (getExceptionDayType() == null) ? "" : "background-color: "
+ getExceptionDayType().getColor().getColorDerivedException();
}
public void reloadSampleColors() {
Util.reloadBindings(editWindow.getFellow("colorSampleOwn"));
Util.reloadBindings(editWindow.getFellow("colorSampleDerived"));
}
}

View file

@ -31,6 +31,7 @@ import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.externalcompanies.entities.ExternalCompany;
import org.navalplanner.business.users.entities.User;
import org.navalplanner.web.common.BaseCRUDController;
import org.navalplanner.web.common.Level;
import org.navalplanner.web.common.components.Autocomplete;
import org.zkoss.zk.ui.Component;
import org.zkoss.zul.Column;
@ -180,4 +181,18 @@ public class ExternalCompanyCRUDController extends
protected void delete(ExternalCompany company) {
externalCompanyModel.deleteCompany(company);
}
@Override
protected boolean beforeDeleting(ExternalCompany company) {
if (externalCompanyModel.isAlreadyInUse(company)) {
messagesForUser.showMessage(
Level.WARNING,
_("{0} \"{1}\" can not be deleted because of it is being used",
getEntityType(),
company.getHumanId()));
return false;
}
return true;
}
}

View file

@ -50,6 +50,7 @@ import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.InputEvent;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Button;
import org.zkoss.zul.Caption;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Listbox;
@ -96,7 +97,7 @@ public class MaterialsController extends
private Component messagesContainer;
private Panel materialsPanel;
private Caption materialsCaption;
private UnitTypeListRenderer unitTypeListRenderer = new UnitTypeListRenderer();
@ -385,10 +386,10 @@ public class MaterialsController extends
private void reloadCategoriesTree(Treeitem treeitem) {
if (treeitem != null) {
final MaterialCategory materialCategory = (MaterialCategory) treeitem.getValue();
Util.reloadBindings(categoriesTree);
categoriesTree.invalidate();
locateAndSelectMaterialCategory(materialCategory);
} else {
Util.reloadBindings(categoriesTree);
categoriesTree.invalidate();
}
}
@ -483,11 +484,12 @@ public class MaterialsController extends
private void refreshMaterialsListTitle() {
Treeitem treeitem = categoriesTree.getSelectedItem();
if (treeitem != null) {
materialsPanel.setTitle(_("List of materials for category: {0}",
materialsCaption.setLabel(_("List of materials for category: {0}",
((MaterialCategory) treeitem.getValue()).getName()));
}
else {
materialsPanel.setTitle
materialsCaption
.setLabel
(_("List of materials for all categories (select one to filter)"));
}
}

View file

@ -39,6 +39,7 @@ 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.zul.Button;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Label;
@ -96,13 +97,17 @@ public class UnitTypeController extends BaseCRUDController<UnitType> {
}
}));
hbox.appendChild(Util.createRemoveButton(new EventListener() {
Button removeButton = Util
.createRemoveButton(new EventListener() {
@Override
public void onEvent(Event event) {
confirmDelete(unitType);
}
}));
});
removeButton.setDisabled(unitTypeModel
.isUnitTypeUsedInAnyMaterial(unitType));
hbox.appendChild(removeButton);
row.appendChild(hbox);
}

View file

@ -159,9 +159,14 @@ public class AssignedTaskQualityFormsToOrderElementModel implements
TaskQualityForm taskQualityForm) {
AdvanceType advanceType = taskQualityForm.getQualityForm()
.getAdvanceType();
advanceTypeDAO.reattach(advanceType);
return taskQualityForm.getOrderElement()
.getDirectAdvanceAssignmentByType(advanceType);
if (advanceType == null) {
return null;
}
else {
advanceTypeDAO.reattach(advanceType);
return taskQualityForm.getOrderElement()
.getDirectAdvanceAssignmentByType(advanceType);
}
}
@Override

View file

@ -764,11 +764,13 @@ public class ManageOrderElementAdvancesController extends
.getValue();
if (!manageOrderElementAdvancesModel
.hasConsolidatedAdvances(advance)) {
if (value == null) {
((Decimalbox) comp).setValue(advance.getMaxValue());
if (value == null
|| (BigDecimal.ZERO.compareTo((BigDecimal) value) >= 0)) {
((Decimalbox) comp).setValue(advance.getAdvanceType()
.getDefaultMaxValue());
((Decimalbox) comp).invalidate();
throw new WrongValueException(comp,
_("The max value must be not empty"));
_("The max value must be greater than 0"));
}
}
}

View file

@ -696,7 +696,7 @@ public class ManageOrderElementAdvancesModel implements
if (listAdvanceMeasurements.size() > 1) {
for (AdvanceMeasurement advanceMeasurement : listAdvanceMeasurements) {
BigDecimal value = advanceMeasurement.getValue();
if ((selectedAdvances.size() > 1) && (value != null)) {
if ((selectedAdvances.size() > 1) && (value != null) && (value.compareTo(BigDecimal.ZERO) > 0)) {
BigDecimal maxValue = directAdvanceAssignment
.getMaxValue();
value = value.setScale(2).divide(maxValue,

View file

@ -45,9 +45,10 @@ import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.navalplanner.business.planner.entities.AggregateOfResourceAllocations;
import org.navalplanner.business.planner.entities.AssignmentFunction;
import org.navalplanner.business.planner.entities.AssignmentFunction.ASSIGNMENT_FUNCTION_NAME;
import org.navalplanner.business.planner.entities.AssignmentFunction.AssignmentFunctionName;
import org.navalplanner.business.planner.entities.CalculatedValue;
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
import org.navalplanner.business.planner.entities.ManualFunction;
import org.navalplanner.business.planner.entities.ResourceAllocation;
import org.navalplanner.business.planner.entities.SigmoidFunction;
import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
@ -58,9 +59,9 @@ import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.business.workingday.EffortDuration;
import org.navalplanner.web.common.EffortDurationBox;
import org.navalplanner.web.common.IMessagesForUser;
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.planner.allocation.streches.StrechesFunctionConfiguration;
import org.zkoss.ganttz.timetracker.ICellForDetailItemRenderer;
import org.zkoss.ganttz.timetracker.IConvertibleToColumn;
@ -227,8 +228,7 @@ public class AdvancedAllocationController extends GenericForwardComposer {
public static Restriction build(IRestrictionSource restrictionSource) {
switch (restrictionSource.getCalculatedValue()) {
case END_DATE:
return Restriction.fixedEffort(restrictionSource.getStart(),
restrictionSource.getTotalEffort());
return Restriction.emptyRestriction();
case NUMBER_OF_HOURS:
return Restriction.onlyAssignOnInterval(restrictionSource
.getStart(), restrictionSource.getEnd());
@ -249,11 +249,6 @@ public class AdvancedAllocationController extends GenericForwardComposer {
return new OnlyOnIntervalRestriction(start, end);
}
private static Restriction fixedEffort(LocalDate start,
EffortDuration effort) {
return new FixedEffortRestriction(start, effort);
}
abstract LocalDate limitStartDate(LocalDate startDate);
abstract LocalDate limitEndDate(LocalDate localDate);
@ -320,55 +315,6 @@ public class AdvancedAllocationController extends GenericForwardComposer {
}
}
private static class FixedEffortRestriction extends Restriction {
private final EffortDuration effort;
private final LocalDate start;
private FixedEffortRestriction(LocalDate start, EffortDuration effort) {
this.start = start;
this.effort = effort;
}
@Override
boolean isDisabledEditionOn(DetailItem item) {
return false;
}
@Override
LocalDate limitEndDate(LocalDate endDate) {
return endDate;
}
@Override
LocalDate limitStartDate(LocalDate argStart) {
return start.compareTo(argStart) > 0 ? start : argStart;
}
@Override
public boolean isInvalidTotalEffort(EffortDuration totalEffort) {
return this.effort.compareTo(totalEffort) != 0;
}
@Override
public void showInvalidEffort(IMessagesForUser messages,
EffortDuration totalEffort) {
messages.showMessage(Level.WARNING, getMessage(totalEffort));
}
private String getMessage(EffortDuration totalEffort) {
return _("there must be {0} effort instead of {1}",
effort.toFormattedString(), totalEffort.toFormattedString());
}
@Override
public void markInvalidEffort(Row groupingRow,
EffortDuration totalEffort) {
groupingRow.markErrorOnTotal(getMessage(totalEffort));
}
}
private static class NoRestriction extends Restriction {
@Override
@ -1192,20 +1138,28 @@ class Row {
effortDurationBox.addEventListener(Events.ON_CHANGE,
new EventListener() {
@Override
@Override
public void onEvent(Event event) {
EffortDuration value = effortDurationBox
.getEffortDurationValue();
getAllocation().withPreviousAssociatedResources().onIntervalWithinTask(
getAllocation().getStartDate(),
getAllocation().getEndDate())
.allocate(value);
fireCellChanged();
ResourceAllocation<?> resourceAllocation = getAllocation();
resourceAllocation
.withPreviousAssociatedResources()
.onIntervalWithinTask(
resourceAllocation.getStartDate(),
resourceAllocation.getEndDate())
.allocate(value);
AssignmentFunction assignmentFunction = resourceAllocation.getAssignmentFunction();
if (assignmentFunction != null) {
assignmentFunction.applyTo(resourceAllocation);
}
fireCellChanged();
reloadEffortsSameRowForDetailItems();
reloadAllEffort();
}
});
}
});
}
private void reloadEffortsSameRowForDetailItems() {
@ -1245,13 +1199,17 @@ class Row {
}
}
private AssignmentFunctionListbox assignmentFunctionsCombo = null;
private Button assignmentFunctionsConfigureButton = null;
private void initializeAssigmentFunctionsCombo() {
hboxAssigmentFunctionsCombo = new Hbox();
AssignmentFunctionListbox assignmentFunctionsCombo = new AssignmentFunctionListbox(
assignmentFunctionsCombo = new AssignmentFunctionListbox(
functions, getAllocation().getAssignmentFunction());
hboxAssigmentFunctionsCombo.appendChild(assignmentFunctionsCombo);
hboxAssigmentFunctionsCombo
.appendChild(getAssignmentFunctionsConfigureButton(assignmentFunctionsCombo));
assignmentFunctionsConfigureButton = getAssignmentFunctionsConfigureButton(assignmentFunctionsCombo);
hboxAssigmentFunctionsCombo.appendChild(assignmentFunctionsConfigureButton);
}
/**
@ -1273,7 +1231,7 @@ class Row {
selectItemAndSavePreviousValue(listitem);
}
}
this.addEventListener(Events.ON_SELECT, onSelectListbox(this));
this.addEventListener(Events.ON_SELECT, onSelectListbox());
this.setMold("select");
}
@ -1289,33 +1247,35 @@ class Row {
return listitem;
}
private EventListener onSelectListbox(
final AssignmentFunctionListbox listbox) {
private EventListener onSelectListbox() {
return new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
IAssignmentFunctionConfiguration function = (IAssignmentFunctionConfiguration) listbox
.getSelectedItem().getValue();
IAssignmentFunctionConfiguration function = (IAssignmentFunctionConfiguration) getSelectedItem()
.getValue();
// Cannot apply function if task contains consolidated day assignments
final ResourceAllocation<?> resourceAllocation = getAllocation();
if (isSigmoid(function.getName())
if (function.isSigmoid()
&& !resourceAllocation
.getConsolidatedAssignments().isEmpty()) {
showCannotApplySigmoidFunction();
listbox.setSelectedItem(listbox.getPreviousListitem());
setSelectedItem(getPreviousListitem());
return;
}
// User didn't accept
if (showConfirmChangeFunctionDialog() != Messagebox.YES) {
listbox.setSelectedItem(listbox.getPreviousListitem());
setSelectedItem(getPreviousListitem());
return;
}
// Apply sigmoid function
// Apply assignment function
if (function != null) {
setPreviousListitem(listbox.getSelectedItem());
setPreviousListitem(getSelectedItem());
function.applyOn(resourceAllocation);
updateAssignmentFunctionsConfigureButton(
assignmentFunctionsConfigureButton,
function.isConfigurable());
}
}
};
@ -1329,10 +1289,6 @@ class Row {
this.previousListitem = previousListitem;
}
private boolean isSigmoid(String value) {
return ASSIGNMENT_FUNCTION_NAME.SIGMOID.toString().equals(value);
}
private void showCannotApplySigmoidFunction() {
try {
Messagebox
@ -1351,23 +1307,30 @@ class Row {
Messagebox.YES | Messagebox.NO, Messagebox.QUESTION);
}
private void setSelectedFunction(String functionName) {
List<Listitem> children = getChildren();
for (Listitem item : children) {
IAssignmentFunctionConfiguration function = (IAssignmentFunctionConfiguration) item
.getValue();
if (function.getName().equals(functionName)) {
setSelectedItem(item);
}
}
}
}
private IAssignmentFunctionConfiguration flat = new IAssignmentFunctionConfiguration() {
@Override
public void goToConfigure() {
try {
Messagebox.show(_("Flat allocation is not configurable"),
_("Warning"), Messagebox.OK, Messagebox.EXCLAMATION);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
throw new UnsupportedOperationException(
"Flat allocation is not configurable");
}
@Override
public String getName() {
return ASSIGNMENT_FUNCTION_NAME.FLAT.toString();
return AssignmentFunctionName.FLAT.toString();
}
@Override
@ -1378,7 +1341,12 @@ class Row {
@Override
public void applyOn(
ResourceAllocation<?> resourceAllocation) {
resourceAllocation.setAssignmentFunction(null);
resourceAllocation.setAssignmentFunctionWithoutApply(null);
resourceAllocation
.withPreviousAssociatedResources()
.onIntervalWithinTask(resourceAllocation.getStartDate(),
resourceAllocation.getEndDate())
.allocate(allEffortInput.getEffortDurationValue());
reloadEfforts();
}
@ -1388,6 +1356,51 @@ class Row {
fireCellChanged();
}
@Override
public boolean isSigmoid() {
return false;
}
@Override
public boolean isConfigurable() {
return false;
}
};
private IAssignmentFunctionConfiguration manualFunction = new IAssignmentFunctionConfiguration() {
@Override
public void goToConfigure() {
throw new UnsupportedOperationException(
"Manual allocation is not configurable");
}
@Override
public String getName() {
return AssignmentFunctionName.MANUAL.toString();
}
@Override
public boolean isTargetedTo(AssignmentFunction function) {
return function instanceof ManualFunction;
}
@Override
public void applyOn(ResourceAllocation<?> resourceAllocation) {
resourceAllocation.setAssignmentFunctionAndApplyIfNotFlat(ManualFunction.create());
}
@Override
public boolean isSigmoid() {
return false;
}
@Override
public boolean isConfigurable() {
return false;
}
};
private abstract class CommonStrechesConfiguration extends
@ -1429,7 +1442,7 @@ class Row {
@Override
public String getName() {
return ASSIGNMENT_FUNCTION_NAME.STRETCHES.toString();
return AssignmentFunctionName.STRETCHES.toString();
}
};
@ -1452,7 +1465,7 @@ class Row {
@Override
public String getName() {
return ASSIGNMENT_FUNCTION_NAME.INTERPOLATION.toString();
return AssignmentFunctionName.INTERPOLATION.toString();
}
};
@ -1460,17 +1473,13 @@ class Row {
@Override
public void goToConfigure() {
try {
Messagebox.show(_("Sigmoid function is not configurable"),
_("Warning"), Messagebox.OK, Messagebox.EXCLAMATION);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
throw new UnsupportedOperationException(
"Sigmoid function is not configurable");
}
@Override
public String getName() {
return ASSIGNMENT_FUNCTION_NAME.SIGMOID.toString();
return AssignmentFunctionName.SIGMOID.toString();
}
@Override
@ -1481,7 +1490,7 @@ class Row {
@Override
public void applyOn(
ResourceAllocation<?> resourceAllocation) {
resourceAllocation.setAssignmentFunction(SigmoidFunction.create());
resourceAllocation.setAssignmentFunctionAndApplyIfNotFlat(SigmoidFunction.create());
reloadEfforts();
}
@ -1491,10 +1500,21 @@ class Row {
fireCellChanged();
}
@Override
public boolean isSigmoid() {
return true;
}
@Override
public boolean isConfigurable() {
return false;
}
};
private IAssignmentFunctionConfiguration[] functions = {
flat,
manualFunction,
defaultStrechesFunction,
strechesWithInterpolation,
sigmoidFunction
@ -1504,12 +1524,7 @@ class Row {
private Button getAssignmentFunctionsConfigureButton(
final Listbox assignmentFunctionsListbox) {
final Button button = new Button("", "/common/img/ico_editar1.png");
button.setHoverImage("/common/img/ico_editar.png");
button.setSclass("icono");
button.setTooltiptext(_("Configure"));
button.addEventListener(Events.ON_CLICK, new EventListener() {
Button button = Util.createEditButton(new EventListener() {
@Override
public void onEvent(Event event) {
IAssignmentFunctionConfiguration configuration = (IAssignmentFunctionConfiguration) assignmentFunctionsListbox
@ -1517,9 +1532,25 @@ class Row {
configuration.goToConfigure();
}
});
IAssignmentFunctionConfiguration configuration = (IAssignmentFunctionConfiguration) assignmentFunctionsListbox
.getSelectedItem().getValue();
updateAssignmentFunctionsConfigureButton(button,
configuration.isConfigurable());
return button;
}
private void updateAssignmentFunctionsConfigureButton(Button button,
boolean configurable) {
if (configurable) {
button.setTooltiptext(_("Configure"));
button.setDisabled(false);
} else {
button.setTooltiptext(_("Not configurable"));
button.setDisabled(true);
}
}
Component getNameLabel() {
if (nameLabel == null) {
nameLabel = new Label();
@ -1554,7 +1585,7 @@ class Row {
List<? extends ResourceAllocation<?>> allocations) {
AssignmentFunction function = getAssignmentFunction(allocations);
return (function != null) ? function.getName()
: ASSIGNMENT_FUNCTION_NAME.FLAT.toString();
: AssignmentFunctionName.FLAT.toString();
}
private AssignmentFunction getAssignmentFunction(
@ -1608,6 +1639,7 @@ class Row {
.getStartDate().toLocalDate());
LocalDate endDate = restriction.limitEndDate(item.getEndDate()
.toLocalDate());
changeAssignmentFunctionToManual();
getAllocation().withPreviousAssociatedResources()
.onIntervalWithinTask(startDate, endDate)
.allocate(value);
@ -1618,6 +1650,15 @@ class Row {
});
}
private void changeAssignmentFunctionToManual() {
assignmentFunctionsCombo
.setSelectedFunction(AssignmentFunctionName.MANUAL.toString());
ResourceAllocation<?> allocation = getAllocation();
if (!(allocation.getAssignmentFunction() instanceof ManualFunction)) {
allocation.setAssignmentFunctionAndApplyIfNotFlat(ManualFunction.create());
}
}
private void reloadEffortOnInterval(Component component, DetailItem item) {
if (cannotBeEdited(item)) {
Label label = (Label) component;

View file

@ -42,6 +42,8 @@ import org.navalplanner.business.calendars.entities.ThereAreHoursOnWorkHoursCalc
import org.navalplanner.business.calendars.entities.ThereAreHoursOnWorkHoursCalculator.ResourcesPerDayIsZero;
import org.navalplanner.business.calendars.entities.ThereAreHoursOnWorkHoursCalculator.ThereAreNoValidPeriods;
import org.navalplanner.business.calendars.entities.ThereAreHoursOnWorkHoursCalculator.ValidPeriodsDontHaveCapacity;
import org.navalplanner.business.planner.entities.AssignmentFunction;
import org.navalplanner.business.planner.entities.AssignmentFunction.AssignmentFunctionName;
import org.navalplanner.business.planner.entities.CalculatedValue;
import org.navalplanner.business.planner.entities.DerivedAllocation;
import org.navalplanner.business.planner.entities.ResourceAllocation;
@ -287,6 +289,8 @@ public abstract class AllocationRow {
private Grid derivedAllocationsGrid;
private Label assignmentFunctionLabel = new Label();
public AllocationRow(CalculatedValue calculatedValue) {
this.currentCalculatedValue = calculatedValue;
this.origin = null;
@ -342,6 +346,17 @@ public abstract class AllocationRow {
effortInput.setSclass("assigned-hours-input");
effortInput.setConstraint(constraintForHoursInput());
loadEffort();
updateAssignmentFunctionLabel();
}
private void updateAssignmentFunctionLabel() {
AssignmentFunction function = getAssignmentFunction();
if (function == null) {
assignmentFunctionLabel.setValue(_(AssignmentFunctionName.FLAT
.toString()));
} else {
assignmentFunctionLabel.setValue(_(function.getName()));
}
}
public abstract ResourcesPerDayModification toResourcesPerDayModification(
@ -464,6 +479,10 @@ public abstract class AllocationRow {
effortInput.setValue(getEffort());
}
public void loadAssignmentFunctionName() {
updateAssignmentFunctionLabel();
}
protected EffortDuration getEffortFromInput() {
return effortInput.getValue() != null ? effortInput
.getEffortDurationValue()
@ -497,6 +516,20 @@ public abstract class AllocationRow {
.setConstraint(constraintForResourcesPerDayInput());
}
private AssignmentFunction getAssignmentFunction() {
if (temporal != null) {
return temporal.getAssignmentFunction();
}
if (origin != null) {
return origin.getAssignmentFunction();
}
return null;
}
public boolean isAssignmentFunctionNotFlat() {
return getAssignmentFunction() != null;
}
private Constraint constraintForHoursInput() {
return (effortInput.isDisabled()) ? null : CONSTRAINT_FOR_HOURS_INPUT;
}
@ -746,4 +779,8 @@ public abstract class AllocationRow {
});
}
public Label getAssignmentFunctionLabel() {
return assignmentFunctionLabel;
}
}

View file

@ -34,6 +34,7 @@ import org.joda.time.LocalDate;
import org.navalplanner.business.calendars.entities.ThereAreHoursOnWorkHoursCalculator.CapacityResult;
import org.navalplanner.business.common.Flagged;
import org.navalplanner.business.orders.entities.HoursGroup;
import org.navalplanner.business.planner.entities.AssignmentFunction;
import org.navalplanner.business.planner.entities.CalculatedValue;
import org.navalplanner.business.planner.entities.DerivedAllocationGenerator.IWorkerFinder;
import org.navalplanner.business.planner.entities.ResourceAllocation;
@ -272,16 +273,24 @@ public class AllocationRowsHandler {
}
private List<? extends AllocationModification> doSuitableAllocation() {
List<? extends AllocationModification> allocationModifications;
switch (calculatedValue) {
case NUMBER_OF_HOURS:
return calculateNumberOfHoursAllocation();
allocationModifications = calculateNumberOfHoursAllocation();
break;
case END_DATE:
return calculateEndDateOrStartDateAllocation();
allocationModifications = calculateEndDateOrStartDateAllocation();
break;
case RESOURCES_PER_DAY:
return calculateResourcesPerDayAllocation();
allocationModifications = calculateResourcesPerDayAllocation();
break;
default:
throw new RuntimeException("cant handle: " + calculatedValue);
}
AssignmentFunction.applyAssignmentFunctionsIfAny(AllocationModification
.getBeingModified(allocationModifications));
return allocationModifications;
}
private List<ResourcesPerDayModification> calculateNumberOfHoursAllocation() {

View file

@ -540,6 +540,7 @@ public class FormBinder {
loadValueForEffortInput();
loadDerivedAllocations();
loadSclassRowSatisfied();
loadAssignmentFunctionNames();
workableDaysAndDatesBinder.afterApplicationReloadValues();
Util.reloadBindings(allocationsGrid);
}
@ -563,6 +564,12 @@ public class FormBinder {
}
}
private void loadAssignmentFunctionNames() {
for (AllocationRow each : rows) {
each.loadAssignmentFunctionName();
}
}
private void loadEffortValues() {
for (AllocationRow each : rows) {
each.loadEffort();
@ -906,4 +913,14 @@ public class FormBinder {
this.behaviour = behaviour;
}
public boolean isAnyNotFlat() {
for (AllocationRow allocationRow : allocationRowsHandler
.getCurrentRows()) {
if (allocationRow.isAssignmentFunctionNotFlat()) {
return true;
}
}
return false;
}
}

View file

@ -142,6 +142,7 @@ public class GenericAllocationRow extends AllocationRow {
if (origin != null) {
result.overrideConsolidatedDayAssignments(origin);
discountFrom.add(origin);
result.setAssignmentFunctionWithoutApply(origin.getAssignmentFunction());
}
result.discountAssignedHoursForResourceFrom(discountFrom);
return result;

View file

@ -34,4 +34,8 @@ public interface IAssignmentFunctionConfiguration {
public void goToConfigure();
public boolean isSigmoid();
public boolean isConfigurable();
}

View file

@ -635,6 +635,8 @@ public class ResourceAllocationController extends GenericForwardComposer {
data.getRealResourcesPerDay());
realResourcesPerDay.setStyle("float: right; padding-right: 1em;");
append(row, data.getAssignmentFunctionLabel());
// On click delete button
Button deleteButton = appendDeleteButton(row);
formBinder.setDeleteButtonFor(data, deleteButton);
@ -701,4 +703,8 @@ public class ResourceAllocationController extends GenericForwardComposer {
return ((getResourceAllocations().size() > 1));
}
public boolean isAnyNotFlat() {
return formBinder != null && formBinder.isAnyNotFlat();
}
}

View file

@ -126,8 +126,11 @@ public class SpecificAllocationRow extends AllocationRow {
SpecificResourceAllocation specific = SpecificResourceAllocation
.create(task);
specific.setResource(resource);
specific
.overrideConsolidatedDayAssignments((SpecificResourceAllocation) getOrigin());
SpecificResourceAllocation origin = (SpecificResourceAllocation) getOrigin();
specific.overrideConsolidatedDayAssignments(origin);
if (origin != null) {
specific.setAssignmentFunctionWithoutApply(origin.getAssignmentFunction());
}
return specific;
}

View file

@ -58,7 +58,7 @@ public abstract class StrechesFunctionConfiguration implements
int exitStatus = stretchesFunctionController.showWindow();
if (exitStatus == Messagebox.OK) {
getAllocation().setAssignmentFunction(
getAllocation().setAssignmentFunctionAndApplyIfNotFlat(
stretchesFunctionController.getAssignmentFunction());
assignmentFunctionChanged();
}
@ -94,7 +94,17 @@ public abstract class StrechesFunctionConfiguration implements
@Override
public void applyOn(ResourceAllocation<?> resourceAllocation) {
resourceAllocation.setAssignmentFunction(StretchesFunction.create());
resourceAllocation.setAssignmentFunctionAndApplyIfNotFlat(StretchesFunction.create());
}
@Override
public boolean isSigmoid() {
return false;
}
@Override
public boolean isConfigurable() {
return true;
}
}

View file

@ -94,6 +94,7 @@ import org.navalplanner.web.planner.consolidations.IAdvanceConsolidationCommand;
import org.navalplanner.web.planner.milestone.IAddMilestoneCommand;
import org.navalplanner.web.planner.milestone.IDeleteMilestoneCommand;
import org.navalplanner.web.planner.order.ISaveCommand.IAfterSaveListener;
import org.navalplanner.web.planner.order.PlanningStateCreator.IActionsOnRetrieval;
import org.navalplanner.web.planner.order.PlanningStateCreator.PlanningState;
import org.navalplanner.web.planner.reassign.IReassignCommand;
import org.navalplanner.web.planner.taskedition.EditTaskController;
@ -327,6 +328,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
List<ICommand<TaskElement>> additional) {
long time = System.currentTimeMillis();
this.planner = planner;
planningState = createPlanningStateFor(order);
currentScenario = scenarioManager.getCurrent();
PlannerConfiguration<TaskElement> configuration = createConfiguration(order);
PROFILING_LOG.info("load data and create configuration took: "
@ -1090,7 +1092,6 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private PlannerConfiguration<TaskElement> createConfiguration(Order order) {
taskElementAdapter.useScenario(currentScenario);
planningState = createPlanningStateFor(order);
taskElementAdapter.setInitDate(asLocalDate(order.getInitDate()));
taskElementAdapter.setDeadline(asLocalDate(order.getDeadline()));
PlannerConfiguration<TaskElement> result = new PlannerConfiguration<TaskElement>(
@ -1113,7 +1114,14 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private PlanningState createPlanningStateFor(Order order) {
return planningStateCreator.retrieveOrCreate(planner.getDesktop(),
order);
order, new IActionsOnRetrieval() {
@Override
public void onRetrieval(PlanningState planningState) {
planningState.reattach();
planningState.reassociateResourcesWithSession();
}
});
}
public static final String COLOR_ASSIGNED_LOAD_GLOBAL = "#E0F3D3"; // Soft

View file

@ -130,10 +130,24 @@ public class PlanningStateCreator {
@Autowired
private ITaskSourceDAO taskSourceDAO;
public interface IActionsOnRetrieval {
public void onRetrieval(PlanningState planningState);
}
public PlanningState retrieveOrCreate(Desktop desktop, Order order) {
return retrieveOrCreate(desktop, order, null);
}
public PlanningState retrieveOrCreate(Desktop desktop, Order order,
IActionsOnRetrieval onRetrieval) {
Object existent = desktop.getAttribute(ATTRIBUTE_NAME);
if (existent instanceof PlanningState) {
return (PlanningState) existent;
PlanningState result = (PlanningState) existent;
if (onRetrieval != null) {
onRetrieval.onRetrieval(result);
}
return result;
}
PlanningState result = createInitialPlanning(reload(order));
desktop.setAttribute(ATTRIBUTE_NAME, result);

View file

@ -28,7 +28,7 @@ public enum Type {
@Override
public String getName() {
return _("All");
return _("All project tasks");
}
@Override
@ -40,7 +40,7 @@ public enum Type {
@Override
public String getName() {
return _("From Today");
return _("From today");
}
@Override
@ -52,7 +52,7 @@ public enum Type {
@Override
public String getName() {
return _("From Chosen");
return _("From chosen date");
}
@Override

View file

@ -110,7 +110,7 @@ public class OrdersTabCreator {
breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
breadcrumbs.appendChild(new Label(getSchedulingLabel()));
breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
breadcrumbs.appendChild(new Label(_("Projects")));
breadcrumbs.appendChild(new Label(_("Projects List")));
}
};
}

View file

@ -364,18 +364,10 @@ public class CutyPrint {
int minWidthPixels) {
String css = "/* ------ Make the area for task names wider ------ */\n";
css += "th.z-tree-col {width: 76px !important;}\n";
css += "th.tree-text {width: " + (24 + minWidthPixels) + "px !important;}\n";
css += "th.tree-text {width: " + (34 + minWidthPixels)
+ "px !important;}\n";
css += ".taskdetailsContainer, .z-west-body, .z-tree-header, .z-tree-body {";
css += "width: " + (176 + minWidthPixels) + "px !important;}\n";
css += ".listdetails .depth_1 input.task_title {";
css += "width: " + (minWidthPixels - 1) + "px !important;}\n";
css += ".listdetails .depth_2 input.task_title {";
css += "width: " + (minWidthPixels - 22) + "px !important;}\n";
css += ".listdetails .depth_3 input.task_title {";
css += "width: " + (minWidthPixels - 43) + "px !important;}\n";
css += ".listdetails .depth_4 input.task_title {";
css += "width: " + (minWidthPixels - 64) + "px !important;}\n";
return css;
}
}

View file

@ -132,4 +132,6 @@ public interface IQualityFormModel {
* @param qualityFormItem
*/
Boolean isTotalPercentage(QualityFormItem item);
void checkHasTasks(QualityForm qualityForm) throws ValidationException;
}

View file

@ -27,15 +27,18 @@ import java.math.BigDecimal;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.LogFactory;
import org.hibernate.validator.InvalidValue;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.qualityforms.entities.QualityForm;
import org.navalplanner.business.qualityforms.entities.QualityFormItem;
import org.navalplanner.business.qualityforms.entities.QualityFormType;
import org.navalplanner.business.users.entities.Profile;
import org.navalplanner.web.common.BaseCRUDController;
import org.navalplanner.web.common.Level;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.users.ProfileCRUDController;
import org.springframework.beans.factory.annotation.Autowired;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
@ -58,6 +61,8 @@ import org.zkoss.zul.impl.InputElement;
*/
public class QualityFormCRUDController extends BaseCRUDController<QualityForm> {
private static final org.apache.commons.logging.Log LOG = LogFactory.getLog(QualityFormCRUDController.class);
@Autowired
private IQualityFormModel qualityFormModel;
@ -465,4 +470,31 @@ public class QualityFormCRUDController extends BaseCRUDController<QualityForm> {
Util.reloadBindings(qualityForms);
}
}
@Override
protected boolean beforeDeleting(QualityForm qualityForm){
return !isReferencedByOtherEntities(qualityForm);
}
private boolean isReferencedByOtherEntities(QualityForm qualityForm) {
try {
qualityFormModel.checkHasTasks(qualityForm);
return false;
} catch (ValidationException e) {
showCannotDeleteQualityFormDialog(e.getInvalidValue().getMessage(),
qualityForm);
}
return true;
}
private void showCannotDeleteQualityFormDialog(String message, QualityForm qualityForm) {
try {
Messagebox.show(_(message), _("Warning"), Messagebox.OK,
Messagebox.EXCLAMATION);
} catch (InterruptedException e) {
LOG.error(
_("Error on showing warning message removing qualityForm: ",
qualityForm.getId()), e);
}
}
}

View file

@ -31,6 +31,7 @@ import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.qualityforms.daos.IQualityFormDAO;
import org.navalplanner.business.qualityforms.entities.QualityForm;
import org.navalplanner.business.qualityforms.entities.QualityFormItem;
import org.navalplanner.business.users.entities.Profile;
import org.navalplanner.web.common.concurrentdetection.OnConcurrentModification;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
@ -217,4 +218,9 @@ public class QualityFormModel implements IQualityFormModel {
.equals(totalPercentage)) : false;
}
@Override
@Transactional(readOnly = true)
public void checkHasTasks(QualityForm qualityForm) throws ValidationException {
qualityFormDAO.checkHasTasks(qualityForm);
}
}

View file

@ -30,6 +30,8 @@ import java.util.Set;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRParameter;
import org.navalplanner.business.common.Registry;
import org.springframework.transaction.annotation.Transactional;
import org.zkoss.util.Locales;
import org.zkoss.zk.au.out.AuDownload;
import org.zkoss.zk.ui.Executions;
@ -100,7 +102,12 @@ public abstract class NavalplannerReportController extends GenericForwardCompose
protected Map<String, Object> getParameters() {
Map<String, Object> parameters = new HashMap<String, Object>();
parameters.put("logo", String.format("/logos/%s/logo.png", getLanguage()));
String companyLogo = Registry.getConfigurationDAO()
.getConfigurationWithReadOnlyTransaction().getCompanyLogoURL();
if (companyLogo == "") {
companyLogo = "/logos/logo.png";
}
parameters.put("logo", companyLogo);
parameters.put(JRParameter.REPORT_LOCALE, getCurrentLocale());
return parameters;
}

View file

@ -932,8 +932,19 @@ public class ResourceLoadController implements Composer {
}
public void filterBy(Order order) {
this.filterBy = order == null ? null : planningStateCreator
.retrieveOrCreate(parent.getDesktop(), order);
this.filterBy = order == null ? null : createPlanningState(order);
}
PlanningState createPlanningState(final Order order) {
return transactionService
.runOnReadOnlyTransaction(new IOnTransaction<PlanningState>() {
@Override
public PlanningState execute() {
return planningStateCreator.retrieveOrCreate(
parent.getDesktop(), order);
}
});
}
public void setPlanningControllerEntryPoints(

View file

@ -540,6 +540,7 @@ public class MachineCRUDController extends BaseCRUDController<Machine> {
.showMessage(
Level.WARNING,
_("This machine cannot be deleted because it has assignments to projects or imputed hours"));
return false;
}
return true;
}

View file

@ -63,8 +63,6 @@ public interface ISettingsModel {
void setEmail(String email);
void setLoginName(String loginName);
String getLoginName();
}

View file

@ -21,15 +21,18 @@ package org.navalplanner.web.users.settings;
import static org.navalplanner.web.I18nHelper._;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.settings.entities.Language;
import org.navalplanner.web.common.IMessagesForUser;
import org.navalplanner.web.common.Level;
import org.navalplanner.web.common.MessagesForUser;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.Textbox;
@ -66,8 +69,21 @@ public class SettingsController extends GenericForwardComposer {
settingsModel.initEditLoggedUser();
}
public Language[] getLanguages() {
return Language.values();
public List<Language> getLanguages() {
List<Language> languages = Arrays.asList(Language.values());
Collections.sort(languages, new Comparator<Language>() {
@Override
public int compare(Language o1, Language o2) {
if (o1.equals(Language.BROWSER_LANGUAGE)) {
return -1;
}
if (o2.equals(Language.BROWSER_LANGUAGE)) {
return 1;
}
return _(o1.getDisplayName()).compareTo(_(o2.getDisplayName()));
}
});
return languages;
}
public boolean save() {
@ -144,10 +160,6 @@ public class SettingsController extends GenericForwardComposer {
return settingsModel.getLoginName();
}
public void setLoginName(String loginName) {
settingsModel.setLoginName(loginName);
}
public void setEmail(String email) {
settingsModel.setEmail(email);
}

View file

@ -182,13 +182,6 @@ public class SettingsModel implements ISettingsModel {
return user.getLoginName();
}
@Override
public void setLoginName(String loginName) {
if (user != null) {
user.setLoginName(loginName);
}
}
@Override
public void setEmail(String email) {
if (user != null) {

View file

@ -210,6 +210,8 @@ public class WorkReportCRUDController extends GenericForwardComposer implements
Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION);
if (Messagebox.OK == status) {
workReportModel.remove(workReport);
messagesForUser.showMessage(Level.INFO,
_("Work report removed successfully"));
loadComponentslist(listWindow);
Util.reloadBindings(listWindow);
}

View file

@ -30,5 +30,5 @@ import org.navalplanner.business.calendars.entities.CalendarExceptionTypeColor;
*/
@XmlEnum
public enum CalendarExceptionTypeColorDTO {
DEFAULT, RED, GREEN, BLUE;
DEFAULT, RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW, BLACK, ORANGE, PURPLE;
}

View file

@ -44,24 +44,36 @@ public class CalendarExceptionTypeColorConverter {
CalendarExceptionTypeColorDTO.RED,
CalendarExceptionTypeColor.DEFAULT);
calendarExceptionTypeColorToDTO.put(CalendarExceptionTypeColor.DEFAULT,
addEquivalence(CalendarExceptionTypeColor.DEFAULT,
CalendarExceptionTypeColorDTO.DEFAULT);
calendarExceptionTypeColorFromDTO.put(
CalendarExceptionTypeColorDTO.DEFAULT,
CalendarExceptionTypeColor.DEFAULT);
calendarExceptionTypeColorToDTO.put(CalendarExceptionTypeColor.GREEN,
addEquivalence(CalendarExceptionTypeColor.GREEN,
CalendarExceptionTypeColorDTO.GREEN);
calendarExceptionTypeColorFromDTO.put(
CalendarExceptionTypeColorDTO.GREEN,
CalendarExceptionTypeColor.GREEN);
calendarExceptionTypeColorToDTO.put(CalendarExceptionTypeColor.BLUE,
addEquivalence(CalendarExceptionTypeColor.BLUE,
CalendarExceptionTypeColorDTO.BLUE);
calendarExceptionTypeColorFromDTO.put(
CalendarExceptionTypeColorDTO.BLUE,
CalendarExceptionTypeColor.BLUE);
addEquivalence(CalendarExceptionTypeColor.MAGENTA,
CalendarExceptionTypeColorDTO.MAGENTA);
addEquivalence(CalendarExceptionTypeColor.CYAN,
CalendarExceptionTypeColorDTO.CYAN);
addEquivalence(CalendarExceptionTypeColor.YELLOW,
CalendarExceptionTypeColorDTO.YELLOW);
addEquivalence(CalendarExceptionTypeColor.ORANGE,
CalendarExceptionTypeColorDTO.ORANGE);
addEquivalence(CalendarExceptionTypeColor.BLACK,
CalendarExceptionTypeColorDTO.BLACK);
}
private static void addEquivalence(CalendarExceptionTypeColor origin,
CalendarExceptionTypeColorDTO destination) {
calendarExceptionTypeColorToDTO.put(origin, destination);
calendarExceptionTypeColorFromDTO.put(destination, origin);
}
public final static CalendarExceptionTypeColorDTO toDTO(

View file

@ -497,6 +497,8 @@ public final class OrderElementConverter {
materialAssignmentDTO.materialCode);
} catch (InstanceNotFoundException e) {
material = Material.create(materialAssignmentDTO.materialCode);
material.setDescription("material-"
+ materialAssignmentDTO.materialCode);
MaterialCategory defaultMaterialCategory = PredefinedMaterialCategories.IMPORTED_MATERIALS_WITHOUT_CATEGORY
.getMaterialCategory();

View file

@ -0,0 +1,76 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 - ComtecSF S.L.
*
* 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/>.
*/
package org.navalplanner.ws.workreports.api;
import java.util.List;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.workreports.entities.IWorkReportsElements;
import org.navalplanner.business.workreports.entities.WorkReportLine;
/**
* This interface should be implemented for each strategy that allows to look
* for the set of {@link OrderElement} associated to
* {@link IWorkReportsElements}, i.e.: an strategy could be only one
* {@link OrderElement} per {@link WorkReportLine}.
*
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
*
*/
public interface IBindingOrderElementStrategy {
/**
* This method allows to get the list of {@link OrderElement} associated to
* a given {@link IWorkReportDTOsElements}, depending on implementation, the
* result could have one or more elements.
*
* @param workReportDTO
* @return list of {@link OrderElement} associated to the
* {@link IWorkReportDTOsElements} param
* @throws ValidationException
*/
List<OrderElement> getOrderElementsBound(
IWorkReportDTOsElements workReportDTO) throws ValidationException;
/**
* This method returns an string representing the code of the
* {@link OrderElement} associated to the {@link IWorkReportsElements} given
* as parameter
*
* @param workReportEntity
* @return the code
*/
String getOrderElementCodesBound(IWorkReportsElements workReportEntity);
/**
* This method allows to assign a list of {@link OrderElement} to the
* {@link IWorkReportsElements} given as parameter. It should throw a
* {@link ValidationException} when the operation could not be done,
* depending on the strategy implemented
*
* @param workReportEntity
* @param list
* @throws ValidationException
*/
void assignOrderElementsToWorkReportLine(
IWorkReportsElements workReportEntity, List<OrderElement> list)
throws ValidationException;
}

View file

@ -0,0 +1,55 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 - ComtecSF S.L.
*
* 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/>.
*/
package org.navalplanner.ws.workreports.api;
import java.util.Set;
import javax.xml.datatype.XMLGregorianCalendar;
import org.navalplanner.ws.common.api.LabelReferenceDTO;
/**
* Interface which must be implemented by {@link WorkReportDTO} and
* {@link WorkReportLineDTO}
*
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
*
*/
public interface IWorkReportDTOsElements {
XMLGregorianCalendar getDate();
void setDate(XMLGregorianCalendar calendar);
String getResource();
void setResource(String resource);
String getOrderElement();
void setOrderElement(String orderElement);
Set<LabelReferenceDTO> getLabels();
void setLabels(Set<LabelReferenceDTO> labels);
Set<DescriptionValueDTO> getDescriptionValues();
void setDescriptionValues(Set<DescriptionValueDTO> descriptionValues);
}

View file

@ -0,0 +1,91 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2011 - ComtecSF S.L.
*
* 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/>.
*/
package org.navalplanner.ws.workreports.api;
import java.util.ArrayList;
import java.util.List;
import org.navalplanner.business.common.Registry;
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
import org.navalplanner.business.common.exceptions.ValidationException;
import org.navalplanner.business.orders.entities.OrderElement;
import org.navalplanner.business.workreports.entities.IWorkReportsElements;
import org.navalplanner.business.workreports.entities.WorkReportLine;
/**
* Singleton implementation for {@link IBindingOrderElementStrategy}, with this
* implementation there could be only one {@link OrderElement} for each
* {@link WorkReportLine}
*
* @author Ignacio Díaz Teijido <ignacio.diaz@comtecsf.es>
*
*/
public class OneOrderElementPerWorkReportLine implements
IBindingOrderElementStrategy {
private static OneOrderElementPerWorkReportLine instance = null;
// This avoids external instantiation
private OneOrderElementPerWorkReportLine() {
}
// Singleton instantiator
public static OneOrderElementPerWorkReportLine getInstance() {
if (instance == null)
instance = new OneOrderElementPerWorkReportLine();
return instance;
}
@Override
public List<OrderElement> getOrderElementsBound(
IWorkReportDTOsElements workReportDTO) throws ValidationException {
List<OrderElement> result = new ArrayList<OrderElement>();
if (workReportDTO.getOrderElement() != null) {
OrderElement orderElement;
try {
orderElement = Registry.getOrderElementDAO().findUniqueByCode(
workReportDTO.getOrderElement());
} catch (InstanceNotFoundException e) {
throw new UnsupportedOperationException("Element not found");
}
result.add(orderElement);
}
return result;
}
@Override
public String getOrderElementCodesBound(
IWorkReportsElements workReportEntity) {
return workReportEntity.getOrderElement().getCode();
}
@Override
public void assignOrderElementsToWorkReportLine(
IWorkReportsElements workReportEntity, List<OrderElement> list)
throws ValidationException {
if (list.size() == 1)
workReportEntity.setOrderElement(list.get(0));
else {
if (workReportEntity instanceof WorkReportLine)
throw new ValidationException(
"List must have exactly one element");
}
}
}

View file

@ -40,7 +40,8 @@ import org.navalplanner.ws.common.api.LabelReferenceDTO;
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
@XmlRootElement(name = "work-report")
public class WorkReportDTO extends IntegrationEntityDTO {
public class WorkReportDTO extends IntegrationEntityDTO implements
IWorkReportDTOsElements {
public final static String ENTITY_TYPE = "work-report";
@ -91,4 +92,54 @@ public class WorkReportDTO extends IntegrationEntityDTO {
return ENTITY_TYPE;
}
@Override
public XMLGregorianCalendar getDate() {
return date;
}
@Override
public void setDate(XMLGregorianCalendar calendar) {
this.date = calendar;
}
@Override
public String getResource() {
return resource;
}
@Override
public void setResource(String resource) {
this.resource = resource;
}
@Override
public String getOrderElement() {
return orderElement;
}
@Override
public void setOrderElement(String orderElement) {
this.orderElement = orderElement;
}
@Override
public Set<LabelReferenceDTO> getLabels() {
return labels;
}
@Override
public void setLabels(Set<LabelReferenceDTO> labels) {
this.labels = labels;
}
@Override
public Set<DescriptionValueDTO> getDescriptionValues() {
return descriptionValues;
}
@Override
public void setDescriptionValues(Set<DescriptionValueDTO> descriptionValues) {
this.descriptionValues = descriptionValues;
}
}

View file

@ -40,7 +40,8 @@ import org.navalplanner.ws.common.api.LabelReferenceDTO;
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
@XmlRootElement(name = "work-report-line")
public class WorkReportLineDTO extends IntegrationEntityDTO {
public class WorkReportLineDTO extends IntegrationEntityDTO implements
IWorkReportDTOsElements {
public final static String ENTITY_TYPE = "work-report-line";
@ -99,4 +100,55 @@ public class WorkReportLineDTO extends IntegrationEntityDTO {
return ENTITY_TYPE;
}
@Override
public XMLGregorianCalendar getDate() {
return date;
}
@Override
public void setDate(XMLGregorianCalendar calendar) {
this.date = calendar;
}
@Override
public String getResource() {
return resource;
}
@Override
public void setResource(String resource) {
this.resource = resource;
}
@Override
public String getOrderElement() {
return orderElement;
}
@Override
public void setOrderElement(String orderElement) {
this.orderElement = orderElement;
}
@Override
public Set<LabelReferenceDTO> getLabels() {
return labels;
}
@Override
public void setLabels(Set<LabelReferenceDTO> labels) {
this.labels = labels;
}
@Override
public Set<DescriptionValueDTO> getDescriptionValues() {
return descriptionValues;
}
@Override
public void setDescriptionValues(Set<DescriptionValueDTO> descriptionValues) {
this.descriptionValues = descriptionValues;
}
}

View file

@ -48,17 +48,24 @@ import org.navalplanner.ws.common.api.LabelReferenceDTO;
import org.navalplanner.ws.common.impl.DateConverter;
import org.navalplanner.ws.common.impl.LabelReferenceConverter;
import org.navalplanner.ws.workreports.api.DescriptionValueDTO;
import org.navalplanner.ws.workreports.api.IBindingOrderElementStrategy;
import org.navalplanner.ws.workreports.api.OneOrderElementPerWorkReportLine;
import org.navalplanner.ws.workreports.api.WorkReportDTO;
import org.navalplanner.ws.workreports.api.WorkReportLineDTO;
import org.springframework.transaction.annotation.Transactional;
/**
* Converter from/to work report related entities to/from DTOs.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
*/
public final class WorkReportConverter {
private static IBindingOrderElementStrategy bindingStrategy = OneOrderElementPerWorkReportLine
.getInstance();
public static WorkReport toEntity(WorkReportDTO workReportDTO)
throws InstanceNotFoundException {
@ -86,17 +93,8 @@ public final class WorkReportConverter {
workReport.setDate(DateConverter.toDate(workReportDTO.date));
}
if (workReportDTO.orderElement != null) {
try {
OrderElement orderElement = Registry.getOrderElementDAO()
.findUniqueByCode(workReportDTO.orderElement);
workReport.setOrderElement(orderElement);
} catch (InstanceNotFoundException e) {
workReport.setOrderElement(null);
throw new ValidationException(
_("There is no task with this code"));
}
}
bindingStrategy.assignOrderElementsToWorkReportLine(workReport,
bindingStrategy.getOrderElementsBound(workReportDTO));
if (workReportDTO.resource != null) {
try {
@ -158,17 +156,8 @@ public final class WorkReportConverter {
.setDate(DateConverter.toDate(workReportLineDTO.date));
}
if (workReportLineDTO.orderElement != null) {
try {
OrderElement orderElement = Registry.getOrderElementDAO()
.findUniqueByCode(workReportLineDTO.orderElement);
workReportLine.setOrderElement(orderElement);
} catch (InstanceNotFoundException e) {
workReportLine.setOrderElement(null);
throw new ValidationException(
_("There is no task with this code"));
}
}
bindingStrategy.assignOrderElementsToWorkReportLine(workReportLine,
bindingStrategy.getOrderElementsBound(workReportLineDTO));
if (workReportLineDTO.resource != null) {
try {
@ -240,10 +229,8 @@ public final class WorkReportConverter {
date = DateConverter.toXMLGregorianCalendar(workReport.getDate());
}
String orderElementCode = null;
if (workReport.getOrderElement() != null) {
orderElementCode = workReport.getOrderElement().getCode();
}
String orderElementCode = bindingStrategy
.getOrderElementCodesBound(workReport);
String resourceNif = null;
if ((workReport.getResource() != null)) {
@ -294,10 +281,7 @@ public final class WorkReportConverter {
resource = ((Worker)line.getResource()).getNif();
}
String orderElement = null;
if(line.getOrderElement() != null){
orderElement = line.getOrderElement().getCode();
}
String orderElement = bindingStrategy.getOrderElementCodesBound(line);
String typeOfWorkHours = null;
if(line.getTypeOfWorkHours() != null){

File diff suppressed because it is too large Load diff

View file

@ -83,7 +83,7 @@
</attribute>
</calendar>
<grid width="160px" sclass="day-details">
<grid width="180px" sclass="day-details">
<auxhead>
<auxheader colspan="2" label="${i18n:_('Day properties')}" />
</auxhead>
@ -94,7 +94,7 @@
<rows>
<row>
<label value="${i18n:_('Day')}" />
<datebox disabled="true"
<datebox disabled="true" buttonVisible="false"
value="@{calendarController.editionController.selectedDay}" />
</row>
<row>

View file

@ -20,7 +20,6 @@
-->
<?page title="${i18n:_('NavalPlan: Calendars')}"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<?init class="org.zkoss.zk.ui.util.Composition" arg0="/common/layout/template.zul"?>

View file

@ -552,6 +552,9 @@ div.z-grid {
padding: 0;
}
.listdetails .z-tree-header {
position:relative;
}
.z-listbox .z-textbox,.z-listbox .z-decimalbox,.z-listbox .z-intbox,
.z-listbox .z-longbox,.z-listbox .z-doublebox {
@ -923,6 +926,9 @@ span.z-dottree-line {
width: 84px;
height: 84px;
margin: 0 0 4px 4px;
}
.perspective tr td, .perspective-active tr td {
font-weight: normal;
font-size: 10px;
}
@ -972,10 +978,19 @@ span.z-dottree-line {
background-color: #E6F2F9;
}
span.perspective, span.perspective-active {
margin: 0 2px;
}
.perspectives-label {
display: none;
}
.taskdetailsContainer {
border-left:0;
border-top:0;
}
.z-button.perspective .z-button-cm,
.z-button.perspective-active .z-button-cm {
white-space:normal;
@ -1395,6 +1410,12 @@ display:none;
overflow: hidden;
}
.color-sample {
height: 10px;
width: 20px;
border: solid 1px black;
}
/* Expand vertical boxes for non-ffox browsers */
.z-vbox {
width:100%;
@ -1489,6 +1510,11 @@ display:none;
color: #555555;
}
.advanced-assignment-area > .z-center-body {
overflow: visible !important;
overflow: visible !important;
}
input.z-spinner-text-disd,
input.z-datebox-text-disd {
color: #000000 !important;
@ -1498,6 +1524,14 @@ input.z-datebox-text-disd {
padding: 0;
}
.z-calendar .z-outside {
color: #CCC;
}
.z-calendar-calday td.z-calendar-seld {
font-weight: bold;
}
.add-resources-or-criteria span {
white-space: nowrap;
}
@ -1734,4 +1768,16 @@ select {
width: 0;
border-right: 1px solid #9ECAD8;
border-left: 1px solid #d9f3ff;
}
}
.logo-area img {
margin-right:10px;
}
.logo-area {
width: 1px;
}
.z-borderlayout {
background-color: transparent;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View file

@ -46,7 +46,7 @@
</n:table>
<n:table width="750" border="0" align="center" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF">
<n:tr>
<n:td height="100" align="left" valign="middle"><n:img src="${contextPath}/common/img/${i18n:_('en')}/logo_login.png" alt="NavalPlan" /></n:td>
<n:td height="100" align="left" valign="middle"><n:img src="${contextPath}/common/img/logo_login.png" alt="NavalPlan" /></n:td>
</n:tr>
</n:table>
<n:table width="750" border="0" align="center" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF">

View file

@ -52,9 +52,11 @@ signature="java.lang.Boolean isDefaultPasswordsControl()"?>
<n:table width="100%" border="0" cellpadding="0" cellspacing="0">
<n:tr>
<n:td width="180" valign="center">
<n:td valign="center" class="logo-area">
<n:a href="${contextPath}/">
<n:img src="${contextPath}/common/img/${i18n:_('en')}/logo.png" /></n:a></n:td>
<n:img src="${templateCtrl.companyLogoURL}" if="${templateCtrl.companyLogoURL!=''}" />
<n:img src="${contextPath}/common/img/logo.png" if="${templateCtrl.companyLogoURL==''}" />
</n:a></n:td>
<n:td valign="top">
<n:table width="100%" border="0" cellspacing="0" cellpadding="0">
<n:tr>
@ -122,9 +124,6 @@ signature="java.lang.Boolean isDefaultPasswordsControl()"?>
<south border="none">
<n:table width="100%">
<n:tr class="footer">
<n:td height="40" align="left" valign="bottom">
<n:img height="40" src="${templateCtrl.companyLogoURL}" if="${templateCtrl.companyLogoURL!=''}" />
</n:td>
<n:td valign="center">
<n:div if="${project:passwd_control()}" id="warningDefaultPasswdadmin"
class="footer-messages-area"
@ -157,7 +156,6 @@ signature="java.lang.Boolean isDefaultPasswordsControl()"?>
<n:img width="110" height="40" src="${contextPath}/common/img/logos_footer_fundacion.png"/>
<n:img width="253" height="40" src="${contextPath}/common/img/logos_footer_administracion.png"/>
</n:td>
</n:tr>
</n:table>
</south>

View file

@ -56,12 +56,19 @@
</row>
<row>
<label value="${i18n:_('Color')}" />
<listbox id="colorsListbox" mold="select"
<hbox align="pack">
<listbox id="colorsListbox" mold="select"
model="@{controller.colors}"
selectedItem="@{controller.exceptionDayType.color}"
itemRenderer="@{controller.colorsRenderer}"/>
itemRenderer="@{controller.colorsRenderer}"
onSelect="controller.reloadSampleColors()" />
<div id="colorSampleOwn" sclass="color-sample" style="@{controller.styleColorOwnException}" />
<label value="${i18n:_('Own exception')}" />
<div id="colorSampleDerived" sclass="color-sample" style="@{controller.styleColorDerivedException}" />
<label value="${i18n:_('Derived exception')}" />
</hbox>
</row>
<row>
<row>
<label value="${i18n:_('Standard Effort')}" />
<effortDurationPicker id="standardEffort" />
</row>

View file

@ -30,14 +30,15 @@
<zk>
<window self="@{define(content)}"
apply="org.navalplanner.web.materials.MaterialsController"
title="${i18n:_('Materials')}">
<vbox id="messagesContainer" />
title="${i18n:_('Materials')}" >
<!-- Categories -->
<hbox width="100%">
<panel title="${i18n:_('Categories')}"
border="normal">
<panelchildren>
<vbox width="100%">
<vbox id="messagesContainer" />
<groupbox closable="false">
<caption label="${i18n:_('Categories')}" />
<hbox>
<textbox id="txtCategory" onOK="materialsController.addMaterialCategory()"
style="padding-bottom: 4px" />
@ -47,7 +48,6 @@
<button label="${i18n:_('Unselect')}" onClick="materialsController.clearSelectionCategoriesTree()" />
</hbox>
<separator spacing="5px" orient="horizontal" />
<tree id="categoriesTree" zclass="z-dottree"
rows="5" vflex="true" multiple="false"
@ -61,15 +61,14 @@
<treecol label="${i18n:_('Operations')}" width="80px" />
</treecols>
</tree>
</panelchildren>
</panel>
</hbox>
</groupbox>
</vbox>
<!-- Materials -->
<hbox width="100%">
<panel title="${i18n:_('List of materials for all categories (select one to filter)')}"
id="materialsPanel" border="normal">
<panelchildren>
<vbox width="100%">
<groupbox closable="false">
<caption id="materialsCaption" label="${i18n:_('List of materials for all categories (select one to filter)')}"/>
<button id="btnAddMaterial"
label="${i18n:_('Add')}"
onClick="materialsController.addMaterialToMaterialCategory(categoriesTree.selectedItem)" />
@ -91,7 +90,8 @@
<textbox id="code" value="@{material.code}" width="95%"
disabled="@{material.category.codeAutogenerated}"
constraint="no empty:${i18n:_('cannot be null or empty')}" />
<textbox value="@{material.description}" width="95%" />
<textbox value="@{material.description}" width="95%"
constraint="no empty:${i18n:_('cannot be null or empty')}" />
<doublebox value="@{material.defaultUnitPrice}" />
<listbox mold="select" model="@{materialsController.unitTypes}"
onSelect = "materialsController.selectUnitType(self)"
@ -107,10 +107,8 @@
</row>
</rows>
</newdatasortablegrid>
</panelchildren>
</panel>
</hbox>
</groupbox>
</vbox>
<!-- Save button -->
<button onClick="materialsController.saveAndContinue()"

View file

@ -21,7 +21,7 @@
<window id="${arg.top_id}" title="${i18n:_('Projects list')}">
<grid id="listing" model="@{controller.orders}" mold="paging"
pageSize="10" fixedLayout="true"
pageSize="15" fixedLayout="true"
rowRenderer= "@{controller.ordersRowRender}"
onInitRender ="controller.sortOrders();" sclass="clickable-rows projects-list">
<columns sizable="true">

View file

@ -36,13 +36,14 @@
<borderlayout id="normalLayout" width="auto" apply="${advancedAllocationController}" class="advancedallocationlayout">
<north height="30px" border="0" sclass="toolbar-box">
<hbox align="center">
<button label="${i18n:_('Accept')}" id="acceptButton" class="save-button global-action"
<button label="${i18n:_('Accept')}" id="acceptButton" image="/common/img/bt_ok.png"
if="${advancedAllocationController.advancedAllocationOfSingleTask}" />
<button label="${i18n:_('Cancel')}" id="cancelButton" class="cancel-button global-action"
<button label="${i18n:_('Cancel')}" id="cancelButton" image="/common/img/bt_cancel.png"
if="${advancedAllocationController.advancedAllocationOfSingleTask}" />
<button image="/common/img/ico_ok.png" tooltiptext="${i18n:_('Accept')}" id="saveButton" class="planner-command"
<button label="${i18n:_('Accept')}" id="saveButton" image="/common/img/bt_ok.png"
if="${!(advancedAllocationController.advancedAllocationOfSingleTask)}" />
<separator/>
<space bar="true" />
<label>${i18n:_('Zoom level')}:</label>
<listbox mold="select" rows="1" id="advancedAllocationZoomLevel"
model="${advancedAllocationController.zoomLevels}"

View file

@ -1176,17 +1176,10 @@ height: 100%
background-image: url("../../zkau/web/ganttz/img/deadline.png");
}
body .perspectives-column {
display:inline;
}
.perspectives-column .z-west-body {
width: 200px !important;
}
#watermark .timetracker_column .today_deadline {
background-image:url(../img/watermark_today.png);
background-repeat: repeat-y;

View file

@ -22,6 +22,10 @@ body .footer {
display: none !important;
}
body .footer-print {
display: inline !important;
}
/* ------ Remove scrolls ------ */
.leftpanelcontainer {
overflow: hidden !important;
@ -43,7 +47,7 @@ body .footer {
/* ------ Reposition main-area ------ */
body .main-area {
margin-left: 0;
margin-top: -32px;
margin-top: -31px;
}
/* ------ Hide possible Javascript execution exceptions ------ */
@ -51,20 +55,10 @@ body .main-area {
display: none;
}
/* Hack for hiding breadcrumbs part in printed diagrams */
a.ruta,
.ruta tr td,
.ruta tr td+td,
.ruta tr td+td+td {
display:none;
td.migas_linea {
padding-top:25px;
}
.ruta tr td+td+td+td+td+td {
font-size: 20px;
display: inline !important;
}
.border-container .taskgroup_start,
.border-container .taskgroup_end {
repeat-y: none;
@ -82,4 +76,16 @@ a.ruta,
display:none;
}
.z-center div, .taskpanel div {
overflow: hidden !important;
}
.logo-area {
height: 70px;
}
.listdetails input.task_title {
width: 100% !important;
}
/* ------ Calculated body width and height added via CutyPrint CSS generator ------ */

View file

@ -27,21 +27,21 @@
]]>
</zscript>
<window border="normal" title="${i18n:_('Reassigning')}"
apply="${controllerForReassigning}">
<window border="none" title="${i18n:_('Reassigning')}"
apply="${controllerForReassigning}" width="300px">
<groupbox mold="3d" style="margin-top: 5px" closable="false">
<caption label="${i18n:_('Reassigning type')}:" />
<hbox>
<radiogroup id="reassigningTypeSelector">
<grid id="reassigningTypesGrid">
<groupbox closable="false">
<caption label="${i18n:_('Reassigning type')}" />
<vbox width="100%">
<radiogroup id="reassigningTypeSelector" width="100%">
<grid id="reassigningTypesGrid" fixedLayout="true" width="100%">
<columns>
<column />
<column width="100%"/>
</columns>
</grid>
</radiogroup>
<datebox id="associatedDate" />
</hbox>
</vbox>
</groupbox>
<hbox>

Some files were not shown because too many files have changed in this diff Show more