Merge branch 'master' into expenses-tracking

This commit is contained in:
Susana Montes Pedreira 2012-05-07 12:50:03 +01:00
commit d7ca618627
228 changed files with 53484 additions and 2862 deletions

View file

@ -42,6 +42,7 @@ Translators
Diego Pino García <dpino@igalia.com>
* [it] Giuseppe Zizza <gzizza@gmail.com>
* [nl] Jeroen Baten <jeroen@jeroenbaten.nl>
* [pl] Krzysztof Kamecki <dwerens90@gmail.com>
* [pt] Helena Grosso <lenagrosso@gmail.com>,
Joaquim Rocha <jrocha@igalia.com>
* [ru] Pavel Rudensky <prudensky@gmail.com>

38
HACKING
View file

@ -351,6 +351,44 @@ command. For example:
mvn -Pprod,postgresql clean install
Compilation options
-------------------
In LibrePlan there are two custom Maven properties, which allow you to configure
some small bits in the project.
* *default.passwordsControl* - Warning about default passwords (``true`` by
default)
If this option is enabled, a warning is show in LibrePlan footer to
application administrators in order to change the default password (which
matches with user login) for the users created by default: admin, user,
wsreader and wswriter.
* *default.exampleUsersDisabled* - Disable default users (``true`` by default)
If true, example default users such as user, wsreader and wswriter are
disabled. This is a good option for production environments.
This option is set to ``false`` if you are using the development profile (the
default one).
How to set compilation options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Maven properties have a default value, but you can change it using the parameter
``-D`` for Maven command to set the value of each option you want to modify. For
example:
* Set *default.passwordsControl* to ``false``::
mvn -Ddefault.passwordsControl=false clean install
* Set *default.passwordsControl* and *default.exampleUsersDisabled* to false::
mvn -Ddefault.passwordsControl=false -Ddefault.exampleUsersDisabled=false clean install
Tests
-----

View file

@ -46,7 +46,7 @@ Instructions:
* Download the package::
$ wget http://downloads.sourceforge.net/project/libreplan/files/LibrePlan/libreplan_1.2.0-1_amd64.deb
$ wget http://downloads.sourceforge.net/project/libreplan/LibrePlan/libreplan_1.2.0-1_amd64.deb
* Install package::

173
NEWS
View file

@ -1,6 +1,179 @@
NEWS
====
Version 1.2.3 (19 Apr 2012)
---------------------------
Summary
~~~~~~~
A new minor version of the LibrePlan 1.2.* version family. The main changes
included in this new release are:
* Money based cost monitoring system: This is a new feature that allows users to
monitor the project cost based on the money spent comparing it to the budget.
Users can configure the budget for each task and, after this, LibrePlan
calculates the cost in money already spent using the worked time tracked, the
type of worked hours (standard, overtime,...) and the cost of each resource
hour according to the value defined by the cost category the worker belongs.
* Polish language: LibrePlan is now translated into Polish thanks to the work
done by Krzysztof Kamecki.
* Other minor enhancements and bugfixing:
* Fixed database synchronization issues which appeared on changing planning
points in the WBS. The problems arose when planning points were moved from
children to their parents or vice versa.
* Default users (user, wsreader and wswriter) are disabled by default.
* Fixed resource usage grouped by criteria load analysis that was being bad
calculated inside a project.
* Task duration was not being refreshed properly when doing an allocation and
you needed to apply the allocation twice to see it right.
* START_IN_FIXED_DATE constraint caused that the project duration was bad
calculated in company view.
Notes
~~~~~
.. WARNING::
Remove web browser cache to avoid any problem with changes in JavaScript
resources.
If you are upgrading from any 1.1.x version without using the Debian package,
you will need to manually execute on your database the SQL sentences from files:
``scripts/database/upgrade_1.2.0.sql``, ``scripts/database/upgrade_1.2.1.sql``,
``scripts/database/upgrade_1.2.2.sql`` and ``scripts/database/upgrade_1.2.3.sql``.
If you are upgrading from 1.2.0 version without using the Debian package,
you will need to manually execute on your database the SQL sentences from files:
``scripts/database/upgrade_1.2.1.sql``, ``scripts/database/upgrade_1.2.2.sql``
and ``scripts/database/upgrade_1.2.3.sql``.
If you are upgrading from 1.2.1 version without using the Debian package,
you will need to manually execute on your database the SQL sentences from files:
``scripts/database/upgrade_1.2.2.sql`` and ``scripts/database/upgrade_1.2.3.sql``.
If you are upgrading from 1.2.2 version without using the Debian package,
you will need to manually execute on your database the SQL sentences from file:
``scripts/database/upgrade_1.2.3.sql``.
Contributors
~~~~~~~~~~~~
Thanks to all the contributors to this new version:
* Jacobo Aragunde Pérez
* Óscar González Fernández
* Susana Montes Pedreira
* Francisco Javier Morán Rúa
* Manuel Rego Casasnovas
* Lorenzo Tilve Álvaro
Translators
~~~~~~~~~~~
Thanks to all the translators in this new version:
* [es] Manuel Rego Casasnovas
* [fr] Philippe Poumaroux
* [gl] Manuel Rego Casasnovas
* [it] Giuseppe Zizza
* [nl] Jeroen Baten
* [pl] Krzysztof Kamecki
Changes
~~~~~~~
* Bug #1417: Add UI validation to prevent empty codes
* doc: Update AUTHORS file info about new Polish translator
* i18n: Add Polish language to enum and modify pom.xml to use English userguide
* i18n: Add Polish translation
* Bug #1358: Removed unnecessary tooltip string
* Bug #1358: Added CSS max dimensions restriction to configured company logo
* Fixed vertical positioning of resources string next to containers
* Bug #1407: Run TaskComponent.updateProperties() after running the scheduling algorithm.
* Remove unused fields in Order Costs Per Resource Report
* Bug #1412: Fix problem converting to string clockStart and clockFinish
* Bug #1409: Rename RelatedWithAnyOf to RelatedWith
* Bug #1409: Fix problem replacing allocations for the ones related to the criterion
* Revert "Bug #1320: When asking a container for start constraints, return the leftmost"
* Bug #1411: Missing Spanish translation for "Project cost by resource"
* Fix Sahi test due to change in string
* i18n: Update Dutch translation
* i18n: Update French translation
* doc: Update HACKING file about the compilation options
* Add new compilation option to disable default users (user, wsreader and wswriter)
* Bug #1395: Fix issue setting width of date boxes to 100px
* i18n: Update Italian translation
* i18n: Update Spanish and Galician translations
* i18n: Update keys.pot files
* Bug #1402: Invalidate the TaskComponents instead of the whole GanttPanel
* Bug #1349: Fix translation issue in choosing template pop-up
* Bug #1349: Mark to translate exception day type
* Bug #1349: Fix translation in calendar type
* Bug #1298: Mark to translate roles in user and profile edition
* Remove CutyCaptTimeout
* Bug #1406: Add UI validation for name field too
* Bug #1406: Add validation in the UI and also a try catch for possible ValidationExceptions
* doc: Fix typo in INSTALL file
* doc: Fix broke link in INSTALL file
* doc: Update information about how to install in Fedora and openSUSE
* doc: Add info about JAVA_OPTS configuration in INSTALL file
* [Bug #1234] Fix the deletion of fields in progress reporting in subcontractor module.
* Fix problems in Liquibase changes in MySQL
* Fix compilation error in previous merge
* Merge branch 'libreplan-1.2' into money-cost-monitoring-system
* doc: Add info about add-apt-repository command in INSTALL file
* Bug #1387: Code refactor of the previous patches for this bug.
* Bug #1387: Fix bug when it happens in the opposite way.
* Show budget information in a read-only field inside task properties tab
* Bug #1387: Fix bug
* Change color of money cost bar to a darker one to avoid accessibility issues
* Bug #1403: Only regenerate codes if isCodeAutogenerated() is true
* Add a map in MoneyCostCalculator to cache calculated values
* Disable Money Cost Bar in company view to avoid performance issues
* Bug #1289: Added subcontractor name to tasks when showing resources is enabled
* Remove unneeded throws in MoneyCostCalculatorTest
* Add unit tests to check MoneyCostCalculator with a different type of hours
* Remove commented lines in MoneyCostCalculatorTest
* Update Copyright info in user documentation
* Improve sentence in "Imputed hours" tab editing a task
* Add information about budget in "Imputed hours" tab
* Add unit tests to check MoneyCostCalculator with a tree of tasks
* Remove unused parameters in CutyPrint.createCSSFile
* Add option to print money cost bar
* Add a new test case to check MoneyCostCalculator when there is not relationship via cost category
* Prevent possible rounding problems dividing BigDecimals
* Prevent NPE if there is not relationship between resource and type of hours via cost category
* Reload budget field in "General data" of templates
* Add field in "General data" tab to show the project budget
* Print Money Cost Bar proportinal to task size
* Prevent NPE calculating money cost for a TaskElement
* Remove method getMoneyCostBarPercentage from ITaskFundamentalProperties
* Improve tooltip message using budget, consumed money and percentage
* Using the new MoneyCostCalculator to print the new Money Cost bar
* Implement money cost calculation in a new class called MoneyCostCalculator
* Fix Money Cost Bar position in containers
* Add money cost percentage in the tooltip
* Change CSS for the money cost bar and reported hours bar
* Change icon for the new money cost bar
* Add new money cost bar at this moment using value, icon and color of reported hours
* doc: Update Fedora and openSUSE documentation for upgrade LibrePlan
* Merge branch 'libreplan-1.2' into money-cost-monitoring-system
* Fix typo in "Interporlation" (extra r)
* doc: Fix date format in on version at NEWS file
* Add no negative constraint in budget fields in edition forms
* Add budget field in order element template edition form
* Use budget field when creating a template from a task or vice versa
* Add budget field in order element details form
* Add budget cell in WBS
* Add new field budget to OrderLineTemplate
* Add basic tests for new attribute budget
* Add new field budget to OrderLine
Version 1.2.2 (15 Mar 2012)
---------------------------

View file

@ -1 +1 @@
1.2.2
1.2.3

6
debian/changelog vendored
View file

@ -1,3 +1,9 @@
libreplan (1.2.3-1) squeeze; urgency=low
* Released LibrePlan 1.2.3
-- Jacobo Aragunde Pérez <jaragunde@igalia.com> Wed, 18 Apr 2012 17:49:00 +0100
libreplan (1.2.2-1) squeeze; urgency=low
* Released LibrePlan 1.2.2

View file

@ -6,3 +6,4 @@ debian/tmp/usr/share/dbconfig-common/data/libreplan/upgrade/pgsql/1.1.0
debian/tmp/usr/share/dbconfig-common/data/libreplan/upgrade/pgsql/1.2.0
debian/tmp/usr/share/dbconfig-common/data/libreplan/upgrade/pgsql/1.2.1
debian/tmp/usr/share/dbconfig-common/data/libreplan/upgrade/pgsql/1.2.2
debian/tmp/usr/share/dbconfig-common/data/libreplan/upgrade/pgsql/1.2.3

3
debian/rules vendored
View file

@ -90,6 +90,9 @@ install:
# Copy SQL upgrade script for version 1.2.2
$(call CMD,cp $(CURDIR)/scripts/database/upgrade_1.2.2.sql \
$(CURDIR)/debian/tmp/usr/share/dbconfig-common/data/libreplan/upgrade/pgsql/1.2.2)
# Copy SQL upgrade script for version 1.2.3
$(call CMD,cp $(CURDIR)/scripts/database/upgrade_1.2.3.sql \
$(CURDIR)/debian/tmp/usr/share/dbconfig-common/data/libreplan/upgrade/pgsql/1.2.3)
# Install Policy file
$(call CMD,mkdir -p $(CURDIR)/debian/tmp/etc/tomcat6/policy.d)
$(call CMD,cp $(CURDIR)/debian/51libreplan.policy \

View file

@ -29,7 +29,7 @@ a) Clone Git repository (recommended)::
b) Download last version source code::
$ wget http://downloads.sourceforge.net/project/libreplan/files/LibrePlan/libreplan_1.2.0.tar.gz
$ wget http://downloads.sourceforge.net/project/libreplan/LibrePlan/libreplan_1.2.0.tar.gz
$ tar -xzvf libreplan_1.2.0.tar.gz
You should review ``HACKING`` file to check that you have installed all the

View file

@ -77,6 +77,7 @@ Translators
Diego Pino García <dpino@igalia.com>
* [it] Giuseppe Zizza <gzizza@gmail.com>
* [nl] Jeroen Baten <jeroen@jeroenbaten.nl>
* [pl] Krzysztof Kamecki <dwerens90@gmail.com>
* [pt] Helena Grosso <lenagrosso@gmail.com>,
Joaquim Rocha <jrocha@igalia.com>
* [ru] Pavel Rudensky <prudensky@gmail.com>

View file

@ -77,6 +77,7 @@ Traductores
Diego Pino García <dpino@igalia.com>
* [it] Giuseppe Zizza <gzizza@gmail.com>
* [nl] Jeroen Baten <jeroen@jeroenbaten.nl>
* [pl] Krzysztof Kamecki <dwerens90@gmail.com>
* [pt] Helena Grosso <lenagrosso@gmail.com>,
Joaquim Rocha <jrocha@igalia.com>
* [ru] Pavel Rudensky <prudensky@gmail.com>

View file

@ -77,6 +77,7 @@ Traductores
Diego Pino García <dpino@igalia.com>
* [it] Giuseppe Zizza <gzizza@gmail.com>
* [nl] Jeroen Baten <jeroen@jeroenbaten.nl>
* [pl] Krzysztof Kamecki <dwerens90@gmail.com>
* [pt] Helena Grosso <lenagrosso@gmail.com>,
Joaquim Rocha <jrocha@igalia.com>
* [ru] Pavel Rudensky <prudensky@gmail.com>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.libreplan</groupId>
<artifactId>libreplan</artifactId>
<version>1.2.2</version>
<version>1.2.3</version>
</parent>
<artifactId>ganttzk</artifactId>
<packaging>jar</packaging>

View file

@ -388,18 +388,19 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
}
});
} catch (ParseException e) {
getStartDateTextBox().setValue(
dateFormat.format(task.getBeginDate()
.toDayRoundedDate()));
// Do nothing as textbox is rested in the next sentence
}
getStartDateTextBox().setValue(
dateFormat.format(task.getBeginDate().toDayRoundedDate()));
} else if (updatedComponent == getEndDateTextBox()) {
try {
Date newEnd = dateFormat.parse(getEndDateTextBox().getValue());
task.resizeTo(LocalDate.fromDateFields(newEnd));
} catch (ParseException e) {
getEndDateTextBox().setValue(
asString(task.getEndDate().toDayRoundedDate()));
// Do nothing as textbox is rested in the next sentence
}
getEndDateTextBox().setValue(
asString(task.getEndDate().toDayRoundedDate()));
}
planner.updateTooltips();
}

View file

@ -41,6 +41,7 @@ import org.zkoss.ganttz.data.GanttDiagramGraph.IDependenciesEnforcerHookFactory;
import org.zkoss.ganttz.data.GanttDiagramGraph.INotificationAfterDependenciesEnforcement;
import org.zkoss.ganttz.data.constraint.Constraint;
import org.zkoss.ganttz.data.constraint.Constraint.IConstraintViolationListener;
import org.zkoss.ganttz.extensions.IContextWithPlannerTask;
import org.zkoss.ganttz.util.ConstraintViolationNotificator;
import org.zkoss.ganttz.util.WeakReferencedListeners.Mode;
@ -471,6 +472,16 @@ public abstract class Task implements ITaskFundamentalProperties {
}
}
public static void reloadResourcesText(IContextWithPlannerTask<?> context) {
Task task = context.getTask();
task.reloadResourcesText();
List<? extends TaskContainer> parents = context.getMapper().getParents(
task);
for (TaskContainer each : parents) {
each.reloadResourcesText();
}
}
public boolean isSubcontracted() {
return fundamentalProperties.isSubcontracted();
}

View file

@ -86,8 +86,8 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
private Listbox listZoomLevels;
private final String FILTER_RESOURCES = _("by resources");
private final String FILTER_CRITERIA = _("by criteria");
private final String FILTER_RESOURCES = _("Resources");
private final String FILTER_CRITERIA = _("Generic allocation criteria");
private String feedBackMessage;
private Boolean filterbyResources;

View file

@ -10,10 +10,10 @@
# Manuel Rego Casasnovas <rego@igalia.com>, 2010, 2011, 2012.
msgid ""
msgstr ""
"Project-Id-Version: 1.2.1\n"
"Project-Id-Version: libreplan-1.2.3\n"
"Report-Msgid-Bugs-To: http://bugs.libreplan.org/\n"
"POT-Creation-Date: 2012-01-13 16:49+0100\n"
"PO-Revision-Date: 2012-01-13 16:00+0000\n"
"POT-Creation-Date: 2012-04-11 08:32+0200\n"
"PO-Revision-Date: 2012-04-11 08:35+0000\n"
"Last-Translator: Manuel Rego Casasnovas <rego@igalia.com>\n"
"Language-Team: Español\n"
"MIME-Version: 1.0\n"
@ -22,12 +22,12 @@ msgstr ""
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:215
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:234
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:216
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:235
msgid "Erase"
msgstr "Borrar"
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:300
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:299
msgid "Add Dependency"
msgstr "Añadir dependencia"
@ -35,11 +35,15 @@ msgstr "Añadir dependencia"
msgid "Worker"
msgstr "Trabajador"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:682
msgid "Show money cost bar"
msgstr "Mostrar barra de coste monetario"
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
msgid "Start"
msgstr "Inicio"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:635
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:661
msgid "Show reported hours"
msgstr "Mostrar horas reportadas"
@ -64,7 +68,7 @@ msgstr "Recursos limitantes"
msgid "The specified dependency is not allowed"
msgstr "La dependencia especificada no está permitida"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:254
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:255
msgid "Set End-End"
msgstr "Definir Fin-Fin"
@ -88,6 +92,10 @@ msgstr "esfuerzo disponible: {0}, esfuerzo asignado: {1}"
msgid "Criterion"
msgstr "Criterio"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:688
msgid "Hide money cost bar"
msgstr "Ocultar barra de coste monetario"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:44
msgid "Print"
msgstr "Imprimir"
@ -116,6 +124,10 @@ msgstr "Fin"
msgid "changing zoom"
msgstr "cambiando zoom"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:91
msgid "Show/Hide money cost bar"
msgstr "Mostrar/Ocultar barra de coste monetario"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
msgid "Quarter"
msgstr "Trimestre"
@ -141,7 +153,7 @@ msgstr "Nombre"
msgid "Name filter"
msgstr "Filtro por nombres"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:615
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:641
msgid "Show progress"
msgstr "Mostrar progreso"
@ -153,14 +165,14 @@ msgstr "Expandir/Plegar todo"
msgid "Show/Hide critical path"
msgstr "Mostrar/Ocultar camino crítico"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Año"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:150
msgid "showing criteria"
msgstr "mostrando criterios"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Año"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:58
msgid "Month"
msgstr "Mes"
@ -169,15 +181,15 @@ msgstr "Mes"
msgid "Show/Hide resources"
msgstr "Mostrar/Ocultar recursos"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:246
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:247
msgid "Set End-Start"
msgstr "Definir Fin-Inicio"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:297
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:308
msgid "decreasing zoom"
msgstr "reduciendo zoom"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:596
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:622
msgid "Hide critical path"
msgstr "Ocultar camino crítico"
@ -185,7 +197,7 @@ msgstr "Ocultar camino crítico"
msgid "Day"
msgstr "Día"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:642
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:668
msgid "Hide reported hours"
msgstr "Ocultar horas reportadas"
@ -206,11 +218,11 @@ msgid "Hour"
msgstr "Hora"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:90
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:114
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:120
msgid "Graphics"
msgstr "Gráficas"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:250
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:251
msgid "Set Start-Start"
msgstr "Definir Inicio-Inicio"
@ -218,7 +230,7 @@ msgstr "Definir Inicio-Inicio"
msgid "See resource allocation"
msgstr "Ver asignación de recursos"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:280
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:291
msgid "increasing zoom"
msgstr "aumentando zoom"
@ -234,10 +246,10 @@ msgstr "Todos"
msgid "Refresh"
msgstr "Actualizar"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:591
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:617
msgid "Show critical path"
msgstr "Mostrar camino crítico"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:620
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:646
msgid "Hide progress"
msgstr "Ocultar progreso"

