Remove slf4j-jdk14 dependency.

Set default config for ExpensesSheet entities obviously in ehcache.xml.
Add log4j loggers.
Minor changes to documentation / i18n.
Code refactoring.
This commit is contained in:
Vova Perebykivskyi 2016-11-15 11:13:21 +02:00
parent 5a7c972d47
commit 46b5997e62
54 changed files with 1066 additions and 1066 deletions

View file

@ -1,8 +1,8 @@
Hacking
=======
This is a guide about how to start hacking on *LibrePlan* project. If you want
more information about *LibrePlan* development you should visit the wiki
This is a guide about how to start hacking on *LibrePlan* project.
If you want more information about *LibrePlan* development you should visit the wiki
available at: http://wiki.libreplan.org/.
.. contents::
@ -15,13 +15,13 @@ Compilation requirements
Needed to clone source code repository
* *Maven 2* - Java software project management and comprehension tool
* *Maven 3* - Java software project management and comprehension tool
Needed to build and compile the project
* *JDK 6* - Java Development Kit
* *JDK 8* - Java Development Kit
Project depends on Java 6 and JDK is needed in order to compile it
Project depends on Java 8 and JDK is needed in order to compile it
* *PostgreSQL* - Object-relational SQL database
@ -56,7 +56,7 @@ Debian/Ubuntu
* Install requirements::
# apt-get install git-core maven2 openjdk-6-jdk postgresql postgresql-client python-docutils make gettext cutycapt
# apt-get install git-core maven openjdk-8-jdk postgresql postgresql-client python-docutils make gettext cutycapt
* Connect to database::
@ -72,7 +72,7 @@ Debian/Ubuntu
* Download source code::
$ git clone git://github.com/Igalia/libreplan.git
$ git clone git://github.com/LibrePlan/libreplan.git
* Compile project::
@ -84,18 +84,18 @@ Debian/Ubuntu
$ cd libreplan-webapp/
$ mvn jetty:run
* Go to http://localhost:8080/libreplan-webapp/
* Go to http://localhost:8080/
Fedora
~~~~~~
* Install requirements::
# yum install git maven java-1.7.0-openjdk-devel postgresql postgresql-server python-docutils make gettext gnu-free-fonts-compat
# yum install git maven java-1.8.0-openjdk-devel postgresql postgresql-server python-docutils make gettext gnu-free-fonts-compat
.. WARNING:: Use the following command in Fedora 16 or below::
# yum install git maven java-1.6.0-openjdk postgresql postgresql-server python-docutils make gettext gnu-free-fonts-compat
# yum install git maven java-1.8.0-openjdk postgresql postgresql-server python-docutils make gettext gnu-free-fonts-compat
* Start database service::
@ -133,7 +133,7 @@ Fedora
* Download source code::
$ git clone git://github.com/Igalia/libreplan.git
$ git clone git://github.com/LibrePlan/libreplan.git
* Compile project::
@ -145,26 +145,26 @@ Fedora
$ cd libreplan-webapp/
$ mvn jetty:run
* Go to http://localhost:8080/libreplan-webapp/
* Go to http://localhost:8080/
openSUSE
~~~~~~~~
* Install requirements::
# zypper install git-core java-1_6_0-openjdk-devel postgresql-server postgresql docutils make gettext-tools
# zypper install git-core java-1_8_0-openjdk-devel postgresql-server postgresql docutils make gettext-tools
* Install Maven::
# cd /opt/
# wget http://www.apache.org/dist//maven/binaries/apache-maven-2.2.1-bin.tar.gz
# tar -xzvf apache-maven-2.2.1-bin.tar.gz
# wget http://www.apache.org/dist//maven/binaries/apache-maven-3.0.5-bin.tar.gz
# tar -xzvf apache-maven-3.0.5-bin.tar.gz
Edit ``/etc/bash.bashrc.local`` and add the following lines::
export M2_HOME=/opt/apache-maven-2.2.1
export M2=$M2_HOME/bin
export PATH=$M2:$PATH
export M2_HOME=/opt/apache-maven-3.0.5
export MVN=$M2_HOME/bin
export PATH=$MVN:$PATH
* Start database service::
@ -194,7 +194,7 @@ openSUSE
* Download source code::
$ git clone git://github.com/Igalia/libreplan.git
$ git clone git://github.com/LibrePlan/libreplan.git
* Compile project::
@ -206,31 +206,31 @@ openSUSE
$ cd libreplan-webapp/
$ mvn jetty:run
* Go to http://localhost:8080/libreplan-webapp/
* Go to http://localhost:8080/
Microsoft Windows
~~~~~~~~
~~~~~~~~~~~~~~~~~
* Download and install latest Java Development Kit 7uXX (JDK7uXX)::
* Download and install latest Java Development Kit 8uXX (JDK8uXX)::
# http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
# http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
* Download and install latest PostgreSQL database::
# http://www.enterprisedb.com/products-services-training/pgdownload#windows
* Download and install Apache Tomcat 6::
* Download and install Apache Tomcat 8::
# http://tomcat.apache.org/download-60.cgi
# http://tomcat.apache.org/download-80.cgi
# Note: in JDK folder there is JRE folder
* Set up JDBC41 PostgreSQL Driver::
# Download latest driver: https://jdbc.postgresql.org/download.html
# Copy downloaded *.jar file to JRE location: (e.g. C:\Program Files\Java\jre7\lib\ext)
# Copy downloaded *.jar file to JAVA_HOME location: (e.g. C:\Program Files\Java\jdk1.7.0_80\jre\lib\ext)
# Put downloaded *.jar file to Tomcat lib location: (e.g. C:\Program Files\Apache Software Foundation\Tomcat 6.0\lib)
# Copy downloaded *.jar file to JRE location: (e.g. C:\Program Files\Java\jre8\lib\ext)
# Copy downloaded *.jar file to JAVA_HOME location: (e.g. C:\Program Files\Java\jdk1.8.0_111\jre\lib\ext)
# Put downloaded *.jar file to Tomcat lib location: (e.g. C:\Program Files\Apache Software Foundation\Tomcat 8.0\lib)
* Create database::
@ -272,7 +272,7 @@ Microsoft Windows
* Configure Apache Tomcat Server
* Go to (e.g. C:/Program Files/Apache Software Foundation/Tomcat 6.0/conf/Catalina/localhost/)
* Go to (e.g. C:/Program Files/Apache Software Foundation/Tomcat 8.0/conf/Catalina/localhost/)
and create there libreplan.xml file with this lines of code::
<?xml version="1.0" encoding="UTF-8"?>
@ -295,7 +295,7 @@ Microsoft Windows
* Set JAVA_HOME environment variable::
# You need to set it to your JDK installed directory (e.g. C:\Program Files\Java\jdk1.7.0_80)
# You need to set it to your JDK installed directory (e.g. C:\Program Files\Java\jdk1.8.0_111)
* Add path of unpacked distributions bin directory of Maven to 'Path' environment variable
@ -310,12 +310,12 @@ Microsoft Windows
* Get *.war file from project folder (e.g ../libreplan/libreplan-webapp/target/libreplan-webapp.war)
* Rename it to libreplan.war
* Put your libreplan.war file to Apache Tomcat webapps folder (e.g. C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\)
* Put your libreplan.war file to Apache Tomcat webapps folder (e.g. C:\Program Files\Apache Software Foundation\Tomcat 8.0\webapps\)
* Start Apache Tomcat server
# Possible location: C:\Program Files\Apache Software Foundation\Tomcat 6.0\bin\Tomcat6.exe
# Possible location: C:\Program Files\Apache Software Foundation\Tomcat 8.0\bin\Tomcat8.exe
* Go to http://localhost:8080/libreplan-webapp/
* Go to http://localhost:8080/
CutyCapt compilation
@ -398,9 +398,8 @@ LibrePlan documentation generation
----------------------------------
In the doc/src folder you'll find several types of documentation
available: technical documentation, user manual, some training
documentation and training exercises. This documentation is available
in several languages.
available: technical documentation, user manual, some training documentation and training exercises.
This documentation is available in several languages.
The supported outputs are HTML and PDF.

View file

@ -1,5 +1,5 @@
Introduction
#############
############
.. contents::
@ -17,7 +17,8 @@ For any specific information you may need about this software, please contact th
Company overview and view management
====================================================
As can be seen in the program's main screen (shot given previously) and the company overview, users can see the list of planned projects to find out about the company's overall situation in relation to orders and the use of resources. The company overview contains 3 views:
As can be seen in the program's main screen (shot given previously) and the company overview, users can see the list of planned projects
to find out about the company's overall situation in relation to orders and the use of resources. The company overview contains 3 views:
* Planning view: View that combines two points of view:
@ -39,7 +40,8 @@ As can be seen in the program's main screen (shot given previously) and the comp
Work Breakdown Structure
The view management commented on previously for the company overview is very similar to the management planned for a single project. A project can be accessed in several ways:
The view management commented on previously for the company overview is very similar to the management planned for a single project.
A project can be accessed in several ways:
* By right clicking on the Gantt chart for the order and then selecting *Plan*.
* By accessing the order list and clicking on the icon for the Gantt diagrams.
@ -80,10 +82,10 @@ On top of the functions offered by the program, there are other features that ma
* History management: The program does not erase information, it only makes it invalid, so users can check older information using date filters.
Usability conventions
==========================
=====================
Information about forms
---------------------------------
-----------------------
Before describing the various functions associated with the most important modules, we need to give a general explanation on how to browse and the forms.
Essentially, there are 3 kinds of editing forms:
@ -102,13 +104,18 @@ Standard icons and buttons
* Search: The magnifying glass is the icon that indicates that the text entry to the left is intended for searching for elements.
Tabs
--------
The program will have content editing and administration forms, which will be represented by graphic components based on tabs. This method is used to organise information from a comprehensive form into different sections that can be accessed by clicking on the names of the different tabs, the others keeping their status. In all cases, the save and cancel options affect the group of sub-forms on the different tabs.
----
The program will have content editing and administration forms, which will be represented by graphic components based on tabs.
This method is used to organise information from a comprehensive form into different sections that can be accessed by clicking on the
names of the different tabs, the others keeping their status. In all cases, the save and cancel options affect the group of sub-forms on
the different tabs.
Explicit actions and context help
--------------------------------------
---------------------------------
The program contains components that provide additional descriptions about the element when hovering over them for one second.
The actions the user may carry out in the program are stated on the button tabs and in the help texts about them, the browsing menu options and the options on the context menus that open out when right clicking on the planner area.
Furthermore, short cuts are given for the main operations by double clicking the listed elements or by associating key events with cursors and the enter key, which is how to add elements when moving through the forms.
The actions the user may carry out in the program are stated on the button tabs and in the help texts about them, the browsing menu
options and the options on the context menus that open out when right clicking on the planner area.
Furthermore, short cuts are given for the main operations by double clicking the listed elements or by associating key events with
cursors and the enter key, which is how to add elements when moving through the forms.

View file

@ -1,9 +1,14 @@
Criteria
#########
########
.. contents::
Criteria are elements that are used in the program to categorise resources and tasks. Tasks need criteria and the resources fulfil them. The following sequence is an example of how to use criteria: A resource is designated the criterion of "welder" (that is the resource fulfils the "welder" category) and a task requires the "welder" criterion to be carried out. As a result, when resources are allocated to tasks, workers with the "welder" criterion are used when allocating resources generically (not applicable to specific allocation). See the chapter on allocating resources to find out more about the different kinds of allocation.
Criteria are elements that are used in the program to categorise resources and tasks. Tasks need criteria and the resources fulfil them.
The following sequence is an example of how to use criteria:
A resource is designated the criterion of "welder" (that is the resource fulfils the "welder" category) and a task requires the "welder"
criterion to be carried out. As a result, when resources are allocated to tasks, workers with the "welder"
criterion are used when allocating resources generically (not applicable to specific allocation).
See the chapter on allocating resources to find out more about the different kinds of allocation.
Several operations can be carried out with criteria in the program:
@ -12,11 +17,12 @@ Several operations can be carried out with criteria in the program:
* Allocation of criteria to tasks.
* Filtering entities according to criteria. Tasks and order items can be filtered according to criteria to carry out operations in the program.
Only the first function out of the three described above will be explained in this section. The two kinds of allocation will be dealt with later, the allocation of resources in the chapter on "Resource management" and the filtering function in the chapter on "Task planning".
Only the first function out of the three described above will be explained in this section. The two kinds of allocation will be dealt with later,
the allocation of resources in the chapter on "Resource management" and the filtering function in the chapter on "Task planning".
Criteria administration
===========================
=======================
Criteria administration can be accessed from the administration menu:
.. figure:: images/menu.png

View file

@ -1,11 +1,13 @@
Calendars
###########
#########
.. contents::
Calendars are the program entities that determine the load capacity of different resources. A calendar consists of a series of days in the year with each day divided into available working hours.
Calendars are the program entities that determine the load capacity of different resources.
A calendar consists of a series of days in the year with each day divided into available working hours.
For example, a public holiday may have 0 hours available and, if the working hours in a workday are 8, this is the number of hours that is designated as available time for that day.
For example, a public holiday may have 0 hours available and, if the working hours in a workday are 8,
this is the number of hours that is designated as available time for that day.
There are two ways of informing the system of how many working hours there are in a day:
@ -13,9 +15,11 @@ There are two ways of informing the system of how many working hours there are i
* According to exceptions. For example, 10 working hours on Monday 30 January.
Administration of calendars
=============================
===========================
The calendar system is hierarchical, meaning that base calendars or calendars based on them can be created, thus maintaining a tree structure. A calendar based on a calendar from a higher level of the tree will take on the daily duties and exceptions, providing that they have not been explicitly modified for the new calendar. The following concepts must be understood to manage calendars:
The calendar system is hierarchical, meaning that base calendars or calendars based on them can be created, thus maintaining a tree structure.
A calendar based on a calendar from a higher level of the tree will take on the daily duties and exceptions, providing that they have not
been explicitly modified for the new calendar. The following concepts must be understood to manage calendars:
* Each day is independent in itself and each year has different days. For example, if 8 December 2009 is a public holiday, this does not mean that 2010 already has 8 December marked as a public holiday.
* Working days are based on weekdays. For example, if it is normal to work 8 hours on Mondays, all the Mondays from all the weeks in the different years will have 8 hours available.
@ -34,9 +38,10 @@ The administration of calendars can be accessed from the procedures on the "Admi
4. Editing an existing calendar.
Creating a new calendar
-------------------------------
-----------------------
In order to create a new calendar, users need to click the "Create" button. The system then shows a form where users can carry out the following procedures:
In order to create a new calendar, users need to click the "Create" button.
The system then shows a form where users can carry out the following procedures:
* Choosing the tab they want to work on.
@ -56,7 +61,8 @@ In order to create a new calendar, users need to click the "Create" button. The
* Distribute different weekly hours for the future.
* Delete previous hour distribution lists.
With these procedures, users of the program can fully personalise the calendars according to their needs. Users need to click the "Save" button to store changes made to the form.
With these procedures, users of the program can fully personalise the calendars according to their needs.
Users need to click the "Save" button to store changes made to the form.
.. figure:: images/calendar-edition.png
:scale: 50
@ -71,11 +77,17 @@ With these procedures, users of the program can fully personalise the calendars
Creating derived calendars
----------------------------------
A derived calendar is a calendar created from another existing one. For example, it has all the features of the original one, but users can change it to contain other options.
A derived calendar is a calendar created from another existing one. For example, it has all the features of the original one,
but users can change it to contain other options.
An example of using derived calendars is when there is a general calendar for Spain, and the creation of a derived calendar to include public holidays in Galicia in additional to the ones defined in the general calendar.
An example of using derived calendars is when there is a general calendar for Spain, and the creation of a derived calendar
to include public holidays in Galicia in additional to the ones defined in the general calendar.
It is important to point out that any change made to the original calendar is made directly to the derived calendar, providing that a specific exception against this was not defined. For example, the calendar for Spain has an 8-hour working day on 17 May, but the calendar for Galicia (a derived calendar) has no working hours on the very same day, as it is a public holiday. If the Spanish calendar was changed to have 4 hours available per day for the week of 17 May, the Galician calendar would also change to have 4 hours available for every day on the same week, except 17 May, which would have no working hours for the reason stated above.
It is important to point out that any change made to the original calendar is made directly to the derived calendar,
providing that a specific exception against this was not defined. For example, the calendar for Spain has an 8-hour working day on 17 May,
but the calendar for Galicia (a derived calendar) has no working hours on the very same day, as it is a public holiday.
If the Spanish calendar was changed to have 4 hours available per day for the week of 17 May, the Galician calendar would also
change to have 4 hours available for every day on the same week, except 17 May, which would have no working hours for the reason stated above.
.. figure:: images/calendar-create-derived.png
:scale: 50
@ -90,13 +102,16 @@ To create a derived calendar in the program, it is necessary to:
* Once this procedure has been carried out, the system shows an editing form with the same characteristics as the forms used to create forms from scratch, with the difference that the proposed exceptions and the hours per weekday are based on the original calendar.
Creating a calendar by copying
-----------------------------------
------------------------------
A copied calendar is a calendar created as an exact copy of another existing one. For example, it has all the features of the original one, but users can also change it to contain other options.
A copied calendar is a calendar created as an exact copy of another existing one. For example, it has all the features of the original one,
but users can also change it to contain other options.
The difference between a copied and a derived calendar is based on the changes in the original. In relation to copies, if the original is modified, the copy is not affected. However, derived calendars are affected by changes made to the original.
The difference between a copied and a derived calendar is based on the changes in the original. In relation to copies, if the original
is modified, the copy is not affected. However, derived calendars are affected by changes made to the original.
An example of using a copied calendar is having a calendar for "Pontevedra" and needing a calendar for "A Coruña", for which most of the features would be the same. However, changes on one calendar should not be reflected in the other.
An example of using a copied calendar is having a calendar for "Pontevedra" and needing a calendar for "A Coruña", for which most of
the features would be the same. However, changes on one calendar should not be reflected in the other.
To create a copied calendar in the program, it is necessary to do the following:
@ -106,9 +121,10 @@ To create a copied calendar in the program, it is necessary to do the following:
* Once this procedure has been carried out, the system shows an editing form with the same characteristics as the forms used to create forms from scratch, with the difference that the proposed exceptions and the hours per weekday are based on the original calendar.
Default calendar
----------------------
----------------
One of the existing calendars in the system can be marked as the default calendar. This calendar is the one that will be designated to any entity in the system that is managed with calendars.
One of the existing calendars in the system can be marked as the default calendar.
This calendar is the one that will be designated to any entity in the system that is managed with calendars.
The following must be carried out to set up a default calendar:
@ -123,16 +139,19 @@ The following must be carried out to set up a default calendar:
Creating a default calendar
Assigning a calendar to resources
-----------------------------------
---------------------------------
Resources can only be activated, i.e. available working hours, if they have an assigned calendar with a valid activation period. If no calendar is assigned to resources, the default calendar is assigned with an activation period that begins on the start date and does not have an expiry date.
Resources can only be activated, i.e. available working hours, if they have an assigned calendar with a valid activation period.
If no calendar is assigned to resources, the default calendar is assigned with an activation period that begins on the start
date and does not have an expiry date.
.. figure:: images/resource-calendar.png
:scale: 50
Calendar of resources
However, users can delete the calendar that has been previously assigned to a resource and create a new calendar based on one that already exists. Consequently, resources can be fully personalised in relation to calendars.
However, users can delete the calendar that has been previously assigned to a resource and create a new calendar based on one that already exists.
Consequently, resources can be fully personalised in relation to calendars.
The following steps have to be carried out to assign a calendar:
@ -155,7 +174,7 @@ The following steps have to be carried out to assign a calendar:
Assigning new calendars to resources
Assigning calendars to orders
----------------------------------
-----------------------------
Projects can have a different calendar to the default calendar. Users need to do the following to change the calendar for the order:
@ -166,8 +185,9 @@ Projects can have a different calendar to the default calendar. Users need to do
* Click "Save" or "Save and continue".
Assigning calendars to tasks
----------------------------------
In the same way that calendars can be assigned to resources or orders, users can carry out the same procedure for planned tasks. This procedure allows specific calendars to be defined for specific stages of a project. To carry out this procedure, it is necessary to:
----------------------------
In the same way that calendars can be assigned to resources or orders, users can carry out the same procedure for planned tasks.
This procedure allows specific calendars to be defined for specific stages of a project. To carry out this procedure, it is necessary to:
* Access the planning of a project.
* Right click the task to which a calendar is to be assigned.

View file