View file

@ -8,10 +8,10 @@
# Philippe Poumaroux <philippe.poumaroux@free.fr>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: 1.2.1\n"
"Project-Id-Version: libreplan-1.2.3\n"
"Report-Msgid-Bugs-To: http://bugs.libreplan.org/\n"
"POT-Creation-Date: 2012-01-13 16:49+0100\n"
"PO-Revision-Date: 2012-01-23 12:36+0000\n"
"POT-Creation-Date: 2012-04-11 08:32+0200\n"
"PO-Revision-Date: 2012-04-11 12:30+0000\n"
"Last-Translator: Philippe Poumaroux <philippe.poumaroux@free.fr>\n"
"Language-Team: Français\n"
"MIME-Version: 1.0\n"
@ -20,12 +20,12 @@ msgstr ""
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:215
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:234
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:216
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:235
msgid "Erase"
msgstr "Supprimer"
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:300
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:299
msgid "Add Dependency"
msgstr "Ajouter une dépendance"
@ -33,11 +33,15 @@ msgstr "Ajouter une dépendance"
msgid "Worker"
msgstr "Travailleur"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:682
msgid "Show money cost bar"
msgstr "Afficher la barre de coût monétaire"
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
msgid "Start"
msgstr "Début"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:635
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:661
msgid "Show reported hours"
msgstr "Afficher les heures comptabilisées"
@ -62,7 +66,7 @@ msgstr "Ressources bloquantes"
msgid "The specified dependency is not allowed"
msgstr "La dépendance indiquée n'est pas disponible"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:254
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:255
msgid "Set End-End"
msgstr "Faire correspondre les achèvements"
@ -86,6 +90,10 @@ msgstr "investissement disponible: {0}, investissement affecté: {1}"
msgid "Criterion"
msgstr "Critère"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:688
msgid "Hide money cost bar"
msgstr "Masquer la barre de coût monétaire"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:44
msgid "Print"
msgstr "Imprimer"
@ -114,6 +122,10 @@ msgstr "Fin"
msgid "changing zoom"
msgstr "Changer le zoom"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:91
msgid "Show/Hide money cost bar"
msgstr "Afficher/Masquer la barre de coût monétaire"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
msgid "Quarter"
msgstr "Trimestre"
@ -139,7 +151,7 @@ msgstr "Nom"
msgid "Name filter"
msgstr "Filtre par nom"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:615
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:641
msgid "Show progress"
msgstr "Monter l'avancement"
@ -151,14 +163,14 @@ msgstr "Déplier/Replier tout"
msgid "Show/Hide critical path"
msgstr "Montrer/Cacher le chemin critique"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Année"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:150
msgid "showing criteria"
msgstr "Montrer les critères"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Année"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:58
msgid "Month"
msgstr "Mois"
@ -167,15 +179,15 @@ msgstr "Mois"
msgid "Show/Hide resources"
msgstr "Montrer/Cacher les ressources"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:246
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:247
msgid "Set End-Start"
msgstr "Ajuster le début sur la fin"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:297
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:308
msgid "decreasing zoom"
msgstr "réduire le zoom"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:596
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:622
msgid "Hide critical path"
msgstr "Cacher le chemin critique"
@ -183,7 +195,7 @@ msgstr "Cacher le chemin critique"
msgid "Day"
msgstr "Jour"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:642
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:668
msgid "Hide reported hours"
msgstr "Cacher les heures comptabilisées"
@ -204,11 +216,11 @@ msgid "Hour"
msgstr "Heure"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:90
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:114
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:120
msgid "Graphics"
msgstr "Graphiques"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:250
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:251
msgid "Set Start-Start"
msgstr "Ajuster sur le début"
@ -216,7 +228,7 @@ msgstr "Ajuster sur le début"
msgid "See resource allocation"
msgstr "Voir l'allocation des ressources"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:280
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:291
msgid "increasing zoom"
msgstr "augmenter le zoom"
@ -232,10 +244,10 @@ msgstr "Tout"
msgid "Refresh"
msgstr "Rafraîchir"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:591
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:617
msgid "Show critical path"
msgstr "Montrer le chemin critique"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:620
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:646
msgid "Hide progress"
msgstr "Cacher l'avancement"

View file

@ -10,11 +10,11 @@
# Manuel Rego Casasnovas <rego@igalia.com>, 2010, 2011, 2012.
msgid ""
msgstr ""
"Project-Id-Version: 1.2.1\n"
"Project-Id-Version: libreplan-1.2.3\n"
"Report-Msgid-Bugs-To: http://bugs.libreplan.org/\n"
"POT-Creation-Date: 2012-01-13 16:49+0100\n"
"PO-Revision-Date: 2012-01-13 16:01+0000\n"
"Last-Translator: Manuel Rego Casasnovas<rego@igalia.com>\n"
"POT-Creation-Date: 2012-04-11 08:32+0200\n"
"PO-Revision-Date: 2012-04-11 08:34+0000\n"
"Last-Translator: Manuel Rego Casasnovas <rego@igalia.com>\n"
"Language-Team: Galego\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -22,12 +22,12 @@ msgstr ""
"Language: gl\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:215
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:234
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:216
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:235
msgid "Erase"
msgstr "Borrar"
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:300
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:299
msgid "Add Dependency"
msgstr "Engadir dependencia"
@ -35,11 +35,15 @@ msgstr "Engadir dependencia"
msgid "Worker"
msgstr "Traballador"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:682
msgid "Show money cost bar"
msgstr "Mostrar barra de coste monetario"
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
msgid "Start"
msgstr "Inicio"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:635
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:661
msgid "Show reported hours"
msgstr "Mostrar horas reportadas"
@ -64,7 +68,7 @@ msgstr "Recursos limitantes"
msgid "The specified dependency is not allowed"
msgstr "A dependencia especificada non está permitida"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:254
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:255
msgid "Set End-End"
msgstr "Definir Fin-Fin"
@ -88,6 +92,10 @@ msgstr "esforzo dispoñible: {0}, esforzo asignado: {1}"
msgid "Criterion"
msgstr "Criterio"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:688
msgid "Hide money cost bar"
msgstr "Ocultar barra de coste monetario"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:44
msgid "Print"
msgstr "Imprimir"
@ -116,6 +124,10 @@ msgstr "Fin"
msgid "changing zoom"
msgstr "cambiando zoom"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:91
msgid "Show/Hide money cost bar"
msgstr "Mostrar/Ocultar barra de coste monetario"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
msgid "Quarter"
msgstr "Trimestre"
@ -141,7 +153,7 @@ msgstr "Nome"
msgid "Name filter"
msgstr "Filtro por nomes"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:615
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:641
msgid "Show progress"
msgstr "Mostrar progreso"
@ -153,14 +165,14 @@ msgstr "Expandir/Pregar todo"
msgid "Show/Hide critical path"
msgstr "Mostrar/Ocultar camiño crítico"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Ano"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:150
msgid "showing criteria"
msgstr "mostrando criterios"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Ano"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:58
msgid "Month"
msgstr "Mes"
@ -169,15 +181,15 @@ msgstr "Mes"
msgid "Show/Hide resources"
msgstr "Mostrar/Ocultar recursos"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:246
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:247
msgid "Set End-Start"
msgstr "Definir Fin-Inicio"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:297
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:308
msgid "decreasing zoom"
msgstr "reducindo zoom"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:596
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:622
msgid "Hide critical path"
msgstr "Ocultar camiño crítico"
@ -185,7 +197,7 @@ msgstr "Ocultar camiño crítico"
msgid "Day"
msgstr "Día"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:642
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:668
msgid "Hide reported hours"
msgstr "Ocultar horas reportadas"
@ -206,11 +218,11 @@ msgid "Hour"
msgstr "Hora"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:90
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:114
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:120
msgid "Graphics"
msgstr "Gráficas"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:250
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:251
msgid "Set Start-Start"
msgstr "Definir Inicio-Inicio"
@ -218,7 +230,7 @@ msgstr "Definir Inicio-Inicio"
msgid "See resource allocation"
msgstr "Ver asignación de recursoss"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:280
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:291
msgid "increasing zoom"
msgstr "aumentando zoom"
@ -234,10 +246,10 @@ msgstr "Todos"
msgid "Refresh"
msgstr "Actualizar"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:591
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:617
msgid "Show critical path"
msgstr "Mostrar camiño crítico"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:620
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:646
msgid "Hide progress"
msgstr "Ocultar progreso"

View file

@ -8,10 +8,10 @@
# Giuseppe Zizza <gzizza@gmail.com>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: 1.2.1\n"
"Project-Id-Version: libreplan-1.2.3\n"
"Report-Msgid-Bugs-To: http://bugs.libreplan.org/\n"
"POT-Creation-Date: 2012-01-13 16:49+0100\n"
"PO-Revision-Date: 2012-01-13 16:09+0000\n"
"POT-Creation-Date: 2012-04-11 08:32+0200\n"
"PO-Revision-Date: 2012-04-11 08:05+0000\n"
"Last-Translator: Giuseppe Zizza <gzizza@gmail.com>\n"
"Language-Team: Italiano\n"
"MIME-Version: 1.0\n"
@ -20,12 +20,12 @@ msgstr ""
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:215
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:234
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:216
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:235
msgid "Erase"
msgstr "Cancella"
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:300
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:299
msgid "Add Dependency"
msgstr "Aggiungi dipendenza"
@ -33,11 +33,15 @@ msgstr "Aggiungi dipendenza"
msgid "Worker"
msgstr "Lavoratore"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:682
msgid "Show money cost bar"
msgstr "Mostra la barra dei costi"
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
msgid "Start"
msgstr "Inizio"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:635
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:661
msgid "Show reported hours"
msgstr "Mostra le ore riportate"
@ -62,7 +66,7 @@ msgstr "Risorse limitanti"
msgid "The specified dependency is not allowed"
msgstr "La dipendenza specifica non è permessa"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:254
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:255
msgid "Set End-End"
msgstr "Imposta Fine-Fine"
@ -86,6 +90,10 @@ msgstr "Forza disponbile: {0}, forza assegnata: {1}"
msgid "Criterion"
msgstr "Criterio"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:688
msgid "Hide money cost bar"
msgstr "Nascondi la barra dei costi"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:44
msgid "Print"
msgstr "Stampa"
@ -114,6 +122,10 @@ msgstr "Fine"
msgid "changing zoom"
msgstr "Cambio vista"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:91
msgid "Show/Hide money cost bar"
msgstr "Mostra/Nascondi la barra dei costi"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
msgid "Quarter"
msgstr "Quarto"
@ -139,7 +151,7 @@ msgstr "Nome"
msgid "Name filter"
msgstr "Nome filtro"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:615
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:641
msgid "Show progress"
msgstr "Mostra progresso"
@ -151,14 +163,14 @@ msgstr "Espandi/Riduci tutti"
msgid "Show/Hide critical path"
msgstr "Mostra/Nascondi percorso critico"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Anno"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:150
msgid "showing criteria"
msgstr "Mostro i criteri"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Anno"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:58
msgid "Month"
msgstr "Mese"
@ -167,15 +179,15 @@ msgstr "Mese"
msgid "Show/Hide resources"
msgstr "Mostra/Nascondi risorse"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:246
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:247
msgid "Set End-Start"
msgstr "Imposta Fine-Inizio"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:297
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:308
msgid "decreasing zoom"
msgstr "Riduco ingrandimento"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:596
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:622
msgid "Hide critical path"
msgstr "Nascondi percorso critico"
@ -183,7 +195,7 @@ msgstr "Nascondi percorso critico"
msgid "Day"
msgstr "Giorno"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:642
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:668
msgid "Hide reported hours"
msgstr "Nascondi ore riportate"
@ -204,11 +216,11 @@ msgid "Hour"
msgstr "Ora"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:90
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:114
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:120
msgid "Graphics"
msgstr "Grafici"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:250
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:251
msgid "Set Start-Start"
msgstr "Imposta Inizio-Inizio"
@ -216,7 +228,7 @@ msgstr "Imposta Inizio-Inizio"
msgid "See resource allocation"
msgstr "Mostra allocazione risorse"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:280
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:291
msgid "increasing zoom"
msgstr "Aumento l'ingrandimento"
@ -232,10 +244,10 @@ msgstr "Tutti"
msgid "Refresh"
msgstr "Aggiorna"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:591
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:617
msgid "Show critical path"
msgstr "Mostra percorso critico"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:620
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:646
msgid "Hide progress"
msgstr "Nascondi progresso"

View file

@ -7,9 +7,9 @@
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 1.2.2\n"
"Project-Id-Version: libreplan-1.2.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-02-24 09:08+0100\n"
"POT-Creation-Date: 2012-04-11 08:32+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -31,11 +31,15 @@ msgstr ""
msgid "Worker"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:682
msgid "Show money cost bar"
msgstr ""
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
msgid "Start"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:635
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:661
msgid "Show reported hours"
msgstr ""
@ -84,6 +88,10 @@ msgstr ""
msgid "Criterion"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:688
msgid "Hide money cost bar"
msgstr ""
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:44
msgid "Print"
msgstr ""
@ -112,6 +120,10 @@ msgstr ""
msgid "changing zoom"
msgstr ""
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:91
msgid "Show/Hide money cost bar"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
msgid "Quarter"
msgstr ""
@ -137,7 +149,7 @@ msgstr ""
msgid "Name filter"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:615
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:641
msgid "Show progress"
msgstr ""
@ -149,14 +161,14 @@ msgstr ""
msgid "Show/Hide critical path"
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:150
msgid "showing criteria"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:58
msgid "Month"
msgstr ""
@ -169,11 +181,11 @@ msgstr ""
msgid "Set End-Start"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:297
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:308
msgid "decreasing zoom"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:596
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:622
msgid "Hide critical path"
msgstr ""
@ -181,7 +193,7 @@ msgstr ""
msgid "Day"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:642
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:668
msgid "Hide reported hours"
msgstr ""
@ -202,7 +214,7 @@ msgid "Hour"
msgstr ""
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:90
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:114
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:120
msgid "Graphics"
msgstr ""
@ -214,7 +226,7 @@ msgstr ""
msgid "See resource allocation"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:280
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:291
msgid "increasing zoom"
msgstr ""
@ -230,10 +242,10 @@ msgstr ""
msgid "Refresh"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:591
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:617
msgid "Show critical path"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:620
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:646
msgid "Hide progress"
msgstr ""

View file

@ -8,10 +8,10 @@
# Jeroen Baten <jeroen@jeroenbaten.nl>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: LibrePlan\n"
"Project-Id-Version: libreplan-1.2.3\n"
"Report-Msgid-Bugs-To: http://bugs.libreplan.org/\n"
"POT-Creation-Date: 2012-02-24 09:08+0100\n"
"PO-Revision-Date: 2012-02-29 19:53+0000\n"
"POT-Creation-Date: 2012-04-11 08:32+0200\n"
"PO-Revision-Date: 2012-04-13 14:30+0000\n"
"Last-Translator: Jeroen Baten <jeroen@jeroenbaten.nl>\n"
"Language-Team: Nederlands\n"
"MIME-Version: 1.0\n"
@ -33,11 +33,15 @@ msgstr "Voeg afhankelijkheid toe"
msgid "Worker"
msgstr "Werker"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:682
msgid "Show money cost bar"
msgstr "Toon geldelijke kosten balk"
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
msgid "Start"
msgstr "Start"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:635
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:661
msgid "Show reported hours"
msgstr "Toon gerapporteerde uren"
@ -86,6 +90,10 @@ msgstr "Beschikbare inspanning: {0}, toegewezen inspanning: {1}"
msgid "Criterion"
msgstr "Criterium"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:688
msgid "Hide money cost bar"
msgstr "Verberg geldelijke kosten balk"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:44
msgid "Print"
msgstr "Afdrukken"
@ -114,6 +122,10 @@ msgstr "Einde"
msgid "changing zoom"
msgstr "wijzig zoom"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:91
msgid "Show/Hide money cost bar"
msgstr "Toon/verberg geldelijke kosten balk"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
msgid "Quarter"
msgstr "Kwartaal"
@ -139,7 +151,7 @@ msgstr "Naam"
msgid "Name filter"
msgstr "Naam filter "
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:615
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:641
msgid "Show progress"
msgstr "Toon voortgang"
@ -151,14 +163,14 @@ msgstr "Inklappen/Uitklappen alles"
msgid "Show/Hide critical path"
msgstr "Toon/Verberg kritieke pad"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Jaar"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:150
msgid "showing criteria"
msgstr "tonen criteria"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Jaar"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:58
msgid "Month"
msgstr "Maand"
@ -171,11 +183,11 @@ msgstr "Toon/Verberg resources"
msgid "Set End-Start"
msgstr "Set End-Start"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:297
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:308
msgid "decreasing zoom"
msgstr "uitzoomen"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:596
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:622
msgid "Hide critical path"
msgstr "Verberg kritieke pad"
@ -183,7 +195,7 @@ msgstr "Verberg kritieke pad"
msgid "Day"
msgstr "Dag"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:642
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:668
msgid "Hide reported hours"
msgstr "Verberg gerapporteerde uren"
@ -204,7 +216,7 @@ msgid "Hour"
msgstr "Uur"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:90
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:114
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:120
msgid "Graphics"
msgstr "Graphics"
@ -216,7 +228,7 @@ msgstr "Set Start-Start"
msgid "See resource allocation"
msgstr "Zie resource allocation"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:280
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:291
msgid "increasing zoom"
msgstr "Inzoomen"
@ -232,10 +244,10 @@ msgstr "Alle"
msgid "Refresh"
msgstr "Ververs"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:591
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:617
msgid "Show critical path"
msgstr "Toon kritieke pad"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:620
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:646
msgid "Hide progress"
msgstr "Verberg voortgang"

View file