@ -1,27 +1,39 @@
Progress
#########
########
.. contents::
The progress of a project shows the degree to which the estimated time of completion of the project is being fulfilled, and the progress of a task indicates the degree to which it is being fulfilled in terms of estimated completion.
The progress of a project shows the degree to which the estimated time of completion of the project is being fulfilled,
and the progress of a task indicates the degree to which it is being fulfilled in terms of estimated completion.
In general, progress cannot be measured automatically; a member of staff with experience or a checklist has to determine the degree of completion of a task or project.
In general, progress cannot be measured automatically; a member of staff with experience or a checklist has to determine the degree
of completion of a task or project.
It should be noted that there is a significant difference between the use of hours assigned to a task or project and the degree of progress of that task or project. While the number of used hours may be more or less than they should be, the project may be behind or ahead of its estimated completion on the day that is being monitored. Several possible situations may arise due to these two measurements:
It should be noted that there is a significant difference between the use of hours assigned to a task or project and the degree
of progress of that task or project. While the number of used hours may be more or less than they should be, the project may be behind
or ahead of its estimated completion on the day that is being monitored. Several possible situations may arise due to these two measurements:
* Less hours are consumed than expected for the element that is to be measured and, at the same time, the project is more behind than expected because progress is lower than estimated for the day that is being monitored.
* Less hours are consumed than expected for the element that is to be measured and, at the same time, the project is more ahead than expected because progress is lower than estimated for the day that is being monitored.
* More hours are consumed than expected and, at the same time, the project is more behind than expected because progress is lower than estimated for the day that is being monitored.
* More hours are consumed than expected and, at the same time, the project is more ahead than expected because progress is lower than expected for the day that is being monitored.
It is possible to compare these possible situations from the planning itself by using information relating to the degree of progress made and also the degree to which the hours have been used. This chapter will deal with the entering of information in order to carry out the monitoring of progress.
It is possible to compare these possible situations from the planning itself by using information relating to the degree of progress
made and also the degree to which the hours have been used. This chapter will deal with the entering of information in order to carry out
the monitoring of progress.
The philosophy of the project for monitoring progress is based on the users stating how far they want to monitor the progress of their projects. As a result, if users want to monitor orders, they only have to enter information for level-1 elements. If they want monitoring to be more precise in relation to tasks, they have to enter information about progress at lower levels, and it is the system that transmits all of the data upwards in the hierarchy.
The philosophy of the project for monitoring progress is based on the users stating how far they want to monitor the progress of their projects.
As a result, if users want to monitor orders, they only have to enter information for level-1 elements. If they want monitoring to be more precise
in relation to tasks, they have to enter information about progress at lower levels, and it is the system that transmits all of the data upwards
in the hierarchy.
Managing types of progress
==========================
All companies have different needs when monitoring project progress, specifically the tasks they consist of. It was therefore necessary to consider the existence of entities in the system called “types of progress”. Users can register the different types of progress in the system to measure a task's progress. For example, a task can be measured in percentage terms, but at the same time, this percentage progress can be translated to progress in *Tonnes* on the agreed amount with the client.
All companies have different needs when monitoring project progress, specifically the tasks they consist of. It was therefore necessary
to consider the existence of entities in the system called “types of progress”. Users can register the different types of progress in the system
to measure a task's progress. For example, a task can be measured in percentage terms, but at the same time, this percentage progress can be
translated to progress in *Tonnes* on the agreed amount with the client.
A type of progress is given a name, a maximum value and a precision value:
@ -56,14 +68,17 @@ Users can create new types of progress in the following way:
* Maximum value accepted by the type of progress.
* Precision value for the type of progress.
Entering progress based on t
======================================
Entering progress based on type
===============================
Entering progress is done on order elements, but it can also be done using a short cut from the planning tasks. The decision on what type of progress users want to associate with each order element is their own responsibility.
Entering progress is done on order elements, but it can also be done using a short cut from the planning tasks.
The decision on what type of progress users want to associate with each order element is their own responsibility.
Users can enter a unique and default type of progress for the whole order.
Before carrying out progress measurements, users need to associate the chosen type with the order. For example, progress in percentage terms to measure progress made on the entire task or an agreed progress rate if progress measurements agreed with the client are to be entered in the future.
Before carrying out progress measurements, users need to associate the chosen type with the order.
For example, progress in percentage terms to measure progress made on the entire task or an agreed progress rate if progress
measurements agreed with the client are to be entered in the future.
.. figure:: images/avance.png
:scale: 40
@ -81,9 +96,11 @@ The following must be done to enter progress measurements:
Comparison of progress with an order element
=================================================
============================================
Users can compare graphically how much progress is being made on the orders with the measurements taken. All types of progress have a column with a check button (called "Show"). When this is marked, the progress chart of measurements taken is shown on the order element.
Users can compare graphically how much progress is being made on the orders with the measurements taken.
All types of progress have a column with a check button (called "Show").
When this is marked, the progress chart of measurements taken is shown on the order element.
.. figure:: images/contraste-avance.png
:scale: 40

View file

@ -31,7 +31,7 @@ Users can create, edit and invalidate (never delete definitively) workers from t
* List of machines: Machines will be shown in lists and will be numbered. This is where their details can be managed.
Management of workers
========================
=====================
The management of workers is carried out by going to the "Resources" tab and then the feature "List of workers". Users can edit all of the workers on the resource list by clicking the standard editing icon.

View file

@ -1,19 +1,23 @@
Orders and order elements
##############################
#########################
.. contents::
Orders describe the work to be carried out by the users who use the program.
Each order corresponds with the projects that the companies are going to offer their clients.
An order consists of one or several order lines. Each order line corresponds with the planning the works on the order should follow when being implemented. Order lines are organised hierarchically without any limitations on depth. The fact that order lines are organised hierarchically shows how several inheritable features work, such as labels.
An order consists of one or several order lines.
Each order line corresponds with the planning the works on the order should follow when being implemented.
Order lines are organised hierarchically without any limitations on depth.
The fact that order lines are organised hierarchically shows how several inheritable features work, such as labels.
The following sections will describe the operations that users can carry out with orders and order lines.
Order
======
=====
An order is a project or work that a client requests from a company. The order for the planned works identifies the project in the company. The difference with comprehensive management programs such as "LibrePlan" is that they only need to use certain order details. These details are:
An order is a project or work that a client requests from a company. The order for the planned works identifies the project in the company.
The difference with comprehensive management programs such as "LibrePlan" is that they only need to use certain order details. These details are:
* Order name
* Order code
@ -128,7 +132,8 @@ Users can access the following tabs from the editing order option:
Editing order elements
==============================
Editing order elements is carried out from the "Order element list" tab by clicking the editing icon, which shows a new screen from which the user can carry out the following:
Editing order elements is carried out from the "Order element list" tab by clicking the editing icon, which shows a new screen
from which the user can carry out the following:
* Edit information about the order element.
* View hours attributed to order elements.
@ -141,7 +146,7 @@ Editing order elements is carried out from the "Order element list" tab by click
The following subsections describe each one of the operations in depth.
Editing information about the order element
------------------------------------------------
-------------------------------------------
Editing information about the order element includes the editing of the following details:
@ -161,7 +166,8 @@ Editing information about the order element includes the editing of the followin
Viewing hours attributed to order elements
------------------------------------------------------
The "Assigned hours" tab enables users to view the work reports associated with an order element and also how many of the estimated hours have already been carried out.
The "Assigned hours" tab enables users to view the work reports associated with an order element and also how many of the estimated hours have
already been carried out.
.. figure:: images/order-element-hours.png
:scale: 50
@ -174,16 +180,19 @@ The screen is divided into two parts:
* Use of estimated hours: The system calculates the total number of hours devoted to a task and compares them with the estimated hours.
Managing progress of order elements
---------------------------------------------
-----------------------------------
Entering types of progress and the management of order element progress has been described in the "Progress" chapter.
Managing order labels
------------------------------
---------------------
Labels, as described in the chapter on labels, enable users to categorise order elements. Consequently, users can group planning or order information based on them.
Labels, as described in the chapter on labels, enable users to categorise order elements.
Consequently, users can group planning or order information based on them.
Users can assign labels directly to an order element or even to a previous order element in the hierarchy. From the moment a label from one of the two previous methods is assigned, the order element and the related planning task are associated with the label, and used for subsequent filtering.
Users can assign labels directly to an order element or even to a previous order element in the hierarchy.
From the moment a label from one of the two previous methods is assigned, the order element and the related planning task are associated with the label,
and used for subsequent filtering.
.. figure:: images/order-element-tags.png
:scale: 50
@ -199,14 +208,16 @@ As can be seen in the image, users can carry out the following procedures from t
Managing criteria required by the order element and hour groups
--------------------------------------------------------------------------------
---------------------------------------------------------------
Both an order and an order element can be assigned criteria that need to be fulfilled for it to be carried out. Criteria can be direct or indirect:
* Direct criteria: These are assigned directly to the order element. They are criteria that are required by the hour groups on the order element.
* Indirect criteria: These are assigned on order elements that are higher in the hierarchy and are inherited by the element that is being edited.
Apart from the required criterion, one or various hour groups that are part of the order element can be defined. It all depends on whether the order element contains other order elements as child nodes or if it is a leaf node. In the first case the information about hours and hour groups can only be viewed, but leaf nodes can be edited. The latter case works as follows:
Apart from the required criterion, one or various hour groups that are part of the order element can be defined.
It all depends on whether the order element contains other order elements as child nodes or if it is a leaf node.
In the first case the information about hours and hour groups can only be viewed, but leaf nodes can be edited. The latter case works as follows:
* The system creates an hour group by default, which is associated to the order element. The details that can be modified for an hour group are:
@ -225,7 +236,8 @@ Apart from the required criterion, one or various hour groups that are part of t
Managing materials
------------------------
Materials are managed in the projects as a list associated with each order line or an order in general. The list of materials is made up of the following fields:
Materials are managed in the projects as a list associated with each order line or an order in general.
The list of materials is made up of the following fields:
* Code
* Date
@ -262,19 +274,22 @@ Working with materials is carried out as follows:
* Users select the units, status and date of assigned materials.
For subsequent monitoring of materials, it is possible to change the status of a unit group of the received material. This procedure is carried out as follows:
For subsequent monitoring of materials, it is possible to change the status of a unit group of the received material.
This procedure is carried out as follows:
* Users click the "Divide" button on the list of materials to the right of each row.
* Users select the number of units they want the row to be divided into.
* The program shows two rows with the material divided.
* Users change the status of the row containing the material.
The advantage of using this dividing tool is the possibility of receiving partial deliveries of material without having to wait to receive it all in order to mark it as received.
The advantage of using this dividing tool is the possibility of receiving partial deliveries of material without having to wait
to receive it all in order to mark it as received.
Managing quality forms
------------------------------------
----------------------
Some order elements must certify that certain tasks have been carried out in order for them to be marked as complete. This is why the program has quality forms, which consist of a list of questions that can be considered important if they are answered positively.
Some order elements must certify that certain tasks have been carried out in order for them to be marked as complete.
This is why the program has quality forms, which consist of a list of questions that can be considered important if they are answered positively.
It is important to mention that a quality form has to be created previously so that it can be assigned to an order element.

View file

@ -1,5 +1,5 @@
Task planning
#######################
#############
.. _planificacion:
.. contents::
@ -8,14 +8,17 @@ Task planning
Task planning
=============
Planning in "LibrePlan" is a process that has been described throughout all of the chapters of the user guide, the chapters on orders and the assigning of resources being particularly important in this respect. This chapter describes basic planning procedures after the order and the Gantt charts have been configured properly.
Planning in "LibrePlan" is a process that has been described throughout all of the chapters of the user guide,
the chapters on orders and the assigning of resources being particularly important in this respect.
This chapter describes basic planning procedures after the order and the Gantt charts have been configured properly.
.. figure:: images/planning-view.png
:scale: 35
Work planning view
As with the company overview, the project planning view is divided into several views based on the information it is analysing. The views of a specific project are:
As with the company overview, the project planning view is divided into several views based on the information it is analysing.
The views of a specific project are:
* Planning view
* Resource load view
@ -23,7 +26,7 @@ As with the company overview, the project planning view is divided into several
* Advanced assignment view
Planning view
----------------------
-------------
The planning view combines three different views:
* Project planning. Project planning can be viewed in the upper right-hand part of the program. It represents the planning in a Gantt chart. This is the view where users can temporarily move tasks, assign dependencies among them, define milestones and establish restrictions.
@ -73,8 +76,10 @@ The planning view also offers several procedures that ultimately function as vie
* Print: Enabling users to print the Gantt chart being viewed at that moment.
Resource load view
--------------------------
The resource load view provides a list of resources that contains a list of tasks or criteria that generate workloads. Each task or criterion is shown as a Gantt chart so that the start and end date of the load can be seen. A different colour is shown depending on whether the resource has a load that is higher or lower than 100%:
------------------
The resource load view provides a list of resources that contains a list of tasks or criteria that generate workloads.
Each task or criterion is shown as a Gantt chart so that the start and end date of the load can be seen.
A different colour is shown depending on whether the resource has a load that is higher or lower than 100%:
* Green: load lower than 100%
* Orange: 100% load
@ -93,7 +98,7 @@ The order list view allows users to go to the order editing and deleting options
Advanced assignment view
----------------------------
------------------------
The advanced assignment view is explained in depth in the "Resource assignment" chapter.

View file

@ -1,21 +1,23 @@
Tags
#########
####
.. contents::
Tags are entities used in the program to conceptually organise tasks or order elements.
Tags are categorised according to tag type. A tag can only belong to one tag type, however, users can create many similar tags belonging to different tag types.
Tags are categorised according to tag type. A tag can only belong to one tag type, however,
users can create many similar tags belonging to different tag types.
Tag types
===========
=========
Tag types are used to group the types of tag that users want to manage in the program. Here are some examples of possible tag types:
i. Client: Users may be interested in tagging tasks, orders or order elements in relation to the client who requests them.
ii. Area: Users may be interested in tagging tasks, orders or order elements in relation to the areas in which they are carried out.
The administration of tag types is managed from the "Administration" menu option. This is where users can edit tag types, create new tag types and add tags to tag types. Users can access the list of tags from this option.
The administration of tag types is managed from the "Administration" menu option.
This is where users can edit tag types, create new tag types and add tags to tag types. Users can access the list of tags from this option.
.. figure:: images/tag-types-list.png
:scale: 50
@ -28,7 +30,9 @@ i. Create a new tag type.
ii. Edit an existing tag type.
iii. Delete a tag type with all of its tags.
Editing and creating tags share the same form. From this form, the user can assign a name to the tag type, create or delete tags and store the changes. The procedure is as follows:
Editing and creating tags share the same form.
From this form, the user can assign a name to the tag type, create or delete tags and store the changes.
The procedure is as follows:
i. Select a tag to edit or click the create button for a new one.
ii. The system shows a form with a text entry for the name and a list of text entries with existing and assigned tags.
@ -46,7 +50,9 @@ vii. Users click "Save" or "Save and continue" to continue editing the form.
Tags
====
Tags are entities that belong to a tag type. These entities can be assigned to order elements. Assigning a tag to an order element means that all the elements descending from this element will inherit the tag to which they belong. Having an assigned tag means that these entities are filtered where searches can be carried out:
Tags are entities that belong to a tag type. These entities can be assigned to order elements.
Assigning a tag to an order element means that all the elements descending from this element will inherit the tag to which they belong.
Having an assigned tag means that these entities are filtered where searches can be carried out:
i. Search for tasks in the Gantt chart.
ii. Search for order elements in the list of order elements.

View file

@ -1,5 +1,5 @@
Materials
##########
#########
.. _materiales:
.. contents::
@ -9,7 +9,8 @@ Administration of materials
Users can manage a basic database of materials, organised by categories.
The categories are containers that can be assigned specific materials and also more categories. They are stored in a tree structure as the materials can belong to leaf or intermediary categories.
The categories are containers that can be assigned specific materials and also more categories.
They are stored in a tree structure as the materials can belong to leaf or intermediary categories.
Users have to do the following to manage categories:

View file

@ -1,5 +1,5 @@
Quality forms
######################
#############
.. _calidad:
.. contents::
@ -8,7 +8,8 @@ Quality forms
Administration of quality forms
===============================
Quality forms consist of a list of questions or sentences that indicate the tasks or processes that should have been completed so that a task can be marked as complete by the company. These forms consist of the following fields:
Quality forms consist of a list of questions or sentences that indicate the tasks or processes that should have been
completed so that a task can be marked as complete by the company. These forms consist of the following fields:
* Name
* Description

View file

@ -1,5 +1,5 @@
Cost management
#################
###############
.. _costes:
.. contents::
@ -25,7 +25,7 @@ Cost management allows users to estimate the costs of resources used in a projec
Managing hour types worked
------------------------------------------
--------------------------
Users need to carry out the following steps to register hour types worked:
@ -55,7 +55,7 @@ Users need to carry out the following steps to register hour types worked:
* Click "Save" or "Save and continue".
Cost categories
-------------------
---------------
Users need to carry out the following steps to register cost categories:

View file

@ -119,7 +119,7 @@ overload)**.
* > 0 is bad, meaning that the resources are overloaded.
Availability ratio
-------------------
------------------
It sums up the capacity that is free in the resources currently allocated to the
project. Therefore it is a measurement of the resource availability to receive more allocations without

View file