@ -0,0 +1,253 @@
# LibrePlan - GanttZK module.
# Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
# Desenvolvemento Tecnolóxico de Galicia
# Copyright (C) 2010-2012 Igalia, S.L.
# This file is distributed under the same license as the LibrePlan package.
#
# Translators:
# Krzysztof Kamecki <dwerens90@gmail.com>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: libreplan-1.2.3\n"
"Report-Msgid-Bugs-To: http://bugs.libreplan.org/\n"
"POT-Creation-Date: 2012-04-11 08:32+0200\n"
"PO-Revision-Date: 2012-04-11 06:39+0000\n"
"Last-Translator: Krzysztof Kamecki <dwerens90@gmail.com>\n"
"Language-Team: Polski\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pl\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 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:216
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:235
msgid "Erase"
msgstr "Usuń"
#: ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java:299
msgid "Add Dependency"
msgstr "Dodaj Zależność"
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
msgid "Worker"
msgstr "Pracownik"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:682
msgid "Show money cost bar"
msgstr ""
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:29
msgid "Start"
msgstr "Start"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:661
msgid "Show reported hours"
msgstr "Pokaż zgłaszane godziny"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:90
msgid "by criteria"
msgstr "po kryteriach"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:85
msgid "Show/Hide reported hours"
msgstr "Pokaż/Ukryj zgłaszane godziny"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:35
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:49
msgid "Zoom"
msgstr "Powiększ"
#: ganttzk/src/main/java/org/zkoss/ganttz/TabsRegistry.java:121
msgid "Limiting resources"
msgstr "Ograniczanie zasobów"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:67
msgid "The specified dependency is not allowed"
msgstr "Określony zasób nie jest dozwolony"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:255
msgid "Set End-End"
msgstr "Ustaw End-End"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:78
msgid "Show/Hide progress"
msgstr "Pokaż/Ukryj postęp"
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
msgid "Task"
msgstr "Zadanie"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:89
msgid "by resources"
msgstr "po zasobach"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java:199
msgid "available effort: {0}, assigned effort: {1}"
msgstr "dostępny wysiłek: {0}, przydzielony wysiłek: {1}"
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:64
msgid "Criterion"
msgstr "Kryterium"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:688
msgid "Hide money cost bar"
msgstr ""
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:44
msgid "Print"
msgstr "Drukuj"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:71
msgid "Week"
msgstr "Tydzień"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:501
msgid "filtering by name"
msgstr "filtruj po nazwie"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java:111
msgid "See scheduling"
msgstr "Zobacz planowanie"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:43
msgid "Show"
msgstr "Pokaż"
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:30
msgid "End"
msgstr "Koniec"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java:243
msgid "changing zoom"
msgstr "zmiana przybliżenia"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:91
msgid "Show/Hide money cost bar"
msgstr ""
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:45
msgid "Quarter"
msgstr "Kwartał"
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
msgid "None"
msgstr "Żaden"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:71
msgid "Flatten/Unflatten tree"
msgstr "Płaskie/Rozwinięte drzewo"
#: ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java:58
msgid "Project"
msgstr "Projekt"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:67
#: ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul:28
msgid "Name"
msgstr "Nazwa"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:50
msgid "Name filter"
msgstr "Filtr nazwy"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:641
msgid "Show progress"
msgstr "Pokaż postęp"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:67
msgid "Expand/Collapse all"
msgstr "Rozwiń/Zwiń wszystkie"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:58
msgid "Show/Hide critical path"
msgstr "Pokaż/Ukryj ścieżkę krytyczną"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:150
msgid "showing criteria"
msgstr "pokaż kryteria"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:32
msgid "Year"
msgstr "Rok"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:58
msgid "Month"
msgstr "Miesiąc"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:64
msgid "Show/Hide resources"
msgstr "Pokaż/Ukryj zasoby"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:247
msgid "Set End-Start"
msgstr "Ustaw End-Start"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:308
msgid "decreasing zoom"
msgstr "zmniejszenie powiększenia"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:622
msgid "Hide critical path"
msgstr "ukryj ścieżkę krytyczną"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:84
msgid "Day"
msgstr "Dzień"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:668
msgid "Hide reported hours"
msgstr "Ukryj zgłoszone godziny"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java:193
msgid "Load: {0}%"
msgstr "Ładowanie: {0}%"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:147
msgid "showing resources"
msgstr "pokazuję zasoby"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:61
msgid "Show/Hide labels"
msgstr "Pokaż/Ukryj etykiety"
#: ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java:97
msgid "Hour"
msgstr "Godzina"
#: ganttzk/src/main/resources/web/ganttz/zul/resourcesLoadLayout.zul:90
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:120
msgid "Graphics"
msgstr "Grafika"
#: ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java:251
msgid "Set Start-Start"
msgstr "Ustaw Start-Start"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java:152
msgid "See resource allocation"
msgstr "Pokaż przydział zasobów"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:291
msgid "increasing zoom"
msgstr "powiększ powiększenie"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:467
msgid "Show all elements"
msgstr "Pokaż wszystkie elementy"
#: ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java:466
msgid "All"
msgstr "Wszystko"
#: ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul:38
msgid "Refresh"
msgstr "Odśwież"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:617
msgid "Show critical path"
msgstr "Pokaż ścieżkę krytyczną"
#: ganttzk/src/main/java/org/zkoss/ganttz/Planner.java:646
msgid "Hide progress"
msgstr "Ukryj postęp"

View file

@ -40,17 +40,17 @@ resourcesLoadPanel = self;
<separator/>
<hbox id="additionalFilterInsertionPoint1" />
<separator/>
${ganttzk_i18n:_('Show')}:
<listbox id="listFilters" mold="select" rows="1" width="100px"
<label id="filterByNameLabel">${ganttzk_i18n:_('Page')}:</label>
<combobox id="filterByNameCombo" width="50px"
onChange="resourcesLoadPanel.onSelectFilterByName(self)" />
<separator/>
${ganttzk_i18n:_('Group by')}:
<listbox id="listFilters" mold="select" rows="1" width="150px"
model="${resourcesLoadPanel.filters}"
selectedIndex="0"
onSelect="resourcesLoadPanel.setFilter(self.selectedItem.value);">
</listbox>
<separator/>
<label id="filterByNameLabel">${ganttzk_i18n:_('Name filter')}:</label>
<combobox id="filterByNameCombo" width="50px"
onChange="resourcesLoadPanel.onSelectFilterByName(self)" />
<separator/>
<hbox id="additionalFilterInsertionPoint2" />
</hbox>
</north>

View file

@ -5,7 +5,7 @@
<parent>
<groupId>org.libreplan</groupId>
<artifactId>libreplan</artifactId>
<version>1.2.2</version>
<version>1.2.3</version>
</parent>
<artifactId>libreplan-business</artifactId>
<packaging>jar</packaging>
@ -134,7 +134,7 @@
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>2.0-rc7</version>
<version>2.0.4</version>
<executions>
<execution>
<phase>process-resources</phase>
@ -162,7 +162,7 @@
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>2.0-rc7</version>
<version>2.0.4</version>
<executions>
<execution>
<phase>process-resources</phase>
@ -205,7 +205,7 @@
<pluginExecutionFilter>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<versionRange>[2.0-rc7,)</versionRange>
<versionRange>[2.0.4,)</versionRange>
<goals>
<goal>update</goal>
</goals>

View file

@ -2,6 +2,7 @@
* This file is part of LibrePlan
*
* Copyright (C) 2010-2011 Wireless Galicia, S.L.
* Copyright (C) 2012 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
@ -19,24 +20,29 @@
package org.libreplan.business.common;
import org.libreplan.business.common.daos.IConfigurationDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.lang.BooleanUtils;
/**
* It contains the compiling option to disable the warning changing default
* password and implements of singleton pattern.
* This is a singleton that contains the compilation options passed from Maven.
*
* Currently we have two options:
* <ul>
* <li>Enable/Disable the warning changing default password</li>
* <li>Enable/Disable default users (such as user, wsreader and wswriter)</li>
* </ul>
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public class Configuration {
private static final Configuration singleton = new Configuration();
@Autowired
private IConfigurationDAO configurationDAO;
private Boolean defaultPasswordsControl;
private Boolean exampleUsersDisabled;
private Configuration() {
}
@ -61,4 +67,19 @@ public class Configuration {
return defaultPasswordsControl;
}
public void setExampleUsersDisabled(Boolean exampleUsersDisabled) {
this.exampleUsersDisabled = exampleUsersDisabled;
}
public Boolean getExampleUsersDisabled() {
return exampleUsersDisabled;
}
/**
* Returns the value of example users disabled compilation option
*/
public static boolean isExampleUsersDisabled() {
return BooleanUtils.isNotFalse(singleton.getExampleUsersDisabled());
}
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -34,6 +34,7 @@ import org.libreplan.business.common.BaseEntity;
* @author Manuel Rego Casasnovas <mrego@igalia.com>
* @author Cristina Alvarino Perez <cristina.alvarino@comtecsf.es>
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
public class Configuration extends BaseEntity {
@ -93,6 +94,13 @@ public class Configuration extends BaseEntity {
private Boolean generateCodeForExpenseSheets = true;
/**
* Currency code according to ISO-4217 (3 letters)
*/
private String currencyCode = "EUR";
private String currencySymbol = "";
public void setDefaultCalendar(BaseCalendar defaultCalendar) {
this.defaultCalendar = defaultCalendar;
}
@ -373,4 +381,22 @@ public class Configuration extends BaseEntity {
this.allowToGatherUsageStatsEnabled = allowToGatherUsageStatsEnabled;
}
@NotNull(message = "currency code not specified")
public String getCurrencyCode() {
return currencyCode;
}
public void setCurrencyCode(String currencyCode) {
this.currencyCode = currencyCode;
}
@NotNull(message = "currency symbol not specified")
public String getCurrencySymbol() {
return currencySymbol;
}
public void setCurrencySymbol(String currencySymbol) {
this.currencySymbol = currencySymbol;
}
}

View file

@ -27,8 +27,6 @@ import org.hibernate.validator.NotEmpty;
*/
public class InfoComponent {
private String code;
private String name;
private String description;
@ -36,15 +34,6 @@ public class InfoComponent {
public InfoComponent() {
}
public void setCode(String code) {
this.code = code;
}
@NotEmpty(message = "code not specified")
public String getCode() {
return code;
}
public void setName(String name) {
this.name = name;
}
@ -64,7 +53,6 @@ public class InfoComponent {
public InfoComponent copy() {
InfoComponent result = new InfoComponent();
result.setCode(getCode());
result.setName(getName());
result.setDescription(getDescription());
return result;

View file

@ -0,0 +1,47 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 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.libreplan.business.orders.entities;
import org.hibernate.validator.NotEmpty;
/**
* @author Jacobo Aragunde Pérez <jaragunde@igalia.com>
*/
public class InfoComponentWithCode extends InfoComponent {
private String code;
public void setCode(String code) {
this.code = code;
}
@NotEmpty(message = "code not specified")
public String getCode() {
return code;
}
public InfoComponentWithCode copy() {
InfoComponentWithCode result = new InfoComponentWithCode();
result.setCode(getCode());
result.setName(getName());
result.setDescription(getDescription());
return result;
}
}

View file

@ -75,7 +75,7 @@ import org.libreplan.business.workreports.entities.WorkReportLine;
public abstract class OrderElement extends IntegrationEntity implements
ICriterionRequirable, ITreeNode<OrderElement> {
protected InfoComponent infoComponent = new InfoComponent();
protected InfoComponentWithCode infoComponent = new InfoComponentWithCode();
private Date initDate;
@ -1269,9 +1269,9 @@ public abstract class OrderElement extends IntegrationEntity implements
}
@Valid
public InfoComponent getInfoComponent() {
public InfoComponentWithCode getInfoComponent() {
if (infoComponent == null) {
infoComponent = new InfoComponent();
infoComponent = new InfoComponentWithCode();
}
return infoComponent;
}

View file

@ -209,9 +209,40 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
public static AllocationsSpecified allocating(
List<ResourcesPerDayModification> resourceAllocations) {
sortResourceAllocations(resourceAllocations);
return new AllocationsSpecified(resourceAllocations);
}
/**
* Specific allocations should be done first in order to generic allocations
* selects the less charged resources if there are several allocations in
* the same task
*
* @param resourceAllocations
* Sorted with specific allocations before generic ones
*/
private static void sortResourceAllocations(
List<ResourcesPerDayModification> resourceAllocations) {
Collections.sort(resourceAllocations,
new Comparator<ResourcesPerDayModification>() {
@Override
public int compare(ResourcesPerDayModification o1,
ResourcesPerDayModification o2) {
if (o1.isSpecific() && o2.isSpecific()) {
return 0;
}
if (o1.isSpecific()) {
return -1;
}
if (o2.isSpecific()) {
return 1;
}
return 0;
}
});
}
private static void checkStartLessOrEqualToEnd(IntraDayDate startInclusive,
IntraDayDate endExclusive) {
Validate.isTrue(startInclusive.compareTo(endExclusive) <= 0,
@ -2123,7 +2154,7 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
getDayAssignmentsState().detachAssignments();
}
void associateAssignmentsToResource() {
public void associateAssignmentsToResource() {
for (DayAssignment dayAssignment : getAssignments()) {
dayAssignment.associateToResource();
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -73,6 +73,7 @@ import org.libreplan.business.workingday.ResourcesPerDay;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public class Task extends TaskElement implements ITaskPositionConstrained {
@ -1218,4 +1219,10 @@ public class Task extends TaskElement implements ITaskPositionConstrained {
public void resetStatus() {
this.currentStatus = null;
}
@Override
public boolean isAnyTaskWithConstraint(PositionConstraintType type) {
return getPositionConstraint().getConstraintType().equals(type);
}
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -63,6 +63,7 @@ import org.libreplan.business.workingday.ResourcesPerDay;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public abstract class TaskElement extends BaseEntity {
@ -769,4 +770,6 @@ public abstract class TaskElement extends BaseEntity {
return null;
}
public abstract boolean isAnyTaskWithConstraint(PositionConstraintType type);
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -44,6 +44,7 @@ import org.libreplan.business.workingday.IntraDayDate;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Javier Moran Rua <jmoran@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public class TaskGroup extends TaskElement {
@ -376,4 +377,15 @@ public class TaskGroup extends TaskElement {
public void resetStatus() {
this.isFinished = this.isInProgress = null;
}
@Override
public boolean isAnyTaskWithConstraint(PositionConstraintType type) {
for (TaskElement taskElement : getChildren()) {
if (taskElement.isAnyTaskWithConstraint(type)) {
return true;
}
}
return false;
}
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -43,6 +43,7 @@ import org.libreplan.business.workingday.IntraDayDate;
/**
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
* @author Javier Moran Rua <jmoran@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public class TaskMilestone extends TaskElement implements ITaskPositionConstrained {
@ -225,4 +226,9 @@ public class TaskMilestone extends TaskElement implements ITaskPositionConstrain
return false;
}
@Override
public boolean isAnyTaskWithConstraint(PositionConstraintType type) {
return getPositionConstraint().getConstraintType().equals(type);
}
}

View file

@ -127,6 +127,11 @@ public abstract class ResourcesPerDayModification extends
return genericAllocation.createEffortDistributor(getResources());
}
@Override
public boolean isSpecific() {
return false;
}
}
private static class OnSpecificAllocation extends
@ -194,6 +199,11 @@ public abstract class ResourcesPerDayModification extends
return resourceAllocation.createEffortDistributor();
}
@Override
public boolean isSpecific() {
return true;
}
}
public static ResourcesPerDayModification create(
@ -319,4 +329,6 @@ public abstract class ResourcesPerDayModification extends
getBeingModified().getNonConsolidatedResourcePerDay());
}
public abstract boolean isSpecific();
}

View file

@ -29,7 +29,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang.Validate;
import org.joda.time.LocalDate;
@ -89,8 +88,19 @@ public abstract class UntilFillingHoursAllocator {
IntraDayDate candidate = untilAllocating(dateFromWhichToAllocate,
each.allocation, each.duration);
currentResult = pickCurrentOrCandidate(currentResult, candidate);
setNewDataForAllocation(each.allocation, currentResult);
// This is done in order that new assignments are taken into account
// for the next allocations in the same task
each.allocation.getResourceAllocation()
.associateAssignmentsToResource();
}
setAssignmentsForEachAllocation(currentResult);
// Then we detach the day assignments as they are going to be associated
// again later
for (EffortPerAllocation each : effortPerAllocation) {
each.allocation.getResourceAllocation().detach();
}
return currentResult;
}
@ -228,22 +238,16 @@ public abstract class UntilFillingHoursAllocator {
}
}
private void setAssignmentsForEachAllocation(IntraDayDate resultDate) {
for (Entry<ResourcesPerDayModification, List<DayAssignment>> entry : resultAssignments
.entrySet()) {
setNewDataForAllocation(entry, resultDate);
}
}
private <T extends DayAssignment> void setNewDataForAllocation(
Entry<ResourcesPerDayModification, List<DayAssignment>> entry,
ResourcesPerDayModification resourcesPerDayModification,
IntraDayDate resultDate) {
@SuppressWarnings("unchecked")
ResourceAllocation<T> allocation = (ResourceAllocation<T>) entry
.getKey().getBeingModified();
ResourcesPerDay resourcesPerDay = entry.getKey().getGoal();
ResourceAllocation<T> allocation = (ResourceAllocation<T>) resourcesPerDayModification
.getBeingModified();
ResourcesPerDay resourcesPerDay = resourcesPerDayModification.getGoal();
@SuppressWarnings("unchecked")
List<T> value = (List<T>) entry.getValue();
List<T> value = (List<T>) resultAssignments
.get(resourcesPerDayModification);
setNewDataForAllocation(allocation, resultDate, resourcesPerDay,
value);
}

View file

@ -38,9 +38,9 @@ public class HoursWorkedPerResourceDTO implements Comparable {
private Date date;
private LocalTime clockStart;
private String clockStart;
private LocalTime clockFinish;
private String clockFinish;
private EffortDuration effort;
@ -59,8 +59,12 @@ public class HoursWorkedPerResourceDTO implements Comparable {
this.workerName = resource.getName();
this.date = workReportLine.getDate();
this.clockStart = workReportLine.getClockStart();
this.clockFinish = workReportLine.getClockFinish();
LocalTime clockStart = workReportLine.getClockStart();
this.clockStart = (clockStart != null) ? clockStart.toString("HH:mm")
: "";
LocalTime clockFinish = workReportLine.getClockFinish();
this.clockFinish = (clockFinish != null) ? clockFinish
.toString("HH:mm") : "";
this.effort = workReportLine.getEffort();
this.orderElementCode = workReportLine.getOrderElement().getCode();
this.orderElementName = workReportLine.getOrderElement().getName();
@ -98,19 +102,19 @@ public class HoursWorkedPerResourceDTO implements Comparable {
this.effort = effort;
}
public LocalTime getClockStart() {
public String getClockStart() {
return clockStart;
}
public void setClockStart(LocalTime clockStart) {
public void setClockStart(String clockStart) {
this.clockStart = clockStart;
}
public LocalTime getClockFinish() {
public String getClockFinish() {
return clockFinish;
}
public void setClockFinish(LocalTime clockFinish) {
public void setClockFinish(String clockFinish) {
this.clockFinish = clockFinish;
}

View file

@ -2,6 +2,7 @@
* This file is part of LibrePlan
*
* Copyright (C) 2011 ComtecSF, S.L.
* Copyright (C) 2012 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
@ -28,6 +29,7 @@ import java.util.Locale;
*
* @author Cristina Alavarino Perez <cristina.alvarino@comtecsf.es>
* @author Ignacio Diaz Teijido <ignacio.diaz@comtecsf.es>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public enum Language {
@ -39,7 +41,8 @@ public enum Language {
PORTUGUESE_LANGUAGE("Português", new Locale("pt")),
ITALIAN_LANGUAGE("Italiano", new Locale("it")),
FRENCH_LANGUAGE("Français", new Locale("fr")),
DUTCH_LANGUAGE("Nederlands", new Locale("nl"));
DUTCH_LANGUAGE("Nederlands", new Locale("nl")),
POLISH_LANGUAGE("Polski", new Locale("pl"));
private final String displayName;

View file

@ -354,14 +354,6 @@ public abstract class OrderElementTemplate extends BaseEntity implements
this.deadlineAsDaysFromBeginning = days;
}
public String getCode() {
return getInfoComponent().getCode();
}
public void setCode(String code) {
getInfoComponent().setCode(code);
}
public String getDescription() {
return getInfoComponent().getDescription();
}
@ -384,7 +376,6 @@ public abstract class OrderElementTemplate extends BaseEntity implements
}
protected void copyTo(OrderElementTemplate result) {
result.setCode(getCode());
result.setName(getName());
result.setDescription(getDescription());
result.setDeadlineAsDaysFromBeginning(getDeadlineAsDaysFromBeginning());

View file

@ -58,16 +58,30 @@
columnDataType="BOOLEAN" />
</changeSet>
<changeSet id="change-column-description-in-order_element-to-text" author="mrego">
<changeSet id="change-column-description-in-order_element-to-text"
author="mrego" dbms="postgresql">
<comment>Change column description in order_element to TEXT</comment>
<modifyDataType tableName="order_element" columnName="description" newDataType="TEXT" />
</changeSet>
<changeSet id="change-column-description-in-order_element_template-to-text" author="mrego">
<changeSet id="change-column-description-in-order_element_template-to-text"
author="mrego" dbms="postgresql">
<comment>Change column description in order_element_template to TEXT</comment>
<modifyDataType tableName="order_element_template" columnName="description" newDataType="TEXT" />
</changeSet>
<changeSet id="change-column-description-in-to-text-in-mysql"
author="mrego" dbms="mysql">
<comment>
Change column description in order_element and
order_element_template to TEXT in MySQL.
Because of using modifyDataType convert the column in LONGTEXT and
this is causing some problems with Hibernate mapping.
</comment>
<sql>ALTER TABLE order_element MODIFY description TEXT</sql>
<sql>ALTER TABLE order_element_template MODIFY description TEXT</sql>
</changeSet>
<changeSet id="add-budget-column-to-order_line" author="mrego">
<comment>add budget column to order_line</comment>
<addColumn tableName="order_line">
@ -254,4 +268,32 @@
baseTableName="sum_expenses" baseColumnNames="order_element_id"
referencedTableName="order_element" referencedColumnNames="id" />
</changeSet>
<changeSet id="add-new-columns-for-currency-in-configuration" author="mrego">
<comment>Add new columns for currency in configuration table</comment>
<addColumn tableName="configuration">
<column name="currency_code" type="VARCHAR(255)" />
</addColumn>
<addDefaultValue tableName="configuration" columnName="currency_code"
defaultValue="EUR" />
<addNotNullConstraint tableName="configuration"
columnName="currency_code"
defaultNullValue="EUR"
columnDataType="VARCHAR(255)" />
<addColumn tableName="configuration">
<column name="currency_symbol" type="VARCHAR(255)" />
</addColumn>
<addDefaultValue tableName="configuration" columnName="currency_symbol"
defaultValue="€" />
<addNotNullConstraint tableName="configuration"
columnName="currency_symbol"
defaultNullValue="€"
columnDataType="VARCHAR(255)" />
</changeSet>
<changeSet id="remove-code-from-order_element_template" author="jaragunde">
<comment>Remove column code in order_element_template table</comment>
<dropColumn tableName="order_element_template" columnName="code" />
</changeSet>
</databaseChangeLog>

View file

@ -144,7 +144,10 @@
factory-method="getInstance"
lazy-init="false">
<property name="defaultPasswordsControl">
<value>${default.passwordsControl}</value>
<value>${default.passwordsControl}</value>
</property>
<property name="exampleUsersDisabled">
<value>${default.exampleUsersDisabled}</value>
</property>
</bean>

View file

@ -68,6 +68,9 @@
<property name="scenariosVisible" not-null="true"
column="scenarios_visible" />
<property name="currencyCode" not-null="true" column="currency_code" />
<property name="currencySymbol" not-null="true" column="currency_symbol" />
<component name="ldapConfiguration" class="org.libreplan.business.common.entities.LDAPConfiguration">
<property name="ldapHost" column="ldap_Host"/>
<property name="ldapPort" column="ldap_port"/>

View file

@ -8,7 +8,7 @@
</generator>
</id>
<version name="version" access="property" type="long" />
<component name="infoComponent" class="org.libreplan.business.orders.entities.InfoComponent">
<component name="infoComponent" class="org.libreplan.business.orders.entities.InfoComponentWithCode">
<property name="name" access="field" />
<property name="description" access="field" type="text" />
<property name="code" access="field" unique="true" />

View file

@ -12,7 +12,6 @@
<component name="infoComponent" class="org.libreplan.business.orders.entities.InfoComponent">
<property name="name" access="field" />
<property name="description" access="field" type="text" />
<property name="code" access="field"/>
</component>
<property name="startAsDaysFromBeginning"
column="start_as_days_from_beginning" />

View file

@ -22,7 +22,6 @@
package org.libreplan.business.test.planner.entities;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.getCurrentArguments;
import static org.easymock.EasyMock.isA;
@ -778,7 +777,7 @@ public class GenericResourceAllocationTest {
givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(8, 6, 2);
IntraDayDate end = ResourceAllocation.allocating(
singletonList(ResourcesPerDayModification.create(
Arrays.asList(ResourcesPerDayModification.create(
genericResourceAllocation,
ResourcesPerDay.amount(new BigDecimal(1)), workers)))
.untilAllocating(hours(12));
@ -798,7 +797,7 @@ public class GenericResourceAllocationTest {
givenGenericResourceAllocationForTask(task);
givenWorkersWithLoads(8, 2, 6);
IntraDayDate end = ResourceAllocation.allocating(
singletonList(ResourcesPerDayModification.create(
Arrays.asList(ResourcesPerDayModification.create(
genericResourceAllocation, ResourcesPerDay.amount(1),
workers))).untilAllocating(hours(16));
assertThat(end.getDate(), equalTo(start.plusDays(2)));

View file

@ -412,12 +412,11 @@ public class UntilFillingHoursAllocatorTest {
givenSpecificAllocations(ResourcesPerDay.amount(1), ResourcesPerDay
.amount(1));
ResourceAllocation.allocating(allocations).untilAllocating(hours(64));
ResourceAllocation<?> generic = allocations.get(0)
ResourceAllocation<?> firstSpecific = allocations.get(0)
.getBeingModified();
ResourceAllocation<?> firstSpecific = allocations.get(1)
.getBeingModified();
ResourceAllocation<?> secondSpecific = allocations.get(2)
ResourceAllocation<?> secondSpecific = allocations.get(1)
.getBeingModified();
ResourceAllocation<?> generic = allocations.get(2).getBeingModified();
assertThat(generic.getAssignments(), haveHours(16, 16));
assertThat(firstSpecific.getAssignments(), haveHours(8, 8));
assertThat(secondSpecific.getAssignments(), haveHours(8, 8));

View file

@ -4,7 +4,7 @@
<parent>
<groupId>org.libreplan</groupId>
<artifactId>libreplan</artifactId>
<version>1.2.2</version>
<version>1.2.3</version>
</parent>
<artifactId>libreplan-webapp</artifactId>
<packaging>war</packaging>
@ -126,6 +126,9 @@
<copy todir="src/main/webapp/help/nl" failonerror="false">
<fileset dir="../doc/src/user/en/html"/>
</copy>
<copy todir="src/main/webapp/help/pl" failonerror="false">
<fileset dir="../doc/src/user/en/html"/>
</copy>
</tasks>
</configuration>
</execution>
@ -434,5 +437,10 @@
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-jdk1.5</artifactId>
</dependency>
<!-- jqPlot -->
<dependency>
<groupId>br.com.digilabs.jqplot</groupId>
<artifactId>jqplot4java</artifactId>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,16 @@
# Locale for completedEstimatedHours.jrxml
title = Raport godzin
subtitle = Zrealizowane szacowane godziny
order = Projekt \:
reference = Data referencyjna \:
criteria = Kryteria \:
labels = Etykiety \:
headers.column1 = Nazwa
headers.column2 = Wszystkie godziny
headers.column2.column1 = Szacowany
headers.column2.column2 = Planowany
headers.column3 = Godziny do tej pory
headers.column3.column1 = Planowany
headers.column3.column2 = Realny
page = strona
of = z

View file

@ -0,0 +1,11 @@
# Locale for hoursWorkedPerWorkerReportInAMonth.jrxml
title = Raport pracy
subtitle = Raport pracy wed\u0142ug zasobów w miesi\u0105cu
parameters.year = Rok\:
parameters.month = Miesi\u0105c\:
headers.column1 = Nazwa
headers.column2 = Godziny
total.hours = Wszystkie godziny\:
note1 = Brak raportów pracy dla zaznaczonych zasobów w tym zakresie wyszukiwania.
page = strona
of = z

View file

@ -9,8 +9,8 @@
<parameter name="labels" class="java.lang.String"/>
<field name="workerName" class="java.lang.String"/>
<field name="date" class="java.util.Date"/>
<field name="clockStart" class="java.util.Date"/>
<field name="clockFinish" class="java.util.Date"/>
<field name="clockStart" class="java.lang.String"/>
<field name="clockFinish" class="java.lang.String"/>
<field name="self" class="org.libreplan.business.reports.dtos.HoursWorkedPerResourceDTO"/>
<field name="effort" class="org.libreplan.business.workingday.EffortDuration"/>
<field name="orderElementCode" class="java.lang.String"/>
@ -343,7 +343,7 @@
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.util.Date"><![CDATA[$F{clockFinish}]]></textFieldExpression>
<textFieldExpression class="java.lang.String"><![CDATA[$F{clockFinish}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="116" y="0" width="70" height="30"/>
@ -355,7 +355,7 @@
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.util.Date"><![CDATA[$F{clockStart}]]></textFieldExpression>
<textFieldExpression class="java.lang.String"><![CDATA[$F{clockStart}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="0" y="0" width="116" height="15"/>

View file

@ -0,0 +1,18 @@
# Locale for hoursWorkedPerWorkerReport.jrxml
title = Raport pracy
subtitle = Przepracowane godziny wed\u0142ug zasobów
date.start = Data rozpocz\u0119cia\:
date.end = Data zako\u0144czenia\:
criteria = Kryteria\:
labels = Etykiety\:
headers.column1 = Start
headers.column2 = Zako\u0144czenie
headers.column3 = Godziny
headers.column4 = Kod/nazwa zadania
headers.column5 = Pola tekstowe
headers.column6 = Etykiety
total.day = Wszystkie godziny wed\u0142ug dnia\:
total.worker = Wszystkie godziny wed\u0142ug pracownika\:
note1 = Nie ma raportów pracy dla zaznaczonych zasobów w zakresie wyszukiwania.
page = strona
of = z

View file

@ -9,6 +9,7 @@
<parameter name="labels" class="java.lang.String"/>
<parameter name="subReportWRL" class="java.lang.String"/>
<parameter name="subReportES" class="java.lang.String"/>
<parameter name="currencySymbol" class="java.lang.String"/>
<field name="orderElementCode" class="java.lang.String"/>
<field name="orderName" class="java.lang.String"/>
<field name="orderElementName" class="java.lang.String"/>
@ -60,20 +61,20 @@
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total.time.money}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<textField isBlankWhenNull="true">
<reportElement x="423" y="45" width="130" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalExpenses}]]></textFieldExpression>
<textFieldExpression class="java.lang.String"><![CDATA[$V{sumTotalExpenses}.setScale(2, RoundingMode.HALF_UP) + " " + $P{currencySymbol}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="true" pattern="###0.00 h">
<reportElement x="287" y="5" width="135" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalHours}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<textField isBlankWhenNull="true">
<reportElement x="423" y="65" width="130" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalCosts}]]></textFieldExpression>
<textFieldExpression class="java.lang.String"><![CDATA[$V{sumTotalCosts}.setScale(2, RoundingMode.HALF_UP) + " " + $P{currencySymbol}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="287" y="45" width="135" height="20"/>
@ -110,10 +111,10 @@
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$R{total}]]></textFieldExpression>
</textField>
<textField pattern="###0.00 €;-###0.00 €" isBlankWhenNull="true">
<textField isBlankWhenNull="true">
<reportElement x="423" y="25" width="130" height="20"/>
<textElement textAlignment="Right" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalCostsByHours}]]></textFieldExpression>
<textFieldExpression class="java.lang.String"><![CDATA[$V{sumTotalCostsByHours}.setScale(2, RoundingMode.HALF_UP) + " " + $P{currencySymbol}]]></textFieldExpression>
</textField>
</band>
</groupFooter>

View file

@ -1,4 +1,5 @@
# Locale for ordersCostPerResourcesReport.jrxml
<<<<<<< HEAD
title = Project report
subtitle = Costs by Resource
date.start = Starting date:
@ -25,4 +26,22 @@ money.spend.subtitle = Dinero empleado:
total.numhours = Número total de horas:
total.time.money = Por causa de las horas:
total.expense.money = Por causa de los gastos:
total.money = Total:
total.money = Total:
=======
title = Informe del proyecto
subtitle = Costes por recurso
date.start = Fecha de inicio:
date.end = Fecha de fin:
criteria = Criterios:
labels = Etiquetas:
headers.column1 = Tipo de horas
headers.column2 = Fecha
headers.column3 = Salario
headers.column4 = Horas
headers.column5 = Costes
total.task = Total por tarea:
total.worker = Total por trabajador:
total = Total por proyecto:
page = página
of = de
>>>>>>> master

View file

@ -0,0 +1,17 @@
# Locale for ordersCostPerResourcesReport.jrxml
title = Raport projektu
subtitle = Koszty wed\u0142ug zasobu
date.start = Data rozpocz\u0119cia\:
date.end = Data zako\u0144czenia\:
criteria = Kryteria \:
labels = Etykiety \:
headers.column1 = Typ godzin
headers.column2 = Data
headers.column3 = Wynagrodzenie
headers.column4 = Godziny
headers.column5 = Koszty
total.task = Ogó\u0142em na dzie\u0144\:
total.worker = Ogó\u0142em na pracownika\:
total = Ca\u0142kowity projekt\:
page = strona
of = z

View file

@ -0,0 +1,27 @@
# Locale for schedulingProgressPerOrderReport.jrxml
title = Raport post\u0119pu
subtitle = Harmonogram post\u0119pu na projekt
tipo = Typ post\u0119pu\:
order = Projekty\:
date.start = Data rozpocz\u0119cia.
date.end = Data zako\u0144czenia\:
date.reference = Data referencyjna\:
headers.column1 = Wszystkie godziny
headers.column1.column1 = Szacowany
headers.column1.column2 = Planowany
headers.column2 = Post\u0119p
headers.column2.column1 = Mierzony
headers.column2.column2 = Kalkulacja
headers.column2.column3 = Planowany
headers.column3 = Godziny do tej pory
headers.column3.column1 = Planowany
headers.column3.column2 = Realny
headers.column4 = Ró\u017cnica
headers.column4.column1 = Koszt
headers.column4.column2 = Planowany
headers.column4.column3 = Wska\u017anik kosztów
headers.column4.column4 = Planowany wska\u017anik
note1 = Zaznaczony typ post\u0119pu nie jest dost\u0119pny dla tego projektu.
note2 = U\u017cywany rozpowszechniany typ procesu.
page = strona
of = z

View file

@ -5,6 +5,7 @@
<parameter name="endingDate" class="java.util.Date"/>
<parameter name="status" class="java.lang.String"/>
<parameter name="logo" class="java.lang.String"/>
<parameter name="currencySymbol" class="java.lang.String"/>
<field name="status" class="java.lang.String"/>
<field name="code" class="java.lang.String"/>
<field name="name" class="java.lang.String"/>
@ -156,7 +157,7 @@
<textField isBlankWhenNull="true">
<reportElement x="434" y="14" width="72" height="15"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$V{sumTotalPricePerDay}]]></textFieldExpression>
<textFieldExpression class="java.lang.String"><![CDATA[$V{sumTotalPricePerDay}.setScale(2, RoundingMode.HALF_UP) + " " + $P{currencySymbol}]]></textFieldExpression>
</textField>
</band>
</groupFooter>
@ -291,7 +292,7 @@
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{totalPrice}]]></textFieldExpression>
<textFieldExpression class="java.lang.String"><![CDATA[$F{totalPrice}.setScale(2, RoundingMode.HALF_UP) + " " + $P{currencySymbol}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="390" y="0" width="65" height="73"/>
@ -303,7 +304,7 @@
<rightPen lineWidth="1.0"/>
</box>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression class="java.math.BigDecimal"><![CDATA[$F{unitPrice}]]></textFieldExpression>
<textFieldExpression class="java.lang.String"><![CDATA[$F{unitPrice}.setScale(2, RoundingMode.HALF_UP) + " " + $P{currencySymbol}]]></textFieldExpression>
</textField>
<textField isBlankWhenNull="true">
<reportElement x="520" y="0" width="60" height="73">

View file

@ -0,0 +1,17 @@
# Locale for timeLineRequiredMaterial.jrxml
title = Materia\u0142y
subtitle = Linia czasowa materia\u0142ów.
date.start = Data rozpocz\u0119cia\:
date.end = Data zako\u0144czenia\:
status = Status\:
headers.title = Dzie\u0144
headers.column1 = Materia\u0142
headers.column2 = Projekt - Zadanie
headers.column3 = Dost\u0119pno\u015b\u0107
headers.column4 = Jednostki
headers.column5 = Cena jednostkowa
headers.column6 = Cena
headers.column7 = Status
headers.total = Ca\u0142kowita cena za dzie\u0144\:
page = strona
of = z

View file

@ -0,0 +1,28 @@
# Locale for workingArrangementPerOrderReport.jrxml
title = Raport projektu
subtitle = Stan planowania zada\u0144.
order = Projekt\:
status = Status\:
name = Nazwa.
code = Kod\:
criteria = Kryteria \:
labels = Etykiety \:
headers1.column1 = Data rozpocz\u0119cia
headers1.column1.column1 = Szacowany
headers1.column1.column2 = Pierwszy raport
headers1.column2 = Data zako\u0144czenia
headers1.column2.column1 = Szacowany
headers1.column2.column2 = Ostatni raport
headers1.column2.column3 = Ostateczny termin
headers1.column3 = Post\u0119p
headers1.column4 = Status
headers1.column5 = Ostateczny termin
headers2.title = Zale\u017cno\u015bci.
headers2.column1 = Nazwa
headers2.column2 = Kod
headers2.column3 = Typ
headers2.column4 = Post\u0119p
overrun = przekroczenia
intime = W czasie.
page = strona
of = z

View file

@ -0,0 +1,24 @@
# Locale for workingProgressPerTaskReport.jrxml
title = Raport post\u0119pu
subtitle = Post\u0119p pracy wed\u0142ug zadania
order = Projekt
reference = Data odniesienia\:
criteria = Kryteria \:
labels = Etykiety \:
headers.column1 = Wszystkie godziny
headers.column1.column1 = Szacowany
headers.column1.column2 = Planowany
headers.column2 = Post\u0119p
headers.column2.column1 = Mierzony
headers.column2.column2 = Kalkulacja
headers.column2.column3 = Planowany
headers.column3 = Godziny do tej pory
headers.column3.column1 = Planowany
headers.column3.column2 = Realny
headers.column4 = Ró\u017cnica
headers.column4.column1 = Koszt
headers.column4.column2 = Planowany
headers.column4.column3 = Wska\u017anik kosztów
headers.column4.column4 = Planowany wska\u017anik
page = strona
of = z

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -844,4 +844,28 @@ public class ConfigurationController extends GenericForwardComposer {
.setAllowToGatherUsageStatsEnabled(allowToGatherUsageStatsEnabled);
}
public Set<String> getCurrencies() {
return configurationModel.getCurrencies();
}
public ListitemRenderer getCurrencyRenderer() {
return new ListitemRenderer() {
@Override
public void render(Listitem item, Object data) throws Exception {
String currencyCode = (String) data;
item.setLabel(currencyCode + " - "
+ configurationModel.getCurrencySymbol(currencyCode));
item.setValue(currencyCode);
}
};
}
public String getSelectedCurrency() {
return configurationModel.getCurrencyCode();
}
public void setSelectedCurrency(String currencyCode) {
configurationModel.setCurrency(currencyCode);
}
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -25,12 +25,16 @@ import static org.libreplan.web.I18nHelper._;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Currency;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.apache.commons.lang.StringUtils;
import org.libreplan.business.calendars.daos.IBaseCalendarDAO;
import org.libreplan.business.calendars.entities.BaseCalendar;
import org.libreplan.business.common.daos.IConfigurationDAO;
@ -66,6 +70,8 @@ public class ConfigurationModel implements IConfigurationModel {
private Map<EntityNameEnum, List<EntitySequence>> entitySequences = new HashMap<EntityNameEnum, List<EntitySequence>>();
private static Map<String, String> currencies = getAllCurrencies();
@Autowired
private IConfigurationDAO configurationDAO;
@ -572,4 +578,39 @@ public class ConfigurationModel implements IConfigurationModel {
.setAllowToGatherUsageStatsEnabled(allowToGatherUsageStatsEnabled);
}
private static Map<String, String> getAllCurrencies() {
Map<String, String> currencies = new TreeMap<String, String>();
for (Locale locale : Locale.getAvailableLocales()) {
if (StringUtils.isNotBlank(locale.getCountry())) {
Currency currency = Currency.getInstance(locale);
currencies.put(currency.getCurrencyCode(),
currency.getSymbol(locale));
}
}
return currencies;
}
@Override
public Set<String> getCurrencies() {
return currencies.keySet();
}
@Override
public String getCurrencySymbol(String currencyCode) {
return currencies.get(currencyCode);
}
@Override
public String getCurrencyCode() {
return configuration.getCurrencyCode();
}
@Override
public void setCurrency(String currencyCode) {
if (configuration != null) {
configuration.setCurrencyCode(currencyCode);
configuration.setCurrencySymbol(currencies.get(currencyCode));
}
}
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -22,6 +22,7 @@
package org.libreplan.web.common;
import java.util.List;
import java.util.Set;
import org.libreplan.business.calendars.entities.BaseCalendar;
import org.libreplan.business.common.entities.EntityNameEnum;
@ -157,4 +158,13 @@ public interface IConfigurationModel {
Boolean getGenerateCodeForExpenseSheets();
void setGenerateCodeForExpenseSheets(Boolean generateCodeForExpenseSheets);
Set<String> getCurrencies();
String getCurrencySymbol(String currencyCode);
String getCurrencyCode();
void setCurrency(String currencyCode);
}

View file

@ -24,7 +24,6 @@ package org.libreplan.web.common;
import static org.libreplan.web.I18nHelper._;
import java.util.ConcurrentModificationException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@ -125,9 +124,4 @@ public abstract class IntegrationEntityModel implements IIntegrationEntityModel
return entitySequenceDAO;
}
public Date getCurrentExpiringDate() {
// TODO Auto-generated method stub
return null;
}
}

View file

@ -24,6 +24,7 @@ package org.libreplan.web.common;
import static org.libreplan.web.I18nHelper._;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
@ -31,6 +32,9 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.libreplan.business.common.Configuration;
import org.libreplan.business.common.IOnTransaction;
import org.libreplan.business.common.Registry;
import org.zkoss.ganttz.util.ComponentsFinder;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
@ -62,6 +66,12 @@ public class Util {
private static final Log LOG = LogFactory.getLog(Util.class);
/**
* Special chars from {@link DecimalFormat} class.
*/
private static final String[] DECIMAL_FORMAT_SPECIAL_CHARS = { "0", ",",
".", "\u2030", "%", "#", ";", "-" };
private Util() {
}
@ -629,4 +639,55 @@ public class Util {
}
}
/**
* Gets currency symbol from {@link Configuration} object.
*
* @return Currency symbol configured in the application
*/
public static String getCurrencySymbol() {
return Registry.getTransactionService().runOnReadOnlyTransaction(
new IOnTransaction<String>() {
@Override
public String execute() {
return Registry.getConfigurationDAO()
.getConfiguration().getCurrencySymbol();
}
});
}
/**
* Returns the value using the money format, that means, 2 figures for the
* decimal part and concatenating the currency symbol from
* {@link Configuration} object.
*/
public static String addCurrencySymbol(BigDecimal value) {
DecimalFormat decimalFormat = (DecimalFormat) DecimalFormat
.getInstance();
decimalFormat.applyPattern(getMoneyFormat());
return decimalFormat.format(value);
}
/**
* Gets money format for a {@link Decimalbox} using 2 figures for the
* decimal part and concatenating the currency symbol
*
* @return Format for a {@link Decimalbox} <code>###.##</code> plus currency
* symbol
*/
public static String getMoneyFormat() {
return "###.## " + escapeDecimalFormatSpecialChars(getCurrencySymbol());
}
/**
* Escapes special chars used in {@link DecimalFormat} to define the number
* format that appear in the <code>currencySymbol</code>.
*/
private static String escapeDecimalFormatSpecialChars(String currencySymbol) {
for (String specialChar : DECIMAL_FORMAT_SPECIAL_CHARS) {
currencySymbol = currencySymbol.replace(specialChar, "'"
+ specialChar + "'");
}
return currencySymbol;
}
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -53,9 +53,15 @@ import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.api.Listbox;
/**
* {@link Bandbox} allowing to choose more than one element from the drop down
* list separating them by "<code>;</code>".<br />
*
* When an element is selected {@link Events.ON_CHANGE} event over this
* component is launched.
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
@SuppressWarnings("serial")
public class BandboxMultipleSearch extends HtmlMacroComponent {
@ -168,6 +174,7 @@ public class BandboxMultipleSearch extends HtmlMacroComponent {
}
}
bandbox.close();
Events.postEvent(Events.ON_CHANGE, this, null);
}
private void searchMultipleFilters() {

View file

@ -0,0 +1,50 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2012 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.libreplan.web.common.components.finders;
import org.libreplan.business.resources.entities.Resource;
/**
* Diferent filters for {@link Resource}.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public enum ResourceFilterEnumByResourceAndCriterion implements IFilterEnum {
RESOURCE(_("Resource")), CRITERION(_("Criterion"));
/**
* Forces to mark the string as needing translation
*/
private static String _(String string) {
return string;
}
private String description;
private ResourceFilterEnumByResourceAndCriterion(String description) {
this.description = description;
}
public String toString() {
return this.description;
}
}

View file

@ -0,0 +1,184 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2012 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.libreplan.web.common.components.finders;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import org.apache.commons.lang.StringUtils;
import org.libreplan.business.hibernate.notification.PredefinedDatabaseSnapshots;
import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.resources.entities.CriterionType;
import org.libreplan.business.resources.entities.Resource;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Implements all the methods needed to search the different criteria to filter
* the {@link Resource}s.<br />
* It provides the following criteria to filter: {@link Resource} and
* {@link Criterion}.
*
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public class ResourceMultipleFiltersFinderByResourceAndCriterion extends MultipleFiltersFinder {
@Autowired
private PredefinedDatabaseSnapshots databaseSnapshots;
protected ResourceMultipleFiltersFinderByResourceAndCriterion() {
}
@Override
public List<FilterPair> getFirstTenFilters() {
getListMatching().clear();
fillWithFirstTenFiltersResources();
fillWithFirstTenFiltersCriterions();
addNoneFilter();
return getListMatching();
}
private List<FilterPair> fillWithFirstTenFiltersResources() {
Map<Class<?>, List<Resource>> mapResources = getMapResources();
Iterator<Class<?>> iteratorClass = mapResources.keySet().iterator();
while (iteratorClass.hasNext() && getListMatching().size() < 10) {
Class<?> className = iteratorClass.next();
for (int i = 0; getListMatching().size() < 10
&& i < mapResources.get(className).size(); i++) {
Resource resource = mapResources.get(className).get(i);
addResource(className, resource);
}
}
return getListMatching();
}
private Map<Class<?>, List<Resource>> getMapResources() {
return databaseSnapshots.snapshotMapResources();
}
private void addResource(Class<?> className, Resource resource) {
String pattern = resource.getName();
getListMatching().add(
new FilterPair(ResourceFilterEnumByResourceAndCriterion.RESOURCE, className
.getSimpleName(), pattern, resource));
}
private List<FilterPair> fillWithFirstTenFiltersCriterions() {
SortedMap<CriterionType, List<Criterion>> mapCriterions = getMapCriterions();
Iterator<CriterionType> iteratorCriterionType = mapCriterions.keySet()
.iterator();
while (iteratorCriterionType.hasNext() && getListMatching().size() < 10) {
CriterionType type = iteratorCriterionType.next();
for (int i = 0; getListMatching().size() < 10
&& i < mapCriterions.get(type).size(); i++) {
Criterion criterion = mapCriterions.get(type).get(i);
addCriterion(type, criterion);
}
}
return getListMatching();
}
private SortedMap<CriterionType, List<Criterion>> getMapCriterions() {
return databaseSnapshots.snapshotCriterionsMap();
}
private void addCriterion(CriterionType type, Criterion criterion) {
String pattern = criterion.getName() + " ( " + type.getName() + " )";
getListMatching().add(
new FilterPair(ResourceFilterEnumByResourceAndCriterion.CRITERION, type
.getResource().toLowerCase(), pattern, criterion));
}
public List<FilterPair> getMatching(String filter) {
getListMatching().clear();
if ((filter != null) && (!filter.isEmpty())) {
filter = StringUtils.deleteWhitespace(filter.toLowerCase());
searchInResources(filter);
searchInCriterionTypes(filter);
}
addNoneFilter();
return getListMatching();
}
private void searchInResources(String filter) {
Map<Class<?>, List<Resource>> mapResources = databaseSnapshots
.snapshotMapResources();
for (Class<?> className : mapResources.keySet()) {
for (Resource resource : mapResources.get(className)) {
String name = StringUtils.deleteWhitespace(resource.getName()
.toLowerCase());
if (name.contains(filter)) {
addResource(className, resource);
if ((filter.length() < 3) && (getListMatching().size() > 9)) {
return;
}
}
}
}
}
private void searchInCriterionTypes(String filter) {
boolean limited = (filter.length() < 3);
for (CriterionType type : getMapCriterions().keySet()) {
String name = StringUtils.deleteWhitespace(type.getName()
.toLowerCase());
if (name.contains(filter)) {
setFilterPairCriterionType(type, limited);
} else {
searchInCriterions(type, filter);
}
}
}
private void searchInCriterions(CriterionType type, String filter) {
List<Criterion> list = getMapCriterions().get(type);
if (list == null) {
return;
}
for (Criterion criterion : list) {
String name = StringUtils.deleteWhitespace(criterion.getName()
.toLowerCase());
if (name.contains(filter)) {
addCriterion(type, criterion);
if ((filter.length() < 3) && (getListMatching().size() > 9)) {
return;
}
}
}
}
private void setFilterPairCriterionType(CriterionType type, boolean limited) {
List<Criterion> list = getMapCriterions().get(type);
if (list == null) {
return;
}
for (Criterion criterion : list) {
addCriterion(type, criterion);
if ((limited) && (getListMatching().size() > 9)) {
return;
}
}
}
}

View file

@ -35,11 +35,11 @@ import org.springframework.beans.factory.annotation.Autowired;
/**
* Implements all the methods needed to search the criterion to filter the
* resources. Provides multiples criterions to filter like {@link Criterion},
* {@link Category} or filter by name or nif.
* resources. Provides multiples criteria to filter like {@link Criterion} or
* {@link CostCategory}.
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
public class ResourcesMultipleFiltersFinder extends MultipleFiltersFinder {
@Autowired

View file

@ -79,7 +79,7 @@ public abstract class TemplateFinder<T extends OrderElementTemplate> extends
}
protected String extractStringFor(T template) {
return template.getName() + " (" + template.getCode() + ")";
return template.getName();
}
@Override
@ -92,7 +92,6 @@ public abstract class TemplateFinder<T extends OrderElementTemplate> extends
protected void generateColumnsForRenderer(Listitem item, T template) {
final Listcell codeCell = new Listcell();
codeCell.setLabel(template.getCode());
codeCell.setParent(item);
codeCell.setStyle("width:200px");

View file

@ -1,91 +0,0 @@
/*
* This file is part of LibrePlan
*
* 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.libreplan.web.common.components.finders;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.libreplan.business.hibernate.notification.PredefinedDatabaseSnapshots;
import org.libreplan.business.resources.entities.Worker;
import org.springframework.beans.factory.annotation.Autowired;
public class WorkerMultipleFiltersFinder extends MultipleFiltersFinder {
@Autowired
private PredefinedDatabaseSnapshots databaseSnapshots;
private IFilterEnum workerFilterEnum = new IFilterEnum() {
@Override
public String toString() {
return "Resource ( Worker )";
}
};
/**
* Forces to mark the string as needing translation
*/
private static String _(String string) {
return string;
}
@Override
public List<FilterPair> getFirstTenFilters() {
getListMatching().clear();
Iterator<Worker> iteratorWorker = getListWorkers().iterator();
while(iteratorWorker.hasNext() && getListMatching().size() < 10) {
Worker worker = iteratorWorker.next();
getListMatching().add(
new FilterPair(workerFilterEnum, worker.getDescription(),
worker));
}
addNoneFilter();
return getListMatching();
}
private List<Worker> getListWorkers() {
return databaseSnapshots.snapshotListWorkers();
}
@Override
public List<FilterPair> getMatching(String filter) {
getListMatching().clear();
if ((filter != null) && (!filter.isEmpty())) {
filter = StringUtils.deleteWhitespace(filter.toLowerCase());
searchInWorkers(filter);
}
addNoneFilter();
return getListMatching();
}
private void searchInWorkers(String filter) {
for (Worker worker : getListWorkers()) {
String name = StringUtils.deleteWhitespace(worker.getDescription()
.toLowerCase());
if(name.contains(filter)) {
getListMatching().add(new FilterPair(
workerFilterEnum, worker.getShortDescription(), worker));
}
}
}
}

View file

@ -38,10 +38,8 @@ import org.libreplan.business.costcategories.entities.CostCategory;
import org.libreplan.business.costcategories.entities.HourCost;
import org.libreplan.business.costcategories.entities.TypeOfWorkHours;
import org.libreplan.web.common.BaseCRUDController;
import org.libreplan.web.common.ConstraintChecker;
import org.libreplan.web.common.Level;
import org.libreplan.web.common.Util;
import org.libreplan.web.util.ValidationExceptionPrinter;
import org.libreplan.web.workreports.WorkReportCRUDController;
import org.zkoss.ganttz.util.ComponentsFinder;
import org.zkoss.zk.ui.Component;
@ -305,6 +303,7 @@ public class CostCategoryCRUDController extends BaseCRUDController<CostCategory>
Decimalbox boxCost = new Decimalbox();
bindDecimalboxCost(boxCost, (HourCost) row.getValue());
boxCost.setConstraint("no empty:" + _("cannot be null or empty"));
boxCost.setFormat(Util.getMoneyFormat());
row.appendChild(boxCost);
}

View file

@ -141,4 +141,13 @@ public class TypeOfWorkHoursCRUDController extends BaseCRUDController<TypeOfWork
protected boolean beforeDeleting(TypeOfWorkHours typeOfWorkHours) {
return !isReferencedByOtherEntities(typeOfWorkHours);
}
public String getCurrencySymbol() {
return Util.getCurrencySymbol();
}
public String getMoneyFormat() {
return Util.getMoneyFormat();
}
}

View file

@ -0,0 +1,123 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2010-2012 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.libreplan.web.dashboard;
import static org.libreplan.web.I18nHelper._;
import java.math.BigDecimal;
import java.util.Date;
import org.joda.time.LocalDate;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.web.common.Util;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Label;
/**
* @author Diego Pino García <dpino@igalia.com>
*
* Contains operations for calculations in the CostStatus table in the
* Dashboard view
*/
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class CostStatusController extends GenericForwardComposer {
private ICostStatusModel costStatusModel;
// Cost Variance
public Label lblCV;
// Cost Performance Index
public Label lblCPI;
// Budget at Completion
public Label lblBAC;
// Estimate at Completion
public Label lblEAC;
// Variance at Completion
public Label lblVAC;
@Override
public void doAfterCompose(org.zkoss.zk.ui.Component comp) throws Exception {
super.doAfterCompose(comp);
self.setAttribute("controller", this);
Util.createBindingsFor(self);
}
public void setOrder(Order order) {
costStatusModel.setCurrentOrder(order);
}
public void render() {
LocalDate today = LocalDate.fromDateFields(new Date());
BigDecimal budgetedCost = costStatusModel
.getBudgetedCostWorkPerformedAt(today);
BigDecimal actualCost = costStatusModel
.getActualCostWorkPerformedAt(today);
BigDecimal costVariance = costStatusModel.getCostVariance(budgetedCost,
actualCost);
setCostVariance(costVariance);
BigDecimal costPerformanceIndex = costStatusModel
.getCostPerformanceIndex(budgetedCost, actualCost);
setCostPerformanceIndex(costPerformanceIndex);
BigDecimal budgetAtCompletion = costStatusModel.getBudgetAtCompletion();
setBudgetAtCompletion(budgetAtCompletion);
BigDecimal estimateAtCompletion = costStatusModel
.getEstimateAtCompletion(budgetAtCompletion,
costPerformanceIndex);
setEstimateAtCompletion(estimateAtCompletion);
BigDecimal varianceAtCompletion = costStatusModel
.getVarianceAtCompletion(budgetAtCompletion,
estimateAtCompletion);
setVarianceAtCompletion(varianceAtCompletion);
}
private void setEstimateAtCompletion(BigDecimal value) {
lblEAC.setValue(String.format("%.2f %%", value.doubleValue()));
}
private void setCostPerformanceIndex(BigDecimal value) {
lblCPI.setValue(String.format("%.2f %%", value.doubleValue()));
}
private void setBudgetAtCompletion(BigDecimal value) {
lblBAC.setValue(String.format(_("%s h"), value.toString()));
}
private void setCostVariance(BigDecimal value) {
lblCV.setValue(String.format(_("%s h"), value.toString()));
}
private void setVarianceAtCompletion(BigDecimal value) {
lblVAC.setValue(String.format(_("%s h"), value.toString()));
}
}

View file

@ -0,0 +1,202 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2010-2012 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.libreplan.web.dashboard;
import java.math.BigDecimal;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import org.joda.time.LocalDate;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.planner.entities.ICostCalculator;
import org.libreplan.business.planner.entities.Task;
import org.libreplan.business.planner.entities.TaskElement;
import org.libreplan.web.planner.order.OrderPlanningModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Diego Pino García <ltilve@igalia.com>
*
* Model for UI operations related to CostStatus in Dashboard view
*
* FIXME: This Model contains several operations for calculating 'Earned
* Value' measures related with cost. The code for calculating the basic
* measures: BCWP, ACWP and BCWS is copied from
* {@link OrderPlanningModel}. At this moment this code cannot be reused
* as it's coupled with the logic for displaying the 'Earned Value'
* chart. We may consider to refactor this code in the future.
*/
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class CostStatusModel implements ICostStatusModel {
@Autowired
private ICostCalculator hoursCostCalculator;
private Order order;
public CostStatusModel() {
}
@Override
@Transactional(readOnly = true)
public BigDecimal getActualCostWorkPerformedAt(LocalDate date) {
SortedMap<LocalDate, BigDecimal> actualCost = calculateActualCostWorkPerformed();
BigDecimal result = actualCost.get(date);
return (result != null) ? result : BigDecimal.ZERO;
}
private SortedMap<LocalDate, BigDecimal> calculateActualCostWorkPerformed() {
SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>();
for (TaskElement taskElement : getAllTaskElements(order)) {
if (taskElement instanceof Task) {
addCost(result, getWorkReportCost((Task) taskElement));
}
}
return accumulateResult(result);
}
private SortedMap<LocalDate, BigDecimal> accumulateResult(
SortedMap<LocalDate, BigDecimal> map) {
SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>();
if (map.isEmpty()) {
return result;
}
BigDecimal accumulatedResult = BigDecimal.ZERO;
for (LocalDate day : map.keySet()) {
BigDecimal value = map.get(day);
accumulatedResult = accumulatedResult.add(value);
result.put(day, accumulatedResult);
}
return result;
}
private void addCost(SortedMap<LocalDate, BigDecimal> currentCost,
SortedMap<LocalDate, BigDecimal> additionalCost) {
for (LocalDate day : additionalCost.keySet()) {
if (!currentCost.containsKey(day)) {
currentCost.put(day, BigDecimal.ZERO);
}
currentCost.put(day,
currentCost.get(day).add(additionalCost.get(day)));
}
}
private List<TaskElement> getAllTaskElements(Order order) {
List<TaskElement> result = order.getAllChildrenAssociatedTaskElements();
result.add(order.getAssociatedTaskElement());
return result;
}
private SortedMap<LocalDate, BigDecimal> getWorkReportCost(Task taskElement) {
return hoursCostCalculator.getWorkReportCost(taskElement);
}
@Override
@Transactional(readOnly = true)
public BigDecimal getBudgetAtCompletion() {
SortedMap<LocalDate, BigDecimal> budgedtedCost = calculateBudgetedCostWorkScheduled();
LocalDate lastKey = budgedtedCost.lastKey();
return (lastKey) != null ? budgedtedCost.get(lastKey) : BigDecimal.ZERO;
}
private SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkScheduled() {
SortedMap<LocalDate, BigDecimal> result = new TreeMap<LocalDate, BigDecimal>();
for (TaskElement taskElement : getAllTaskElements(order)) {
if (taskElement instanceof Task) {
addCost(result, getEstimatedCost((Task) taskElement));
}
}
return accumulateResult(result);
}
private SortedMap<LocalDate, BigDecimal> getEstimatedCost(Task task) {
return hoursCostCalculator.getEstimatedCost(task);
}
@Override
@Transactional(readOnly = true)
public BigDecimal getBudgetedCostWorkPerformedAt(LocalDate date) {
SortedMap<LocalDate, BigDecimal> budgetedCost = calculateBudgetedCostWorkPerformed();
BigDecimal result = budgetedCost.get(date);
return (result != null) ? result : BigDecimal.ZERO;
}
private SortedMap<LocalDate, BigDecimal> calculateBudgetedCostWorkPerformed() {
SortedMap<LocalDate, BigDecimal> estimatedCost = new TreeMap<LocalDate, BigDecimal>();
for (TaskElement taskElement : getAllTaskElements(order)) {
if (taskElement instanceof Task) {
addCost(estimatedCost, getAdvanceCost((Task) taskElement));
}
}
return accumulateResult(estimatedCost);
}
private SortedMap<LocalDate, BigDecimal> getAdvanceCost(Task task) {
return hoursCostCalculator.getAdvanceCost(task);
}
@Override
public BigDecimal getCostPerformanceIndex(BigDecimal budgetedCost,
BigDecimal actualCost) {
if (BigDecimal.ZERO.compareTo(actualCost) == 0) {
return BigDecimal.ZERO;
}
return asPercentage(budgetedCost.divide(actualCost));
}
private BigDecimal asPercentage(BigDecimal value) {
return value.multiply(BigDecimal.valueOf(100)).setScale(2);
}
@Override
public BigDecimal getCostVariance(BigDecimal budgetedCost,
BigDecimal actualCost) {
return budgetedCost.subtract(actualCost);
}
@Override
public BigDecimal getEstimateAtCompletion(BigDecimal budgetAtCompletion,
BigDecimal costPerformanceIndex) {
if (BigDecimal.ZERO.compareTo(costPerformanceIndex) == 0) {
return BigDecimal.ZERO;
}
return asPercentage(budgetAtCompletion.divide(costPerformanceIndex));
}
@Override
public BigDecimal getVarianceAtCompletion(BigDecimal budgetAtCompletion,
BigDecimal estimateAtCompletion) {
return budgetAtCompletion.subtract(estimateAtCompletion);
}
@Override
public void setCurrentOrder(Order order) {
this.order = order;
}
}

View file

@ -21,29 +21,40 @@ package org.libreplan.web.dashboard;
import static org.libreplan.web.I18nHelper._;
import java.awt.Color;
import java.awt.Font;
import java.math.BigDecimal;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.planner.entities.TaskStatusEnum;
import org.libreplan.web.common.Util;
import org.libreplan.web.dashboard.DashboardModel.Interval;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.CategoryModel;
import org.zkoss.zul.Chart;
import org.zkoss.zul.Div;
import org.zkoss.zul.PieModel;
import org.zkoss.zul.SimpleCategoryModel;
import org.zkoss.zul.SimplePieModel;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Label;
import org.zkoss.zul.Window;
import br.com.digilabs.jqplot.Chart;
import br.com.digilabs.jqplot.JqPlotUtils;
import br.com.digilabs.jqplot.chart.BarChart;
import br.com.digilabs.jqplot.chart.PieChart;
import br.com.digilabs.jqplot.elements.Serie;
/**
* Controller for dashboardfororder view
* @author Nacho Barrientos <nacho@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
*
* Controller for dashboardfororder view
*/
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -53,12 +64,10 @@ public class DashboardController extends GenericForwardComposer {
private Window dashboardWindow;
private Chart progressKPIglobalProgressChart;
private Chart progressKPItaskStatusChart;
private Chart progressKPItaskDeadlineViolationStatusChart;
private Chart timeKPImarginWithDeadlineChart;
private Chart timeKPIEstimationAccuracyChart;
private Chart timeKPILagInTaskCompletionChart;
private Grid gridTasksSummary;
private Grid gridMarginWithDeadline;
private org.zkoss.zk.ui.Component costStatus;
private Div projectDashboardChartsDiv;
private Div projectDashboardNoTasksWarningDiv;
@ -69,171 +78,415 @@ public class DashboardController extends GenericForwardComposer {
@Override
public void doAfterCompose(org.zkoss.zk.ui.Component comp) throws Exception {
super.doAfterCompose(comp);
this.dashboardWindow = (Window)comp;
this.dashboardWindow = (Window) comp;
self.setAttribute("controller", this);
Util.createBindingsFor(this.dashboardWindow);
}
public void setCurrentOrder(Order order) {
dashboardModel.setCurrentOrder(order);
if(dashboardModel.tasksAvailable()) {
this.reloadCharts();
if (dashboardModel.tasksAvailable()) {
showCharts();
} else {
this.hideChartsAndShowWarningMessage();
hideCharts();
}
if (this.dashboardWindow != null) {
Util.reloadBindings(this.dashboardWindow);
renderGlobalProgress();
renderTaskStatus();
renderTaskCompletationLag();
renderTasksSummary();
renderDeadlineViolation();
renderMarginWithDeadline();
renderEstimationAccuracy();
renderCostStatus(order);
}
}
private void reloadCharts() {
generateProgressKPIglobalProgressChart();
generateProgressKPItaskStatusChart();
generateProgressKPItaskDeadlineViolationStatusChart();
generateTimeKPImarginWithDeadlineChart();
generateTimeKPIEstimationAccuracyChart();
generateTimeKPILagInTaskCompletionChart();
private void renderCostStatus(Order order) {
CostStatusController costStatusController = getCostStatusController();
costStatusController.setOrder(order);
costStatusController.render();
}
private void hideChartsAndShowWarningMessage() {
private CostStatusController getCostStatusController() {
return (CostStatusController) costStatus.getAttribute("controller");
}
private void renderMarginWithDeadline() {
marginWithDeadline(dashboardModel.getMarginWithDeadLine());
absoluteMarginWithDeadline(dashboardModel
.getAbsoluteMarginWithDeadLine());
}
private void marginWithDeadline(BigDecimal value) {
Label label = (Label) gridMarginWithDeadline
.getFellowIfAny("lblRelative");
if (label != null) {
if (value != null) {
label.setValue(String.format(_("%.2f %%"),
value.doubleValue() * 100));
} else {
label.setValue(_("<No deadline>"));
}
}
}
private void absoluteMarginWithDeadline(Integer value) {
Label label = (Label) gridMarginWithDeadline
.getFellowIfAny("lblAbsolute");
if (label != null) {
if (value != null) {
label.setValue(String.format(_("%d days"), value));
} else {
label.setValue(_("<No deadline>"));
}
}
}
private void renderDeadlineViolation() {
final String divId = "deadline-violation";
PieChart<Number> pieChart = new PieChart<Number>(
_("Deadline Violation"));
pieChart.addValue(_("On schedule"),
dashboardModel.getPercentageOfOnScheduleTasks());
pieChart.addValue(_("Violated deadline"),
dashboardModel.getPercentageOfTasksWithViolatedDeadline());
pieChart.addValue(_("No deadline"),
dashboardModel.getPercentageOfTasksWithNoDeadline());
renderChart(pieChart, divId);
}
private void renderChart(Chart<?> chart, String divId) {
String jsCode = JqPlotUtils.createJquery(chart, divId);
Clients.evalJavaScript(jsCode);
}
private void renderTaskCompletationLag() {
final String divId = "task-completation-lag";
BarChart<Integer> barChart;
barChart = new BarChart<Integer>("Task Completation Lead/Lag");
barChart.setFillZero(true);
barChart.setHighlightMouseDown(true);
barChart.setStackSeries(false);
barChart.setBarMargin(30);
barChart.addSeries(new Serie("Tasks"));
TaskCompletationData taskCompletationData = TaskCompletationData
.create(dashboardModel);
barChart.setTicks(taskCompletationData.getTicks());
barChart.addValues(taskCompletationData.getValues());
barChart.getAxes().getXaxis()
.setLabel(_("Number of Days / Days Interval"));
renderChart(barChart, divId);
}
private void renderEstimationAccuracy() {
final String divId = "estimation-accuracy";
BarChart<Integer> barChart;
barChart = new BarChart<Integer>("Estimation Accuracy");
barChart.setFillZero(true);
barChart.setHighlightMouseDown(true);
barChart.setStackSeries(false);
barChart.setBarMargin(30);
barChart.addSeries(new Serie("Tasks"));
EstimationAccuracy estimationAccuracyData = EstimationAccuracy
.create(dashboardModel);
barChart.setTicks(estimationAccuracyData.getTicks());
barChart.addValues(estimationAccuracyData.getValues());
barChart.getAxes().getXaxis()
.setLabel(_("Number of Tasks / % Deviation"));
renderChart(barChart, divId);
}
private void renderTasksSummary() {
Map<TaskStatusEnum, Integer> taskStatus = dashboardModel
.calculateTaskStatus();
taskStatus("lblTasksFinished", taskStatus.get(TaskStatusEnum.FINISHED));
taskStatus("lblTasksBlocked", taskStatus.get(TaskStatusEnum.BLOCKED));
taskStatus("lblTasksInProgress",
taskStatus.get(TaskStatusEnum.IN_PROGRESS));
taskStatus("lblTasksReadyToStart",
taskStatus.get(TaskStatusEnum.READY_TO_START));
}
private void taskStatus(String key, Integer value) {
Label label = (Label) gridTasksSummary.getFellowIfAny(key);
if (label != null) {
label.setValue(String.format(_("%d tasks"), value));
}
}
private void renderTaskStatus() {
final String divId = "task-status";
PieChart<Number> taskStatus = new PieChart<Number>(_("Task Status"));
taskStatus.addValue(_("Finished"),
dashboardModel.getPercentageOfFinishedTasks());
taskStatus.addValue(_("In progress"),
dashboardModel.getPercentageOfInProgressTasks());
taskStatus.addValue(_("Ready to start"),
dashboardModel.getPercentageOfReadyToStartTasks());
taskStatus.addValue(_("Blocked"),
dashboardModel.getPercentageOfBlockedTasks());
renderChart(taskStatus, divId);
}
private void renderGlobalProgress() {
GlobalProgress globalProgress = GlobalProgress.create();
// Current values
globalProgress.current(GlobalProgress.CRITICAL_PATH_DURATION,
dashboardModel.getCriticalPathProgressByDuration());
globalProgress.current(GlobalProgress.CRITICAL_PATH_HOURS,
dashboardModel.getCriticalPathProgressByNumHours());
globalProgress.current(GlobalProgress.ALL_TASKS_HOURS,
dashboardModel.getAdvancePercentageByHours());
// Expected values
globalProgress.expected(GlobalProgress.CRITICAL_PATH_DURATION,
dashboardModel.getExpectedCriticalPathProgressByDuration());
globalProgress.expected(GlobalProgress.CRITICAL_PATH_HOURS,
dashboardModel.getExpectedCriticalPathProgressByNumHours());
globalProgress.expected(GlobalProgress.ALL_TASKS_HOURS,
dashboardModel.getExpectedAdvancePercentageByHours());
globalProgress.render();
}
private void showCharts() {
projectDashboardChartsDiv.setVisible(true);
projectDashboardNoTasksWarningDiv.setVisible(false);
}
private void hideCharts() {
projectDashboardChartsDiv.setVisible(false);
projectDashboardNoTasksWarningDiv.setVisible(true);
}
private void generateTimeKPILagInTaskCompletionChart() {
CategoryModel categoryModel;
categoryModel = refreshTimeKPILagInTaskCompletionCategoryModel();
Font labelFont = new Font("serif", Font.PLAIN, 10);
timeKPILagInTaskCompletionChart.setXAxisTickFont(labelFont);
Color[] seriesColorMappings = {Color.BLUE};
timeKPILagInTaskCompletionChart.setAttribute("series-color-mappings",
seriesColorMappings);
timeKPILagInTaskCompletionChart.setModel(categoryModel);
}
/**
*
* @author Diego Pino García <dpino@igalia.com>
*
*/
static class GlobalProgress {
private void generateTimeKPIEstimationAccuracyChart() {
CategoryModel categoryModel;
categoryModel = refreshTimeKPIEstimationAccuracyCategoryModel();
Font labelFont = new Font("serif", Font.PLAIN, 10);
timeKPIEstimationAccuracyChart.setXAxisTickFont(labelFont);
Color[] seriesColorMappings = {Color.BLUE};
timeKPIEstimationAccuracyChart.setAttribute("series-color-mappings",
seriesColorMappings);
timeKPIEstimationAccuracyChart.setModel(categoryModel);
}
public static final String ALL_TASKS_HOURS = _("All tasks (hours)");
public static final String CRITICAL_PATH_HOURS = _("Critical path (hours)");
public static final String CRITICAL_PATH_DURATION = _("Critical path (duration)");
private final Map<String, BigDecimal> current = new LinkedHashMap<String, BigDecimal>();
private final Map<String, BigDecimal> expected = new LinkedHashMap<String, BigDecimal>();
private static List<Series> series = new ArrayList<Series>() {
{
add(Series.create(_("Current"), "#33c"));
add(Series.create(_("Expected"), "#c33"));
}
};
private GlobalProgress() {
private void generateTimeKPImarginWithDeadlineChart() {
CategoryModel categoryModel;
categoryModel = refreshTimeKPImarginWithDeadlineCategoryModel();
if (categoryModel == null) { // Project has no deadline set.
timeKPImarginWithDeadlineChart.setVisible(false);
return;
}
timeKPImarginWithDeadlineChart.setAttribute("range-axis-lower-bound",
new Double(-3.0));
timeKPImarginWithDeadlineChart.setAttribute("range-axis-upper-bound",
new Double(3.0));
Color[] seriesColorMappings = new Color[1];
if(dashboardModel.getMarginWithDeadLine().compareTo(BigDecimal.ZERO) >= 0) {
seriesColorMappings[0] = Color.GREEN;
} else {
seriesColorMappings[0] = Color.RED;
public void current(String key, BigDecimal value) {
current.put(key, value);
}
timeKPImarginWithDeadlineChart.setAttribute("series-color-mappings",
seriesColorMappings);
timeKPImarginWithDeadlineChart.setModel(categoryModel);
}
private void generateProgressKPItaskStatusChart() {
PieModel model = refreshProgressKPItaskStatusPieModel();
progressKPItaskStatusChart.setModel(model);
}
private void generateProgressKPItaskDeadlineViolationStatusChart() {
PieModel model = refreshProgressKPItaskDeadlieViolationStatusPieModel();
progressKPItaskDeadlineViolationStatusChart.setModel(model);
}
private void generateProgressKPIglobalProgressChart() {
CategoryModel categoryModel;
categoryModel = refreshProgressKPIglobalProgressCategoryModel();
progressKPIglobalProgressChart.setAttribute("range-axis-lower-bound",
new Double(0.0));
progressKPIglobalProgressChart.setAttribute("range-axis-upper-bound",
new Double(100.0));
progressKPIglobalProgressChart.setModel(categoryModel);
}
private PieModel refreshProgressKPItaskStatusPieModel() {
PieModel model = new SimplePieModel();
model.setValue(_("Finished"), dashboardModel.getPercentageOfFinishedTasks());
model.setValue(_("In progress"), dashboardModel.getPercentageOfInProgressTasks());
model.setValue(_("Ready to start"), dashboardModel.getPercentageOfReadyToStartTasks());
model.setValue(_("Blocked"), dashboardModel.getPercentageOfBlockedTasks());
return model;
}
private PieModel refreshProgressKPItaskDeadlieViolationStatusPieModel() {
PieModel model = new SimplePieModel();
model.setValue(_("On schedule"), dashboardModel.getPercentageOfOnScheduleTasks());
model.setValue(_("Violated deadline"), dashboardModel.getPercentageOfTasksWithViolatedDeadline());
model.setValue(_("No deadline"), dashboardModel.getPercentageOfTasksWithNoDeadline());
return model;
}
private CategoryModel refreshProgressKPIglobalProgressCategoryModel() {
CategoryModel result = new SimpleCategoryModel();
result.setValue(_("Current"), _("All tasks (hours)"),
dashboardModel.getAdvancePercentageByHours());
result.setValue(_("Expected"), _("All tasks (hours)"),
dashboardModel.getTheoreticalAdvancePercentageByHoursUntilNow());
result.setValue(_("Current"), _("Critical path (hours)"),
dashboardModel.getCriticalPathProgressByNumHours());
result.setValue(_("Expected"), _("Critical path (hours)"), dashboardModel
.getTheoreticalProgressByNumHoursForCriticalPathUntilNow());
result.setValue(_("Current"), _("Critical path (duration)"),
dashboardModel.getCriticalPathProgressByDuration());
result.setValue(_("Expected"), _("Critical path (duration)"),
dashboardModel.getTheoreticalProgressByDurationForCriticalPathUntilNow());
return result;
}
private CategoryModel refreshTimeKPImarginWithDeadlineCategoryModel() {
CategoryModel result = null;
BigDecimal marginWithDeadLine = dashboardModel.getMarginWithDeadLine();
if (marginWithDeadLine != null) {
result = new SimpleCategoryModel();
result.setValue(_("None"), _("Deviation"), marginWithDeadLine);
public void expected(String key, BigDecimal value) {
expected.put(key, value);
}
return result;
public static GlobalProgress create() {
return new GlobalProgress();
}
public String getPercentages() {
return String.format("'[%s, %s]'",
jsonifyPercentages(current.values()),
jsonifyPercentages(expected.values()));
}
private String jsonifyPercentages(Collection<BigDecimal> array) {
List<String> result = new ArrayList<String>();
int i = 1;
for (BigDecimal each : array) {
result.add(String.format("[%.2f, %d]", each.doubleValue(), i++));
}
return String.format("[%s]", StringUtils.join(result, ","));
}
private String jsonify(Collection<?> list) {
Collection<String> result = new ArrayList<String>();
for (Object each : list) {
if (each.getClass() == String.class) {
result.add(String.format("\"%s\"", each.toString()));
} else {
result.add(String.format("%s", each.toString()));
}
}
return String.format("'[%s]'", StringUtils.join(result, ','));
}
public String getSeries() {
return jsonify(series);
}
/**
* The order of the ticks is taken from the keys in current
*
* @return
*/
public String getTicks() {
return jsonify(current.keySet());
}
public void render() {
String command = String.format(
"global_progress.render(%s, %s, %s);", getPercentages(),
getTicks(), getSeries());
Clients.evalJavaScript(command);
}
}
private CategoryModel refreshTimeKPIEstimationAccuracyCategoryModel() {
CategoryModel result = new SimpleCategoryModel();
List<Double> values = dashboardModel.getFinishedTasksEstimationAccuracyHistogram();
Iterator<Double> it = values.iterator();
for(int ii= DashboardModel.EA_STRETCHES_MIN_VALUE;
ii < DashboardModel.EA_STRETCHES_MAX_VALUE;
ii += DashboardModel.EA_STRETCHES_PERCENTAGE_STEP) {
result.setValue(_("None"), _(String.valueOf(ii)), it.next());
/**
*
* @author Diego Pino García <dpino@igalia.com>
*
*/
static class Series {
private String label;
private String color;
private Series() {
}
result.setValue(_("None"),
_(">"+DashboardModel.EA_STRETCHES_MAX_VALUE),
it.next());
return result;
public static Series create(String label) {
Series series = new Series();
series.label = label;
return series;
}
public static Series create(String label, String color) {
Series series = new Series();
series.label = label;
series.color = color;
return series;
}
@Override
public String toString() {
return String.format("{\"label\": \"%s\", \"color\": \"%s\"}",
label, color);
}
}
private CategoryModel refreshTimeKPILagInTaskCompletionCategoryModel() {
CategoryModel result = new SimpleCategoryModel();
List<Double> values = dashboardModel.getLagInTaskCompletionHistogram();
Iterator<Double> it = values.iterator();
for(double ii= DashboardModel.LTC_STRETCHES_MIN_VALUE;
ii < DashboardModel.LTC_STRETCHES_MAX_VALUE;
ii += DashboardModel.LTC_STRETCHES_STEP) {
result.setValue(_("None"), _(String.valueOf(ii)), it.next());
/**
*
* @author Diego Pino García<dpino@igalia.com>
*
*/
static class TaskCompletationData {
private final IDashboardModel dashboardModel;
private Map<Interval, Integer> taskCompletationData;
private TaskCompletationData(IDashboardModel dashboardModel) {
this.dashboardModel = dashboardModel;
}
result.setValue(_("None"),
_(">"+DashboardModel.LTC_STRETCHES_MAX_VALUE),
it.next());
return result;
public static TaskCompletationData create(IDashboardModel dashboardModel) {
return new TaskCompletationData(dashboardModel);
}
private Map<Interval, Integer> getData() {
if (taskCompletationData == null) {
taskCompletationData = dashboardModel
.calculateTaskCompletation();
}
return taskCompletationData;
}
public String[] getTicks() {
Set<Interval> intervals = getData().keySet();
String[] result = new String[intervals.size()];
int i = 0;
for (Interval each : intervals) {
result[i++] = each.toString();
}
return result;
}
public Collection<Integer> getValues() {
return getData().values();
}
}
/**
*
* @author Diego Pino García<dpino@igalia.com>
*
*/
static class EstimationAccuracy {
private final IDashboardModel dashboardModel;
private Map<Interval, Integer> estimationAccuracyData;
private EstimationAccuracy(IDashboardModel dashboardModel) {
this.dashboardModel = dashboardModel;
}
public static EstimationAccuracy create(IDashboardModel dashboardModel) {
return new EstimationAccuracy(dashboardModel);
}
private Map<Interval, Integer> getData() {
if (estimationAccuracyData == null) {
estimationAccuracyData = dashboardModel
.calculateEstimationAccuracy();
}
return estimationAccuracyData;
}
public String[] getTicks() {
Set<Interval> intervals = getData().keySet();
String[] result = new String[intervals.size()];
int i = 0;
for (Interval each : intervals) {
result[i++] = each.toString();
}
return result;
}
public Collection<Integer> getValues() {
return getData().values();
}
}
}

View file

@ -22,10 +22,14 @@ package org.libreplan.web.dashboard;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.joda.time.Days;
import org.joda.time.LocalDate;
@ -64,14 +68,14 @@ public class DashboardModel implements IDashboardModel {
public static double LTC_STRETCHES_MIN_VALUE = 0;
public static double LTC_STRETCHES_MAX_VALUE = 0;
private Order currentOrder;
private Integer taskCount = null;
private Map<TaskStatusEnum, BigDecimal> taskStatusStats;
private Map<TaskDeadlineViolationStatusEnum, BigDecimal> taskDeadlineViolationStatusStats;
private final Map<TaskStatusEnum, BigDecimal> taskStatusStats;
private final Map<TaskDeadlineViolationStatusEnum, BigDecimal> taskDeadlineViolationStatusStats;
private List<Double> taskEstimationAccuracyHistogram;
private BigDecimal marginWithDeadLine;
private Integer absoluteMarginWithDeadLine;
private List<Double> lagInTaskCompletionHistogram;
public DashboardModel() {
@ -81,10 +85,11 @@ public class DashboardModel implements IDashboardModel {
TaskDeadlineViolationStatusEnum.class);
}
@Override
public void setCurrentOrder(Order order) {
this.currentOrder = order;
this.taskCount = null;
if(tasksAvailable()) {
if (tasksAvailable()) {
this.calculateTaskStatusStatistics();
this.calculateTaskViolationStatusStatistics();
this.calculateMarginWithDeadLine();
@ -94,38 +99,49 @@ public class DashboardModel implements IDashboardModel {
}
/* Progress KPI: "Number of tasks by status" */
@Override
public BigDecimal getPercentageOfFinishedTasks() {
return taskStatusStats.get(TaskStatusEnum.FINISHED);
}
@Override
public BigDecimal getPercentageOfInProgressTasks() {
return taskStatusStats.get(TaskStatusEnum.IN_PROGRESS);
}
@Override
public BigDecimal getPercentageOfReadyToStartTasks() {
return taskStatusStats.get(TaskStatusEnum.READY_TO_START);
}
@Override
public BigDecimal getPercentageOfBlockedTasks() {
return taskStatusStats.get(TaskStatusEnum.BLOCKED);
}
/* Progress KPI: "Deadline violation" */
@Override
public BigDecimal getPercentageOfOnScheduleTasks() {
return taskDeadlineViolationStatusStats.get(TaskDeadlineViolationStatusEnum.ON_SCHEDULE);
return taskDeadlineViolationStatusStats
.get(TaskDeadlineViolationStatusEnum.ON_SCHEDULE);
}
@Override
public BigDecimal getPercentageOfTasksWithViolatedDeadline() {
return taskDeadlineViolationStatusStats.get(TaskDeadlineViolationStatusEnum.DEADLINE_VIOLATED);
return taskDeadlineViolationStatusStats
.get(TaskDeadlineViolationStatusEnum.DEADLINE_VIOLATED);
}
@Override
public BigDecimal getPercentageOfTasksWithNoDeadline() {
return taskDeadlineViolationStatusStats.get(TaskDeadlineViolationStatusEnum.NO_DEADLINE);
return taskDeadlineViolationStatusStats
.get(TaskDeadlineViolationStatusEnum.NO_DEADLINE);
}
/* Progress KPI: "Global Progress of the Project" */
public BigDecimal getAdvancePercentageByHours(){
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
@Override
public BigDecimal getAdvancePercentageByHours() {
TaskGroup rootAsTaskGroup = (TaskGroup) getRootTask();
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
@ -133,17 +149,20 @@ public class DashboardModel implements IDashboardModel {
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
}
public BigDecimal getTheoreticalAdvancePercentageByHoursUntilNow(){
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
@Override
public BigDecimal getExpectedAdvancePercentageByHours() {
TaskGroup rootAsTaskGroup = (TaskGroup) getRootTask();
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
BigDecimal ratio = rootAsTaskGroup.getTheoreticalProgressByNumHoursForAllTasksUntilNow();
BigDecimal ratio = rootAsTaskGroup
.getTheoreticalProgressByNumHoursForAllTasksUntilNow();
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
}
@Override
public BigDecimal getCriticalPathProgressByNumHours() {
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
TaskGroup rootAsTaskGroup = (TaskGroup) getRootTask();
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
@ -151,17 +170,20 @@ public class DashboardModel implements IDashboardModel {
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
}
public BigDecimal getTheoreticalProgressByNumHoursForCriticalPathUntilNow() {
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
@Override
public BigDecimal getExpectedCriticalPathProgressByNumHours() {
TaskGroup rootAsTaskGroup = (TaskGroup) getRootTask();
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
BigDecimal ratio = rootAsTaskGroup.getTheoreticalProgressByNumHoursForCriticalPathUntilNow();
BigDecimal ratio = rootAsTaskGroup
.getTheoreticalProgressByNumHoursForCriticalPathUntilNow();
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
}
@Override
public BigDecimal getCriticalPathProgressByDuration() {
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
TaskGroup rootAsTaskGroup = (TaskGroup) getRootTask();
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
@ -169,16 +191,19 @@ public class DashboardModel implements IDashboardModel {
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
}
public BigDecimal getTheoreticalProgressByDurationForCriticalPathUntilNow() {
TaskGroup rootAsTaskGroup = (TaskGroup)getRootTask();
@Override
public BigDecimal getExpectedCriticalPathProgressByDuration() {
TaskGroup rootAsTaskGroup = (TaskGroup) getRootTask();
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
BigDecimal ratio = rootAsTaskGroup.getTheoreticalProgressByDurationForCriticalPathUntilNow();
BigDecimal ratio = rootAsTaskGroup
.getTheoreticalProgressByDurationForCriticalPathUntilNow();
return ratio.multiply(BigDecimal.TEN).multiply(BigDecimal.TEN);
}
/* Time KPI: Margin with deadline */
@Override
public BigDecimal getMarginWithDeadLine() {
return this.marginWithDeadLine;
}
@ -207,7 +232,35 @@ public class DashboardModel implements IDashboardModel {
BigDecimal.ROUND_HALF_EVEN);
}
@Override
public Integer getAbsoluteMarginWithDeadLine() {
if (absoluteMarginWithDeadLine == null) {
calculateAbsoluteMarginWithDeadLine();
}
return absoluteMarginWithDeadLine;
}
private void calculateAbsoluteMarginWithDeadLine() {
TaskElement rootTask = getRootTask();
Date deadline = currentOrder.getDeadline();
if (rootTask == null) {
throw new RuntimeException("Root task is null");
}
if (deadline == null) {
this.absoluteMarginWithDeadLine = null;
return;
}
absoluteMarginWithDeadLine = daysBetween(rootTask.getEndAsLocalDate(),
LocalDate.fromDateFields(deadline));
}
private int daysBetween(LocalDate start, LocalDate end) {
return Days.daysBetween(start, end).getDays();
}
/* Time KPI: Estimation accuracy */
@Override
public List<Double> getFinishedTasksEstimationAccuracyHistogram() {
return this.taskEstimationAccuracyHistogram;
}
@ -216,21 +269,19 @@ public class DashboardModel implements IDashboardModel {
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
CalculateFinishedTasksEstimationDeviationVisitor visitor =
new CalculateFinishedTasksEstimationDeviationVisitor();
CalculateFinishedTasksEstimationDeviationVisitor visitor = new CalculateFinishedTasksEstimationDeviationVisitor();
TaskElement rootTask = getRootTask();
rootTask.acceptVisitor(visitor);
List<Double> deviations = visitor.getDeviations();
// [-100, -90), [-90, -80), ..., [190, 200), [200, inf)
this.taskEstimationAccuracyHistogram = createHistogram(
EA_STRETCHES_MIN_VALUE,
EA_STRETCHES_MAX_VALUE,
EA_STRETCHES_PERCENTAGE_STEP,
deviations);
EA_STRETCHES_MIN_VALUE, EA_STRETCHES_MAX_VALUE,
EA_STRETCHES_PERCENTAGE_STEP, deviations);
}
/* Time KPI: Lead/Lag in task completion */
@Override
public List<Double> getLagInTaskCompletionHistogram() {
return this.lagInTaskCompletionHistogram;
}
@ -239,8 +290,7 @@ public class DashboardModel implements IDashboardModel {
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
CalculateFinishedTasksLagInCompletionVisitor visitor =
new CalculateFinishedTasksLagInCompletionVisitor();
CalculateFinishedTasksLagInCompletionVisitor visitor = new CalculateFinishedTasksLagInCompletionVisitor();
TaskElement rootTask = getRootTask();
rootTask.acceptVisitor(visitor);
List<Double> deviations = visitor.getDeviations();
@ -253,45 +303,228 @@ public class DashboardModel implements IDashboardModel {
LTC_STRETCHES_MAX_VALUE = Collections.max(deviations);
}
LTC_STRETCHES_STEP = (LTC_STRETCHES_MAX_VALUE - LTC_STRETCHES_MIN_VALUE)
/LTC_NUMBER_OF_INTERVALS;
/ LTC_NUMBER_OF_INTERVALS;
this.lagInTaskCompletionHistogram = createHistogram(
LTC_STRETCHES_MIN_VALUE,
LTC_STRETCHES_MAX_VALUE,
LTC_STRETCHES_STEP,
deviations);
LTC_STRETCHES_MIN_VALUE, LTC_STRETCHES_MAX_VALUE,
LTC_STRETCHES_STEP, deviations);
}
private List<Double> createHistogram(double lowBound, double highBound,
double intervalStep, List<Double> values) {
double variableRange = highBound - lowBound;
/* TODO: What if highBound == lowBound? */
int numberOfClasses = (int)(variableRange/intervalStep);
int[] classes = new int[numberOfClasses+1];
int numberOfClasses = (int) (variableRange / intervalStep);
int[] classes = new int[numberOfClasses + 1];
for(Double value: values) {
for (Double value : values) {
int index;
if (value >= highBound) {
index = numberOfClasses;
} else {
index = (int)(numberOfClasses *
(((value.doubleValue() - lowBound))/variableRange));
index = (int) (numberOfClasses * (((value.doubleValue() - lowBound)) / variableRange));
}
classes[index]++;
}
List<Double> histogram = new ArrayList<Double>();
int numberOfConsideredTasks = values.size();
for (int numberOfElementsInClass: classes) {
for (int numberOfElementsInClass : classes) {
Double relativeCount = new Double(0.0);
if (numberOfConsideredTasks > 0) {
relativeCount = new Double(1.0*numberOfElementsInClass/
numberOfConsideredTasks);
relativeCount = new Double(1.0 * numberOfElementsInClass
/ numberOfConsideredTasks);
}
histogram.add(relativeCount);
}
return histogram;
}
/**
* Calculates the task completation deviations for the current order
*
* All the deviations are groups in Interval.MAX_INTERVALS intervals of
* equal size. If the order contains just one single task then, the upper
* limit will be the deviation of the task + 3, and the lower limit will be
* deviation of the task - 2
*
* Each {@link Interval} contains the number of tasks that fit in that
* interval
*
* @return
*/
@Override
public Map<Interval, Integer> calculateTaskCompletation() {
Map<Interval, Integer> result = new LinkedHashMap<Interval, Integer>();
Double max, min;
// Get deviations of finished tasks, calculate max, min and delta
List<Double> deviations = getTaskLagDeviations();
if (deviations.isEmpty()) {
return result;
}
if (deviations.size() == 1) {
max = deviations.get(0).doubleValue() + 3;
min = deviations.get(0).doubleValue() - 2;
} else {
max = Collections.max(deviations);
min = Collections.min(deviations);
}
double delta = (max - min) / Interval.MAX_INTERVALS;
// Create MAX_INTERVALS
double from = min;
for (int i = 0; i < Interval.MAX_INTERVALS; i++) {
result.put(Interval.create(from, from + delta), Integer.valueOf(0));
from = from + delta;
}
// Construct map with number of tasks for each interval
final Set<Interval> intervals = result.keySet();
for (Double each : deviations) {
Interval interval = Interval.containingValue(intervals, each);
if (interval != null) {
Integer value = result.get(interval);
result.put(interval, value + 1);
}
}
return result;
}
private List<Double> getTaskLagDeviations() {
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
CalculateFinishedTasksLagInCompletionVisitor visitor = new CalculateFinishedTasksLagInCompletionVisitor();
TaskElement rootTask = getRootTask();
rootTask.acceptVisitor(visitor);
return visitor.getDeviations();
}
/**
* Calculates the estimation accuracy deviations for the current order
*
* All the deviations are groups in Interval.MAX_INTERVALS intervals of
* equal size. If the order contains just one single task then, the upper
* limit will be the deviation of the task + 30, and the lower limit will be
* deviation of the task - 20
*
* Each {@link Interval} contains the number of tasks that fit in that
* interval
*
* @return
*/
@Override
public Map<Interval, Integer> calculateEstimationAccuracy() {
Map<Interval, Integer> result = new LinkedHashMap<Interval, Integer>();
Double max, min;
// Get deviations of finished tasks, calculate max, min and delta
List<Double> deviations = getEstimationAccuracyDeviations();
if (deviations.isEmpty()) {
return result;
}
if (deviations.size() == 1) {
max = deviations.get(0).doubleValue() + 30;
min = deviations.get(0).doubleValue() - 20;
} else {
max = Collections.max(deviations);
min = Collections.min(deviations);
}
double delta = (max - min) / Interval.MAX_INTERVALS;
// Create MAX_INTERVALS
double from = min;
for (int i = 0; i < Interval.MAX_INTERVALS; i++) {
result.put(Interval.create(from, from + delta), Integer.valueOf(0));
from = from + delta;
}
// Construct map with number of tasks for each interval
final Set<Interval> intervals = result.keySet();
for (Double each : deviations) {
Interval interval = Interval.containingValue(intervals, each);
if (interval != null) {
Integer value = result.get(interval);
result.put(interval, value + 1);
}
}
return result;
}
private List<Double> getEstimationAccuracyDeviations() {
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
CalculateFinishedTasksEstimationDeviationVisitor visitor = new CalculateFinishedTasksEstimationDeviationVisitor();
TaskElement rootTask = getRootTask();
rootTask.acceptVisitor(visitor);
return visitor.getDeviations();
}
/**
*
* @author Diego Pino García<dpino@igalia.com>
*
*/
static class Interval {
public static final double MAX_INTERVALS = 6;
private double min;
private double max;
private Interval() {
}
public static Interval create(double min, double max) {
return new Interval(min, max);
}
private Interval(double min, double max) {
this.min = min;
this.max = max;
}
public static Interval copy(Interval interval) {
return new Interval(interval.min, interval.max);
}
public static Interval containingValue(Collection<Interval> intervals,
Double value) {
for (Interval each : intervals) {
if (each.includes(value)) {
return each;
}
}
return null;
}
private boolean includes(double value) {
return (value >= min) && (value <= max);
}
@Override
public String toString() {
return String.format("[%d, %d]", (int) Math.ceil(min),
(int) Math.ceil(max));
}
}
@Override
public Map<TaskStatusEnum, Integer> calculateTaskStatus() {
AccumulateTasksStatusVisitor visitor = new AccumulateTasksStatusVisitor();
TaskElement rootTask = getRootTask();
if (this.getRootTask() == null) {
throw new RuntimeException("Root task is null");
}
resetTasksStatusInGraph();
rootTask.acceptVisitor(visitor);
return visitor.getTaskStatusData();
}
private void calculateTaskStatusStatistics() {
AccumulateTasksStatusVisitor visitor = new AccumulateTasksStatusVisitor();
TaskElement rootTask = getRootTask();
@ -311,7 +544,8 @@ public class DashboardModel implements IDashboardModel {
throw new RuntimeException("Root task is null");
}
rootTask.acceptVisitor(visitor);
Map<TaskDeadlineViolationStatusEnum, Integer> count = visitor.getTaskDeadlineViolationStatusData();
Map<TaskDeadlineViolationStatusEnum, Integer> count = visitor
.getTaskDeadlineViolationStatusData();
mapAbsoluteValuesToPercentages(count, taskDeadlineViolationStatusStats);
}
@ -342,8 +576,9 @@ public class DashboardModel implements IDashboardModel {
}
private int countTasksInAResultMap(Map<? extends Object, Integer> map) {
/* It's only needed to count the number of tasks once
* each time setOrder is called.
/*
* It's only needed to count the number of tasks once each time setOrder
* is called.
*/
if (this.taskCount != null) {
return this.taskCount.intValue();
@ -356,6 +591,7 @@ public class DashboardModel implements IDashboardModel {
return sum;
}
@Override
public boolean tasksAvailable() {
return getRootTask() != null;
}

View file

@ -0,0 +1,58 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2010-2012 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.libreplan.web.dashboard;
import java.math.BigDecimal;
import org.joda.time.LocalDate;
import org.libreplan.business.orders.entities.Order;
/**
*
* @author Diego Pino García <dpino@igalia.com>
*
*/
interface ICostStatusModel {
BigDecimal getActualCostWorkPerformedAt(LocalDate day);
// Budget at Completion (BAC)
BigDecimal getBudgetAtCompletion();
BigDecimal getBudgetedCostWorkPerformedAt(LocalDate day);
// Cost Performance Index (CPI)
BigDecimal getCostPerformanceIndex(BigDecimal budgetedCost,
BigDecimal actualCost);
// Cost Variance (CV)
BigDecimal getCostVariance(BigDecimal budgetedCost, BigDecimal actualCost);
// Estimate at Completion (EAC)
BigDecimal getEstimateAtCompletion(BigDecimal budgetAtCompletion,
BigDecimal costPerformanceIndex);
// Variance at Completion (VAC)
BigDecimal getVarianceAtCompletion(BigDecimal budgetAtCompletion,
BigDecimal estimateAtCompletion);
void setCurrentOrder(Order order);
}

View file

@ -21,8 +21,11 @@ package org.libreplan.web.dashboard;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.planner.entities.TaskStatusEnum;
import org.libreplan.web.dashboard.DashboardModel.Interval;
interface IDashboardModel {
@ -49,22 +52,31 @@ interface IDashboardModel {
/* Progress KPI: "Global Progress of the Project" */
BigDecimal getAdvancePercentageByHours();
BigDecimal getTheoreticalAdvancePercentageByHoursUntilNow();
BigDecimal getExpectedAdvancePercentageByHours();
BigDecimal getCriticalPathProgressByNumHours();
BigDecimal getTheoreticalProgressByNumHoursForCriticalPathUntilNow();
BigDecimal getExpectedCriticalPathProgressByNumHours();
BigDecimal getCriticalPathProgressByDuration();
BigDecimal getTheoreticalProgressByDurationForCriticalPathUntilNow();
BigDecimal getExpectedCriticalPathProgressByDuration();
/* Time KPI: "Margin with deadline" */
BigDecimal getMarginWithDeadLine();
Integer getAbsoluteMarginWithDeadLine();
/* Time KPI: "Estimation accuracy" */
List<Double> getFinishedTasksEstimationAccuracyHistogram();
/* Time KPI: "Lead/Lag in task completion" */
List<Double> getLagInTaskCompletionHistogram();
Map<TaskStatusEnum, Integer> calculateTaskStatus();
Map<Interval, Integer> calculateTaskCompletation();
Map<Interval, Integer> calculateEstimationAccuracy();
}

View file

@ -554,4 +554,9 @@ public class MaterialsController extends
}
}
}
public String getMoneyFormat() {
return Util.getMoneyFormat();
}
}

View file

@ -184,4 +184,8 @@ public class AssignedHoursToOrderElementController extends
return assignedHoursToOrderElementModel.getExpenseSheetLines();
}
public String getCurrencySymbol() {
return Util.getCurrencySymbol();
}
}

View file

@ -67,4 +67,8 @@ public class DetailsOrderElementController extends
return !orderElementModel.getOrderElement().isLeaf();
}
public String getMoneyFormat() {
return Util.getMoneyFormat();
}
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -30,6 +30,7 @@ import org.libreplan.business.labels.entities.Label;
import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderLineGroup;
import org.libreplan.business.planner.entities.PositionConstraintType;
import org.libreplan.business.qualityforms.entities.QualityForm;
import org.libreplan.business.resources.entities.Criterion;
import org.libreplan.business.resources.entities.CriterionType;
@ -45,6 +46,7 @@ import org.zkoss.zk.ui.Desktop;
*
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Diego Pino García <dpino@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
public interface IOrderModel extends IIntegrationEntityModel {
@ -130,4 +132,6 @@ public interface IOrderModel extends IIntegrationEntityModel {
boolean hasImputedExpenseSheets(OrderElement order);
boolean isAnyTaskWithConstraint(PositionConstraintType type);
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -45,6 +45,7 @@ import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.Order.SchedulingMode;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderStatusEnum;
import org.libreplan.business.planner.entities.PositionConstraintType;
import org.libreplan.business.templates.entities.OrderTemplate;
import org.libreplan.business.users.entities.UserRole;
import org.libreplan.web.common.IMessagesForUser;
@ -86,6 +87,7 @@ import org.zkoss.zul.Comboitem;
import org.zkoss.zul.ComboitemRenderer;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Decimalbox;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Label;
@ -108,6 +110,7 @@ import org.zkoss.zul.api.Window;
*
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
@org.springframework.stereotype.Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -387,11 +390,45 @@ public class OrderCRUDController extends GenericForwardComposer {
return result;
}
private void setConstraintsFor(SchedulingMode mode) {
initDate.setConstraint(mode == SchedulingMode.FORWARD ? "no empty"
: null);
deadline.setConstraint(mode == SchedulingMode.BACKWARDS ? "no empty"
: null);
private void setConstraintsFor(final SchedulingMode mode) {
initDate.setConstraint(new Constraint() {
@Override
public void validate(Component comp, Object value)
throws WrongValueException {
if (value == null) {
if (mode == SchedulingMode.FORWARD) {
throw new WrongValueException(
comp,
_("Starting date cannot be empty in forward mode"));
}
if (orderModel
.isAnyTaskWithConstraint(PositionConstraintType.AS_SOON_AS_POSSIBLE)) {
throw new WrongValueException(comp,
_("Starting date cannot be empty because there is a task with constraint \"as soon as possible\""));
}
}
}
});
deadline.setConstraint(new Constraint() {
@Override
public void validate(Component comp, Object value)
throws WrongValueException {
if (value == null) {
if (mode == SchedulingMode.BACKWARDS) {
throw new WrongValueException(
comp,
_("Deadline cannot be empty in backwards mode"));
}
if (orderModel
.isAnyTaskWithConstraint(PositionConstraintType.AS_LATE_AS_POSSIBLE)) {
throw new WrongValueException(comp,
_("Deadline cannot be empty because there is a task with constraint \"as late as possible\""));
}
}
}
});
}
private void changeFocusAccordingTo(SchedulingMode chosen) {
@ -1184,7 +1221,7 @@ public class OrderCRUDController extends GenericForwardComposer {
appendDate(row, order.getInitDate());
appendDate(row, order.getDeadline());
appendCustomer(row, order.getCustomer());
appendObject(row, order.getTotalBudget());
appendObject(row, Util.addCurrencySymbol(order.getTotalBudget()));
appendObject(row, order.getTotalHours());
appendObject(row, _(order.getState().toString()));
appendOperations(row, order);
@ -1303,8 +1340,8 @@ public class OrderCRUDController extends GenericForwardComposer {
return orderModel.gettooltipText(order);
}
public void reloadTotalBudget(Label txtTotalBudget) {
Util.reloadBindings(txtTotalBudget);
public void reloadTotalBudget(Decimalbox decimalboxTotalBudget) {
Util.reloadBindings(decimalboxTotalBudget);
}
/**
@ -1538,4 +1575,9 @@ public class OrderCRUDController extends GenericForwardComposer {
}
};
}
public String getMoneyFormat() {
return Util.getMoneyFormat();
}
}

View file

@ -393,6 +393,7 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
IOrderElementModel model = orderModel
.getOrderElementModel(currentOrderElement);
orderElementController.openWindow(model);
updateNameFor(currentOrderElement);
updateHoursFor(currentOrderElement);
updateBudgetFor(currentOrderElement);
}
@ -619,6 +620,7 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
public void refreshRow(Treeitem item) {
try {
getRenderer().updateNameFor((OrderElement) item.getValue());
getRenderer().updateHoursFor((OrderElement) item.getValue());
getRenderer().updateBudgetFor((OrderElement) item.getValue());
getRenderer().render(item, item.getValue());
@ -752,4 +754,16 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
};
}
@Override
protected INameHandler<OrderElement> getNameHandler() {
return new INameHandler<OrderElement>() {
@Override
public String getNameFor(OrderElement element) {
return element.getName();
}
};
}
}

View file

@ -3,7 +3,7 @@
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2012 Igalia, S.L.
* Copyright (C) 2010-2012 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
@ -56,6 +56,7 @@ import org.libreplan.business.orders.entities.Order;
import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.orders.entities.OrderLineGroup;
import org.libreplan.business.planner.entities.IMoneyCostCalculator;
import org.libreplan.business.planner.entities.PositionConstraintType;
import org.libreplan.business.qualityforms.daos.IQualityFormDAO;
import org.libreplan.business.qualityforms.entities.QualityForm;
import org.libreplan.business.requirements.entities.DirectCriterionRequirement;
@ -863,4 +864,12 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
}
}
public boolean isAnyTaskWithConstraint(PositionConstraintType type) {
if ((planningState == null) || (planningState.getRootTask() == null)) {
return false;
}
return planningState.getRootTask().isAnyTaskWithConstraint(type);
}
}

View file

@ -236,9 +236,9 @@ class OrderElementOperations extends TreeElementOperationsController<OrderElemen
private int showConfirmCreateTemplateDialog() {
try {
return Messagebox
.show(_("Unsaved changes will be lost. Would you like to continue?",
_("Confirm create template"), Messagebox.YES
| Messagebox.NO, Messagebox.QUESTION));
.show(_("Unsaved changes will be lost. Would you like to continue?"),
_("Confirm create template"), Messagebox.OK
| Messagebox.CANCEL, Messagebox.QUESTION);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}

View file

@ -338,7 +338,8 @@ public abstract class AssignedMaterialsController<T, A> extends GenericForwardCo
Label lblName = new Label(materialCategory.getName());
Label lblUnits = new Label(getUnits(materialCategory).toString());
Label lblPrice = new Label(getPrice(materialCategory).toString());
Label lblPrice = new Label(getPrice(materialCategory).toString()
+ getCurrencySymbol());
Treerow tr = null;
ti.setValue(node);
@ -573,4 +574,12 @@ public abstract class AssignedMaterialsController<T, A> extends GenericForwardCo
.getId().equals(material.getUnitType().getId())));
}
public String getCurrencySymbol() {
return Util.getCurrencySymbol();
}
public String getMoneyFormat() {
return Util.getMoneyFormat();
}
}

View file

@ -90,6 +90,7 @@ import org.libreplan.business.workingday.EffortDuration;
import org.libreplan.business.workingday.EffortDuration.IEffortFrom;
import org.libreplan.business.workingday.IntraDayDate;
import org.libreplan.business.workingday.IntraDayDate.PartialDay;
import org.libreplan.web.common.Util;
import org.libreplan.web.planner.order.PlanningStateCreator.PlanningState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
@ -118,41 +119,8 @@ public class TaskElementAdapter {
private static final Log LOG = LogFactory.getLog(TaskElementAdapter.class);
private static TaskPositionConstraint getLeftMostFixedDateConstraintAmongChildren(
TaskGroup container) {
TaskPositionConstraint constraint = null;
for(TaskElement child : ((TaskGroup)container).getChildren()) {
TaskPositionConstraint currentConstraint = null;
if (child instanceof ITaskPositionConstrained) {
ITaskPositionConstrained task = (ITaskPositionConstrained) child;
currentConstraint = task.getPositionConstraint();
}
else if (child instanceof TaskGroup) {
currentConstraint = getLeftMostFixedDateConstraintAmongChildren(
(TaskGroup) child);
}
if(currentConstraint != null &&
currentConstraint.getConstraintType().equals(
PositionConstraintType.START_IN_FIXED_DATE) &&
(constraint == null || currentConstraint.getConstraintDate().
compareTo(constraint.getConstraintDate()) < 0)) {
constraint = currentConstraint;
}
}
return constraint;
}
public static List<Constraint<GanttDate>> getStartConstraintsFor(
TaskElement taskElement, LocalDate orderInitDate) {
if (taskElement instanceof TaskGroup) {
TaskPositionConstraint constraint =
getLeftMostFixedDateConstraintAmongChildren((TaskGroup) taskElement);
if(constraint == null) {
return Collections.emptyList();
}
return Collections.singletonList(equalTo(toGantt(
constraint.getConstraintDate())));
}
if (taskElement instanceof ITaskPositionConstrained) {
ITaskPositionConstrained task = (ITaskPositionConstrained) taskElement;
TaskPositionConstraint startConstraint = task
@ -1087,19 +1055,18 @@ public class TaskElementAdapter {
if (taskElement.getOrderElement() instanceof Order) {
result.append(_("State") + ": ").append(getOrderState());
} else {
result.append(
_("Budget: {0}€, Consumed: {1}€ ({2}%)",
getBudget(),
getMoneyCost(),
getMoneyCostBarPercentage().multiply(
new BigDecimal(100)))).append(
"<br/>");
String budget = Util.addCurrencySymbol(getBudget());
String moneyCost = Util.addCurrencySymbol(getMoneyCost());
Map<String, BigDecimal> mapCosts = getMoneyItemizedCost();
String costHours = Util.addCurrencySymbol(mapCosts.get("costHours"));
String costExpenses = Util.addCurrencySymbol(mapCosts.get("costExpenses"));
result.append(
_("Budget: {0}, Consumed: {1} ({2}%)", budget, moneyCost,
getMoneyCostBarPercentage().multiply(new BigDecimal(100))))
.append("<br/>");
result.append(
_("cost because of worked hours: {0}€, cost because of expenses: {1}€",
mapCosts.get("costHours"), mapCosts.get("costExpenses")))
.append("<br/>");
costHours, costExpenses));
}
String labels = buildLabelsText();

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -57,7 +57,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zkoss.ganttz.data.GanttDate;
import org.zkoss.ganttz.extensions.IContextWithPlannerTask;
/**
@ -152,7 +151,6 @@ public class AdvanceConsolidationModel implements IAdvanceConsolidationModel {
updateConsolidationInAdvanceIfIsNeeded();
ganttTask.enforceDependenciesDueToPositionPotentiallyModified();
ganttTask.reloadResourcesText();
context.reloadCharts();
}
}

View file

@ -226,6 +226,7 @@ public class PlanningStateCreator {
}
}
PlanningState result = createPlanning(reload(order));
result.onRetrieval();
desktop.setAttribute(ATTRIBUTE_NAME, result);
return result;
}
@ -1133,14 +1134,13 @@ public class PlanningStateCreator {
}
}
public static class RelatedWithAnyOf implements
public static class RelatedWith implements
IAllocationCriteria {
private final Collection<? extends Criterion> anyOf;
private final Criterion criterion;
public RelatedWithAnyOf(
Collection<? extends Criterion> anyOf) {
this.anyOf = anyOf;
public RelatedWith(Criterion criterion) {
this.criterion = criterion;
}
@Override
@ -1156,7 +1156,7 @@ public class PlanningStateCreator {
private boolean someCriterionIn(
Collection<? extends Criterion> allocationCriterions) {
for (Criterion each : allocationCriterions) {
if (this.anyOf.contains(each)) {
if (criterion.equals(each)) {
return true;
}
}

View file

@ -101,4 +101,8 @@ public class SubcontractController extends GenericForwardComposer {
subcontractModel.removeSubcontractedTaskData();
}
public String getMoneyFormat() {
return Util.getMoneyFormat();
}
}

View file

@ -202,6 +202,7 @@ public class MonteCarloTabCreator {
asLocalDate(order.getDeadline()), resourcesSearcher);
GanttDiagramGraph<TaskElement, DependencyWithVisibility> graph = createFor(
order, adapter);
graph.addTask(order.getAssociatedTaskElement());
graph.addTasks(order.getAllChildrenAssociatedTaskElements());
addDependencies(graph, order);
return criticalPathCalculator.calculateCriticalPath(graph);

View file

@ -1,7 +1,7 @@
/*
* This file is part of LibrePlan
*
* Copyright (C) 2011 Igalia, S.L.
* Copyright (C) 2011-2012 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
@ -158,7 +158,6 @@ public class AdvancedAllocationTaskController extends GenericForwardComposer {
private void askForReloads() {
if (context != null) {
context.getTask().reloadResourcesText();
context.reloadCharts();
}
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -39,6 +39,7 @@ import org.libreplan.web.planner.taskedition.TaskPropertiesController.ResourceAl
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.zkoss.ganttz.TaskComponent;
import org.zkoss.ganttz.extensions.IContextWithPlannerTask;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
@ -309,8 +310,12 @@ public class EditTaskController extends GenericForwardComposer {
private void askForReloads() {
if (context != null) {
context.getTask().reloadResourcesText();
org.zkoss.ganttz.data.Task.reloadResourcesText(context);
context.reloadCharts();
if (context.getRelativeTo() instanceof TaskComponent) {
((TaskComponent) context.getRelativeTo()).updateProperties();
((TaskComponent) context.getRelativeTo()).invalidate();
}
}
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -639,4 +639,9 @@ public class TaskPropertiesController extends GenericForwardComposer {
.toDate();
Util.reloadBindings(startDateBox);
}
public String getMoneyFormat() {
return Util.getMoneyFormat();
}
}

View file

@ -90,6 +90,8 @@ public class OrderCostsPerResourceController extends LibrePlanReportController {
result.put("labels", getParameterLabels());
result.put("subReportWRL", "costWorkReportLinesReport.jasper");
result.put("subReportES", "costExpenseSheetLinesReport.jasper");
result.put("currencySymbol", Util.getCurrencySymbol());
return result;
}

View file

@ -3,7 +3,7 @@
*
* 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.
* Copyright (C) 2010-2012 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
@ -39,6 +39,7 @@ import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.joda.time.LocalDate;
import org.libreplan.business.common.daos.IConfigurationDAO;
import org.libreplan.business.costcategories.entities.TypeOfWorkHours;
import org.libreplan.business.expensesheet.entities.ExpenseSheetLine;
import org.libreplan.business.labels.daos.ILabelDAO;
@ -68,6 +69,7 @@ import org.springframework.transaction.annotation.Transactional;
/**
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
* @author Manuel Rego Casasnovas <rego@igalia.com>
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@ -85,6 +87,9 @@ public class OrderCostsPerResourceModel implements IOrderCostsPerResourceModel {
@Autowired
private ICriterionTypeDAO criterionTypeDAO;
@Autowired
private IConfigurationDAO configurationDAO;
private List<Order> selectedOrders = new ArrayList<Order>();
private List<Label> selectedLabels = new ArrayList<Label>();

View file

@ -129,6 +129,7 @@ public class SchedulingProgressPerOrderModel implements ISchedulingProgressPerOr
private void initializeResourceAllocations(Set<ResourceAllocation<?>> resourceAllocations) {
for (ResourceAllocation<?> each: resourceAllocations) {
each.getAssignedHours();
each.getDerivedAllocations().size();
}
}

View file

@ -185,6 +185,8 @@ public class TimeLineRequiredMaterialController extends
result.put("startingDate", getStartingDate());
result.put("endingDate", getEndingDate());
result.put("status", getSelectedStatusName());
result.put("currencySymbol", Util.getCurrencySymbol());
return result;
}

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