@ -1,5 +1,5 @@
Connectors
##################
##########
.. contents::
@ -214,7 +214,7 @@ not available for that ``total duration``. But in Libreplan if the worker is on
The Tim connector also takes care of this translation.
E-mail connector
==============
================
E-mail is a method of exchanging digital messages from an author to one or more recipients.
@ -273,4 +273,4 @@ gathering data and sending it to user`s e-mail. See also the Scheduler manual.
.. NOTE::
The success or failure information would be displayed in pop-up window.
The success or failure information would be displayed in pop-up window.

View file

@ -1,5 +1,5 @@
Scheduler
##################
#########
.. contents::
@ -44,7 +44,7 @@ The ``job scheduling list`` view allows users to
* start a process manually
Add or Edit Job
=================
===============
From the ``job scheduling list`` view, click
* ``Create`` button to add a new Job or
@ -83,5 +83,4 @@ will be shown.
Start Job Manually
==================
As an alternative to wait until the Job is run as scheduled by the scheduler, you can click this button to start the
process directly. Afterwards the success/failure info will be shown in ``pop-up window``.
process directly. Afterwards the success/failure info will be shown in ``pop-up window``.

View file

@ -1,5 +1,5 @@
About
#################
#####
.. _acercade:
.. contents::
@ -21,7 +21,7 @@ S.L.
Licence
========
=======
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
@ -38,7 +38,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
Written by
================
==========
LibrePlan Team
--------------
@ -109,15 +109,19 @@ Contributors
Public funding
================================
==============
Inside the global scope that LibrePlan is designed for regarding planning management, a project was developed to solve some common polanning problems. This project is partially financed by Xunta de Galicia, Ministerio de Industria, Turismo e Comercio, and by the European Union, Fondo Europeo de Desenvolvemento Rexional.
Inside the global scope that LibrePlan is designed for regarding planning management,
a project was developed to solve some common planning problems.
This project is partially financed by Xunta de Galicia, Ministerio de Industria, Turismo e Comercio, and by the European Union,
Fondo Europeo de Desenvolvemento Rexional.
.. figure:: images/logos.png
:scale: 100
This project was part of Plan Avanza:
.. figure:: images/avanza.png
:scale: 100
:scale: 100

View file

@ -29,8 +29,7 @@ import org.zkoss.ganttz.data.Task;
*/
public class MilestoneComponent extends TaskComponent {
public MilestoneComponent(Task task,
IDisabilityConfiguration disabilityConfiguration) {
public MilestoneComponent(Task task, IDisabilityConfiguration disabilityConfiguration) {
super(task, disabilityConfiguration);
}

View file

@ -74,12 +74,10 @@ import org.zkoss.zul.Combobox;
public class Planner extends HtmlMacroComponent {
private static final String PLANNER_COMMAND = "planner-command";
private static final Log PROFILING_LOG = ProfilingLogFactory.getLog(Planner.class);
private static int PIXELS_PER_TASK_LEVEL = 21;
private static int PIXELS_PER_CHARACTER = 5;
private String EXPAND_ALL_BUTTON = "expandAll";
private GanttZKDiagramGraph diagramGraph;
@ -120,8 +118,7 @@ public class Planner extends HtmlMacroComponent {
private Listbox listZoomLevels = null;
private WeakReferencedListeners<IChartVisibilityChangedListener> chartVisibilityListeners =
WeakReferencedListeners.create();
private WeakReferencedListeners<IChartVisibilityChangedListener> chartVisibilityListeners = WeakReferencedListeners.create();
private IGraphChangeListener showCriticalPathOnChange = new IGraphChangeListener() {
@Override
@ -163,7 +160,8 @@ public class Planner extends HtmlMacroComponent {
private boolean visibleChart;
public Planner() {}
public Planner() {
}
public static boolean guessContainersExpandedByDefaultGivenPrintParameters(Map<String, String> printParameters) {
return guessContainersExpandedByDefault(convertToURLParameters(printParameters));
@ -180,30 +178,22 @@ public class Planner extends HtmlMacroComponent {
public static boolean guessContainersExpandedByDefault(Map<String, String[]> queryURLParameters) {
String[] values = queryURLParameters.get("expanded");
return values != null && toLowercaseSet(values).contains("all");
}
public static boolean guessShowAdvancesByDefault(Map<String, String[]> queryURLParameters) {
String[] values = queryURLParameters.get("advances");
return values != null && toLowercaseSet(values).contains("all");
}
public static boolean guessShowReportedHoursByDefault(Map<String, String[]> queryURLParameters) {
String[] values = queryURLParameters.get("reportedHours");
return values != null && toLowercaseSet(values).contains("all");
}
public static boolean guessShowMoneyCostBarByDefault(Map<String, String[]> queryURLParameters) {
String[] values = queryURLParameters.get("moneyCostBar");
return values != null && toLowercaseSet(values).contains("all");
}
private static Set<String> toLowercaseSet(String[] values) {
@ -233,6 +223,8 @@ public class Planner extends HtmlMacroComponent {
IDomainAndBeansMapper<?> mapper = getContext().getMapper();
int widest = 0;
int pixelsPerTaskLevel = 21;
int pixelsPerCharacter = 5;
for (Task task : tasks) {
int numberOfAncestors = mapper.findPositionFor(task).getAncestors().size();
@ -240,7 +232,7 @@ public class Planner extends HtmlMacroComponent {
widest = Math.max(
widest,
numberOfCharacters * PIXELS_PER_CHARACTER + numberOfAncestors * PIXELS_PER_TASK_LEVEL);
numberOfCharacters * pixelsPerCharacter + numberOfAncestors * pixelsPerTaskLevel);
if ( expand && !task.isLeaf() ) {
widest = Math.max(widest, calculateMinimumWidthForTaskNameColumn(expand, task.getTasks()));
@ -451,7 +443,7 @@ public class Planner extends HtmlMacroComponent {
+ (System.currentTimeMillis() - timeSetupingAndAddingComponents) + " ms");
setAuService(new AuService() {
public boolean service(AuRequest request, boolean everError){
public boolean service(AuRequest request, boolean everError) {
String command = request.getCommand();
int zoomindex;
int scrollLeft;
@ -493,6 +485,7 @@ public class Planner extends HtmlMacroComponent {
private <T> List<CommandOnTaskContextualized<T>> contextualize(FunctionalityExposedForExtensions<T> context,
List<ICommandOnTask<T>> commands) {
List<CommandOnTaskContextualized<T>> result = new ArrayList<>();
for (ICommandOnTask<T> c : commands) {
result.add(contextualize(context, c));
@ -551,11 +544,11 @@ public class Planner extends HtmlMacroComponent {
@SuppressWarnings("unchecked")
private void insertGlobalCommands() {
Component commontoolbar = getCommonCommandsInsertionPoint();
Component commonToolbar = getCommonCommandsInsertionPoint();
Component plannerToolbar = getSpecificCommandsInsertionPoint();
if ( !contextualizedGlobalCommands.isEmpty() ) {
commontoolbar.getChildren().removeAll(commontoolbar.getChildren());
commonToolbar.getChildren().removeAll(commonToolbar.getChildren());
}
for (CommandContextualized<?> c : contextualizedGlobalCommands) {
@ -569,7 +562,7 @@ public class Planner extends HtmlMacroComponent {
plannerToolbar.appendChild(c.toButton());
}
} else {
commontoolbar.appendChild(c.toButton());
commonToolbar.appendChild(c.toButton());
}
}
@ -616,12 +609,12 @@ public class Planner extends HtmlMacroComponent {
if ( isShowingCriticalPath ) {
context.hideCriticalPath();
diagramGraph.removePostGraphChangeListener(showCriticalPathOnChange);
showCriticalPathButton.setSclass("planner-command");
showCriticalPathButton.setSclass(PLANNER_COMMAND);
showCriticalPathButton.setTooltiptext(_("Show critical path"));
} else {
context.showCriticalPath();
diagramGraph.addPostGraphChangeListener(showCriticalPathOnChange);
showCriticalPathButton.setSclass("planner-command clicked");
showCriticalPathButton.setSclass(PLANNER_COMMAND + " clicked");
showCriticalPathButton.setTooltiptext(_("Hide critical path"));
}
@ -643,7 +636,7 @@ public class Planner extends HtmlMacroComponent {
if ( isShowingAdvances ) {
context.hideAdvances();
diagramGraph.removePostGraphChangeListener(showAdvanceOnChange);
showAdvancesButton.setSclass("planner-command");
showAdvancesButton.setSclass(PLANNER_COMMAND);
showAdvancesButton.setTooltiptext(_("Show progress"));
if ( progressTypesCombo.getItemCount() > 0 ) {
@ -652,7 +645,7 @@ public class Planner extends HtmlMacroComponent {
} else {
context.showAdvances();
diagramGraph.addPostGraphChangeListener(showAdvanceOnChange);
showAdvancesButton.setSclass("planner-command clicked");
showAdvancesButton.setSclass(PLANNER_COMMAND + " clicked");
showAdvancesButton.setTooltiptext(_("Hide progress"));
}
@ -667,12 +660,12 @@ public class Planner extends HtmlMacroComponent {
if ( isShowingReportedHours ) {
context.hideReportedHours();
diagramGraph.removePostGraphChangeListener(showReportedHoursOnChange);
showReportedHoursButton.setSclass("planner-command");
showReportedHoursButton.setSclass(PLANNER_COMMAND);
showReportedHoursButton.setTooltiptext(_("Show reported hours"));
} else {
context.showReportedHours();
diagramGraph.addPostGraphChangeListener(showReportedHoursOnChange);
showReportedHoursButton.setSclass("planner-command clicked");
showReportedHoursButton.setSclass(PLANNER_COMMAND + " clicked");
showReportedHoursButton.setTooltiptext(_("Hide reported hours"));
}
@ -686,12 +679,12 @@ public class Planner extends HtmlMacroComponent {
if ( isShowingMoneyCostBar ) {
context.hideMoneyCostBar();
diagramGraph.removePostGraphChangeListener(showMoneyCostBarOnChange);
showMoneyCostBarButton.setSclass("planner-command");
showMoneyCostBarButton.setSclass(PLANNER_COMMAND);
showMoneyCostBarButton.setTooltiptext(_("Show money cost bar"));
} else {
context.showMoneyCostBar();
diagramGraph.addPostGraphChangeListener(showMoneyCostBarOnChange);
showMoneyCostBarButton.setSclass("planner-command clicked");
showMoneyCostBarButton.setSclass(PLANNER_COMMAND + " clicked");
showMoneyCostBarButton.setTooltiptext(_("Hide money cost bar"));
}
@ -792,10 +785,10 @@ public class Planner extends HtmlMacroComponent {
if ( isExpandAll ) {
context.collapseAll();
expandAllButton.setSclass("planner-command");
expandAllButton.setSclass(PLANNER_COMMAND);
} else {
context.expandAll();
expandAllButton.setSclass("planner-command clicked");
expandAllButton.setSclass(PLANNER_COMMAND + " clicked");
}
}
@ -806,7 +799,7 @@ public class Planner extends HtmlMacroComponent {
Button expandAllButton = (Button) getFellow(EXPAND_ALL_BUTTON);
if ( disabilityConfiguration.isExpandAllEnabled() ) {
context.expandAll();
expandAllButton.setSclass("planner-command clicked");
expandAllButton.setSclass(PLANNER_COMMAND + " clicked");
}
}
@ -841,10 +834,10 @@ public class Planner extends HtmlMacroComponent {
if ( disabilityConfiguration.isFlattenTreeEnabled() ) {
if (isFlattenTree) {
predicate.setFilterContainers(false);
flattenTreeButton.setSclass("planner-command");
flattenTreeButton.setSclass(PLANNER_COMMAND);
} else {
predicate.setFilterContainers(true);
flattenTreeButton.setSclass("planner-command clicked");
flattenTreeButton.setSclass(PLANNER_COMMAND + " clicked");
}
setTaskListPredicate(predicate);
@ -906,7 +899,6 @@ public class Planner extends HtmlMacroComponent {
return c.toButton();
}
}
return null;
}
@ -941,7 +933,6 @@ public class Planner extends HtmlMacroComponent {
}
}
}
return null;
}

View file

@ -52,12 +52,14 @@ import org.zkoss.zk.ui.Component;
*/
public class PlannerConfiguration<T> implements IDisabilityConfiguration {
private static final String PRINT_NOT_SUPPORTED = "print not supported";
public interface IPrintAction {
void doPrint();
void doPrint(Map<String, String> parameters);
void doPrint(HashMap<String, String> parameters, Planner planner);
void doPrint(Map<String, String> parameters, Planner planner);
}
public interface IReloadChartListener {
@ -290,11 +292,9 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
}
public static List<Constraint<GanttDate>> getStartConstraintsGiven(GanttDate notBeforeThan) {
if ( notBeforeThan != null ) {
return Collections.singletonList(biggerOrEqualThan(notBeforeThan));
}
return Collections.emptyList();
return notBeforeThan != null
? Collections.singletonList(biggerOrEqualThan(notBeforeThan))
: Collections.emptyList();
}
public List<Constraint<GanttDate>> getStartConstraints() {
@ -302,11 +302,9 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
}
public static List<Constraint<GanttDate>> getEndConstraintsGiven(GanttDate notAfterThan) {
if ( notAfterThan != null ) {
return Collections.singletonList(lessOrEqualThan(notAfterThan));
}
return Collections.emptyList();
return notAfterThan != null
? Collections.singletonList(lessOrEqualThan(notAfterThan))
: Collections.emptyList();
}
public List<Constraint<GanttDate>> getEndConstraints() {
@ -430,21 +428,21 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
public void print() {
if ( !isPrintEnabled() ) {
throw new UnsupportedOperationException("print not supported");
throw new UnsupportedOperationException(PRINT_NOT_SUPPORTED);
}
printAction.doPrint();
}
public void print(Map<String, String> parameters) {
if ( !isPrintEnabled() ) {
throw new UnsupportedOperationException("print not supported");
throw new UnsupportedOperationException(PRINT_NOT_SUPPORTED);
}
printAction.doPrint(parameters);
}
public void print(HashMap<String, String> parameters, Planner planner) {
if ( !isPrintEnabled() ) {
throw new UnsupportedOperationException("print not supported");
throw new UnsupportedOperationException(PRINT_NOT_SUPPORTED);
}
printAction.doPrint(parameters, planner);
}

View file

@ -23,28 +23,27 @@ import java.util.ArrayList;
import java.util.List;
/**
*
* @author Óscar González Fernández <ogonzalez@igalia.com>
*/
public class Emitter<T> {
public interface IEmissionListener<T> {
public void newEmission(T value);
void newEmission(T value);
}
private T lastValue;
private List<IEmissionListener<? super T>> listeners = new ArrayList<IEmissionListener<? super T>>();
public static <T> Emitter<T> withInitial(T initialValue) {
return new Emitter<T>(initialValue);
}
private List<IEmissionListener<? super T>> listeners = new ArrayList<>();
private Emitter(T initialValue) {
this.lastValue = initialValue;
}
public static <T> Emitter<T> withInitial(T initialValue) {
return new Emitter<>(initialValue);
}
public T getLastValue() {
return lastValue;
}

View file

@ -64,7 +64,7 @@ ganttz.GanttPanel = zk.$extends(
/*
* The canvas is inserted in the DOM after this component, so it's not available right now.
* It is queried instead.
* Using throttle to not re-query it constantly
* Using throttle to not re-query it constantly.
*/
_getTimeplotContainer: common.Common.throttle(500, function() {
return jq('canvas.timeplot-canvas').parent();
@ -81,7 +81,7 @@ ganttz.GanttPanel = zk.$extends(
jq('#ganttpanel_inner_scroller_y').height(px);
},
reScrollX : function(px){
reScrollX : function(px) {
jq('#ganttpanel_inner_scroller_x').width(px);
}
},
@ -90,7 +90,7 @@ ganttz.GanttPanel = zk.$extends(
return this._instance;
},
setInstance : function(instance){
setInstance : function(instance) {
this._instance = instance;
}
});

View file

@ -43,7 +43,8 @@ import org.zkoss.zul.Label;
public class OnColumnsRowRendererTest {
private static class Data {}
private static class Data {
}
private static class CellRenderer implements ICellForDetailItemRenderer<DetailItem, Data> {
@Override
@ -103,27 +104,27 @@ public class OnColumnsRowRendererTest {
@Test(expected = NullPointerException.class)
public void itNeedsTheTypeAsClass() {
OnColumnsRowRenderer.create(null, createStub(), new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(null, createStub(), new ArrayList<>());
}
@Test
public void itCanHaveEmptyDetailItems() {
OnColumnsRowRenderer.create(Data.class, createStub(), new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(Data.class, createStub(), new ArrayList<>());
}
@Test
public void itCanInferTheGenericType() {
OnColumnsRowRenderer.create(new CellRenderer(), new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(new CellRenderer(), new ArrayList<>());
}
@Test(expected = IllegalArgumentException.class)
public void ifComesFromRawTypeIsNotInferrable() {
OnColumnsRowRenderer.create(createStub(), new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(createStub(), new ArrayList<>());
}
@Test(expected = IllegalArgumentException.class)
public void ifItNotShowsTheActualTypeIsNotInferrable() {
OnColumnsRowRenderer.create(new CellRendererNotInferable<Data>(), new ArrayList<DetailItem>());
OnColumnsRowRenderer.create(new CellRendererNotInferable<Data>(), new ArrayList<>());
}
@SuppressWarnings("serial")

View file

@ -40,7 +40,7 @@ import org.libreplan.business.expensesheet.daos.IExpenseSheetDAO;
import org.libreplan.business.resources.entities.Resource;
/**
* ExpenseSheet Entity
* ExpenseSheet Entity.
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
@ -57,8 +57,7 @@ public class ExpenseSheet extends IntegrationEntity implements IHumanIdentifiabl
private boolean personal = false;
@Valid
private SortedSet<ExpenseSheetLine> expenseSheetLines = new TreeSet<>(
new ExpenseSheetLineComparator());
private SortedSet<ExpenseSheetLine> expenseSheetLines = new TreeSet<>(new ExpenseSheetLineComparator());
private Integer lastExpenseSheetLineSequenceCode = 0;
@ -78,8 +77,7 @@ public class ExpenseSheet extends IntegrationEntity implements IHumanIdentifiabl
return create(new ExpenseSheet());
}
public static ExpenseSheet create(LocalDate firstExpense, LocalDate lastExpense,
BigDecimal total) {
public static ExpenseSheet create(LocalDate firstExpense, LocalDate lastExpense, BigDecimal total) {
return create(new ExpenseSheet(firstExpense, lastExpense, total));
}
@ -120,6 +118,7 @@ public class ExpenseSheet extends IntegrationEntity implements IHumanIdentifiabl
return Collections.unmodifiableSortedSet(expenseSheetLines);
}
/** Field setter of entity, do not remove! */
public void setLastExpenseSheetLineSequenceCode(Integer lastExpenseSheetLineSequenceCode) {
this.lastExpenseSheetLineSequenceCode = lastExpenseSheetLineSequenceCode;
}
@ -144,11 +143,9 @@ public class ExpenseSheet extends IntegrationEntity implements IHumanIdentifiabl
public void generateExpenseSheetLineCodes(int numberOfDigits) {
for (ExpenseSheetLine line : this.getExpenseSheetLines()) {
if ((line.getCode() == null) || (line.getCode().isEmpty())
|| (!line.getCode().startsWith(this.getCode()))) {
if ((line.getCode() == null) || (line.getCode().isEmpty()) || (!line.getCode().startsWith(this.getCode()))) {
this.incrementLastExpenseSheetLineSequenceCode();
String lineCode = EntitySequence.formatValue(numberOfDigits,
this.getLastExpenseSheetLineSequenceCode());
String lineCode = EntitySequence.formatValue(numberOfDigits, this.getLastExpenseSheetLineSequenceCode());
line.setCode(this.getCode() + EntitySequence.CODE_SEPARATOR_CHILDREN + lineCode);
}
}
@ -161,8 +158,7 @@ public class ExpenseSheet extends IntegrationEntity implements IHumanIdentifiabl
lastExpenseSheetLineSequenceCode++;
}
public void keepSortedExpenseSheetLines(ExpenseSheetLine expenseSheetLine,
LocalDate newDate) {
public void keepSortedExpenseSheetLines(ExpenseSheetLine expenseSheetLine, LocalDate newDate) {
this.expenseSheetLines.remove(expenseSheetLine);
expenseSheetLine.setDate(newDate);
this.expenseSheetLines.add(expenseSheetLine);
@ -210,12 +206,10 @@ public class ExpenseSheet extends IntegrationEntity implements IHumanIdentifiabl
return getCode() + (description != null ? description : "");
}
public ExpenseSheetLine getExpenseSheetLineByCode(String code)
throws ValidationException {
public ExpenseSheetLine getExpenseSheetLineByCode(String code) throws ValidationException {
if (StringUtils.isBlank(code)) {
throw new ValidationException(
"missing the code with which find the expense sheet line");
throw new ValidationException("missing the code with which find the expense sheet line");
}
for (ExpenseSheetLine l : this.expenseSheetLines) {
@ -252,8 +246,7 @@ public class ExpenseSheet extends IntegrationEntity implements IHumanIdentifiabl
for (ExpenseSheetLine line : expenseSheetLines) {
Resource resourceLine = line.getResource();
if ((resourceLine == null)
|| (!resourceLine.getId().equals(resource.getId()))) {
if ((resourceLine == null) || (!resourceLine.getId().equals(resource.getId()))) {
return false;
}
}

View file

@ -31,7 +31,7 @@ import org.libreplan.business.orders.entities.OrderElement;
import org.libreplan.business.resources.entities.Resource;
/**
* ExpenseSheetLine Entity
* ExpenseSheetLine Entity.
*
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
@ -53,19 +53,16 @@ public class ExpenseSheetLine extends IntegrationEntity {
* Constructor for Hibernate. Do not use!
*/
protected ExpenseSheetLine() {
}
private ExpenseSheetLine(BigDecimal value, String concept, LocalDate date,
OrderElement orderElement) {
private ExpenseSheetLine(BigDecimal value, String concept, LocalDate date, OrderElement orderElement) {
this.orderElement = orderElement;
this.concept = concept;
this.value = value;
this.setDate(date);
}
public static ExpenseSheetLine create(BigDecimal value, String concept, LocalDate date,
OrderElement orderElement) {
public static ExpenseSheetLine create(BigDecimal value, String concept, LocalDate date, OrderElement orderElement) {
return create(new ExpenseSheetLine(value, concept, date, orderElement));
}
@ -80,13 +77,10 @@ public class ExpenseSheetLine extends IntegrationEntity {
}
private boolean isDifferent(BigDecimal value) {
if (this.value == null && value == null) {
if ( this.value == null && value == null ) {
return false;
}
if (this.value != null && value != null) {
return (this.value.compareTo(value) != 0);
}
return true;
return !(this.value != null && value != null) || this.value.compareTo(value) != 0;
}
@Min(message = "value must be greater or equal than 0", value = 0)
@ -134,13 +128,10 @@ public class ExpenseSheetLine extends IntegrationEntity {
}
private boolean isDifferent(LocalDate date) {
if (this.date == null && date == null) {
if ( this.date == null && date == null ) {
return false;
}
if (this.date != null && date != null) {
return (this.date.compareTo(date) != 0);
}
return true;
return !(this.date != null && date != null) || this.date.compareTo(date) != 0;
}
@NotNull(message = "date not specified")

View file

@ -124,4 +124,21 @@
timeToLiveSeconds="1800"
overflowToDisk="false"
/>
<cache name="org.libreplan.business.expensesheet.entities.ExpenseSheetLine"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
/>
<cache name="org.libreplan.business.expensesheet.entities.ExpenseSheet"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
/>
</ehcache>

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.libreplan.business.advance.entities" default-access="field">

View file

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.libreplan.business.expensesheet.entities" default-access="field">
<!-- ExpenseSheetLine -->
<class name="ExpenseSheetLine" table="expense_sheet_line">
<cache usage="nonstrict-read-write" />
<id name="id" type="long" access="property">
<generator class="increment">
<param name="max_lo">100</param>
@ -33,7 +34,9 @@
<!-- ExpenseSheet -->
<class name="ExpenseSheet" table="expense_sheet">
<cache usage="nonstrict-read-write" />
<id name="id" type="long" access="property">
<generator class="increment">
<param name="max_lo">100</param>

View file

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.libreplan.business.logs.entities" default-access="field">
<class name="IssueLog" table="issue_log">
<id name="id" column="id" type="long" access="property">
<generator class="increment">
<param name="max_lo">100</param>
@ -58,6 +58,7 @@
</class>
<class name="RiskLog" table="risk_log">
<id name="id" column="id" type="long" access="property">
<generator class="increment">
<param name="max_lo">100</param>

View file

@ -49,36 +49,35 @@ import org.libreplan.business.workingday.ResourcesPerDay;
/**
* Tests for {@link BaseCalendar}.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public class BaseCalendarTest {
public static final LocalDate JUNE_NEXT_YEAR = new LocalDate(
(new LocalDate())
.getYear(), 6, 1).plusYears(1);
private static final LocalDate JUNE_NEXT_YEAR = new LocalDate((new LocalDate()).getYear(), 6, 1).plusYears(1);
public static final LocalDate MONDAY_LOCAL_DATE = JUNE_NEXT_YEAR
.dayOfWeek().withMinimumValue();
public static final LocalDate TUESDAY_LOCAL_DATE = MONDAY_LOCAL_DATE
.plusDays(1);
public static final LocalDate WEDNESDAY_LOCAL_DATE = MONDAY_LOCAL_DATE
.plusDays(2);
public static final LocalDate THURSDAY_LOCAL_DATE = MONDAY_LOCAL_DATE
.plusDays(3);
public static final LocalDate FRIDAY_LOCAL_DATE = MONDAY_LOCAL_DATE
.plusDays(4);
public static final LocalDate SATURDAY_LOCAL_DATE = MONDAY_LOCAL_DATE
.plusDays(5);
public static final LocalDate SUNDAY_LOCAL_DATE = MONDAY_LOCAL_DATE
.plusDays(6);
private static final LocalDate MONDAY_LOCAL_DATE = JUNE_NEXT_YEAR.dayOfWeek().withMinimumValue();
private static final LocalDate TUESDAY_LOCAL_DATE = MONDAY_LOCAL_DATE.plusDays(1);
private static final LocalDate WEDNESDAY_LOCAL_DATE = MONDAY_LOCAL_DATE.plusDays(2);
private static final LocalDate THURSDAY_LOCAL_DATE = MONDAY_LOCAL_DATE.plusDays(3);
private static final LocalDate FRIDAY_LOCAL_DATE = MONDAY_LOCAL_DATE.plusDays(4);
private static final LocalDate SATURDAY_LOCAL_DATE = MONDAY_LOCAL_DATE.plusDays(5);
private static final LocalDate SUNDAY_LOCAL_DATE = MONDAY_LOCAL_DATE.plusDays(6);
private static final LocalDate[] DAYS_OF_A_WEEK_EXAMPLE = {
MONDAY_LOCAL_DATE, TUESDAY_LOCAL_DATE, WEDNESDAY_LOCAL_DATE,
THURSDAY_LOCAL_DATE, FRIDAY_LOCAL_DATE, SATURDAY_LOCAL_DATE,
SUNDAY_LOCAL_DATE };
MONDAY_LOCAL_DATE, TUESDAY_LOCAL_DATE,
WEDNESDAY_LOCAL_DATE, THURSDAY_LOCAL_DATE,
FRIDAY_LOCAL_DATE, SATURDAY_LOCAL_DATE,
SUNDAY_LOCAL_DATE
};
public static final LocalDate CHRISTMAS_DAY_LOCAL_DATE = new LocalDate(
JUNE_NEXT_YEAR.getYear(), 12, 25);
public static final LocalDate CHRISTMAS_DAY_LOCAL_DATE = new LocalDate(JUNE_NEXT_YEAR.getYear(), 12, 25);
public static BaseCalendar createBasicCalendar() {
BaseCalendar calendar = BaseCalendar.create();
@ -98,10 +97,10 @@ public class BaseCalendarTest {
}
/**
* Creates a {@link Capacity} with normal {@link EffortDuration} and no
* extra hours limit
* Creates a {@link Capacity} with normal {@link EffortDuration} and no extra hours limit.
*
* @param effort
* @return
* @return {@link Capacity}
*/
private static Capacity withNormalDuration(EffortDuration effort) {
return Capacity.create(effort).overAssignableWithoutLimit();
@ -114,15 +113,13 @@ public class BaseCalendarTest {
}
public static CalendarExceptionType createCalendarExceptionType() {
CalendarExceptionType result = CalendarExceptionType.create("TEST",
CalendarExceptionTypeColor.DEFAULT, true);
return result;
return CalendarExceptionType.create("TEST", CalendarExceptionTypeColor.DEFAULT, true);
}
public static void addChristmasAsExceptionDay(BaseCalendar calendar) {
CalendarException christmasDay = CalendarException.create(
CHRISTMAS_DAY_LOCAL_DATE, EffortDuration.zero(),
createCalendarExceptionType());
CalendarException christmasDay =
CalendarException.create(CHRISTMAS_DAY_LOCAL_DATE, EffortDuration.zero(), createCalendarExceptionType());
calendar.addExceptionDay(christmasDay);
}
@ -152,7 +149,7 @@ public class BaseCalendarTest {
assertFalse(calendar.onlyGivesZeroHours());
}
public static BaseCalendar createChristmasCalendar() {
private static BaseCalendar createChristmasCalendar() {
BaseCalendar calendar = createBasicCalendar();
addChristmasAsExceptionDay(calendar);
return calendar;
@ -162,12 +159,10 @@ public class BaseCalendarTest {
public void testCapacityOnBasic() {
BaseCalendar calendar = createBasicCalendar();
EffortDuration wednesdayHours = calendar
.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE));
EffortDuration wednesdayHours = calendar.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE));
assertThat(wednesdayHours, equalTo(hours(8)));
EffortDuration sundayHours = calendar
.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE));
EffortDuration sundayHours = calendar.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE));
assertThat(sundayHours, equalTo(zero()));
}
@ -181,8 +176,7 @@ public class BaseCalendarTest {
public void testCapacityOnChristmas() {
BaseCalendar calendar = createChristmasCalendar();
EffortDuration duration = calendar
.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE));
EffortDuration duration = calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE));
assertThat(duration, equalTo(EffortDuration.zero()));
}
@ -198,12 +192,10 @@ public class BaseCalendarTest {
public void testCapacityOnDerivedBasicCalendar() {
BaseCalendar calendar = createBasicCalendar().newDerivedCalendar();
EffortDuration wednesdayHours = calendar
.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE));
EffortDuration wednesdayHours = calendar.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE));
assertThat(wednesdayHours, equalTo(hours(8)));
EffortDuration sundayHours = calendar
.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE));
EffortDuration sundayHours = calendar.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE));
assertThat(sundayHours, equalTo(zero()));
}
@ -211,8 +203,7 @@ public class BaseCalendarTest {
public void testCapacityOnDerivedChristmasCalendar() {
BaseCalendar calendar = createChristmasCalendar().newDerivedCalendar();
EffortDuration hours = calendar
.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE));
EffortDuration hours = calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE));
assertThat(hours, equalTo(EffortDuration.zero()));
}
@ -220,20 +211,16 @@ public class BaseCalendarTest {
public void testCapacityOnDerivedBasicCalendarWithException() {
BaseCalendar calendar = createBasicCalendar().newDerivedCalendar();
CalendarException day = CalendarException.create(WEDNESDAY_LOCAL_DATE,
hours(4), createCalendarExceptionType());
CalendarException day = CalendarException.create(WEDNESDAY_LOCAL_DATE, hours(4), createCalendarExceptionType());
calendar.addExceptionDay(day);
EffortDuration mondayHours = calendar
.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE));
EffortDuration mondayHours = calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE));
assertThat(mondayHours, equalTo(hours(8)));
EffortDuration wednesdayHours = calendar
.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE));
EffortDuration wednesdayHours = calendar.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE));
assertThat(wednesdayHours, equalTo(hours(4)));
EffortDuration sundayHours = calendar
.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE));
EffortDuration sundayHours = calendar.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE));
assertThat(sundayHours, equalTo(zero()));
}
@ -241,13 +228,10 @@ public class BaseCalendarTest {
public void testCapacityOnDerivedChristmasCalendarRedefiningExceptionDay() {
BaseCalendar calendar = createChristmasCalendar().newDerivedCalendar();
CalendarException day = CalendarException.create(
CHRISTMAS_DAY_LOCAL_DATE, hours(4),
createCalendarExceptionType());
CalendarException day = CalendarException.create(CHRISTMAS_DAY_LOCAL_DATE, hours(4), createCalendarExceptionType());
calendar.addExceptionDay(day);
EffortDuration hours = calendar
.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE));
EffortDuration hours = calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE));
assertThat(hours, equalTo(hours(4)));
}
@ -255,15 +239,13 @@ public class BaseCalendarTest {
public void testCapacityOnInterval() {
BaseCalendar calendar = createBasicCalendar();
int mondayToWednesdayHours = calendar.getWorkableHours(
MONDAY_LOCAL_DATE, WEDNESDAY_LOCAL_DATE);
int mondayToWednesdayHours = calendar.getWorkableHours(MONDAY_LOCAL_DATE, WEDNESDAY_LOCAL_DATE);
assertThat(mondayToWednesdayHours, equalTo(24));
}
@Test
public void testCapacityOnPerWeek() {
BaseCalendar calendar = createBasicCalendar();
int weekHours = calendar.getWorkableHoursPerWeek(WEDNESDAY_LOCAL_DATE);
assertThat(weekHours, equalTo(40));
}
@ -272,12 +254,10 @@ public class BaseCalendarTest {
public void testAddTwoExceptionDaysInTheSameDate() {
BaseCalendar calendar = createBasicCalendar();
CalendarException day = CalendarException.create(MONDAY_LOCAL_DATE,
hours(8), createCalendarExceptionType());
CalendarException day = CalendarException.create(MONDAY_LOCAL_DATE, hours(8), createCalendarExceptionType());
calendar.addExceptionDay(day);
CalendarException day2 = CalendarException.create(MONDAY_LOCAL_DATE,
hours(4), createCalendarExceptionType());
CalendarException day2 = CalendarException.create(MONDAY_LOCAL_DATE, hours(4), createCalendarExceptionType());
calendar.addExceptionDay(day2);
}
@ -285,7 +265,6 @@ public class BaseCalendarTest {
public void testCreateNewVersion() {
BaseCalendar calendar = createBasicCalendar();
calendar.newVersion((new LocalDate()).plusDays(1));
assertThat(calendar.getCalendarDataVersions().size(), equalTo(2));
}
@ -325,18 +304,13 @@ public class BaseCalendarTest {
calendar.setCapacityAt(Days.WEDNESDAY, withNormalDuration(hours(4)));
calendar.setCapacityAt(Days.SUNDAY, withNormalDuration(hours(4)));
assertThat(calendar.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE)),
equalTo(hours(4)));
assertThat(calendar.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE)), equalTo(hours(4)));
assertThat(calendar.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE
.minusWeeks(1))), equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE.minusWeeks(1))), equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE)),
equalTo(hours(4)));
assertThat(calendar.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE)), equalTo(hours(4)));
assertThat(calendar.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE
.minusWeeks(1))),
equalTo(zero()));
assertThat(calendar.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE.minusWeeks(1))), equalTo(zero()));
}
@Test
@ -347,19 +321,13 @@ public class BaseCalendarTest {
calendar.setCapacityAt(Days.MONDAY, withNormalDuration(hours(1)));
calendar.setCapacityAt(Days.SUNDAY, withNormalDuration(hours(2)));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)),
equalTo(hours(1)));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)), equalTo(hours(1)));
assertThat(calendar.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE)),
equalTo(hours(2)));
assertThat(calendar.getCapacityOn(wholeDay(SUNDAY_LOCAL_DATE)), equalTo(hours(2)));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE
.minusWeeks(1))),
equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE.minusWeeks(1))), equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE
.minusDays(1))),
equalTo(zero()));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE.minusDays(1))), equalTo(zero()));
}
@Test
@ -374,7 +342,6 @@ public class BaseCalendarTest {
@Test(expected = IllegalArgumentException.class)
public void testRemoveExceptionDayDerivedCalendar() {
BaseCalendar calendar = createChristmasCalendar().newDerivedCalendar();
calendar.removeExceptionDay(CHRISTMAS_DAY_LOCAL_DATE);
}
@ -391,23 +358,23 @@ public class BaseCalendarTest {
@Test
public void testCapacityOnNewVersionFromChristmasCalendar() {
BaseCalendar calendar = createChristmasCalendar();
CalendarException day = CalendarException.create(
CHRISTMAS_DAY_LOCAL_DATE.plusYears(1), EffortDuration.zero(),
createCalendarExceptionType());
CHRISTMAS_DAY_LOCAL_DATE.plusYears(1), EffortDuration.zero(), createCalendarExceptionType());
calendar.addExceptionDay(day);
calendar.newVersion(CHRISTMAS_DAY_LOCAL_DATE.plusDays(1));
CalendarExceptionType type = createCalendarExceptionType();
calendar.updateExceptionDay(CHRISTMAS_DAY_LOCAL_DATE.plusYears(1),
Capacity.create(hours(8)).withAllowedExtraEffort(
type.getCapacity().getAllowedExtraEffort()), type);
assertThat(calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE
.plusYears(1))), equalTo(hours(8)));
calendar.updateExceptionDay(
CHRISTMAS_DAY_LOCAL_DATE.plusYears(1),
Capacity.create(hours(8)).withAllowedExtraEffort(type.getCapacity().getAllowedExtraEffort()),
type);
assertThat(calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE)),
equalTo(zero()));
assertThat(calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE.plusYears(1))), equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE)), equalTo(zero()));
}
public static void setHoursForAllDays(BaseCalendar calendar, Integer hours) {
@ -428,14 +395,11 @@ public class BaseCalendarTest {
calendar.newVersion(FRIDAY_LOCAL_DATE);
setHoursForAllDays(calendar, 2);
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)),
equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)), equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE)),
equalTo(hours(4)));
assertThat(calendar.getCapacityOn(wholeDay(WEDNESDAY_LOCAL_DATE)), equalTo(hours(4)));
assertThat(calendar.getCapacityOn(wholeDay(FRIDAY_LOCAL_DATE)),
equalTo(hours(2)));
assertThat(calendar.getCapacityOn(wholeDay(FRIDAY_LOCAL_DATE)), equalTo(hours(2)));
}
@ -449,36 +413,29 @@ public class BaseCalendarTest {
calendar.newVersion(WEDNESDAY_LOCAL_DATE);
setHoursForAllDays(calendar, 2);
assertThat(baseCalendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)),
equalTo(hours(8)));
assertThat(baseCalendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)), equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)),
equalTo(hours(4)));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)), equalTo(hours(4)));
assertThat(baseCalendar.getCapacityOn(wholeDay(FRIDAY_LOCAL_DATE)),
equalTo(hours(8)));
assertThat(baseCalendar.getCapacityOn(wholeDay(FRIDAY_LOCAL_DATE)), equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(FRIDAY_LOCAL_DATE)),
equalTo(hours(2)));
assertThat(calendar.getCapacityOn(wholeDay(FRIDAY_LOCAL_DATE)), equalTo(hours(2)));
assertThat(calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE)),
equalTo(zero()));
assertThat(calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE)), equalTo(zero()));
}
@Test
public void testAddExceptionToNewVersionCalendar() {
BaseCalendar calendar = createBasicCalendar();
calendar.newVersion(CHRISTMAS_DAY_LOCAL_DATE
.plusDays(1));
calendar.newVersion(CHRISTMAS_DAY_LOCAL_DATE.plusDays(1));
CalendarException day = CalendarException.create(
CHRISTMAS_DAY_LOCAL_DATE, EffortDuration.zero(),
createCalendarExceptionType());
CHRISTMAS_DAY_LOCAL_DATE, EffortDuration.zero(), createCalendarExceptionType());
calendar.addExceptionDay(day);
assertThat(calendar.getExceptions().size(), equalTo(1));
assertThat(calendar.getExceptions().iterator().next().getDate(),
equalTo(CHRISTMAS_DAY_LOCAL_DATE));
assertThat(calendar.getExceptions().iterator().next().getDate(), equalTo(CHRISTMAS_DAY_LOCAL_DATE));
}
@Test
@ -489,8 +446,7 @@ public class BaseCalendarTest {
private void thenForAllDaysReturnsZero() {
for (LocalDate localDate : DAYS_OF_A_WEEK_EXAMPLE) {
assertThat(calendarFixture.getCapacityOn(wholeDay(localDate)),
equalTo(zero()));
assertThat(calendarFixture.getCapacityOn(wholeDay(localDate)), equalTo(zero()));
}
}
@ -534,15 +490,11 @@ public class BaseCalendarTest {
BaseCalendar calendar = createChristmasCalendar();
BaseCalendar derived = calendar.newDerivedCalendar();
assertThat(calendar.getExceptionDay(CHRISTMAS_DAY_LOCAL_DATE),
notNullValue());
assertThat(derived.getExceptionDay(CHRISTMAS_DAY_LOCAL_DATE),
notNullValue());
assertThat(calendar.getExceptionDay(CHRISTMAS_DAY_LOCAL_DATE), notNullValue());
assertThat(derived.getExceptionDay(CHRISTMAS_DAY_LOCAL_DATE), notNullValue());
assertThat(calendar.getOwnExceptionDay(CHRISTMAS_DAY_LOCAL_DATE),
notNullValue());
assertThat(derived.getOwnExceptionDay(CHRISTMAS_DAY_LOCAL_DATE),
nullValue());
assertThat(calendar.getOwnExceptionDay(CHRISTMAS_DAY_LOCAL_DATE), notNullValue());
assertThat(derived.getOwnExceptionDay(CHRISTMAS_DAY_LOCAL_DATE), nullValue());
}
@Test
@ -564,8 +516,7 @@ public class BaseCalendarTest {
calendar.setParent(parent);
assertThat(calendar.getParent(), equalTo(parent));
assertThat(calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE)),
equalTo(zero()));
assertThat(calendar.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE)), equalTo(zero()));
}
@Test
@ -574,8 +525,7 @@ public class BaseCalendarTest {
BaseCalendar derived = calendar.newDerivedCalendar();
BaseCalendar copy = derived.newCopy();
assertThat(copy.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE)),
equalTo(zero()));
assertThat(copy.getCapacityOn(wholeDay(CHRISTMAS_DAY_LOCAL_DATE)), equalTo(zero()));
assertThat(copy.getParent(), equalTo(calendar));
assertThat(copy.getCalendarDataVersions().size(), equalTo(1));
}
@ -599,14 +549,11 @@ public class BaseCalendarTest {
calendar.setParent(parent2);
assertThat(calendar.getParent(), equalTo(parent2));
assertThat(calendar.getParent(MONDAY_LOCAL_DATE),
equalTo(parent1));
assertThat(calendar.getParent(MONDAY_LOCAL_DATE), equalTo(parent1));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)),
equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)), equalTo(hours(8)));
assertThat(calendar.getCapacityOn(wholeDay(FRIDAY_LOCAL_DATE)),
equalTo(hours(4)));
assertThat(calendar.getCapacityOn(wholeDay(FRIDAY_LOCAL_DATE)), equalTo(hours(4)));
}
@Test
@ -614,16 +561,12 @@ public class BaseCalendarTest {
BaseCalendar calendar = createBasicCalendar();
calendar.newVersion(WEDNESDAY_LOCAL_DATE);
calendar.addExceptionDay(CalendarException.create(MONDAY_LOCAL_DATE,
zero(), createCalendarExceptionType()));
calendar.addExceptionDay(CalendarException.create(FRIDAY_LOCAL_DATE,
zero(), createCalendarExceptionType()));
calendar.addExceptionDay(CalendarException.create(MONDAY_LOCAL_DATE, zero(), createCalendarExceptionType()));
calendar.addExceptionDay(CalendarException.create(FRIDAY_LOCAL_DATE, zero(), createCalendarExceptionType()));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)),
equalTo(zero()));
assertThat(calendar.getCapacityOn(wholeDay(MONDAY_LOCAL_DATE)), equalTo(zero()));
assertThat(calendar.getCapacityOn(wholeDay(FRIDAY_LOCAL_DATE)),
equalTo(zero()));
assertThat(calendar.getCapacityOn(wholeDay(FRIDAY_LOCAL_DATE)), equalTo(zero()));
assertThat(calendar.getOwnExceptions().size(), equalTo(2));
}
@ -633,9 +576,7 @@ public class BaseCalendarTest {
BaseCalendar calendar = createBasicCalendar();
LocalDate pastMonth = (new LocalDate()).minusMonths(1);
CalendarException exceptionDay = CalendarException.create(pastMonth,
zero(),
createCalendarExceptionType());
CalendarException exceptionDay = CalendarException.create(pastMonth, zero(), createCalendarExceptionType());
calendar.addExceptionDay(exceptionDay);
}
@ -645,8 +586,7 @@ public class BaseCalendarTest {
BaseCalendar calendar = createBasicCalendar();
LocalDate pastMonth = (new LocalDate()).minusMonths(1);
CalendarException exceptionDay = CalendarException.create(pastMonth,
zero(), createCalendarExceptionType());
CalendarException exceptionDay = CalendarException.create(pastMonth, zero(), createCalendarExceptionType());
calendar.addExceptionDay(exceptionDay);
calendar.removeExceptionDay(pastMonth);
@ -669,23 +609,18 @@ public class BaseCalendarTest {
LocalDate currentDate = new LocalDate();
calendar.newVersion(currentDate.plusWeeks(4));
assertThat(calendar.getExpiringDate(currentDate), equalTo(currentDate
.plusWeeks(4)));
assertThat(calendar.getExpiringDate(currentDate.plusWeeks(4)),
nullValue());
assertThat(calendar.getExpiringDate(currentDate), equalTo(currentDate.plusWeeks(4)));
assertThat(calendar.getExpiringDate(currentDate.plusWeeks(4)), nullValue());
calendar.setExpiringDate(currentDate.plusWeeks(2), currentDate);
assertThat(calendar.getExpiringDate(currentDate), equalTo(currentDate
.plusWeeks(2)));
assertThat(calendar.getExpiringDate(currentDate.plusWeeks(4)),
nullValue());
assertThat(calendar.getExpiringDate(currentDate), equalTo(currentDate.plusWeeks(2)));
assertThat(calendar.getExpiringDate(currentDate.plusWeeks(4)), nullValue());
}
@Test
public void testAllowNewVersionOnCurrentDate() {
BaseCalendar calendar = createBasicCalendar();
calendar.newVersion(new LocalDate());
}
@ -705,15 +640,12 @@ public class BaseCalendarTest {
calendar.newVersion(currentDate.plusWeeks(4));
assertThat(calendar.getValidFrom(currentDate), nullValue());
assertThat(calendar.getValidFrom(currentDate.plusWeeks(4)),
equalTo(currentDate.plusWeeks(4)));
assertThat(calendar.getValidFrom(currentDate.plusWeeks(4)), equalTo(currentDate.plusWeeks(4)));
calendar.setValidFrom(currentDate.plusWeeks(2), currentDate
.plusWeeks(4));
calendar.setValidFrom(currentDate.plusWeeks(2), currentDate.plusWeeks(4));
assertThat(calendar.getValidFrom(currentDate), nullValue());
assertThat(calendar.getValidFrom(currentDate.plusWeeks(4)),
equalTo(currentDate.plusWeeks(2)));
assertThat(calendar.getValidFrom(currentDate.plusWeeks(4)), equalTo(currentDate.plusWeeks(2)));
}
@Test
@ -741,12 +673,10 @@ public class BaseCalendarTest {
public void testGetNonWorkableDays() {
BaseCalendar calendar = createBasicCalendar();
Set<LocalDate> nonWorkableDays = calendar.getNonWorkableDays(
MONDAY_LOCAL_DATE, WEDNESDAY_LOCAL_DATE);
Set<LocalDate> nonWorkableDays = calendar.getNonWorkableDays(MONDAY_LOCAL_DATE, WEDNESDAY_LOCAL_DATE);
assertTrue(nonWorkableDays.isEmpty());
nonWorkableDays = calendar.getNonWorkableDays(MONDAY_LOCAL_DATE,
SUNDAY_LOCAL_DATE);
nonWorkableDays = calendar.getNonWorkableDays(MONDAY_LOCAL_DATE, SUNDAY_LOCAL_DATE);
assertFalse(nonWorkableDays.isEmpty());
assertTrue(nonWorkableDays.contains(SATURDAY_LOCAL_DATE));
assertTrue(nonWorkableDays.contains(SUNDAY_LOCAL_DATE));
@ -755,26 +685,28 @@ public class BaseCalendarTest {
@Test
public void aCalendarHasAMethodToConvertAnAmountOfResourcesPerDayToAEffortDuration() {
BaseCalendar calendar = createBasicCalendar();
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(1)), equalTo(hours(8)));
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(2)), equalTo(hours(16)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(1)),
equalTo(hours(8)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(2)),
equalTo(hours(16)));
}
@Test
public void asDurationOnRespectsTheOverAssignablePropertyOfCalendarData() {
BaseCalendar calendar = createBasicCalendar();
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(8))
.overAssignableWithoutLimit());
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(8)).overAssignableWithoutLimit());
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(1)), equalTo(hours(8)));
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(2)), equalTo(hours(16)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(1)),
equalTo(hours(8)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(2)),
equalTo(hours(16)));
}
@Test(expected = NullPointerException.class)
@ -786,97 +718,95 @@ public class BaseCalendarTest {
@Test
public void getCapacityWithOvertimeOnReturnsTheCapacityForThatDay() {
BaseCalendar calendar = createBasicCalendar();
Capacity capacitySet = Capacity.create(hours(8))
.overAssignableWithoutLimit();
Capacity capacitySet = Capacity.create(hours(8)).overAssignableWithoutLimit();
calendar.setCapacityAt(Days.MONDAY, capacitySet);
assertThat(calendar.getCapacityWithOvertime(MONDAY_LOCAL_DATE),
equalTo(capacitySet));
assertThat(calendar.getCapacityWithOvertime(MONDAY_LOCAL_DATE), equalTo(capacitySet));
}
@Test
public void asDurationOnRespectsTheNotOverAssignablePropertyOfCalendarData() {
BaseCalendar calendar = createBasicCalendar();
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(8))
.notOverAssignableWithoutLimit());
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(8)).notOverAssignableWithoutLimit());
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(1)), equalTo(hours(8)));
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(2)), equalTo(hours(8)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(1)),
equalTo(hours(8)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(2)),
equalTo(hours(8)));
}
@Test
public void DurationOnRespectsTheExtraEffortPropertyOfCalendarData() {
BaseCalendar calendar = createBasicCalendar();
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(8))
.withAllowedExtraEffort(hours(2)));
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(8)).withAllowedExtraEffort(hours(2)));
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(1)), equalTo(hours(8)));
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(2)), equalTo(hours(10)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(1)),
equalTo(hours(8)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(2)),
equalTo(hours(10)));
}
private void addExceptionOn(BaseCalendar calendar, LocalDate onDate,
Capacity capacity) {
calendar.addExceptionDay(CalendarException.create(onDate, capacity,
createCalendarExceptionType()));
private void addExceptionOn(BaseCalendar calendar, LocalDate onDate, Capacity capacity) {
calendar.addExceptionDay(CalendarException.create(onDate, capacity, createCalendarExceptionType()));
}
@Test
public void asDurationOnRespectsAnOverAssignableCalendarException() {
BaseCalendar calendar = createBasicCalendar();
addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(1))
.overAssignableWithoutLimit());
addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(1)).overAssignableWithoutLimit());
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(1)), equalTo(hours(1)));
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(2)), equalTo(hours(2)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(1)),
equalTo(hours(1)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(2)),
equalTo(hours(2)));
}
@Test
public void asDurationOnRespectsANotOverAssignableCalendarException() {
BaseCalendar calendar = createBasicCalendar();
addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(1))
.notOverAssignableWithoutLimit());
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(1)), equalTo(hours(1)));
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(2)), equalTo(hours(1)));
addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(1)).notOverAssignableWithoutLimit());
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(1)),
equalTo(hours(1)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(2)),
equalTo(hours(1)));
}
@Test
public void asDurationOnRespectsCapacityExtraEffort() {
BaseCalendar calendar = createBasicCalendar();
addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(2))
.withAllowedExtraEffort(hours(3)));
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(1)), equalTo(hours(2)));
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(2)), equalTo(hours(4)));
assertThat(calendar.asDurationOn(
PartialDay.wholeDay(MONDAY_LOCAL_DATE),
ResourcesPerDay.amount(3)), equalTo(hours(5)));
addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(2)).withAllowedExtraEffort(hours(3)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(1)),
equalTo(hours(2)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(2)),
equalTo(hours(4)));
assertThat(
calendar.asDurationOn(PartialDay.wholeDay(MONDAY_LOCAL_DATE), ResourcesPerDay.amount(3)),
equalTo(hours(5)));
}
@Test
public void canWorkOnRespectsTheCapacityOfTheException() {
BaseCalendar calendar = createBasicCalendar();
addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(0))
.withAllowedExtraEffort(hours(0)));
addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(0)).withAllowedExtraEffort(hours(0)));
assertFalse(calendar.canWorkOn(MONDAY_LOCAL_DATE));
}
@ -884,8 +814,7 @@ public class BaseCalendarTest {
@Test
public void canWorkOnRespectsIsOverAssignable() {
BaseCalendar calendar = createBasicCalendar();
addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(0))
.overAssignableWithoutLimit());
addExceptionOn(calendar, MONDAY_LOCAL_DATE, Capacity.create(hours(0)).overAssignableWithoutLimit());
assertTrue(calendar.canWorkOn(MONDAY_LOCAL_DATE));
}
@ -893,21 +822,18 @@ public class BaseCalendarTest {
@Test
public void canWorkOnRespectsCalendarData() {
BaseCalendar calendar = createBasicCalendar();
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(0))
.overAssignableWithoutLimit());
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(0)).overAssignableWithoutLimit());
assertTrue(calendar.canWorkOn(MONDAY_LOCAL_DATE));
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(0))
.notOverAssignableWithoutLimit());
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(0)).notOverAssignableWithoutLimit());
assertFalse(calendar.canWorkOn(MONDAY_LOCAL_DATE));
}
@Test
public void theAvailabilityTimeLineTakesIntoAccountTheDaysItCannotWorkDueToCalendarData() {
BaseCalendar calendar = createBasicCalendar();
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(0))
.notOverAssignableWithoutLimit());
calendar.setCapacityAt(Days.MONDAY, Capacity.create(hours(0)).notOverAssignableWithoutLimit());
AvailabilityTimeLine availability = calendar.getAvailability();
assertFalse(availability.isValid(MONDAY_LOCAL_DATE));

View file

@ -1,5 +1,6 @@
# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender

View file

@ -354,6 +354,11 @@
<artifactId>zk</artifactId>
</dependency>
<dependency>
<groupId>org.zkoss.common</groupId>
<artifactId>zcommon</artifactId>
</dependency>
<!-- LibrePlan ZK Components -->
<dependency>
<groupId>org.libreplan</groupId>

View file

@ -42,12 +42,14 @@ import org.apache.log4j.xml.DOMConfigurator;
*/
public class LoggingConfiguration implements ServletContextListener {
private static final String lineSeparator = System.getProperty("line.separator");
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
private static Pattern propertyPattern = Pattern.compile("\\$\\{\\s*(.+?)\\s*\\}");
@Override
public void contextInitialized(ServletContextEvent sce) {
if ( System.getProperty("libreplan-log-directory") != null ) {
// log4j will do the replacement automatically.
// log4j will do the replacement automatically
return;
}
@ -58,17 +60,13 @@ public class LoggingConfiguration implements ServletContextListener {
new DOMConfigurator().doConfigure(newConfiguration, LogManager.getLoggerRepository());
} catch (IOException e) {
e.printStackTrace();
// let log4j be loaded without replacements
// Let log4j be loaded without replacements
}
}
private String findLogDirectory(ServletContext servletContext) {
File result = logDirectoryFile(servletContext);
if ( result != null ) {
return result.getAbsolutePath() + "/";
}
return "";
return result != null ? result.getAbsolutePath() + "/" : "";
}
private File logDirectoryFile(ServletContext servletContext) {
@ -85,11 +83,8 @@ public class LoggingConfiguration implements ServletContextListener {
}
File home = new File(System.getProperty("user.home"));
if ( home.canWrite() ) {
return tryToAppendApplicationName(home, applicationName);
}
return null;
return home.canWrite() ? tryToAppendApplicationName(home, applicationName) : null;
}
private File findTomcatLogDirectory() {
@ -98,29 +93,18 @@ public class LoggingConfiguration implements ServletContextListener {
return null;
}
File[] tomcatLogDirectories = file.listFiles(pathname -> {
return pathname.getName().contains("tomcat");
});
File[] tomcatLogDirectories = file.listFiles(pathname -> pathname.getName().contains("tomcat"));
if ( tomcatLogDirectories.length == 0 ) {
return null;
}
return tomcatLogDirectories[0];
return tomcatLogDirectories.length == 0 ? null : tomcatLogDirectories[0];
}
private File tryToAppendApplicationName(File logDirectory, String applicationName) {
File forApplication = new File(logDirectory, applicationName);
if ( forApplication.mkdir() || forApplication.canWrite() ) {
return forApplication;
}
return logDirectory;
return forApplication.mkdir() || forApplication.canWrite() ? forApplication : logDirectory;
}
private boolean isTomcat(ServletContext servletContext) {
String serverInfo = servletContext.getServerInfo();
return serverInfo != null && serverInfo.contains("Tomcat");
}
@ -130,7 +114,6 @@ public class LoggingConfiguration implements ServletContextListener {
return each;
}
}
return "";
}
@ -142,21 +125,18 @@ public class LoggingConfiguration implements ServletContextListener {
return new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("log4j.xml")));
}
private String withReplacements(Map<String, String> replacements, BufferedReader originalConfiguration)
throws IOException {
private String withReplacements(Map<String, String> replacements, BufferedReader originalConfiguration) throws IOException {
StringBuilder result = new StringBuilder();
String line;
while ((line = originalConfiguration.readLine()) != null) {
result.append(doReplacement(replacements, line)).append(lineSeparator);
result.append(doReplacement(replacements, line)).append(LINE_SEPARATOR);
}
return result.toString();
}
private static Pattern propertyPattern = Pattern.compile("\\$\\{\\s*(.+?)\\s*\\}");
private static String doReplacement(Map<String, String> propertyReplacements, String line) {
String result = line;

View file

@ -46,9 +46,9 @@ import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.event.BookmarkEvent;
/**
* Handler for EntryPoints. In other way it is also wrapper for URL redirecting.
* Handler for EntryPoints.
* In other way it is also wrapper for URL redirecting.
* <br />
*
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Vova Perebykivskyi <vova@libreplan-enterprise.com>
*/
@ -82,55 +82,6 @@ public class EntryPointsHandler<T> {
private static final ThreadLocal<List<String>> linkCapturer = new ThreadLocal<>();
public static void setupEntryPointsForThisRequest(HttpServletRequest request, Map<String, String> entryPoints) {
request.setAttribute(MANUALLY_SET_PARAMS, entryPoints);
}
public interface ICapture {
void capture();
}
/**
* It capture the first redirect done via an {@link EntryPoint} in the
* provided {@link ICapture} and returns the path.
*
* @see #capturePaths(ICapture)
* @param redirects
* @throws IllegalStateException
* if no {@link EntryPoint} point call is done.
*/
public static String capturePath(ICapture redirects) {
List<? extends String> result = capturePaths(redirects);
if (result.isEmpty()) {
throw new IllegalStateException("a call to an entry point should be done");
}
return result.get(0);
}
/**
* It captures the redirects done via {@link EntryPoint} in the provided
* {@link ICapture} and returns the paths.
*
* @param redirects
* @return
*/
public static List<? extends String> capturePaths(ICapture redirects) {
linkCapturer.set(new ArrayList<>());
try {
redirects.capture();
List<String> list = linkCapturer.get();
if (list == null) {
throw new RuntimeException(ICapture.class.getName() + " cannot be nested");
}
return Collections.unmodifiableList(list);
} finally {
linkCapturer.set(null);
}
}
public EntryPointsHandler(IConverterFactory converterFactory,
IExecutorRetriever executorRetriever,
Class<T> interfaceDefiningEntryPoints) {
@ -157,6 +108,53 @@ public class EntryPointsHandler<T> {
}
}
public static void setupEntryPointsForThisRequest(HttpServletRequest request, Map<String, String> entryPoints) {
request.setAttribute(MANUALLY_SET_PARAMS, entryPoints);
}
public interface ICapture {
void capture();
}
/**
* It capture the first redirect done via an {@link EntryPoint} in the provided {@link ICapture} and returns the path.
*
* @see #capturePaths(ICapture)
* @param redirects
* @throws IllegalStateException
* if no {@link EntryPoint} point call is done.
*/
public static String capturePath(ICapture redirects) {
List<? extends String> result = capturePaths(redirects);
if (result.isEmpty()) {
throw new IllegalStateException("a call to an entry point should be done");
}
return result.get(0);
}
/**
* It captures the redirects done via {@link EntryPoint} in the provided {@link ICapture} and returns the paths.
*
* @param redirects
* @return {@link List<? extends String>}
*/
public static List<? extends String> capturePaths(ICapture redirects) {
linkCapturer.set(new ArrayList<>());
try {
redirects.capture();
List<String> list = linkCapturer.get();
if (list == null) {
throw new RuntimeException(ICapture.class.getName() + " cannot be nested");
}
return Collections.unmodifiableList(list);
} finally {
linkCapturer.set(null);
}
}
public void doTransition(String methodName, Object... values) {
if (!metadata.containsKey(methodName)) {
LOG.error("Method " + methodName +
@ -173,7 +171,7 @@ public class EntryPointsHandler<T> {
return;
}
if (isFlagedInThisRequest()) {
if ( isFlaggedInThisRequest()) {
return;
}
flagAlreadyExecutedInThisRequest();
@ -202,7 +200,7 @@ public class EntryPointsHandler<T> {
return getFragment(parameterNames, stringRepresentations);
}
private boolean isFlagedInThisRequest() {
private boolean isFlaggedInThisRequest() {
return getRequest().getAttribute(FLAG_ATTRIBUTE) == this;
}
@ -227,9 +225,9 @@ public class EntryPointsHandler<T> {
* After migration from ZK 5 to ZK 8 it starts to throw 404 error on pages that were redirected with parameters.
* Solution is to make question mark (?) symbol after page.
*
* Before: http://localhost:8081/myaccount/personalTimesheet.zul;date=2016-07-08;resource=WORKER0004
* Before: http://localhost:8080/myaccount/personalTimesheet.zul;date=2016-07-08;resource=WORKER0004
*
* After: http://localhost:8081/myaccount/personalTimesheet.zul?date=2016-07-08;resource=WORKER0004
* After: http://localhost:8080/myaccount/personalTimesheet.zul?date=2016-07-08;resource=WORKER0004
*/
private String buildRedirectURL(String fragment) {
return page + "?" + stripPound(fragment);
@ -260,17 +258,13 @@ public class EntryPointsHandler<T> {
private static void callMethod(Object target, Method superclassMethod, Object[] params) {
try {
Method method = target.getClass().getMethod(
superclassMethod.getName(),
superclassMethod.getParameterTypes());
Method method = target.getClass().getMethod(superclassMethod.getName(), superclassMethod.getParameterTypes());
method.invoke(target, params);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public <S extends T> boolean applyIfMatches(S controller) {
HttpServletRequest request = getRequest();
@ -288,7 +282,7 @@ public class EntryPointsHandler<T> {
}
public <S extends T> boolean applyIfMatches(S controller, String fragment) {
if (isFlagedInThisRequest()) {
if ( isFlaggedInThisRequest()) {
return false;
}
@ -312,8 +306,9 @@ public class EntryPointsHandler<T> {
HashSet<String> requiredParams = new HashSet<>(Arrays.asList(entryPointAnnotation.value()));
if (matrixParamsNames.equals(requiredParams)) {
final Object[] arguments = retrieveArguments(matrixParams,
entryPointAnnotation, entryPointMetadata.method.getParameterTypes());
final Object[] arguments =
retrieveArguments(matrixParams, entryPointAnnotation, entryPointMetadata.method.getParameterTypes());
Util.executeIgnoringCreationOfBindings(
() -> callMethod(controller, entryPointMetadata.method, arguments));
@ -342,9 +337,8 @@ public class EntryPointsHandler<T> {
return !uri.startsWith(";") ? ";" + uri : uri;
}
private Object[] retrieveArguments(Map<String, String> matrixParams,
EntryPoint linkToStateAnnotation,
Class<?>[] parameterTypes) {
private Object[] retrieveArguments(
Map<String, String> matrixParams, EntryPoint linkToStateAnnotation, Class<?>[] parameterTypes) {
Object[] result = new Object[parameterTypes.length];

View file

@ -75,6 +75,8 @@ public class ExpenseSheetCRUDController
extends BaseCRUDController<ExpenseSheet>
implements IExpenseSheetCRUDController {
private static final String NOT_EMPTY = "cannot be empty";
private IExpenseSheetModel expenseSheetModel;
/**
@ -102,8 +104,13 @@ public class ExpenseSheetCRUDController
private boolean cancel = false;
public ExpenseSheetCRUDController() {
expenseSheetModel = (IExpenseSheetModel) SpringUtil.getBean("expenseSheetModel");
URLHandlerRegistry = (IURLHandlerRegistry) SpringUtil.getBean("URLHandlerRegistry");
if ( expenseSheetModel == null ) {
expenseSheetModel = (IExpenseSheetModel) SpringUtil.getBean("expenseSheetModel");
}
if ( URLHandlerRegistry == null ) {
URLHandlerRegistry = (IURLHandlerRegistry) SpringUtil.getBean("URLHandlerRegistry");
}
}
@Override
@ -185,11 +192,11 @@ public class ExpenseSheetCRUDController
private boolean validateNewLine() {
if (expenseSheetModel.getNewExpenseSheetLine().getDate() == null) {
throw new WrongValueException(this.dateboxExpenseDate, _("cannot be empty"));
throw new WrongValueException(this.dateboxExpenseDate, _(NOT_EMPTY));
}
if (expenseSheetModel.getNewExpenseSheetLine().getOrderElement() == null) {
throw new WrongValueException(this.bandboxTasks, _("cannot be empty"));
throw new WrongValueException(this.bandboxTasks, _(NOT_EMPTY));
}
BigDecimal value = expenseSheetModel.getNewExpenseSheetLine().getValue();
@ -328,7 +335,7 @@ public class ExpenseSheetCRUDController
}
});
dateboxExpense.setConstraint("no empty:" + _("cannot be empty"));
dateboxExpense.setConstraint("no empty:" + _(NOT_EMPTY));
row.appendChild(dateboxExpense);
}
@ -344,6 +351,7 @@ public class ExpenseSheetCRUDController
Listitem selectedItem = bandboxSearch.getSelectedItem();
setResourceInESL(selectedItem, expenseSheetLine);
};
bandboxSearch.setListboxEventListener(Events.ON_SELECT, eventListenerUpdateResource);
bandboxSearch.setListboxEventListener(Events.ON_OK, eventListenerUpdateResource);
bandboxSearch.setBandboxEventListener(Events.ON_CHANGING, eventListenerUpdateResource);
@ -361,7 +369,7 @@ public class ExpenseSheetCRUDController
code.setValue(line.getCode());
}
code.addEventListener("onChange", (EventListener) event -> {
code.addEventListener("onChange", event -> {
final ExpenseSheetLine line1 = row.getValue();
line1.setCode(code.getValue());
});
@ -375,7 +383,7 @@ public class ExpenseSheetCRUDController
delete.setHoverImage("/common/img/ico_borrar.png");
delete.setSclass("icono");
delete.setTooltiptext(_("Delete"));
delete.addEventListener(Events.ON_CLICK, (EventListener) event -> confirmRemove(row.getValue()));
delete.addEventListener(Events.ON_CLICK, event -> confirmRemove(row.getValue()));
row.appendChild(delete);
}
@ -418,17 +426,37 @@ public class ExpenseSheetCRUDController
bandboxSearch.setListboxEventListener(Events.ON_SELECT, eventListenerUpdateOrderElement);
bandboxSearch.setListboxEventListener(Events.ON_OK, eventListenerUpdateOrderElement);
bandboxSearch.setBandboxEventListener(Events.ON_CHANGING, eventListenerUpdateOrderElement);
bandboxSearch.setBandboxConstraint("no empty:" + _("cannot be empty"));
bandboxSearch.setBandboxConstraint("no empty:" + _(NOT_EMPTY));
row.appendChild(bandboxSearch);
}
private Constraint checkConstraintLineCodes(final ExpenseSheetLine line) {
return (comp, value) -> {
if (!getExpenseSheet().isCodeAutogenerated()) {
String code = (String) value;
if (code == null || code.isEmpty()) {
throw new WrongValueException(comp, _("Code cannot be empty."));
} else {
String oldCode = line.getCode();
line.setCode(code);
if (!getExpenseSheet().isNonRepeatedExpenseSheetLinesCodesConstraint()) {
line.setCode(oldCode);
throw new WrongValueException(comp, _("The code must be unique."));
}
}
}
};
}
private void setOrderElementInESL(Listitem selectedItem, ExpenseSheetLine line) {
OrderElement orderElement = (selectedItem == null ? null : (OrderElement) selectedItem.getValue());
OrderElement orderElement = selectedItem == null ? null : (OrderElement) selectedItem.getValue();
line.setOrderElement(orderElement);
}
private void setResourceInESL(Listitem selectedItem, ExpenseSheetLine expenseSheetLine) {
Resource resource = (selectedItem == null ? null : (Resource) selectedItem.getValue());
Resource resource = selectedItem == null ? null : (Resource) selectedItem.getValue();
expenseSheetLine.setResource(resource);
}
}
@ -442,26 +470,6 @@ public class ExpenseSheetCRUDController
};
}
private Constraint checkConstraintLineCodes(final ExpenseSheetLine line) {
return (comp, value) -> {
if (!getExpenseSheet().isCodeAutogenerated()) {
String code = (String) value;
if (code == null || code.isEmpty()) {
throw new WrongValueException(comp, _("Code cannot be empty."));
} else {
String oldCode = line.getCode();
line.setCode(code);
if (!getExpenseSheet().isNonRepeatedExpenseSheetLinesCodesConstraint()) {
line.setCode(oldCode);
throw new WrongValueException(comp, _("The code must be unique."));
}
}
}
};
}
public Constraint checkConstraintExpendeCode() {
return (comp, value) -> {
if (!getExpenseSheet().isCodeAutogenerated()) {

View file

@ -27,9 +27,14 @@ import org.zkoss.zk.ui.util.Clients;
public abstract class LoadChartFiller extends ChartFiller {
public static final String COLOR_CAPABILITY_LINE = "#000000"; // Black
public static final String COLOR_ASSIGNED_LOAD = "#98D471"; // Green
public static final String COLOR_OVERLOAD = "#FF5A11"; // Red
/** Black */
public static final String COLOR_CAPABILITY_LINE = "#000000";
/** Green */
public static final String COLOR_ASSIGNED_LOAD = "#98D471";
/** Red */
public static final String COLOR_OVERLOAD = "#FF5A11";
@Override
public void fillChart(Timeplot chart, Interval interval, Integer size) {
@ -43,7 +48,7 @@ public abstract class LoadChartFiller extends ChartFiller {
ValueGeometry valueGeometry = getValueGeometry();
TimeGeometry timeGeometry = getTimeGeometry(interval);
Plotinfo[] plotInfos = getPlotInfos(interval);
Plotinfo[] plotInfos = getPlotInfo(interval);
for (Plotinfo each : plotInfos) {
appendPlotinfo(chart, each, valueGeometry, timeGeometry);
}
@ -58,8 +63,8 @@ public abstract class LoadChartFiller extends ChartFiller {
* The order must be from the topmost one to the lowest one.
*
* @param interval
* @return the {@link Plotinfo plot infos} to show
* @return the {@link Plotinfo plot info} to show
*/
protected abstract Plotinfo[] getPlotInfos(Interval interval);
protected abstract Plotinfo[] getPlotInfo(Interval interval);
}

View file

@ -14,22 +14,19 @@ import org.zkoss.ganttz.util.Interval;
public abstract class StandardLoadChartFiller extends LoadChartFiller {
@Override
protected Plotinfo[] getPlotInfos(Interval interval) {
protected Plotinfo[] getPlotInfo(Interval interval) {
final ILoadChartData data = getDataOn(interval);
Plotinfo plotInfoLoad = createPlotinfoFromDurations(getLoad(data),
interval);
Plotinfo plotInfoLoad = createPlotinfoFromDurations(getLoad(data), interval);
plotInfoLoad.setFillColor(COLOR_ASSIGNED_LOAD);
plotInfoLoad.setLineWidth(0);
Plotinfo plotInfoMax = createPlotinfoFromDurations(
getCalendarMaximumAvailability(data), interval);
Plotinfo plotInfoMax = createPlotinfoFromDurations(getCalendarMaximumAvailability(data), interval);
plotInfoMax.setLineColor(COLOR_CAPABILITY_LINE);
plotInfoMax.setFillColor("#FFFFFF");
plotInfoMax.setLineWidth(2);
Plotinfo plotInfoOverload = createPlotinfoFromDurations(
getOverload(data), interval);
Plotinfo plotInfoOverload = createPlotinfoFromDurations(getOverload(data), interval);
plotInfoOverload.setFillColor(COLOR_OVERLOAD);
plotInfoOverload.setLineWidth(0);
@ -38,23 +35,17 @@ public abstract class StandardLoadChartFiller extends LoadChartFiller {
protected abstract ILoadChartData getDataOn(Interval interval);
protected LocalDate getStart(LocalDate explicitlySpecifiedStart,
Interval interval) {
if (explicitlySpecifiedStart == null) {
return interval.getStart();
}
return Collections.max(asList(explicitlySpecifiedStart,
interval.getStart()));
protected LocalDate getStart(LocalDate explicitlySpecifiedStart, Interval interval) {
return explicitlySpecifiedStart == null
? interval.getStart()
: Collections.max(asList(explicitlySpecifiedStart, interval.getStart()));
}
@SuppressWarnings("unchecked")
protected LocalDate getEnd(LocalDate explicitlySpecifiedEnd,
Interval interval) {
if (explicitlySpecifiedEnd == null) {
return interval.getFinish();
}
return Collections.min(asList(explicitlySpecifiedEnd,
interval.getFinish()));
protected LocalDate getEnd(LocalDate explicitlySpecifiedEnd, Interval interval) {
return explicitlySpecifiedEnd == null
? interval.getFinish()
: Collections.min(asList(explicitlySpecifiedEnd, interval.getFinish()));
}
private SortedMap<LocalDate, EffortDuration> getLoad(ILoadChartData data) {
@ -65,8 +56,7 @@ public abstract class StandardLoadChartFiller extends LoadChartFiller {
return groupAsNeededByZoom(data.getOverload());
}
private SortedMap<LocalDate, EffortDuration> getCalendarMaximumAvailability(
ILoadChartData data) {
private SortedMap<LocalDate, EffortDuration> getCalendarMaximumAvailability(ILoadChartData data) {
return groupAsNeededByZoom(data.getAvailability());
}

View file

@ -32,7 +32,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -122,6 +121,13 @@ import org.zkoss.zul.Vbox;
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class CompanyPlanningModel implements ICompanyPlanningModel {
/** All the status but CANCELLED and STORED */
private static final EnumSet<OrderStatusEnum> STATUS_VISUALIZED = OrderStatusEnum.getVisibleStatus();
private static final String CENTER = "center";
private static final String INDICATOR = "indicator";
@Autowired
private IOrderDAO orderDAO;
@ -134,12 +140,6 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
@Autowired
private ICompanyEarnedValueCalculator earnedValueCalculator;
private List<IZoomLevelChangedListener> keepAliveZoomListeners = new ArrayList<>();
private List<Checkbox> earnedValueChartConfigurationCheckboxes = new ArrayList<>();
private List<IChartVisibilityChangedListener> keepAliveChartVisibilityListeners = new ArrayList<>();
@Autowired
private IConfigurationDAO configurationDAO;
@ -149,18 +149,21 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
@Autowired
private TaskElementAdapter taskElementAdapterCreator;
private Scenario currentScenario;
@Autowired
private PredefinedDatabaseSnapshots databaseSnapshots;
private List<IZoomLevelChangedListener> keepAliveZoomListeners = new ArrayList<>();
private List<Checkbox> earnedValueChartConfigurationCheckboxes = new ArrayList<>();
private List<IChartVisibilityChangedListener> keepAliveChartVisibilityListeners = new ArrayList<>();
private Scenario currentScenario;
private LocalDate filterStartDate;
private LocalDate filterFinishDate;
/** All the status but CANCELLED and STORED */
private static final EnumSet<OrderStatusEnum> STATUS_VISUALIZED = OrderStatusEnum.getVisibleStatus();
private static final class TaskElementNavigator implements IStructureNavigator<TaskElement> {
@Override
@ -229,18 +232,18 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
}
else {
// If the chart is not expanded, we load the data later with a listener
(planner.getFellow("graphics")).addEventListener("onOpen",
new EventListener() {
@Override
public void onEvent(Event event) {
transactionService.runOnReadOnlyTransaction((IOnTransaction<Void>) () -> {
setupChartAndItsContent(planner, chartComponent);
return null;
});
// Data is loaded only once, then we remove the listener
event.getTarget().removeEventListener("onOpen", this);
}
planner.getFellow("graphics").addEventListener("onOpen", new EventListener() {
@Override
public void onEvent(Event event) {
transactionService.runOnReadOnlyTransaction((IOnTransaction<Void>) () -> {
setupChartAndItsContent(planner, chartComponent);
return null;
});
// Data is loaded only once, then we remove the listener
event.getTarget().removeEventListener("onOpen", this);
}
});
}
}
@ -313,7 +316,6 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
private Timeplot createEmptyTimeplot() {
Timeplot timeplot = new Timeplot();
timeplot.appendChild(new Plotinfo());
return timeplot;
}
@ -341,7 +343,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
datebox.addEventListener(Events.ON_CHANGE, event -> {
LocalDate date = new LocalDate(datebox.getValue());
updateEarnedValueChartLegend(vbox, earnedValueChartFiller, date);
dateInfutureMessage(datebox);
dateInFutureMessage(datebox);
});
}
@ -355,7 +357,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
}
}
private void dateInfutureMessage(Datebox datebox) {
private void dateInFutureMessage(Datebox datebox) {
Date value = datebox.getValue();
Date today = LocalDate.fromDateFields(new Date()).toDateTimeAtStartOfDay().toDate();
@ -374,15 +376,18 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
final Div div = new Div();
Timeplot timePlot = loadChartEmitter.getLastValue();
if (timePlot != null) {
div.appendChild(timePlot);
}
loadChartEmitter.addListener(timePlot1 -> {
div.getChildren().clear();
if (timePlot1 != null) {
div.appendChild(timePlot1);
}
});
div.setSclass("plannergraph");
hbox.appendChild(div);
@ -394,8 +399,8 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
public static org.zkoss.zk.ui.Component getLoadChartLegend() {
Hbox hbox = new Hbox();
hbox.setClass("legend-container");
hbox.setAlign("center");
hbox.setPack("center");
hbox.setAlign(CENTER);
hbox.setPack(CENTER);
Executions.createComponents("/planner/_legendLoadChartCompany.zul", hbox, null);
return hbox;
@ -407,8 +412,8 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
Vbox vbox = new Vbox();
vbox.setClass("legend-container");
vbox.setAlign("center");
vbox.setPack("center");
vbox.setAlign(CENTER);
vbox.setPack(CENTER);
Hbox dateHbox = new Hbox();
dateHbox.appendChild(new Label(_("Select date")));
@ -438,6 +443,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
private org.zkoss.zk.ui.Component getEarnedValueChartConfigurableLegend(
CompanyEarnedValueChartFiller earnedValueChartFiller, LocalDate date) {
Hbox mainhbox = new Hbox();
mainhbox.setId("indicatorsTable");
@ -456,7 +462,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
for (EarnedValueType type : EarnedValueType.values()) {
Checkbox checkbox = new Checkbox(type.getAcronym());
checkbox.setTooltiptext(type.getName());
checkbox.setAttribute("indicator", type);
checkbox.setAttribute(INDICATOR, type);
checkbox.setStyle("color: " + type.getColor());
Label valueLabel = new Label(getLabelTextEarnedValueType(
@ -468,6 +474,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
hbox.appendChild(valueLabel);
columnNumber = columnNumber + 1;
switch (columnNumber) {
case 1:
@ -518,7 +525,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
private void markAsSelectedDefaultIndicators() {
for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) {
EarnedValueType type = (EarnedValueType) checkbox.getAttribute("indicator");
EarnedValueType type = (EarnedValueType) checkbox.getAttribute(INDICATOR);
switch (type) {
@ -541,7 +548,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) {
if (checkbox.isChecked()) {
EarnedValueType type = (EarnedValueType) checkbox.getAttribute("indicator");
EarnedValueType type = (EarnedValueType) checkbox.getAttribute(INDICATOR);
result.add(type);
}
}
@ -593,7 +600,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
}
@Override
public void doPrint(HashMap<String, String> parameters, Planner planner) {
public void doPrint(Map<String, String> parameters, Planner planner) {
CutyPrint.print(parameters, planner);
}
@ -626,6 +633,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
});
keepAliveChartVisibilityListeners.add(chartVisibilityChangedListener);
return chartVisibilityChangedListener;
}
@ -679,6 +687,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
}
}
Collections.sort(result, (arg0, arg1) -> arg0.getStartDate().compareTo(arg1.getStartDate()));
return result;
}
@ -724,6 +733,9 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
}
state = (OrderStatusEnum) filterPair.getValue();
break;
default:
break;
}
}
@ -739,8 +751,8 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
Date endDate = FilterUtils.readProjectsEndDate();
String name = FilterUtils.readProjectsName();
boolean calculateStartDate = (startDate == null);
boolean calculateEndDate = (endDate == null);
boolean calculateStartDate = startDate == null;
boolean calculateEndDate = endDate == null;
// Filter predicate needs to be calculated based on the projects dates
if ( (calculateStartDate) || (calculateEndDate) ) {
@ -762,6 +774,7 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
startDate = Collections.min(
notNull(startDate, each.getInitDate(), associatedTaskElement.getStartDate()));
}
if ( calculateEndDate ) {
endDate = Collections.max(
notNull(endDate, each.getDeadline(), associatedTaskElement.getEndDate()));
@ -789,15 +802,11 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
@Override
public Date getFilterStartDate() {
return ((filterStartDate == null) ? null : filterStartDate.toDateTimeAtStartOfDay().toDate());
return filterStartDate == null ? null : filterStartDate.toDateTimeAtStartOfDay().toDate();
}
@Override
public Date getFilterFinishDate() {
return ((filterStartDate == null) ? null : filterFinishDate.toDateTimeAtStartOfDay().toDate());
}
private AvailabilityTimeLine.Interval getFilterInterval() {
return AvailabilityTimeLine.Interval.create(filterStartDate, filterFinishDate);
return filterStartDate == null ? null : filterFinishDate.toDateTimeAtStartOfDay().toDate();
}
private class CompanyLoadChartFiller extends StandardLoadChartFiller {
@ -829,19 +838,25 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
@Override
protected void calculateBudgetedCostWorkScheduled(Interval interval) {
setIndicatorInInterval(EarnedValueType.BCWS, interval,
setIndicatorInInterval(
EarnedValueType.BCWS,
interval,
earnedValueCalculator.calculateBudgetedCostWorkScheduled(getFilterInterval()));
}
@Override
protected void calculateActualCostWorkPerformed(Interval interval) {
setIndicatorInInterval(EarnedValueType.ACWP, interval,
setIndicatorInInterval(
EarnedValueType.ACWP,
interval,
earnedValueCalculator.calculateActualCostWorkPerformed(getFilterInterval()));
}
@Override
protected void calculateBudgetedCostWorkPerformed(Interval interval) {
setIndicatorInInterval(EarnedValueType.BCWP, interval,
setIndicatorInInterval(
EarnedValueType.BCWP,
interval,
earnedValueCalculator.calculateBudgetedCostWorkPerformed(getFilterInterval()));
}
@ -850,6 +865,10 @@ public class CompanyPlanningModel implements ICompanyPlanningModel {
return getEarnedValueSelectedIndicators();
}
private AvailabilityTimeLine.Interval getFilterInterval() {
return AvailabilityTimeLine.Interval.create(filterStartDate, filterFinishDate);
}
}
@Override

View file

@ -98,7 +98,6 @@ import org.zkoss.ganttz.util.Interval;
import org.zkoss.ganttz.util.ProfilingLogFactory;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import java.math.BigDecimal;
@ -108,7 +107,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -150,51 +148,15 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private static final Log LOG = LogFactory.getLog(OrderPlanningModel.class);
private static final Log PROFILING_LOG = ProfilingLogFactory
.getLog(OrderPlanningModel.class);
private static final Log PROFILING_LOG = ProfilingLogFactory.getLog(OrderPlanningModel.class);
public static <T extends Collection<Resource>> T loadRequiredDataFor(T resources) {
for (Resource each : resources) {
reattachCalendarFor(each);
private static final String CENTER = "center";
// Loading criterions so there are no repeated instances
forceLoadOfCriterions(each);
}
return resources;
}
private static void reattachCalendarFor(Resource each) {
if (each.getCalendar() != null) {
BaseCalendarModel.forceLoadBaseCalendar(each.getCalendar());
}
}
static void forceLoadOfCriterions(Resource resource) {
Set<CriterionSatisfaction> criterionSatisfactions = resource.getCriterionSatisfactions();
for (CriterionSatisfaction each : criterionSatisfactions) {
each.getCriterion().getName();
each.getCriterion().getType();
}
}
public static ZoomLevel calculateDefaultLevel(PlannerConfiguration<TaskElement> configuration) {
if (configuration.getData().isEmpty()) {
return ZoomLevel.DETAIL_ONE;
}
TaskElement earliest = Collections.min(configuration.getData(), TaskElement.getByStartDateComparator());
TaskElement latest = Collections.max(configuration.getData(), TaskElement.getByEndAndDeadlineDateComparator());
LocalDate startDate = earliest.getStartAsLocalDate();
LocalDate endDate = latest.getBiggestAmongEndOrDeadline();
return ZoomLevel.getDefaultZoomByDates(startDate, endDate);
}
private static final String INDICATOR = "indicator";
@Autowired
private IOrderDAO orderDAO;
private PlanningState planningState;
@Autowired
private IUserDAO userDAO;
@ -237,14 +199,19 @@ public class OrderPlanningModel implements IOrderPlanningModel {
@Autowired
private ISubcontractCommand subcontractCommand;
private List<IZoomLevelChangedListener> keepAliveZoomListeners = new ArrayList<>();
@Autowired
private IOrderEarnedValueCalculator earnedValueCalculator;
@Autowired
private IOrderResourceLoadCalculator resourceLoadCalculator;
@Autowired
private PlanningStateCreator planningStateCreator;
private List<IZoomLevelChangedListener> keepAliveZoomListeners = new ArrayList<>();
private PlanningState planningState;
private List<Checkbox> earnedValueChartConfigurationCheckboxes = new ArrayList<>();
private List<IChartVisibilityChangedListener> keepAliveChartVisibilityListeners = new ArrayList<>();
@ -253,6 +220,51 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private String tabSelected = "load_tab";
private OrderEarnedValueChartFiller earnedValueChartFiller;
private Vbox earnedValueChartLegendContainer;
private Datebox earnedValueChartLegendDatebox;
private Chart earnedValueChart;
public static <T extends Collection<Resource>> T loadRequiredDataFor(T resources) {
for (Resource each : resources) {
reattachCalendarFor(each);
// Loading criterions so there are no repeated instances
forceLoadOfCriterions(each);
}
return resources;
}
private static void reattachCalendarFor(Resource each) {
if (each.getCalendar() != null) {
BaseCalendarModel.forceLoadBaseCalendar(each.getCalendar());
}
}
static void forceLoadOfCriterions(Resource resource) {
Set<CriterionSatisfaction> criterionSatisfactions = resource.getCriterionSatisfactions();
for (CriterionSatisfaction each : criterionSatisfactions) {
each.getCriterion().getName();
each.getCriterion().getType();
}
}
public static ZoomLevel calculateDefaultLevel(PlannerConfiguration<TaskElement> configuration) {
if (configuration.getData().isEmpty()) {
return ZoomLevel.DETAIL_ONE;
}
TaskElement earliest = Collections.min(configuration.getData(), TaskElement.getByStartDateComparator());
TaskElement latest = Collections.max(configuration.getData(), TaskElement.getByEndAndDeadlineDateComparator());
LocalDate startDate = earliest.getStartAsLocalDate();
LocalDate endDate = latest.getBiggestAmongEndOrDeadline();
return ZoomLevel.getDefaultZoomByDates(startDate, endDate);
}
private static class NullSeparatorCommandOnTask<T> implements ICommandOnTask<T> {
@Override
@ -401,11 +413,8 @@ public class OrderPlanningModel implements IOrderPlanningModel {
return zoomListener;
}
private OrderEarnedValueChartFiller earnedValueChartFiller;
private void setupAdvanceAssignmentPlanningController(
final Planner planner,
AdvanceAssignmentPlanningController advanceAssignmentPlanningController) {
final Planner planner, AdvanceAssignmentPlanningController advanceAssignmentPlanningController) {
advanceAssignmentPlanningController.setReloadEarnedValueListener(
() -> Registry.getTransactionService().runOnReadOnlyTransaction(
@ -464,10 +473,6 @@ public class OrderPlanningModel implements IOrderPlanningModel {
return result;
}
private Vbox earnedValueChartLegendContainer;
private Datebox earnedValueChartLegendDatebox;
private void appendEarnedValueChartAndLegend(
Tabpanel earnedValueChartPanel,
Timeplot chartEarnedValueTimeplot,
@ -476,8 +481,8 @@ public class OrderPlanningModel implements IOrderPlanningModel {
Vbox vbox = new Vbox();
this.earnedValueChartLegendContainer = vbox;
vbox.setClass("legend-container");
vbox.setAlign("center");
vbox.setPack("center");
vbox.setAlign(CENTER);
vbox.setPack(CENTER);
Hbox dateHbox = new Hbox();
dateHbox.appendChild(new Label(_("Select date")));
@ -520,8 +525,6 @@ public class OrderPlanningModel implements IOrderPlanningModel {
refillLoadChartWhenNeeded(changeHooker, planner, loadChart, false);
}
private Chart earnedValueChart;
private void setupEarnedValueChart(Timeplot chartEarnedValueTimeplot,
OrderEarnedValueChartFiller earnedValueChartFiller,
Planner planner,
@ -611,7 +614,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
}
@Override
public void doPrint(HashMap<String, String> parameters, Planner planner) {
public void doPrint(Map<String, String> parameters, Planner planner) {
CutyPrint.print(order, parameters, planner);
}
@ -679,15 +682,16 @@ public class OrderPlanningModel implements IOrderPlanningModel {
if ( id.equals(tabSelected) ) {
tab.setSelected(true);
}
tab.addEventListener("onClick", (EventListener) event -> selectTab(id));
tab.addEventListener("onClick", event -> selectTab(id));
return tab;
}
private org.zkoss.zk.ui.Component getLoadChartLegend() {
Hbox hbox = new Hbox();
hbox.setClass("legend-container");
hbox.setAlign("center");
hbox.setPack("center");
hbox.setAlign(CENTER);
hbox.setPack(CENTER);
Executions.createComponents("/planner/_legendLoadChartOrder.zul", hbox, null);
return hbox;
@ -715,8 +719,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
}
private void appendEventListenerToDateboxIndicators() {
earnedValueChartLegendDatebox.addEventListener(Events.ON_CHANGE, (EventListener) event -> {
earnedValueChartLegendDatebox.addEventListener(Events.ON_CHANGE, event -> {
updateEarnedValueChartLegend();
dateInFutureMessage(earnedValueChartLegendDatebox);
});
@ -729,8 +732,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
earnedValueChartLegendDatebox.setValue(earnedValueChartLegendDatebox.getValue());
}
catch (WrongValueException e) {
// The user moved the gantt and the legend became out of the visualization area,
// reset to a correct date
// The user moved the gantt and the legend became out of the visualization area, reset to a correct date
earnedValueChartLegendDatebox
.setValue(earnedValueChartFiller.initialDateForIndicatorValues().toDateTimeAtStartOfDay().toDate());
}
@ -766,7 +768,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
for (EarnedValueType type : EarnedValueType.values()) {
Checkbox checkbox = new Checkbox(type.getAcronym());
checkbox.setTooltiptext(type.getName());
checkbox.setAttribute("indicator", type);
checkbox.setAttribute(INDICATOR, type);
checkbox.setStyle("color: " + type.getColor());
Label valueLabel = new Label(getLabelTextEarnedValueType(earnedValueChartFiller, type, date));
@ -777,6 +779,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
hbox.appendChild(valueLabel);
columnNumber = columnNumber + 1;
switch (columnNumber) {
case 1:
column1.appendChild(hbox);
@ -785,6 +788,10 @@ public class OrderPlanningModel implements IOrderPlanningModel {
case 2:
column2.appendChild(hbox);
columnNumber = 0;
break;
default:
break;
}
earnedValueChartConfigurationCheckboxes.add(checkbox);
@ -817,7 +824,8 @@ public class OrderPlanningModel implements IOrderPlanningModel {
private void markAsSelectedDefaultIndicators() {
for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) {
EarnedValueType type = (EarnedValueType) checkbox.getAttribute("indicator");
EarnedValueType type = (EarnedValueType) checkbox.getAttribute(INDICATOR);
switch (type) {
case BCWS:
case ACWP:
@ -832,17 +840,6 @@ public class OrderPlanningModel implements IOrderPlanningModel {
}
}
private Set<EarnedValueType> getEarnedValueSelectedIndicators() {
Set<EarnedValueType> result = new HashSet<>();
for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) {
if ( checkbox.isChecked() ) {
EarnedValueType type = (EarnedValueType) checkbox.getAttribute("indicator");
result.add(type);
}
}
return result;
}
private void setEventListenerConfigurationCheckboxes(final Chart earnedValueChart) {
for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) {
checkbox.addEventListener(Events.ON_CHECK, event -> transactionService.runOnReadOnlyTransaction(() -> {
@ -997,8 +994,8 @@ public class OrderPlanningModel implements IOrderPlanningModel {
Messagebox.show(
_("Unsaved changes will be lost. Are you sure?"), _("Confirm exit dialog"),
Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION,
(EventListener) evt -> {
if (evt.getName().equals("onOK")) {
evt -> {
if ("onOK".equals(evt.getName())) {
ConfirmCloseUtil.resetConfirmClose();
Executions.sendRedirect("/planner/index.zul;company_scheduling");
}
@ -1043,6 +1040,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
});
keepAliveChartVisibilityListeners.add(chartVisibilityChangedListener);
return chartVisibilityChangedListener;
}
@ -1069,9 +1067,6 @@ public class OrderPlanningModel implements IOrderPlanningModel {
return zoomListener;
}
@Autowired
private PlanningStateCreator planningStateCreator;
private PlanningState createPlanningStateFor(Order order) {
return planningStateCreator.retrieveOrCreate(planner.getDesktop(), order, planningState1 -> {
planningState1.reattach();
@ -1087,10 +1082,10 @@ public class OrderPlanningModel implements IOrderPlanningModel {
*/
private class OrderLoadChartFiller extends LoadChartFiller {
// Soft green
/** Soft green */
private static final String COLOR_ASSIGNED_LOAD_GLOBAL = "#E0F3D3";
// Soft red
/** Soft red */
private static final String COLOR_OVERLOAD_GLOBAL = "#FFD4C2";
private final Order order;
@ -1105,7 +1100,7 @@ public class OrderPlanningModel implements IOrderPlanningModel {
}
@Override
protected Plotinfo[] getPlotInfos(Interval interval) {
protected Plotinfo[] getPlotInfo(Interval interval) {
resourceLoadCalculator.setOrder(order, planningState.getAssignmentsCalculator());
ContiguousDaysLine<EffortDuration> maxCapacityOnResources =
@ -1195,6 +1190,17 @@ public class OrderPlanningModel implements IOrderPlanningModel {
return getEarnedValueSelectedIndicators();
}
private Set<EarnedValueType> getEarnedValueSelectedIndicators() {
Set<EarnedValueType> result = new HashSet<>();
for (Checkbox checkbox : earnedValueChartConfigurationCheckboxes) {
if ( checkbox.isChecked() ) {
EarnedValueType type = (EarnedValueType) checkbox.getAttribute(INDICATOR);
result.add(type);
}
}
return result;
}
}
private ISubcontractCommand buildSubcontractCommand(EditTaskController editTaskController) {

View file

@ -41,13 +41,13 @@ import org.zkoss.zul.Image;
import org.zkoss.zul.Label;
/**
* Handles Resources Load tab creation (Global and Local)
* Handles Resources Load tab creation (Global and Local).
*
* @author Óscar González Fernández <ogonzalez@igalia.com>
*/
public class ResourcesLoadTabCreator {
private String RESOURCES_LOAD = "Resources Load";
private static final String RESOURCES_LOAD = "Resources Load";
private final IOrderPlanningGate orderPlanningGate;

View file

@ -60,83 +60,39 @@ public class CutyPrint {
private static final String CUTYCAPT_COMMAND = "cutycapt";
// Estimated maximum execution time (ms)
private static final String INDEX_ZUL = "/planner/index.zul";
private static final String PX_IMPORTANT = "px !important; } \n";
/** Estimated maximum execution time (ms) */
private static final int CAPTURE_DELAY = 10000;
/**
* Default width in pixels of the task name text field for depth level 1.
* <p />
* Got from .listdetails .depth_1 input.task_title { width: 121px; } at
* src/main/webapp/planner/css/ganttzk.css
* Got from .listdetails .depth_1 input.task_title { width: 121px; } at src/main/webapp/planner/css/ganttzk.css
*/
private static final int BASE_TASK_NAME_PIXELS = 121;
private static int TASK_HEIGHT = 25;
public static void print(Order order) {
print("/planner/index.zul", entryPointForShowingOrder(order), Collections.<String, String> emptyMap());
}
public static void print(Order order, Map<String, String> parameters) {
print("/planner/index.zul", entryPointForShowingOrder(order), parameters);
}
public static void print(Order order, HashMap<String, String> parameters, Planner planner) {
print("/planner/index.zul", entryPointForShowingOrder(order), parameters, planner);
}
public static void print() {
print("/planner/index.zul", Collections.<String, String> emptyMap(), Collections.<String, String> emptyMap());
}
public static void print(Map<String, String> parameters) {
print("/planner/index.zul", Collections.<String, String> emptyMap(), parameters);
}
public static void print(HashMap<String, String> parameters, Planner planner) {
print("/planner/index.zul", Collections.<String, String> emptyMap(), parameters, planner);
}
private static Map<String, String> entryPointForShowingOrder(Order order) {
final Map<String, String> result = new HashMap<>();
result.put("order", order.getCode() + "");
return result;
}
public static void print(
final String forwardURL, final Map<String, String> entryPointsMap, Map<String, String> parameters) {
print(forwardURL, entryPointsMap, parameters, null);
}
public static void print(final String forwardURL,
final Map<String, String> entryPointsMap,
Map<String, String> parameters,
Planner planner) {
CutyCaptParameters params = new CutyCaptParameters(forwardURL, entryPointsMap, parameters, planner);
String generatedSnapshotServerPath = takeSnapshot(params);
openInAnotherTab(generatedSnapshotServerPath);
}
private static void openInAnotherTab(String producedPrintFilePath) {
Executions.getCurrent().sendRedirect(producedPrintFilePath, "_blank");
}
private static class CutyCaptParameters {
private static final AtomicLong counter = new AtomicLong();
private final HttpServletRequest request = (HttpServletRequest) Executions.getCurrent().getNativeRequest();
private final ServletContext context = request.getSession().getServletContext();
private final String forwardURL;
private final Map<String, String> entryPointsMap;
private final Map<String, String> printParameters;
private final Planner planner;
private final boolean containersExpandedByDefault;
private final int minWidthForTaskNameColumn;
private final String generatedSnapshotServerPath;
@ -149,10 +105,9 @@ public class CutyPrint {
Planner planner) {
this.forwardURL = forwardURL;
this.entryPointsMap = (entryPointsMap != null) ? entryPointsMap : Collections.<String, String> emptyMap();
this.entryPointsMap = (entryPointsMap != null) ? entryPointsMap : Collections.emptyMap();
this.printParameters =
(printParameters != null) ? printParameters : Collections.<String, String> emptyMap();
this.printParameters = (printParameters != null) ? printParameters : Collections.emptyMap();
this.planner = planner;
@ -166,11 +121,13 @@ public class CutyPrint {
}
private String buildCaptureDestination(String extension) {
if ( StringUtils.isEmpty(extension) ) {
extension = ".pdf";
String newExtension = extension;
if ( StringUtils.isEmpty(newExtension) ) {
newExtension = ".pdf";
}
return String.format("/print/%tY%<tm%<td%<tH%<tM%<tS-%s%s", new Date(), recentUniqueToken, extension);
return String.format("/print/%tY%<tm%<td%<tH%<tM%<tS-%s%s", new Date(), recentUniqueToken, newExtension);
}
/**
@ -197,10 +154,10 @@ public class CutyPrint {
result.put("url", buildSnapshotURLParam());
int width = buildMinWidthParam();
result.put("min-width", width + "");
result.put("min-width", Integer.toString(width));
result.put("min-height", buildMinHeightParam() + "");
result.put("delay", CAPTURE_DELAY + "");
result.put("min-height", Integer.toString(buildMinHeightParam()));
result.put("delay", Integer.toString(CAPTURE_DELAY));
result.put("user-style-path", buildCustomCSSParam(width));
result.put("out", buildPathToOutputFileParam());
result.put("header", String.format("Accept-Language:%s", Locales.getCurrent().getLanguage()));
@ -216,8 +173,8 @@ public class CutyPrint {
HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
EntryPointsHandler.setupEntryPointsForThisRequest(request, entryPointsMap);
// Pending to forward and process additional parameters
// as show labels, resources, zoom or expand all
// Pending to forward and process additional parameters as show labels, resources, zoom or expand all
request.getRequestDispatcher(forwardURL).forward(request, response);
}
});
@ -241,20 +198,16 @@ public class CutyPrint {
private String resolveLocalHost() {
try {
InetAddress host = InetAddress.getByName(request.getLocalName());
return host.getHostName();
return InetAddress.getByName(request.getLocalName()).getHostName();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
private int buildMinWidthParam() {
if ( planner != null && planner.getTimeTracker() != null ) {
return planner.getTimeTracker().getHorizontalSize() + calculateTaskDetailsWidth();
}
return 0;
return planner != null && planner.getTimeTracker() != null
? planner.getTimeTracker().getHorizontalSize() + calculateTaskDetailsWidth()
: 0;
}
private int calculateTaskDetailsWidth() {
@ -264,8 +217,10 @@ public class CutyPrint {
private int buildMinHeightParam() {
int PRINT_VERTICAL_SPACING = 160;
return (containersExpandedByDefault ? planner.getAllTasksNumber() :
planner.getTaskNumber()) * TASK_HEIGHT + PRINT_VERTICAL_SPACING;
return (containersExpandedByDefault
? planner.getAllTasksNumber()
: planner.getTaskNumber())
* TASK_HEIGHT + PRINT_VERTICAL_SPACING;
}
private String buildCustomCSSParam(int plannerWidth) {
@ -283,14 +238,12 @@ public class CutyPrint {
FileUtils.copyFile(new File(sourceFile), destination);
} catch (IOException e) {
LOG.error("Can't create a temporal file for storing the CSS files", e);
return sourceFile;
}
FileWriter appendToFile = null;
try {
appendToFile = new FileWriter(destination, true);
appendToFile.write(cssLinesToAppend);
appendToFile.flush();
} catch (IOException e) {
@ -329,10 +282,10 @@ public class CutyPrint {
int PRINT_VERTICAL_PADDING = 50;
int height = (tasksNumber * TASK_HEIGHT) + PRINT_VERTICAL_PADDING;
String heightCSS = "";
heightCSS += " body div#scroll_container { height: " + height + "px !important;} \n"; /* 1110 */
heightCSS += " body div#timetracker { height: " + (height + 20) + "px !important; } \n";
heightCSS += " body div.plannerlayout { height: " + (height + 80) + "px !important; } \n";
heightCSS += " body div.main-layout { height: " + (height + 90) + "px !important; } \n";
heightCSS += " body div#scroll_container { height: " + height + PX_IMPORTANT; /* 1110 */
heightCSS += " body div#timetracker { height: " + (height + 20) + PX_IMPORTANT;
heightCSS += " body div.plannerlayout { height: " + (height + 80) + PX_IMPORTANT;
heightCSS += " body div.main-layout { height: " + (height + 90) + PX_IMPORTANT;
return heightCSS;
}
@ -351,6 +304,71 @@ public class CutyPrint {
return context.getRealPath(generatedSnapshotServerPath);
}
private static IServletRequestHandler executeOnOriginalContext(final IServletRequestHandler original) {
final SecurityContext originalContext = SecurityContextHolder.getContext();
final Locale current = Locales.getCurrent();
return new IServletRequestHandler() {
@Override
public void handle(
HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Locales.setThreadLocal(current);
SecurityContextHolder.setContext(originalContext);
original.handle(request, response);
}
};
}
}
public static void print(Order order) {
print(INDEX_ZUL, entryPointForShowingOrder(order), Collections.emptyMap());
}
public static void print(Order order, Map<String, String> parameters) {
print(INDEX_ZUL, entryPointForShowingOrder(order), parameters);
}
public static void print(Order order, Map<String, String> parameters, Planner planner) {
print(INDEX_ZUL, entryPointForShowingOrder(order), parameters, planner);
}
public static void print() {
print(INDEX_ZUL, Collections.emptyMap(), Collections.emptyMap());
}
public static void print(Map<String, String> parameters) {
print(INDEX_ZUL, Collections.emptyMap(), parameters);
}
public static void print(Map<String, String> parameters, Planner planner) {
print(INDEX_ZUL, Collections.emptyMap(), parameters, planner);
}
private static Map<String, String> entryPointForShowingOrder(Order order) {
final Map<String, String> result = new HashMap<>();
result.put("order", order.getCode() + "");
return result;
}
public static void print(final String forwardURL, final Map<String, String> entryPointsMap, Map<String, String> parameters) {
print(forwardURL, entryPointsMap, parameters, null);
}
public static void print(final String forwardURL,
final Map<String, String> entryPointsMap,
Map<String, String> parameters,
Planner planner) {
CutyCaptParameters params = new CutyCaptParameters(forwardURL, entryPointsMap, parameters, planner);
String generatedSnapshotServerPath = takeSnapshot(params);
openInAnotherTab(generatedSnapshotServerPath);
}
private static void openInAnotherTab(String producedPrintFilePath) {
Executions.getCurrent().sendRedirect(producedPrintFilePath, "_blank");
}
/**
@ -381,7 +399,7 @@ public class CutyPrint {
printProcess = capture.start();
printProcess.waitFor();
// once the printProcess finishes, the print snapshot is available
// Once the printProcess finishes, the print snapshot is available
return generatedSnapshotServerPath;
} catch (InterruptedException e) {
throw new RuntimeException(e);
@ -406,20 +424,4 @@ public class CutyPrint {
}
}
private static IServletRequestHandler executeOnOriginalContext(final IServletRequestHandler original) {
final SecurityContext originalContext = SecurityContextHolder.getContext();
final Locale current = Locales.getCurrent();
return new IServletRequestHandler() {
@Override
public void handle(
HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Locales.setThreadLocal(current);
SecurityContextHolder.setContext(originalContext);
original.handle(request, response);
}
};
}
}

View file

@ -134,15 +134,14 @@ public class ResourceLoadController implements Composer {
}
};
public ResourceLoadController() {}
public ResourceLoadController() {
}
@Override
public void doAfterCompose(org.zkoss.zk.ui.Component comp) {
this.parent = comp;
}
public void add(IToolbarCommand... commands) {
Validate.noNullElements(commands);
this.commands.addAll(Arrays.asList(commands));
@ -179,7 +178,6 @@ public class ResourceLoadController implements Composer {
});
}
public interface IListenerAdder {
Object addAndReturnListener(ResourcesLoadPanel panel);
@ -197,10 +195,12 @@ public class ResourceLoadController implements Composer {
super(onChange, filterBy);
}
@Override
void setup(ResourcesLoadPanel panel) {
panel.setLoadChart(buildChart(emitter));
}
@Override
public Object addAndReturnListener(ResourcesLoadPanel panel) {
IChartVisibilityChangedListener visibilityChangedListener = fillOnChartVisibilityChange();
panel.addChartVisibilityListener(visibilityChangedListener);
@ -209,8 +209,7 @@ public class ResourceLoadController implements Composer {
}
private IChartVisibilityChangedListener fillOnChartVisibilityChange() {
IChartVisibilityChangedListener result = new IChartVisibilityChangedListener() {
return new IChartVisibilityChangedListener() {
@Override
public void chartVisibilityChanged(final boolean visible) {
if (visible && loadChart != null) {
@ -218,7 +217,6 @@ public class ResourceLoadController implements Composer {
}
}
};
return result;
}
private Tabbox buildChart(Emitter<Timeplot> timePlot) {
@ -291,7 +289,6 @@ public class ResourceLoadController implements Composer {
private Timeplot createEmptyTimeplot() {
Timeplot timeplot = new Timeplot();
timeplot.appendChild(new Plotinfo());
return timeplot;
}
}
@ -318,13 +315,17 @@ public class ResourceLoadController implements Composer {
return filterBy != null;
}
void setup(ResourcesLoadPanel panel) {}
void setup(ResourcesLoadPanel panel) {
}
void checkDependencies() {}
void checkDependencies() {
}
void applyToParameters(ResourceLoadParameters parameters) {}
void applyToParameters(ResourceLoadParameters parameters) {
}
void updateUI(ResourcesLoadPanel panel, ResourceLoadDisplayData generatedData) {}
void updateUI(ResourcesLoadPanel panel, ResourceLoadDisplayData generatedData) {
}
}
private abstract static class DependingOnFiltering extends VisualizationModifier {
@ -514,7 +515,6 @@ public class ResourceLoadController implements Composer {
if ( isAppliedToOrder() ) {
return;
}
panel.setSecondOptionalFilter(buildBandboxFilterer());
}
@ -543,7 +543,6 @@ public class ResourceLoadController implements Composer {
private Label getLabel() {
updateLabelValue();
return label;
}
@ -711,11 +710,9 @@ public class ResourceLoadController implements Composer {
// TODO resolve deprecated
if ( !ObjectUtils.equals(aElement.getId(), bElement.getId()) ) {
return false;
}
}
return true;
}
@ -801,7 +798,8 @@ public class ResourceLoadController implements Composer {
private List<IListenerAdder> listenersToAdd = null;
public Reloader() {}
public Reloader() {
}
private List<VisualizationModifier> getVisualizationModifiers() {
if ( visualizationModifiers != null ) {
@ -897,7 +895,6 @@ public class ResourceLoadController implements Composer {
public IOnTransaction<Void> reload() {
return () -> {
reloadInTransaction();
return null;
};
}
@ -1066,7 +1063,6 @@ public class ResourceLoadController implements Composer {
}
public void setPlanningControllerEntryPoints(IOrderPlanningGate planningControllerEntryPoints) {
this.planningControllerEntryPoints = planningControllerEntryPoints;
}

View file

@ -27,15 +27,16 @@ import org.libreplan.business.workingday.EffortDuration;
import org.libreplan.business.workreports.entities.WorkReport;
/**
* Simple class to represent the personal timesheets to be shown in the list.<br />
*
* This is only a utility class for the UI, everything will be saved using
* {@link WorkReport} class.
* Simple class to represent the personal timesheets to be shown in the list.
* <br />
* This is only a utility class for the UI, everything will be saved using {@link WorkReport} class.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public class PersonalTimesheetDTO {
private static final String MMMM_Y_PATTERN = "MMMM y";
private LocalDate date;
private WorkReport workReport;
@ -61,9 +62,8 @@ public class PersonalTimesheetDTO {
* @param tasksNumber
* Number of tasks in the personal timesheet
*/
public PersonalTimesheetDTO(LocalDate date, WorkReport workReport,
EffortDuration resourceCapacity, EffortDuration totalHours,
int tasksNumber) {
public PersonalTimesheetDTO(LocalDate date, WorkReport workReport, EffortDuration resourceCapacity,
EffortDuration totalHours, int tasksNumber) {
this.date = date;
this.workReport = workReport;
this.resourceCapacity = resourceCapacity;
@ -101,30 +101,31 @@ public class PersonalTimesheetDTO {
*/
public static String toString(PersonalTimesheetsPeriodicityEnum periodicity, LocalDate date) {
switch (periodicity) {
case WEEKLY:
LocalDate start = periodicity.getStart(date);
LocalDate end = periodicity.getEnd(date);
String string = date.toString("w");
if (start.getMonthOfYear() == end.getMonthOfYear()) {
string += " (" + date.toString("MMMM y") + ")";
string += " (" + date.toString(MMMM_Y_PATTERN) + ")";
} else {
if (start.getYear() == end.getYear()) {
string += " (" + start.toString("MMMM") + " - "
+ end.toString("MMMM y") + ")";
string += " (" + start.toString("MMMM") + " - " + end.toString(MMMM_Y_PATTERN) + ")";
} else {
string += " (" + start.toString("MMMM y") + " - "
+ end.toString("MMMM y") + ")";
string += " (" + start.toString(MMMM_Y_PATTERN) + " - " + end.toString(MMMM_Y_PATTERN) + ")";
}
}
return _("Week {0}", string);
case TWICE_MONTHLY:
return (date.getDayOfMonth() <= 15) ?
_("{0} 1st fortnight", date.toString("MMMM y")) :
_("{0} 2nd fortnight", date.toString("MMMM y"));
return (date.getDayOfMonth() <= 15)
? _("{0} 1st fortnight", date.toString(MMMM_Y_PATTERN))
: _("{0} 2nd fortnight", date.toString(MMMM_Y_PATTERN));
case MONTHLY:
default:
return date.toString("MMMM y");
return date.toString(MMMM_Y_PATTERN);
}
}

View file

@ -3575,6 +3575,9 @@ msgid "Extra"
msgstr "Extra"
#: libreplan-webapp/src/main/java/org/libreplan/web/common/components/TwoWaySelector.java:79
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:576
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:585
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:593
msgid "Unassigned"
msgstr "Sense assignar"
@ -7221,12 +7224,6 @@ msgstr "Nombre d'aplicacions finalitzades"
msgid "Invalid queue element"
msgstr "Element de cua invàlid"
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:576
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:585
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:593
msgid "Unassigned"
msgstr "Sense assignar"
#: libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardController.java:236
#: libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardController.java:263
#: libreplan-webapp/src/main/webapp/myaccount/_personalTimesheetsArea.zul:35

View file

@ -3542,6 +3542,9 @@ msgid "Extra"
msgstr "Navíc"
#: libreplan-webapp/src/main/java/org/libreplan/web/common/components/TwoWaySelector.java:79
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:576
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:585
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:593
msgid "Unassigned"
msgstr "Nepřiděleno"
@ -7138,12 +7141,6 @@ msgstr "Počet dokončených aplikací"
msgid "Invalid queue element"
msgstr "Neplatný prvek fronty"
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:576
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:585
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:593
msgid "Unassigned"
msgstr "Nepřiděleno"
#: libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardController.java:236
#: libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardController.java:263
#: libreplan-webapp/src/main/webapp/myaccount/_personalTimesheetsArea.zul:35

View file

@ -3543,6 +3543,9 @@ msgid "Extra"
msgstr "Extra"
#: libreplan-webapp/src/main/java/org/libreplan/web/common/components/TwoWaySelector.java:79
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:576
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:585
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:593
msgid "Unassigned"
msgstr "Nicht zugeordnet"
@ -7139,12 +7142,6 @@ msgstr "Anzahl beendetet Anwendungen"
msgid "Invalid queue element"
msgstr "Ungültiges Ablaufelement"
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:576
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:585
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:593
msgid "Unassigned"
msgstr ""
#: libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardController.java:236
#: libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardController.java:263
#: libreplan-webapp/src/main/webapp/myaccount/_personalTimesheetsArea.zul:35

View file

@ -2977,6 +2977,9 @@ msgid "Project"
msgstr "Projekt"
#: libreplan-webapp/src/main/java/org/libreplan/web/common/components/TwoWaySelector.java:79
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:575
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:584
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:592
msgid "Unassigned"
msgstr "Nieprzypisany"
@ -6032,12 +6035,6 @@ msgstr "Liczba zakończonych aplikacji"
msgid "Invalid queue element"
msgstr "Nieprawidłowy element kolejki"
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:575
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:584
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:592
msgid "Unassigned"
msgstr "Nieprzypisany"
#: libreplan-webapp/src/main/java/org/libreplan/web/orders/criterionrequirements/AssignedCriterionRequirementController.java:405
msgid "At least one HoursGroup is needed"
msgstr "Co najmniej jedna HoursGroup jest potrzebna"

View file

@ -3577,6 +3577,9 @@ msgid "Extra"
msgstr "Extra"
#: libreplan-webapp/src/main/java/org/libreplan/web/common/components/TwoWaySelector.java:79
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:576
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:585
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:593
msgid "Unassigned"
msgstr "Não atribuído"
@ -7223,12 +7226,6 @@ msgstr "Número de aplicações finalizadas"
msgid "Invalid queue element"
msgstr "Elemento de fila inválido"
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:576
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:585
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:593
msgid "Unassigned"
msgstr "Não atribuído"
#: libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardController.java:236
#: libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardController.java:263
#: libreplan-webapp/src/main/webapp/myaccount/_personalTimesheetsArea.zul:35

View file

@ -2978,6 +2978,9 @@ msgid "Project"
msgstr "Проект"
#: libreplan-webapp/src/main/java/org/libreplan/web/common/components/TwoWaySelector.java:79
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:575
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:584
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:592
msgid "Unassigned"
msgstr "Нераспределенные"
@ -5962,12 +5965,6 @@ msgstr "Количество законченных приложений"
msgid "Invalid queue element"
msgstr "Неверный элемент очереди"
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:575
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:584
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:592
msgid "Unassigned"
msgstr "Нераспределенный"
#: libreplan-webapp/src/main/webapp/externalcompanies/_editExternalCompany.zul:61
#: libreplan-webapp/src/main/webapp/common/layout/login.zul:70
msgid "User"

View file

@ -3575,6 +3575,9 @@ msgid "Extra"
msgstr "额外"
#: libreplan-webapp/src/main/java/org/libreplan/web/common/components/TwoWaySelector.java:79
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:576
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:585
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:593
msgid "Unassigned"
msgstr "未分配"
@ -7221,12 +7224,6 @@ msgstr "完成的应用程序数量"
msgid "Invalid queue element"
msgstr "无效的队列元素"
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:576
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:585
#: libreplan-webapp/src/main/java/org/libreplan/web/limitingresources/ManualAllocationController.java:593
msgid "Unassigned"
msgstr "Unassigned"
#: libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardController.java:236
#: libreplan-webapp/src/main/java/org/libreplan/web/dashboard/DashboardController.java:263
#: libreplan-webapp/src/main/webapp/myaccount/_personalTimesheetsArea.zul:35

View file

@ -2,102 +2,115 @@
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<!-- Pattern to output the caller's file name and line number -->
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
</appender>
<appender name="rolling" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${libreplan-log-directory}libreplan.log" />
<param name="datePattern" value="'.'yyyy-MM-dd" /> <!-- Rollover each midnight -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<!-- Pattern to output the caller's file name and line number -->
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
</appender>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
</appender>
<appender name="rolling" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${libreplan-log-directory}libreplan.log" />
<param name="datePattern" value="'.'yyyy-MM-dd" /> <!-- Rollover each midnight -->
<appender name="rolling-errors" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${libreplan-log-directory}libreplan-error.log" />
<param name="datePattern" value="'.'yyyy-MM-dd" /> <!-- Rollover each midnight -->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
</appender>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
<appender name="rolling-errors" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${libreplan-log-directory}libreplan-error.log" />
<param name="datePattern" value="'.'yyyy-MM-dd" /> <!-- Rollover each midnight -->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="ERROR" />
</filter>
</appender>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
<appender name="rolling-profiling" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${libreplan-log-directory}libreplan-profile.log" />
<param name="datePattern" value="'.'yyyy-MM-dd" /> <!-- Rollover each midnight -->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="ERROR" />
</filter>
</appender>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
<appender name="rolling-profiling" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${libreplan-log-directory}libreplan-profile.log" />
<param name="datePattern" value="'.'yyyy-MM-dd" /> <!-- Rollover each midnight -->
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="INFO" />
</filter>
</appender>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<param name="BufferSize" value="1000" />
<appender-ref ref="console" />
<appender-ref ref="rolling" />
<appender-ref ref="rolling-errors" />
</appender>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="INFO" />
</filter>
</appender>
<appender name="ASYNC-profiling" class="org.apache.log4j.AsyncAppender">
<param name="BufferSize" value="1000" />
<appender-ref ref="rolling-profiling" />
<appender-ref ref="console" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<param name="BufferSize" value="1000" />
<appender-ref ref="console" />
<appender-ref ref="rolling" />
<appender-ref ref="rolling-errors" />
</appender>
<logger name="profiling" additivity="false">
<level value="INFO" />
<appender-ref ref="ASYNC-profiling" />
</logger>
<appender name="ASYNC-profiling" class="org.apache.log4j.AsyncAppender">
<param name="BufferSize" value="1000" />
<appender-ref ref="rolling-profiling" />
<appender-ref ref="console" />
</appender>
<appender name="logins" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${libreplan-log-directory}libreplan-logins.log" />
<param name="datePattern" value="'.'yyyy-MM-dd" /> <!-- Rollover each midnight -->
<appender name="logins" class="org.apache.log4j.DailyRollingFileAppender">
<param name="file" value="${libreplan-log-directory}libreplan-logins.log" />
<param name="datePattern" value="'.'yyyy-MM-dd" /> <!-- Rollover each midnight -->
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
</appender>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
</appender>
<appender name="ASYNC-logins" class="org.apache.log4j.AsyncAppender">
<param name="BufferSize" value="1000" />
<appender-ref ref="logins" />
</appender>
<appender name="ASYNC-logins" class="org.apache.log4j.AsyncAppender">
<param name="BufferSize" value="1000" />
<appender-ref ref="logins" />
</appender>
<logger name="org.libreplan.web.users.services.AuthenticationProviderLoggingDecorator"
additivity="true">
<level value="INFO" />
<appender-ref ref="ASYNC-logins" />
</logger>
<appender name="second-level-cache-file" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="${libreplan-log-directory}libreplan-second-level-cache.log" />
<param name="MaxFileSize" value="5000KB"/>
<param name="MaxBackupIndex" value="4"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
</appender>
<appender name="second-level-cache-file" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="${libreplan-log-directory}libreplan-second-level-cache.log" />
<param name="MaxFileSize" value="5000KB"/>
<param name="MaxBackupIndex" value="4"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p [%d{dd-MMMM HH:mm:ss}] [%t] %c %x - %m%n" />
</layout>
</appender>
<logger name="org.libreplan.web.users.services.AuthenticationProviderLoggingDecorator" additivity="true">
<level value="INFO" />
<appender-ref ref="ASYNC-logins" />
</logger>
<logger name="org.hibernate.cache">
<level value="INFO"/>
<appender-ref ref="second-level-cache-file" />
</logger>
<logger name="profiling" additivity="false">
<level value="INFO" />
<appender-ref ref="ASYNC-profiling" />
</logger>
<root>
<priority value="INFO" />
<appender-ref ref="ASYNC" />
</root>
</log4j:configuration>
<logger name="org.hibernate.cache">
<level value="INFO"/>
<appender-ref ref="second-level-cache-file" />
</logger>
<!-- To filter empty lazy objects -->
<logger name="org.hibernate.engine.internal.StatefulPersistenceContext">
<level value="ERROR"/>
<appender-ref ref="ASYNC"/>
</logger>
<!-- To filter roles -->
<logger name="org.springframework.security.config.http.FilterInvocationSecurityMetadataSourceParser">
<level value="ERROR"/>
<appender-ref ref="ASYNC"/>
</logger>
<root>
<priority value="INFO" />
<appender-ref ref="ASYNC" />
</root>
</log4j:configuration>

View file

@ -124,9 +124,7 @@
<servlet>
<display-name>CXF Servlet</display-name>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

View file

@ -29,9 +29,7 @@
<preference>
<name>ThreadLocal</name>
<value>
org.springframework.security.core.context.ThreadLocalSecurityContextHolderStrategy=contextHolder
</value>
<value>org.springframework.security.core.context.ThreadLocalSecurityContextHolderStrategy=contextHolder</value>
</preference>

View file

@ -22,11 +22,10 @@
<?taglib uri="/WEB-INF/tld/i18n.tld" prefix="i18n" ?>
<zk>
<zscript><![CDATA[
rsController = arg.get("resourceLoadController");;
]]>
<zscript>
<![CDATA[
rsController = arg.get("resourceLoadController");;
]]>
</zscript>
<div apply="${rsController}" sclass="parentResourceLoad" self="@{define(content_tabSwitcher)}" height="100%">
</div>
<div apply="${rsController}" sclass="parentResourceLoad" self="@{define(content_tabSwitcher)}" height="100%"/>
</zk>

48
pom.xml
View file

@ -38,7 +38,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jetty-port>8081</jetty-port>
<jetty-port>8080</jetty-port>
<jetty-stop-port>9967</jetty-stop-port>
</properties>
@ -166,6 +166,12 @@
<id>thirdparty</id>
<url>http://nexus.libreplan.org/nexus/content/repositories/thirdparty-libreplan16/</url>
</repository>
<!-- ZK CE repository -->
<repository>
<id>ZK CE</id>
<url>http://mavensync.zkoss.org/maven2/</url>
</repository>
</repositories>
<!-- Dependency management -->
@ -404,13 +410,6 @@
<version>1.2</version>
</dependency>
<!-- Slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<!-- Log4j -->
<dependency>
<groupId>org.slf4j</groupId>
@ -462,9 +461,26 @@
<groupId>org.jruby</groupId>
<artifactId>jruby</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.zkoss.common</groupId>
<artifactId>zcommon</artifactId>
<version>8.0.1.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- JGraphT -->
<dependency>
<groupId>org.jgrapht</groupId>
@ -588,7 +604,7 @@
<dependency>
<groupId>org.zkoss.zkforge</groupId>
<artifactId>timeplotz</artifactId>
<version>1.1_50_1</version>
<version>1.1_50</version>
</dependency>
<dependency>
@ -833,12 +849,11 @@
<reload>manual</reload>
<stopPort>${jetty-stop-port}</stopPort>
<stopKey>stop</stopKey>
<!-- Log to the console. -->
<!-- Log to the console -->
<requestLog implementation="org.eclipse.jetty.server.NCSARequestLog">
<!--
This do anything for Jetty,
but is aworkaround for a Maven bug
that prevents the requestLog from being set.
but is a workaround for a Maven bug that prevents the requestLog from being set.
-->
<append>true</append>
</requestLog>
@ -854,20 +869,13 @@
<version>${jdbcDriver.version}</version>
</dependency>
<!-- connection pooling -->
<!-- Connection pooling -->
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
<version>0.8.0.RELEASE</version>
</dependency>
<!-- connection pooling dependencies -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>