ItEr57S07RFInfraestucturaEscenariosItEr56S07: Merge branch 'master' into scenarios
Conflicts: navalplanner-business/src/main/java/org/navalplanner/business/planner/entities/Task.java navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml navalplanner-business/src/main/resources/org/navalplanner/business/planner/entities/ResourceAllocations.hbm.xml navalplanner-business/src/test/java/org/navalplanner/business/test/planner/entities/TaskTest.java navalplanner-business/src/test/resources/navalplanner-business-spring-config-test.xml navalplanner-webapp/src/main/java/org/navalplanner/web/common/CustomMenuController.java navalplanner-webapp/src/main/java/org/navalplanner/web/planner/company/CompanyPlanningModel.java navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/OrderPlanningModel.java navalplanner-webapp/src/main/java/org/navalplanner/web/planner/order/SaveCommand.java navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml navalplanner-webapp/src/test/resources/navalplanner-webapp-spring-config-test.xml
This commit is contained in:
commit
bb6fd1993e
148 changed files with 7404 additions and 622 deletions
|
|
@ -1,5 +1,5 @@
|
|||
Introduction
|
||||
############
|
||||
Introduction
|
||||
#############
|
||||
|
||||
.. contents::
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Criteria
|
||||
Criteria
|
||||
#########
|
||||
|
||||
.. contents::
|
||||
|
|
@ -10,7 +10,7 @@ Several operations can be carried out with criteria in the program:
|
|||
* Criteria administration
|
||||
* Allocation of criteria to resources.
|
||||
* 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.
|
||||
* 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".
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Calendars
|
||||
Calendars
|
||||
###########
|
||||
|
||||
.. contents::
|
||||
|
|
@ -114,7 +114,7 @@ The following must be carried out to set up a default calendar:
|
|||
|
||||
* Go to the *Administration* menu.
|
||||
* Click the *Configuration* procedure.
|
||||
* Where *Default calendar* appears, select the calendar to be used as the program’s default calendar.
|
||||
* Where *Default calendar* appears, select the calendar to be used as the program's default calendar.
|
||||
* Click *Save*.
|
||||
|
||||
.. figure:: images/default-calendar.png
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Progress
|
||||
Progress
|
||||
#########
|
||||
|
||||
.. contents::
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Management of resources
|
||||
Management of resources
|
||||
#######################
|
||||
|
||||
.. _recursos:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Orders and order elements
|
||||
Orders and order elements
|
||||
##############################
|
||||
|
||||
.. contents::
|
||||
|
|
@ -13,10 +13,10 @@ The following sections will describe the operations that users can carry out wit
|
|||
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 “NavalPlan” 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 "NavalPlan" is that they only need to use certain order details. These details are:
|
||||
|
||||
* Order name
|
||||
* Order code
|
||||
* Order name
|
||||
* Order code
|
||||
* Total amount of order
|
||||
* Estimated start date
|
||||
* End date
|
||||
|
|
@ -211,7 +211,7 @@ Apart from the required criterion, one or various hour groups that are part of t
|
|||
* 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:
|
||||
|
||||
* Code for the hour group if it is not automatically generated.
|
||||
* Type of criterion. Users can choose to assign a machine or worker criterion.
|
||||
* Type of criterion. Users can choose to assign a machine or worker criterion.
|
||||
* Number of hours in the hour group.
|
||||
* List of criteria to be applied to the hour group. To add new criteria, users have to click "Add criterion" and select one from the search engine, which appears after clicking the button.
|
||||
|
||||
|
|
@ -253,7 +253,7 @@ Working with materials is carried out as follows:
|
|||
* The system shows the materials that belong to the selected categories.
|
||||
* From the materials list, users select the materials to assign to the order element.
|
||||
* Users click "Assign".
|
||||
* The system shows the selected list of materials on the "Materials" tab with new fields to complete.
|
||||
* The system shows the selected list of materials on the "Materials" tab with new fields to complete.
|
||||
|
||||
.. figure:: images/order-element-material-assign.png
|
||||
:scale: 50
|
||||
|
|
@ -269,7 +269,7 @@ For subsequent monitoring of materials, it is possible to change the status of a
|
|||
* 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
|
||||
------------------------------------
|
||||
|
|
@ -290,7 +290,7 @@ To manage quality forms:
|
|||
* The program has a search engine for quality forms. There are two types of quality forms: according to element or percentage.
|
||||
|
||||
* Element: Every element is independent.
|
||||
* Percentage: Every question increases progress in the order element by a percentage. It must be possible for percentages to be increased to 100%.
|
||||
* Percentage: Every question increases progress in the order element by a percentage. It must be possible for percentages to be increased to 100%.
|
||||
|
||||
* Users select one of the forms created in the administration interface and click "Assign".
|
||||
* The program assigns the form chosen from the list of forms assigned to the order element.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Task planning
|
||||
Task planning
|
||||
#######################
|
||||
|
||||
.. _planificacion:
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
Task planning
|
||||
=============
|
||||
|
||||
Planning in “NavalPlan” 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 "NavalPlan" 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
|
||||
|
|
@ -34,7 +34,7 @@ The planning view combines three different views:
|
|||
* Orange area: Indicating a resource load over 100% as a result of the current project.
|
||||
* Yellow area: Indicating a resource load over 100% as a result of other projects.
|
||||
|
||||
* Graph view and value gained indicators. These can be viewed from the “Value gained” tab. The generated graph is based on the value gained technique and the indicators that are calculated for each of the workdays of the project. The calculated indicators are:
|
||||
* Graph view and value gained indicators. These can be viewed from the "Value gained" tab. The generated graph is based on the value gained technique and the indicators that are calculated for each of the workdays of the project. The calculated indicators are:
|
||||
|
||||
* BCWS: accumulative time function for the number of hours planned up to a certain date. It will be 0 at the planned start of the task and the total number of planned hours at the end. As with all accumulative graphs, it will always increase. The function for a task will be the sum of the daily assignments until the calculation day. This function has values for all times, provided that resources have been assigned.
|
||||
* ACWP: accumulative time function for the hours attributed in the work reports up to a certain date. This function will only have a value of 0 before the date of the task's first work report and its value will continue to increase as time passes and work report hours are added. It will have no value after the date of the last work report.
|
||||
|
|
@ -56,20 +56,20 @@ In the project planning, users can carry out the following procedures:
|
|||
|
||||
* Creating a new milestone. Click the task before the milestone that is to be added and select the "Add milestone" option. Milestones can be moved by selecting the task with the mouse pointer and dragging it to the desired position.
|
||||
* Moving tasks without disturbing dependencies. Right click the body of the task, and drag it to the desired position. If no restrictions or dependencies are disturbed, the system will update the daily assignment of resources to the task and place the task in the selected date.
|
||||
* Assign restrictions. Click the task in question and select the ”Task properties” option. A *pop-up* will appear with a “Restrictions” field that can be changed. Restrictions can conflict with dependencies, which is why each order states whether dependencies take priority or not over restrictions. The restrictions that can be established are:
|
||||
* Assign restrictions. Click the task in question and select the "Task properties" option. A *pop-up* will appear with a "Restrictions" field that can be changed. Restrictions can conflict with dependencies, which is why each order states whether dependencies take priority or not over restrictions. The restrictions that can be established are:
|
||||
|
||||
* *As soon as possible*: Indicating that the task must start as soon as possible.
|
||||
* *Not before*. Indicating that the task must not start before a certain date.
|
||||
* *Start on a specific date*. Indicating that the task must start on a specific date.
|
||||
|
||||
|
||||
The planning view also offers several procedures that ultimately function as viewing options:
|
||||
The planning view also offers several procedures that ultimately function as viewing options:
|
||||
|
||||
* Zoom level: Users can choose the zoom level they require. There are several zoom levels: annual, four-monthly, monthly, weekly and daily.
|
||||
* Search filters: Users can filter tasks based on labels or criteria.
|
||||
* Critical path. As a result of using the *Dijkstra* algorithm to calculate paths on graphs, the critical path was implemented which can be viewed by clicking on the "Critical path" button from the viewing options.
|
||||
* Show labels: Enabling users to view the labels assigned to tasks in a project, which can be viewed on screen or printed.
|
||||
* Show resources: Enabling users to view the resources assigned to tasks in a project, which can be viewed on screen or printed.
|
||||
* Show labels: Enabling users to view the labels assigned to tasks in a project, which can be viewed on screen or printed.
|
||||
* Show resources: Enabling users to view the resources assigned to tasks in a project, which can be viewed on screen or printed.
|
||||
* Print: Enabling users to print the Gantt chart being viewed at that moment.
|
||||
|
||||
Resource load view
|
||||
|
|
@ -94,7 +94,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.
|
||||
The advanced assignment view is explained in depth in the "Resource assignment" chapter.
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Assignment of resources
|
||||
Assignment of resources
|
||||
########################
|
||||
|
||||
.. asigacion_
|
||||
|
|
@ -11,7 +11,7 @@ The assignment of resources is one of the program's most important features, and
|
|||
|
||||
Both types of assignment are explained in the following sections.
|
||||
|
||||
To carry out either of the two types of resource assignment, the following steps are necessary:
|
||||
To carry out either of the two types of resource assignment, the following steps are necessary:
|
||||
|
||||
* Go to the planning of an order.
|
||||
* Right click on the task to be planned.
|
||||
|
|
@ -37,7 +37,7 @@ To carry out either of the two types of resource assignment, the following steps
|
|||
.. figure:: images/resource-assignment.png
|
||||
:scale: 50
|
||||
|
||||
Resource assignment
|
||||
Resource assignment
|
||||
|
||||
* Users select "Search resources".
|
||||
* The program shows a new screen consisting of a criteria tree and a list to the right of workers that fulfil the selected criteria:
|
||||
|
|
@ -64,7 +64,7 @@ To carry out either of the two types of resource assignment, the following steps
|
|||
Specific assignment
|
||||
===================
|
||||
|
||||
This is the specific assignment of a resource to a project task, i.e. the user decides which specific “name and surname(s)” or “machine” must be assigned to a task.
|
||||
This is the specific assignment of a resource to a project task, i.e. the user decides which specific "name and surname(s)" or "machine" must be assigned to a task.
|
||||
|
||||
Specific assignment can be carried out on the screen shown in this image:
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ Specific assignment can be carried out on the screen shown in this image:
|
|||
.. figure:: images/asignacion-especifica.png
|
||||
:scale: 50
|
||||
|
||||
Specific resource assignment
|
||||
Specific resource assignment
|
||||
|
||||
When a resource is specifically assigned, the program creates daily assignments in relation to the percentage of daily assigned resources selected, by previously comparing it with the available resource calendar. For example, an assignment of 0.5 resources for a 32-hour task means that 4 hours per day are assigned to the specific resource to fulfil the task (supposing a working calendar of 8 hours per day).
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ Generic assignment occurs when users do not choose resources specifically, but l
|
|||
.. figure:: images/asignacion-xenerica.png
|
||||
:scale: 50
|
||||
|
||||
Generic resource assignment
|
||||
Generic resource assignment
|
||||
|
||||
The assignment system uses the following assumptions as a basis:
|
||||
|
||||
|
|
@ -105,19 +105,19 @@ The generic assignment algorithm functions in the following way:
|
|||
|
||||
* All resources and days are treated as containers where daily assignment of hours fit, based on the maximum assignment capacity in the task calendar.
|
||||
* The system searches for the resources that fulfil the criterion.
|
||||
* The system analyses which assignments currently have different resources that fulfil criteria.
|
||||
* The system analyses which assignments currently have different resources that fulfil criteria.
|
||||
* The resources that fulfil the criteria are chosen from those that have sufficient availability.
|
||||
* If freer resources are not available, assignments are made to the resources that have less availability.
|
||||
* Over-assignment of resources only starts when all the resources that fulfil the respective criteria are 100% assigned until the total amount required to carry out the task is attained.
|
||||
|
||||
Generic machine assignment
|
||||
Generic machine assignment
|
||||
--------------------------
|
||||
|
||||
Generic machine assignment functions in the same way as worker assignment. For example, when a machine is assigned to a task, the system stores a generic assignment of hours for all machines that fulfil the criteria as described for the resources in general. However, in addition, the system performs the following procedure for machines:
|
||||
|
||||
* For all machines chosen for generic assignment:
|
||||
|
||||
* It collects the machine's configuration information: alpha value, assigned workers and criteria.
|
||||
* It collects the machine's configuration information: alpha value, assigned workers and criteria.
|
||||
* If the machine has an assigned list of workers, the program chooses the number required by the machine depending on the assigned calendar. For example, if the machine calendar is 16 hours per day and the resource calendar is 8 hours, the program assigns two resources from the list of available resources.
|
||||
* If the machine has one or several assigned criteria, the program makes generic assignments from among the resources that fulfil the criteria assigned to the machine.
|
||||
|
||||
|
|
@ -125,14 +125,14 @@ Generic machine assignment functions in the same way as worker assignment. For e
|
|||
Advanced assignment
|
||||
===================
|
||||
|
||||
Advanced assignments allow users to design assignments that are automatically carried out by the application in order to personalise them. This procedure allows users to manually choose the daily hours that are dedicated by resources to tasks that are assigned or define a function that is applied to the assignment.
|
||||
Advanced assignments allow users to design assignments that are automatically carried out by the application in order to personalise them. This procedure allows users to manually choose the daily hours that are dedicated by resources to tasks that are assigned or define a function that is applied to the assignment.
|
||||
|
||||
The steps to follow in order to manage advanced assignments are:
|
||||
|
||||
* Go to the advanced assignment window. There are two ways to access advanced assignments:
|
||||
|
||||
* Go to a specific order and change the view to advanced assignment. In this case, all the tasks on the order and assigned resources (specific and generic) will be shown.
|
||||
* Go to the resource assignment window by clicking the "Advanced assignment" button. In this case, the assignments that show the resources (generic and specific) assigned for a task will be shown.
|
||||
* Go to the resource assignment window by clicking the "Advanced assignment" button. In this case, the assignments that show the resources (generic and specific) assigned for a task will be shown.
|
||||
|
||||
.. figure:: images/advance-assignment.png
|
||||
:scale: 45
|
||||
|
|
@ -153,12 +153,12 @@ The steps to follow in order to manage advanced assignments are:
|
|||
|
||||
|
||||
* Date. Date on which the segment ends. If the following value is established (length), the date is calculated, alternatively, length is calculated.
|
||||
* Defining the length of each segment. This indicates what percentage of the task’s duration is required for the segment.
|
||||
* Defining the length of each segment. This indicates what percentage of the task's duration is required for the segment.
|
||||
* Defining the amount of work. This indicates what workload percentage is expected to be completed in this segment. The quantity of work must be incremental. For example, if there is a 10% segment, the next one must be larger (for example, 20%).
|
||||
* Segment graphs and accumulated loads.
|
||||
|
||||
|
||||
* Users then click “Accept”.
|
||||
* Users then click "Accept".
|
||||
* The program stores the function and applies it to the daily resource assignments.
|
||||
|
||||
.. figure:: images/stretches.png
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
Work reports
|
||||
Work reports
|
||||
#################
|
||||
|
||||
.. contents::
|
||||
|
||||
Work reports enable the monitoring of the hours that existing resources dedicate to the tasks in which they are scheduled.
|
||||
|
||||
The program allows users to configure new forms to enter dedicated hours, specifying the fields that they want to appear in these models, to incorporate reports from tasks that are carried out by workers and to monitor workers.
|
||||
The program allows users to configure new forms to enter dedicated hours, specifying the fields that they want to appear in these models, to incorporate reports from tasks that are carried out by workers and to monitor workers.
|
||||
|
||||
Before being able to add entries for resources, users must at least specify a work report type that defines the structure, including all the rows that are added to it. Users can create as many work reports on the system as necessary.
|
||||
|
||||
Work report type
|
||||
Work report type
|
||||
================
|
||||
|
||||
A work report has a series of fields that are common to the whole report, and a set of work report lines with specific values for the fields defined in each row. For example, resources and tasks are common to all reports, however, there can be other new fields such as “incidents”, which are not required in all types.
|
||||
A work report has a series of fields that are common to the whole report, and a set of work report lines with specific values for the fields defined in each row. For example, resources and tasks are common to all reports, however, there can be other new fields such as "incidents", which are not required in all types.
|
||||
|
||||
Users can configure different work report types so that a company can design its reports to meet its own needs:
|
||||
|
||||
.. figure:: images/work-report-types.png
|
||||
:scale: 40
|
||||
|
||||
Work report types
|
||||
Work report types
|
||||
|
||||
The administration of the work report types allows users to configure this type of feature and add new text fields or optional tags. In the first tab for editing work report types, it is possible to configure the type for the obligatory attributes (if they are applicable to the whole report or if they are specified at line level), and add new optional fields.
|
||||
|
||||
|
|
@ -45,16 +45,16 @@ Users can add new fields to the reports:
|
|||
Creating a work report type with personalised fields
|
||||
|
||||
|
||||
Users can configure date, resource and order element fields if they appear in the header of the report, which means they apply to the whole report, or if they are added to each of the rows.
|
||||
Users can configure date, resource and order element fields if they appear in the header of the report, which means they apply to the whole report, or if they are added to each of the rows.
|
||||
|
||||
Finally, new additional text fields or tags can be added to the existing ones, in the work report header or in each line, by using the “Additional text” and “Tag type” fields respectively. Users can configure the order in which these elements are to be entered in the “Management of additional fields and tags” tab.
|
||||
Finally, new additional text fields or tags can be added to the existing ones, in the work report header or in each line, by using the "Additional text" and "Tag type" fields respectively. Users can configure the order in which these elements are to be entered in the "Management of additional fields and tags" tab.
|
||||
|
||||
Work report list
|
||||
================
|
||||
|
||||
As soon as the format of the reports to be incorporated into the system have been configured, users can enter the details in the created form according to the structure defined in the corresponding work report type. In order to do this, users need to follow these steps:
|
||||
|
||||
* Click the “New work report” button associated with the desired report from the list of work report types.
|
||||
* Click the "New work report" button associated with the desired report from the list of work report types.
|
||||
* The program then shows the report based on the configurations given for the type. See the following image.
|
||||
|
||||
.. figure:: images/work-report-type.png
|
||||
|
|
@ -68,8 +68,8 @@ As soon as the format of the reports to be incorporated into the system have bee
|
|||
* Task code: Code of the task to which the work report is being assigned. Similar to the rest of the fields, if the field is the header, the value is entered once or as many times as necessary on the lines of the report.
|
||||
* Date: Date of the report or each line, depending on whether the heading or line is configured.
|
||||
* Number of hours. The number of work hours in the project.
|
||||
* Start and finish times. Start and finish times for the work in order to calculate definitive work hours. This field only appears in the case of the hour assignment policies, “According to start and finish times” and ”According to the number of hours and start and finish range”.
|
||||
* Type of hours: Enabling users to choose the type of hour, e.g. “Normal”, “Extraordinary”, etc.
|
||||
* Start and finish times. Start and finish times for the work in order to calculate definitive work hours. This field only appears in the case of the hour assignment policies, "According to start and finish times" and "According to the number of hours and start and finish range".
|
||||
* Type of hours: Enabling users to choose the type of hour, e.g. "Normal", "Extraordinary", etc.
|
||||
|
||||
* Click "Save" or "Save and continue".
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Tags
|
||||
Tags
|
||||
#########
|
||||
|
||||
.. contents::
|
||||
|
|
@ -15,12 +15,12 @@ Tag types are used to group the types of tag that users want to manage in the pr
|
|||
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
|
||||
|
||||
List of tag types
|
||||
List of tag types
|
||||
|
||||
From the list of tag types, users can:
|
||||
|
||||
|
|
@ -32,11 +32,11 @@ Editing and creating tags share the same form. From this form, the user can assi
|
|||
|
||||
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.
|
||||
iii. If users wish to add a new tag, they must click on the “New tag” button.
|
||||
iii. If users wish to add a new tag, they must click on the "New tag" button.
|
||||
iv. The system shows a new row on the list with an empty text box that users must edit.
|
||||
v. Users enter a name for the tag.
|
||||
vi. The system adds the name to the list.
|
||||
vii. Users click “Save” or “Save and continue” to continue editing the form.
|
||||
vii. Users click "Save" or "Save and continue" to continue editing the form.
|
||||
|
||||
.. figure:: images/tag-types-edition.png
|
||||
:scale: 50
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Materials
|
||||
Materials
|
||||
##########
|
||||
.. _materiales:
|
||||
.. contents::
|
||||
|
|
@ -7,18 +7,18 @@
|
|||
Administration of materials
|
||||
===========================
|
||||
|
||||
Users can manage a basic database of materials, organised by categories.
|
||||
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.
|
||||
|
||||
Users have to do the following to manage categories:
|
||||
|
||||
* Go to the “Administration->Materials” option.
|
||||
* Go to the "Administration->Materials" option.
|
||||
* The program shows a tree of categories.
|
||||
* The user enters a category name in the text box and then clicks “Add”.
|
||||
* The user enters a category name in the text box and then clicks "Add".
|
||||
* The program adds the category to the tree.
|
||||
|
||||
If users want to insert a category into the category tree, they have to first select the parent category in the tree and then click “Add”.
|
||||
If users want to insert a category into the category tree, they have to first select the parent category in the tree and then click "Add".
|
||||
|
||||
.. figure:: images/material.png
|
||||
:scale: 50
|
||||
|
|
@ -27,7 +27,7 @@ If users want to insert a category into the category tree, they have to first se
|
|||
|
||||
Users have to do the following to manage materials:
|
||||
|
||||
* Select the category to which materials are to be included and click ”Add” to the right of “Materials”.
|
||||
* Select the category to which materials are to be included and click "Add" to the right of "Materials".
|
||||
* The program adds a new empty row with fields to enter details about the material:
|
||||
|
||||
* Code: Material type code (this can be the external code from an ERP).
|
||||
|
|
@ -37,7 +37,7 @@ Users have to do the following to manage materials:
|
|||
* Category: Category to which it belongs.
|
||||
* Availability: Whether or not the material has been removed.
|
||||
|
||||
* Users complete the fields and click “Save”.
|
||||
* Users complete the fields and click "Save".
|
||||
|
||||
The assignment of materials to order elements is explained in the chapter on "Orders".
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Quality forms
|
||||
Quality forms
|
||||
######################
|
||||
|
||||
.. _calidad:
|
||||
|
|
@ -19,8 +19,8 @@ Quality forms consist of a list of questions or sentences that indicate the task
|
|||
|
||||
Users must carry out the following steps to manage the quality forms:
|
||||
|
||||
* From the “Administration” menu, access the “Quality forms” option.
|
||||
* Click edit an existing form or “Create”.
|
||||
* From the "Administration" menu, access the "Quality forms" option.
|
||||
* Click edit an existing form or "Create".
|
||||
* The program shows a form with a name, description and type.
|
||||
* Select the type.
|
||||
* The program shows the fields that are allowed for each type:
|
||||
|
|
@ -28,7 +28,7 @@ Users must carry out the following steps to manage the quality forms:
|
|||
* Percentage: question and percentage.
|
||||
* Item: question.
|
||||
|
||||
* Click “Save” or “Save and continue”.
|
||||
* Click "Save" or "Save and continue".
|
||||
|
||||
.. figure:: images/quality.png
|
||||
:scale: 50
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Users
|
||||
Users
|
||||
########
|
||||
|
||||
.. _tareas:
|
||||
|
|
@ -17,27 +17,27 @@ Managing users
|
|||
Roles are predefined in the system. A user profile consists of one or several roles. Users must have certain roles to carry out certain operations.
|
||||
|
||||
Users have one or several profiles or one or several roles directly so that specific or generic authorisation can be assigned.
|
||||
|
||||
|
||||
It is necessary to carry out the following steps to manage users:
|
||||
|
||||
* Go to “Manage users” on the “Administration” menu.
|
||||
* Go to "Manage users" on the "Administration" menu.
|
||||
* The program shows a form with a list of users.
|
||||
* Click the editing button for the chosen user or click the “Create” button.
|
||||
* Click the editing button for the chosen user or click the "Create" button.
|
||||
* A form will appear with the following fields:
|
||||
|
||||
* User name.
|
||||
* Password
|
||||
* Authorised/unauthorised.
|
||||
* Email
|
||||
* List of associated roles. Users need to search for one of the roles shown on the selection list and click “Assign” to add a new role.
|
||||
* List of associated profiles. Users need to search for one of the profiles shown on the selection list and click “Assign” to add a new profile.
|
||||
* List of associated roles. Users need to search for one of the roles shown on the selection list and click "Assign" to add a new role.
|
||||
* List of associated profiles. Users need to search for one of the profiles shown on the selection list and click "Assign" to add a new profile.
|
||||
|
||||
.. figure:: images/manage-user.png
|
||||
:scale: 50
|
||||
|
||||
Managing users
|
||||
|
||||
* Click “Save” or “Save and continue”.
|
||||
* Click "Save" or "Save and continue".
|
||||
|
||||
|
||||
Managing profiles
|
||||
|
|
@ -45,13 +45,13 @@ Managing profiles
|
|||
|
||||
Users need to carry out the following steps to manage the program's profiles.
|
||||
|
||||
* Go to “Manage user profiles” on the “Administration” menu.
|
||||
* Go to "Manage user profiles" on the "Administration" menu.
|
||||
* The program shows a list of profiles.
|
||||
* Click the editing button for the chosen profile or click “Create”.
|
||||
* Click the editing button for the chosen profile or click "Create".
|
||||
* A form appears in the program with the following fields:
|
||||
|
||||
* Name
|
||||
* List of roles (authorisations) associated with the profile. Users must select a role from the role list and click “Add” to add one that is associated with the profile.
|
||||
* List of roles (authorisations) associated with the profile. Users must select a role from the role list and click "Add" to add one that is associated with the profile.
|
||||
|
||||
.. figure:: images/manage-user-profile.png
|
||||
:scale: 50
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ Managing hour types worked
|
|||
|
||||
Users need to carry out the following steps to register hour types worked:
|
||||
|
||||
* Select “Manage hour types worked ” on the “Administration” menu.
|
||||
* Select "Manage hour types worked" on the "Administration" menu.
|
||||
* The program shows a list of existing hour types.
|
||||
|
||||
.. figure:: images/hour-type-list.png
|
||||
|
|
@ -37,7 +37,7 @@ Users need to carry out the following steps to register hour types worked:
|
|||
|
||||
Hour type list
|
||||
|
||||
* Click “Edit” or “Create”.
|
||||
* Click "Edit" or "Create".
|
||||
* The program shows an hour type editing form.
|
||||
|
||||
.. figure:: images/hour-type-edit.png
|
||||
|
|
@ -52,22 +52,22 @@ Users need to carry out the following steps to register hour types worked:
|
|||
* The default rate.
|
||||
* Hour type activation/de-activation.
|
||||
|
||||
* Click “Save” or “Save and continue”.
|
||||
* Click "Save" or "Save and continue".
|
||||
|
||||
Cost categories
|
||||
-------------------
|
||||
|
||||
Users need to carry out the following steps to register cost categories:
|
||||
|
||||
* Select “Manage cost categories” on the “Administration” menu.
|
||||
* Select "Manage cost categories" on the "Administration" menu.
|
||||
* The program shows a list of existing categories.
|
||||
|
||||
.. figure:: images/category-cost-list.png
|
||||
:scale: 50
|
||||
|
||||
Cost category list
|
||||
Cost category list
|
||||
|
||||
* Click “Edit” or “Create” button.
|
||||
* Click "Edit" or "Create" button.
|
||||
* The program shows a cost category editing form.
|
||||
|
||||
.. figure:: images/category-cost-edit.png
|
||||
|
|
@ -85,8 +85,8 @@ Users need to carry out the following steps to register cost categories:
|
|||
* Start and finish date (the latter is optional) for the period that applies to the cost category.
|
||||
* Hourly rate for this specific category
|
||||
|
||||
* Click “Save” or “Save and continue”.
|
||||
* Click "Save" or "Save and continue".
|
||||
|
||||
|
||||
The assignment of cost categories to resources is described in the chapter on resources. Go to the “Resources” section.
|
||||
The assignment of cost categories to resources is described in the chapter on resources. Go to the "Resources" section.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
Reports
|
||||
=======
|
||||
|
||||
“NavalPlan” is integrated with *JasperReports* to manage reports, which allows users to enter various reports to analyse available data in the program.
|
||||
"NavalPlan" is integrated with *JasperReports* to manage reports, which allows users to enter various reports to analyse available data in the program.
|
||||
|
||||
The defined reports are:
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#
|
||||
|
||||
RST_HTML_FLAGS = --link-stylesheet --stylesheet-path=html/lsr.css
|
||||
RST_TEX_FLAGS = --documentclass=igaliabk --font-encoding=OT1
|
||||
RST_TEX_FLAGS = --documentclass=igaliabk --font-encoding=OT1 --output-encoding=utf-8
|
||||
OUTPUT_BASE = output
|
||||
|
||||
rst_srcs := $(filter-out index.rst,$(wildcard *.rst))
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
#######################################
|
||||
Documentación de usuario da aplicación
|
||||
#######################################
|
||||
#############################
|
||||
Navalplan: User documentation
|
||||
#############################
|
||||
|
||||
.. image:: images/logo.png
|
||||
:align: left
|
||||
|
||||
No seguinte documento proporciónase a documentación de axuda necesaria para utilizar a aplicación de xestión da produción do auxiliar do naval NavalPlan.
|
||||
Following document contains necessary help for using Navalplan, the application for production and planning management for Galician ancillary naval industry.
|
||||
|
||||
Esta documentación estó organizada do seguinte modo:
|
||||
This document is divided in three main sections:
|
||||
|
||||
En primeiro lugar descrébense os obxectivos fundamentais da aplicación e o comportamento global da mesma a modo introductorio e como contextualización xeral do uso da mesma.
|
||||
First, global goals and behaviour.
|
||||
|
||||
A continuación introdúcense as entidades básicas que será necesario administrar para poder empregar todas as funcionalidades de NavalPlan e que se mencionarán nas seguintes seccións da documentación.
|
||||
Second, basic entities to understand the minimum concepts to use Navalplan.
|
||||
|
||||
Posteriormente, detállanse os procesos completos de creación de pedidos e proxectos, planificación, asignación de recursos, imputación de avances e extración de resultados.
|
||||
Finally, complete processes description to create orders, projects, project planning, resources assignment, advance assignment and result extraction.
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@ Documentación de usuario da aplicación
|
|||
.. image:: images/logo.png
|
||||
:align: left
|
||||
|
||||
No seguinte documento proporciónase a documentación de axuda necesaria para utilizar a aplicación de xestión da produción do auxiliar do naval NavalPlan.
|
||||
En el siguiente document se proporciona la documentación de ayuda necesaria para utilizar la aplicación de gestión de la producción y planificación del auxiliar del naval Navalplan.
|
||||
|
||||
Esta documentación estó organizada do seguinte modo:
|
||||
Esta documentación está organizada del siguiente modo:
|
||||
|
||||
En primeiro lugar descrébense os obxectivos fundamentais da aplicación e o comportamento global da mesma a modo introductorio e como contextualización xeral do uso da mesma.
|
||||
En primer lugar se describen los objetivos principales de la aplicación, comportamiento global y contextualización general del uso y necesidades de la misma.
|
||||
|
||||
A continuación introdúcense as entidades básicas que será necesario administrar para poder empregar todas as funcionalidades de NavalPlan e que se mencionarán nas seguintes seccións da documentación.
|
||||
A continuación se introducen las entidades básicas que será necesario conocer para utilizar las funcionalidades de Navalplan.
|
||||
|
||||
Posteriormente, detállanse os procesos completos de creación de pedidos e proxectos, planificación, asignación de recursos, imputación de avances e extración de resultados.
|
||||
Finalmente, se detallan los procesos completos de creación de pedidos, proyectos, planificación de proyectos, asignación de recursos, imputación de avances y extracción de resultados.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.zkoss.ganttz;
|
||||
|
||||
/**
|
||||
* Listener for changes in the charts visibility on planner layout.
|
||||
*
|
||||
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
||||
*/
|
||||
public interface IChartVisibilityChangedListener {
|
||||
|
||||
public void chartVisibilityChanged(boolean visible);
|
||||
|
||||
}
|
||||
|
|
@ -372,6 +372,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
|
|||
|
||||
private void updateComponents() {
|
||||
getNameBox().setValue(task.getName());
|
||||
getNameBox().setDisabled(!canRenameTask());
|
||||
getNameBox().setTooltiptext(task.getName());
|
||||
|
||||
getStartDateBox().setValue(task.getBeginDate());
|
||||
|
|
@ -396,6 +397,10 @@ public class LeftTasksTreeRow extends GenericForwardComposer {
|
|||
&& task.canBeExplicitlyResized();
|
||||
}
|
||||
|
||||
private boolean canRenameTask() {
|
||||
return disabilityConfiguration.isRenamingTasksEnabled();
|
||||
}
|
||||
|
||||
private String asString(Date date) {
|
||||
return dateFormat.format(date);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,9 @@ import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
|
|||
import org.zkoss.ganttz.util.ComponentsFinder;
|
||||
import org.zkoss.ganttz.util.LongOperationFeedback;
|
||||
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
|
||||
import org.zkoss.ganttz.util.WeakReferencedListeners;
|
||||
import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation;
|
||||
import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification;
|
||||
import org.zkoss.ganttz.util.script.IScriptsRegister;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.Executions;
|
||||
|
|
@ -58,6 +60,7 @@ import org.zkoss.zk.ui.event.Event;
|
|||
import org.zkoss.zk.ui.event.EventListener;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zk.ui.util.Clients;
|
||||
import org.zkoss.zkex.zul.api.South;
|
||||
import org.zkoss.zul.Button;
|
||||
import org.zkoss.zul.ListModel;
|
||||
import org.zkoss.zul.Listbox;
|
||||
|
|
@ -138,6 +141,9 @@ public class Planner extends HtmlMacroComponent {
|
|||
|
||||
private Listbox listZoomLevels = null;
|
||||
|
||||
private WeakReferencedListeners<IChartVisibilityChangedListener> chartVisibilityListeners = WeakReferencedListeners
|
||||
.create();
|
||||
|
||||
public Planner() {
|
||||
registerNeededScripts();
|
||||
}
|
||||
|
|
@ -301,6 +307,8 @@ public class Planner extends HtmlMacroComponent {
|
|||
}
|
||||
listZoomLevels.setSelectedIndex(getZoomLevel().ordinal());
|
||||
|
||||
this.visibleChart = configuration.isExpandPlanningViewCharts();
|
||||
((South) getFellow("graphics")).setOpen(this.visibleChart);
|
||||
}
|
||||
|
||||
private void resettingPreviousComponentsToNull() {
|
||||
|
|
@ -450,6 +458,8 @@ public class Planner extends HtmlMacroComponent {
|
|||
|
||||
private FilterAndParentExpandedPredicates predicate;
|
||||
|
||||
private boolean visibleChart;
|
||||
|
||||
public void showCriticalPath() {
|
||||
Button showCriticalPathButton = (Button) getFellow("showCriticalPath");
|
||||
if (disabilityConfiguration.isCriticalPathEnabled()) {
|
||||
|
|
@ -592,4 +602,25 @@ public class Planner extends HtmlMacroComponent {
|
|||
return predicate;
|
||||
}
|
||||
|
||||
public void changeChartVisibility(boolean visible) {
|
||||
visibleChart = visible;
|
||||
chartVisibilityListeners
|
||||
.fireEvent(new IListenerNotification<IChartVisibilityChangedListener>() {
|
||||
@Override
|
||||
public void doNotify(
|
||||
IChartVisibilityChangedListener listener) {
|
||||
listener.chartVisibilityChanged(visibleChart);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean isVisibleChart() {
|
||||
return visibleChart;
|
||||
}
|
||||
|
||||
public void addChartVisibilityListener(
|
||||
IChartVisibilityChangedListener chartVisibilityChangedListener) {
|
||||
chartVisibilityListeners.addListener(chartVisibilityChangedListener);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,4 +39,8 @@ public interface IDisabilityConfiguration {
|
|||
|
||||
public boolean isFlattenTreeEnabled();
|
||||
|
||||
public boolean isRenamingTasksEnabled();
|
||||
|
||||
public boolean isExpandPlanningViewCharts();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,6 +134,8 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
|
|||
|
||||
private boolean flattenTreeEnabled = true;
|
||||
|
||||
private boolean renamingTasksEnabled = true;
|
||||
|
||||
// private String identifier = null;
|
||||
|
||||
private IDetailItemModificator firstLevelModificators = SeveralModificators
|
||||
|
|
@ -146,6 +148,8 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
|
|||
|
||||
private IPrintAction printAction;
|
||||
|
||||
private boolean expandPlanningViewCharts;
|
||||
|
||||
public PlannerConfiguration(IAdapterToTaskFundamentalProperties<T> adapter,
|
||||
IStructureNavigator<T> navigator, List<? extends T> data) {
|
||||
this.adapter = adapter;
|
||||
|
|
@ -298,6 +302,15 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
|
|||
return flattenTreeEnabled;
|
||||
}
|
||||
|
||||
public void setRenamingTasksEnabled(boolean renamingTasksEnabled) {
|
||||
this.renamingTasksEnabled = renamingTasksEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRenamingTasksEnabled() {
|
||||
return renamingTasksEnabled;
|
||||
}
|
||||
|
||||
public IDetailItemModificator getSecondLevelModificators() {
|
||||
return secondLevelModificators;
|
||||
}
|
||||
|
|
@ -358,4 +371,13 @@ public class PlannerConfiguration<T> implements IDisabilityConfiguration {
|
|||
printAction.doPrint(parameters, planner);
|
||||
}
|
||||
|
||||
public void setExpandPlanningViewCharts(boolean expandPlanningViewCharts) {
|
||||
this.expandPlanningViewCharts = expandPlanningViewCharts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpandPlanningViewCharts() {
|
||||
return expandPlanningViewCharts;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.zkoss.ganttz.data.limitingresource;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.apache.commons.lang.builder.ToStringBuilder;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.zkoss.ganttz.data.resourceload.LoadLevel;
|
||||
|
||||
public class QueueTask {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(QueueTask.class);
|
||||
|
||||
private final LocalDate start;
|
||||
|
||||
private final LocalDate end;
|
||||
|
||||
private final LoadLevel loadLevel;
|
||||
|
||||
private final int totalResourceWorkHours;
|
||||
|
||||
private final int assignedHours;
|
||||
|
||||
public QueueTask(LocalDate start, LocalDate end,
|
||||
int totalResourceWorkHours, int assignedHours, LoadLevel loadLevel) {
|
||||
Validate.notNull(start);
|
||||
Validate.notNull(end);
|
||||
Validate.notNull(loadLevel);
|
||||
Validate.notNull(totalResourceWorkHours);
|
||||
Validate.notNull(assignedHours);
|
||||
Validate.isTrue(!start.isAfter(end));
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.loadLevel = loadLevel;
|
||||
this.totalResourceWorkHours = totalResourceWorkHours;
|
||||
this.assignedHours = assignedHours;
|
||||
}
|
||||
|
||||
public LocalDate getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public LocalDate getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
// public boolean overlaps(QueueTask other) {
|
||||
// return start.isBefore(other.end) && end.isAfter(other.start);
|
||||
// }
|
||||
|
||||
/**
|
||||
* @param loadPeriods
|
||||
* @return
|
||||
* @throws IllegalArgumentException
|
||||
* if some of the QueueTask overlaps
|
||||
*/
|
||||
public static List<QueueTask> sort(List<QueueTask> loadPeriods)
|
||||
throws IllegalArgumentException {
|
||||
ArrayList<QueueTask> result = new ArrayList<QueueTask>(loadPeriods);
|
||||
// Collections.sort(result, new Comparator<QueueTask>() {
|
||||
|
||||
// @Override
|
||||
// public int compare(QueueTask o1, QueueTask o2) {
|
||||
// if (o1.overlaps(o2)) {
|
||||
// LOG.warn(o1 + " overlaps with " + o2);
|
||||
// throw new IllegalArgumentException(o1 + " overlaps with "
|
||||
// + o2);
|
||||
// }
|
||||
// int comparison = compareLocalDates(o1.start, o2.start);
|
||||
// if (comparison != 0) {
|
||||
// return comparison;
|
||||
// }
|
||||
// return compareLocalDates(o1.end, o2.end);
|
||||
// }
|
||||
// });
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int compareLocalDates(LocalDate l1, LocalDate l2) {
|
||||
if (l1.isBefore(l2)) {
|
||||
return -1;
|
||||
}
|
||||
if (l1.isAfter(l2)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringBuilder.reflectionToString(this);
|
||||
}
|
||||
|
||||
public LoadLevel getLoadLevel() {
|
||||
return loadLevel;
|
||||
}
|
||||
|
||||
public int getTotalResourceWorkHours() {
|
||||
return totalResourceWorkHours;
|
||||
}
|
||||
|
||||
public int getAssignedHours() {
|
||||
return assignedHours;
|
||||
}
|
||||
}
|
||||
|
|
@ -222,7 +222,6 @@ MutableTreeModel<LoadTimeLine> modelForTree,
|
|||
Label label = new Label();
|
||||
final String conceptName = principal.getConceptName();
|
||||
label.setValue(conceptName);
|
||||
limitValue(result, label, 40);
|
||||
result.appendChild(label);
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,9 +44,11 @@ import org.zkoss.zk.ui.event.Event;
|
|||
import org.zkoss.zk.ui.event.EventListener;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zul.Button;
|
||||
import org.zkoss.zul.Comboitem;
|
||||
import org.zkoss.zul.ListModel;
|
||||
import org.zkoss.zul.Separator;
|
||||
import org.zkoss.zul.SimpleListModel;
|
||||
import org.zkoss.zul.api.Combobox;
|
||||
import org.zkoss.zul.api.Listbox;
|
||||
public class ResourcesLoadPanel extends HtmlMacroComponent {
|
||||
|
||||
|
|
@ -82,6 +84,10 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
private String feedBackMessage;
|
||||
private Boolean filterbyResources;
|
||||
|
||||
private boolean refreshNameFilter = true;
|
||||
private int filterByNamePosition = 0;
|
||||
private int numberOfGroupsByName = 10;
|
||||
|
||||
public ResourcesLoadPanel(List<LoadTimeLine> groups,
|
||||
TimeTracker timeTracker, Component componentOnWhichGiveFeedback) {
|
||||
this.componentOnWhichGiveFeedback = componentOnWhichGiveFeedback;
|
||||
|
|
@ -112,6 +118,8 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
this.filterbyResources = false;
|
||||
this.feedBackMessage = _("showing criterions");
|
||||
}
|
||||
refreshNameFilter = true;
|
||||
filterByNamePosition = 0;
|
||||
invalidatingChangeHappenedWithFeedback();
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +237,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
private MutableTreeModel<LoadTimeLine> createModelForTree() {
|
||||
MutableTreeModel<LoadTimeLine> result = MutableTreeModel
|
||||
.create(LoadTimeLine.class);
|
||||
for (LoadTimeLine loadTimeLine : this.groups) {
|
||||
for (LoadTimeLine loadTimeLine : this.getGroupsToShow()) {
|
||||
result.addToRoot(loadTimeLine);
|
||||
result = addNodes(result, loadTimeLine);
|
||||
}
|
||||
|
|
@ -272,10 +280,19 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
TimeTrackerComponent timeTrackerHeader = createTimeTrackerHeader();
|
||||
getFellow("insertionPointTimetracker").appendChild(timeTrackerHeader);
|
||||
|
||||
Component additionalFilter = (Component) getVariable("additionalFilter", true);
|
||||
if(additionalFilter != null) {
|
||||
getFellow("additionalFilterInsertionPoint").appendChild(additionalFilter);
|
||||
}
|
||||
|
||||
timeTrackerHeader.afterCompose();
|
||||
timeTrackerComponent.afterCompose();
|
||||
listZoomLevels = (Listbox) getFellow("listZoomLevels");
|
||||
listZoomLevels.setSelectedIndex(timeTracker.getDetailLevel().ordinal());
|
||||
|
||||
if(refreshNameFilter) {
|
||||
setupNameFilter();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearComponents() {
|
||||
|
|
@ -300,4 +317,74 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
|
|||
resourceLoadList.addSeeScheduledOfListener(seeScheduledOfListener);
|
||||
}
|
||||
|
||||
private void setupNameFilter() {
|
||||
Combobox filterByNameCombo = (Combobox) getFellow("filterByNameCombo");
|
||||
filterByNameCombo.getChildren().clear();
|
||||
int size = groups.size();
|
||||
|
||||
if(size > numberOfGroupsByName) {
|
||||
int position = 0;
|
||||
while(position < size) {
|
||||
String firstName = groups.get(position).getConceptName();
|
||||
String lastName;
|
||||
int newPosition = position + numberOfGroupsByName;
|
||||
if(newPosition - 1 < size) {
|
||||
lastName = groups.get(newPosition - 1)
|
||||
.getConceptName();
|
||||
}
|
||||
else {
|
||||
lastName = groups.get(size - 1)
|
||||
.getConceptName();
|
||||
}
|
||||
|
||||
Comboitem item = new Comboitem();
|
||||
item.setLabel(firstName.substring(0, 1) + " - " + lastName.substring(0, 1));
|
||||
item.setDescription(firstName + " - " + lastName);
|
||||
item.setValue(new Integer(position));
|
||||
filterByNameCombo.appendChild(item);
|
||||
position = newPosition;
|
||||
}
|
||||
}
|
||||
|
||||
Comboitem lastItem = new Comboitem();
|
||||
lastItem.setLabel(_("All"));
|
||||
lastItem.setDescription(_("Show all elements"));
|
||||
lastItem.setValue(new Integer(-1));
|
||||
filterByNameCombo.appendChild(lastItem);
|
||||
|
||||
filterByNameCombo.setSelectedIndex(0);
|
||||
refreshNameFilter = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns only the LoadTimeLine objects that have to be show
|
||||
* according to the name filter.
|
||||
* @return
|
||||
*/
|
||||
private List<LoadTimeLine> getGroupsToShow() {
|
||||
if(filterByNamePosition == -1) {
|
||||
return groups;
|
||||
}
|
||||
int endPosition =
|
||||
(filterByNamePosition + numberOfGroupsByName < groups.size())?
|
||||
filterByNamePosition + numberOfGroupsByName :
|
||||
groups.size();
|
||||
return groups.subList(filterByNamePosition, endPosition);
|
||||
}
|
||||
|
||||
public void onSelectFilterByName(Integer filterByNamePosition) {
|
||||
this.filterByNamePosition = filterByNamePosition.intValue();
|
||||
this.feedBackMessage = _("filtering by name");
|
||||
invalidatingChangeHappenedWithFeedback();
|
||||
}
|
||||
|
||||
public void setNameFilterDisabled(boolean disabled) {
|
||||
Combobox combo = ((Combobox) getFellow("filterByNameCombo"));
|
||||
if(combo.isDisabled() != disabled) {
|
||||
filterByNamePosition = disabled? -1 :
|
||||
((Integer)combo.getSelectedItemApi().getValue()).intValue();
|
||||
combo.setDisabled(disabled);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -48,6 +48,7 @@
|
|||
<macro-uri>~./ganttz/resourceload/leftPane.zul</macro-uri>
|
||||
</component>
|
||||
|
||||
|
||||
<component>
|
||||
<component-name>leftPane</component-name>
|
||||
<component-class>org.zkoss.ganttz.LeftPane</component-class>
|
||||
|
|
@ -79,6 +80,7 @@
|
|||
</mold>
|
||||
</component>
|
||||
|
||||
|
||||
<component>
|
||||
<component-name>taskRow</component-name>
|
||||
<component-class>org.zkoss.ganttz.TaskRow</component-class>
|
||||
|
|
@ -145,6 +147,7 @@
|
|||
</mold>
|
||||
</component>
|
||||
|
||||
|
||||
<component>
|
||||
<component-name>timetracker</component-name>
|
||||
<component-class>org.zkoss.ganttz.timetracker.TimeTrackerComponent</component-class>
|
||||
|
|
|
|||
|
|
@ -67,7 +67,8 @@ planner = self;
|
|||
</center>
|
||||
</borderlayout>
|
||||
</center>
|
||||
<south collapsible="true" title="Graphics" sclass="scheduling-graphics">
|
||||
<south collapsible="true" title="Graphics" sclass="scheduling-graphics"
|
||||
id="graphics" onOpen="planner.changeChartVisibility(event.open);">
|
||||
<div id="insertionPointChart" />
|
||||
</south>
|
||||
</borderlayout>
|
||||
|
|
|
|||
|
|
@ -43,6 +43,12 @@ resourcesLoadPanel = self;
|
|||
model="${resourcesLoadPanel.filters}"
|
||||
onSelect="resourcesLoadPanel.setFilter(self.selectedItem.value);">
|
||||
</listbox>
|
||||
<separator/>
|
||||
${i18n:_('Show elements between')}:
|
||||
<combobox id="filterByNameCombo"
|
||||
onChange="resourcesLoadPanel.onSelectFilterByName(self.selectedItemApi.value)" />
|
||||
<separator/>
|
||||
<hbox id="additionalFilterInsertionPoint" />
|
||||
</hbox>
|
||||
</north>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
zkLimitingResourcesList = addLimitingResourcesListMethods( {});
|
||||
|
||||
function addLimitingResourcesListMethods(object) {
|
||||
var scrollSync;
|
||||
|
||||
function watermark() {
|
||||
return document.getElementById('watermark');
|
||||
}
|
||||
|
||||
function timetracker() {
|
||||
return document.getElementById('timetracker');
|
||||
}
|
||||
|
||||
function resourceloadlist() {
|
||||
return YAHOO.util.Selector.query('.limitingresourceslist')[0];
|
||||
}
|
||||
|
||||
function taskspanelgap() {
|
||||
return YAHOO.util.Selector.query('.taskspanelgap')[0];
|
||||
}
|
||||
|
||||
function resourcesloadgraph() {
|
||||
return YAHOO.util.Selector.query('.resourcesloadgraph div')[0];
|
||||
}
|
||||
|
||||
function scrolledpannel() {
|
||||
return YAHOO.util.Selector.query('.rightpanellayout div')[0];
|
||||
}
|
||||
|
||||
|
||||
function timetrackergap() {
|
||||
return YAHOO.util.Selector.query('.timetrackergap')[0];
|
||||
}
|
||||
|
||||
function leftpanel() {
|
||||
return YAHOO.util.Selector.query('.leftpanelgap .z-tree-body')[0];
|
||||
}
|
||||
|
||||
|
||||
object.init = function(cmp) {
|
||||
this.adjustTimeTrackerSize(cmp);
|
||||
YAHOO.util.Event.addListener(window, 'resize',
|
||||
zkLimitingResourcesList.adjustTimeTrackerSize, cmp);
|
||||
scrollSync = new ScrollSync(cmp);
|
||||
scrollSync.synchXChangeTo(timetracker);
|
||||
|
||||
listenToScroll();
|
||||
};
|
||||
|
||||
function listenToScroll() {
|
||||
|
||||
var timetrackergap_ = timetrackergap();
|
||||
var scrolledpannel_ = scrolledpannel();
|
||||
var resourcesloadgraph_ = resourcesloadgraph();
|
||||
var leftpanel_ = leftpanel();
|
||||
|
||||
var onScroll = function() {
|
||||
timetrackergap_.style["left"] = "-" + scrolledpannel_.scrollLeft + "px";
|
||||
leftpanel_.style["top"] = "-" + scrolledpannel_.scrollTop + "px";
|
||||
resourcesloadgraph_.scrollLeft = scrolledpannel_.scrollLeft;
|
||||
|
||||
};
|
||||
|
||||
YAHOO.util.Selector.query('.rightpanellayout div')[0].onscroll = onScroll;
|
||||
|
||||
}
|
||||
|
||||
object.adjustTimeTrackerSize = function(cmp) {
|
||||
watermark().style["height"] = cmp.clientHeight + "px";
|
||||
timetracker().style["width"] = cmp.clientWidth + "px";
|
||||
/* Set watermark width */
|
||||
YAHOO.util.Selector.query('.limitingresourceslist')[0].style["width"] = YAHOO.util.Selector
|
||||
.query('.second_level_')[0].clientWidth
|
||||
+ "px";
|
||||
YAHOO.util.Selector.query('.rightpanellayout tr#watermark td')[0].style["height"] =
|
||||
/* Calculate min : taskspanelgap().clientHeight + 120 + 'px'; ) */
|
||||
YAHOO.util.Selector.query('.limitingresourceslist')[0].clientHeight + 120
|
||||
+ "px";
|
||||
};
|
||||
|
||||
object.adjustResourceLoadRows = function(cmp) {
|
||||
YAHOO.util.Selector.query('.row_resourceload').each(function(node) {
|
||||
node.style["width"] = cmp.clientWidth + "px";
|
||||
});
|
||||
};
|
||||
|
||||
object.adjustScrollHorizontalPosition = function(cmp, offsetInPx) {
|
||||
cmp.scrollLeft = offsetInPx;
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
|
@ -22,13 +22,16 @@ package org.navalplanner.business.advance.entities;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.validator.AssertTrue;
|
||||
import org.hibernate.validator.NotNull;
|
||||
import org.hibernate.validator.Valid;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.orders.entities.OrderElement;
|
||||
import org.navalplanner.business.planner.entities.consolidations.NonCalculatedConsolidatedValue;
|
||||
|
||||
public class AdvanceMeasurement extends BaseEntity {
|
||||
|
||||
|
|
@ -53,6 +56,9 @@ public class AdvanceMeasurement extends BaseEntity {
|
|||
|
||||
private Date communicationDate;
|
||||
|
||||
@Valid
|
||||
private Set<NonCalculatedConsolidatedValue> nonCalculatedConsolidatedValues = new HashSet<NonCalculatedConsolidatedValue>();
|
||||
|
||||
public AdvanceMeasurement() {
|
||||
}
|
||||
|
||||
|
|
@ -165,4 +171,13 @@ public class AdvanceMeasurement extends BaseEntity {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setNonCalculatedConsolidatedValues(
|
||||
Set<NonCalculatedConsolidatedValue> nonCalculatedConsolidatedValues) {
|
||||
this.nonCalculatedConsolidatedValues = nonCalculatedConsolidatedValues;
|
||||
}
|
||||
|
||||
public Set<NonCalculatedConsolidatedValue> getNonCalculatedConsolidatedValues() {
|
||||
return nonCalculatedConsolidatedValues;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ package org.navalplanner.business.advance.entities;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
|
|
@ -31,6 +33,7 @@ import org.hibernate.validator.NotNull;
|
|||
import org.hibernate.validator.Valid;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.orders.entities.OrderElement;
|
||||
import org.navalplanner.business.planner.entities.consolidations.NonCalculatedConsolidation;
|
||||
|
||||
/**
|
||||
* Represents an {@link AdvanceAssignment} that is own of this
|
||||
|
|
@ -60,6 +63,9 @@ public class DirectAdvanceAssignment extends AdvanceAssignment {
|
|||
private SortedSet<AdvanceMeasurement> advanceMeasurements = new TreeSet<AdvanceMeasurement>(
|
||||
new AdvanceMeasurementComparator());
|
||||
|
||||
@Valid
|
||||
private Set<NonCalculatedConsolidation> nonCalculatedConsolidations = new HashSet<NonCalculatedConsolidation>();
|
||||
|
||||
private boolean fake = false;
|
||||
|
||||
public DirectAdvanceAssignment() {
|
||||
|
|
@ -195,4 +201,13 @@ public class DirectAdvanceAssignment extends AdvanceAssignment {
|
|||
return true;
|
||||
}
|
||||
|
||||
public void setNonCalculatedConsolidation(
|
||||
Set<NonCalculatedConsolidation> nonCalculatedConsolidation) {
|
||||
this.nonCalculatedConsolidations = nonCalculatedConsolidation;
|
||||
}
|
||||
|
||||
public Set<NonCalculatedConsolidation> getNonCalculatedConsolidation() {
|
||||
return nonCalculatedConsolidations;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,12 @@
|
|||
|
||||
package org.navalplanner.business.advance.entities;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.validator.Valid;
|
||||
import org.navalplanner.business.orders.entities.OrderLineGroup;
|
||||
import org.navalplanner.business.planner.entities.consolidations.CalculatedConsolidation;
|
||||
|
||||
/**
|
||||
* Represents an {@link AdvanceAssignment} that is defined in some of the
|
||||
|
|
@ -30,6 +35,9 @@ import org.navalplanner.business.orders.entities.OrderLineGroup;
|
|||
*/
|
||||
public class IndirectAdvanceAssignment extends AdvanceAssignment {
|
||||
|
||||
@Valid
|
||||
private Set<CalculatedConsolidation> calculatedConsolidations = new HashSet<CalculatedConsolidation>();
|
||||
|
||||
public static IndirectAdvanceAssignment create() {
|
||||
IndirectAdvanceAssignment indirectAdvanceAssignment = new IndirectAdvanceAssignment();
|
||||
indirectAdvanceAssignment.setNewObject(true);
|
||||
|
|
@ -63,4 +71,13 @@ public class IndirectAdvanceAssignment extends AdvanceAssignment {
|
|||
super(reportGlobalAdvance);
|
||||
}
|
||||
|
||||
public void setCalculatedConsolidation(
|
||||
Set<CalculatedConsolidation> calculatedConsolidations) {
|
||||
this.calculatedConsolidations = calculatedConsolidations;
|
||||
}
|
||||
|
||||
public Set<CalculatedConsolidation> getCalculatedConsolidation() {
|
||||
return calculatedConsolidations;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,11 +211,6 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours {
|
|||
|
||||
public void addExceptionDay(CalendarException day)
|
||||
throws IllegalArgumentException {
|
||||
if (day.getDate().compareTo(new LocalDate()) <= 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"You can not modify the past adding a new exception day");
|
||||
}
|
||||
|
||||
if (isExceptionDayAlreadyInExceptions(day)) {
|
||||
throw new IllegalArgumentException(
|
||||
"This day is already in the exception days");
|
||||
|
|
@ -230,11 +225,6 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours {
|
|||
|
||||
public void removeExceptionDay(LocalDate date)
|
||||
throws IllegalArgumentException {
|
||||
if (date.compareTo(new LocalDate()) <= 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"You can not modify the past removing an exception day");
|
||||
}
|
||||
|
||||
CalendarException day = getOwnExceptionDay(date);
|
||||
if (day == null) {
|
||||
throw new IllegalArgumentException(
|
||||
|
|
@ -440,11 +430,6 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours {
|
|||
* new calendar will be used from that date onwards.
|
||||
*/
|
||||
public void newVersion(LocalDate date) throws IllegalArgumentException {
|
||||
if (date.compareTo(new LocalDate()) <= 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Date for new version must be greater than current date");
|
||||
}
|
||||
|
||||
CalendarData calendarData = getCalendarDataBeforeTheLastIfAny();
|
||||
if ((calendarData.getExpiringDate() != null)
|
||||
&& (date.compareTo(calendarData.getExpiringDate()) <= 0)) {
|
||||
|
|
@ -650,11 +635,6 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours {
|
|||
+ "because of this is the last version");
|
||||
}
|
||||
|
||||
if (expiringDate.compareTo(new LocalDate()) <= 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"This date must be greater than current date");
|
||||
}
|
||||
|
||||
Integer index = calendarDataVersions.indexOf(calendarData);
|
||||
if (index > 0) {
|
||||
CalendarData preivousCalendarData = calendarDataVersions
|
||||
|
|
@ -707,12 +687,22 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours {
|
|||
return isLastVersion(new LocalDate(date));
|
||||
}
|
||||
|
||||
public boolean isFirstVersion(Date date) {
|
||||
return isFirstVersion(new LocalDate(date));
|
||||
}
|
||||
|
||||
public boolean isLastVersion(LocalDate date) {
|
||||
CalendarData calendarData = getCalendarData(date);
|
||||
Integer index = calendarDataVersions.indexOf(calendarData);
|
||||
return (index == (calendarDataVersions.size() - 1));
|
||||
}
|
||||
|
||||
public boolean isFirstVersion(LocalDate date) {
|
||||
CalendarData calendarData = getCalendarData(date);
|
||||
Integer index = calendarDataVersions.indexOf(calendarData);
|
||||
return (index == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a set of non workable days (0 hours) for a specific period
|
||||
* depending on the calendar restrictions.
|
||||
|
|
@ -759,13 +749,8 @@ public class BaseCalendar extends IntegrationEntity implements IWorkHours {
|
|||
throw new IllegalArgumentException(
|
||||
"You can not remove the current calendar data");
|
||||
}
|
||||
if (validFrom.compareTo(new LocalDate()) > 0) {
|
||||
calendarDataVersions.remove(lastCalendarData);
|
||||
getLastCalendarData().removeExpiringDate();
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"You can not modify the past removing a calendar data");
|
||||
}
|
||||
calendarDataVersions.remove(lastCalendarData);
|
||||
getLastCalendarData().removeExpiringDate();
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"You just can remove the last calendar data");
|
||||
|
|
|
|||
|
|
@ -37,6 +37,12 @@ public class CalendarExceptionType extends IntegrationEntity {
|
|||
return create(new CalendarExceptionType(name, color, notAssignable));
|
||||
}
|
||||
|
||||
public static CalendarExceptionType create(String code, String name,
|
||||
String color, Boolean notAssignable) {
|
||||
return create(new CalendarExceptionType(name, color, notAssignable),
|
||||
code);
|
||||
}
|
||||
|
||||
private String name;
|
||||
private String color;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ public enum PredefinedCalendarExceptionTypes {
|
|||
|
||||
private PredefinedCalendarExceptionTypes(String name, String color,
|
||||
Boolean notAssignable) {
|
||||
calendarExceptionType = CalendarExceptionType.create(name, color,
|
||||
// Using the name as code in order to be more human friendly
|
||||
calendarExceptionType = CalendarExceptionType.create(name, name, color,
|
||||
notAssignable);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ public class Configuration extends BaseEntity {
|
|||
|
||||
private Boolean generateCodeForUnitTypes = false;
|
||||
|
||||
private Boolean expandCompanyPlanningViewCharts = true;
|
||||
|
||||
private Boolean expandOrderPlanningViewCharts = true;
|
||||
|
||||
public void setDefaultCalendar(BaseCalendar defaultCalendar) {
|
||||
this.defaultCalendar = defaultCalendar;
|
||||
}
|
||||
|
|
@ -143,4 +147,22 @@ public class Configuration extends BaseEntity {
|
|||
return generateCodeForUnitTypes;
|
||||
}
|
||||
|
||||
public void setExpandCompanyPlanningViewCharts(
|
||||
Boolean expandCompanyPlanningViewCharts) {
|
||||
this.expandCompanyPlanningViewCharts = expandCompanyPlanningViewCharts;
|
||||
}
|
||||
|
||||
public Boolean isExpandCompanyPlanningViewCharts() {
|
||||
return expandCompanyPlanningViewCharts;
|
||||
}
|
||||
|
||||
public void setExpandOrderPlanningViewCharts(
|
||||
Boolean expandOrderPlanningViewCharts) {
|
||||
this.expandOrderPlanningViewCharts = expandOrderPlanningViewCharts;
|
||||
}
|
||||
|
||||
public Boolean isExpandOrderPlanningViewCharts() {
|
||||
return expandOrderPlanningViewCharts;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.daos;
|
||||
|
||||
import org.navalplanner.business.common.daos.GenericDAOHibernate;
|
||||
import org.navalplanner.business.planner.entities.consolidations.Consolidation;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* DAO for {@Consolidation}
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
@Repository
|
||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||
public class ConsolidationDAO extends GenericDAOHibernate<Consolidation, Long>
|
||||
implements IConsolidationDAO {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.daos;
|
||||
|
||||
import org.navalplanner.business.common.daos.IGenericDAO;
|
||||
import org.navalplanner.business.planner.entities.consolidations.Consolidation;
|
||||
|
||||
/**
|
||||
* DAO interface for {@link Consolidation}
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
|
||||
public interface IConsolidationDAO extends IGenericDAO<Consolidation, Long> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.daos;
|
||||
|
||||
import org.navalplanner.business.common.daos.IGenericDAO;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
|
||||
/**
|
||||
* DAO interface for {@link ILimitingResourceQueueDAO}
|
||||
*
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*/
|
||||
public interface ILimitingResourceQueueDAO extends
|
||||
IGenericDAO<LimitingResourceQueue, Long> {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.daos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.common.daos.IGenericDAO;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
|
||||
/**
|
||||
* DAO interface for {@link ILimitingResourceQueueElementDAO}
|
||||
*
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*/
|
||||
public interface ILimitingResourceQueueElementDAO extends
|
||||
IGenericDAO<LimitingResourceQueueElement, Long> {
|
||||
|
||||
List<LimitingResourceQueueElement> getAll();
|
||||
|
||||
/**
|
||||
* Returns all {@link LimitingResourceQueueElement} that are assigned to a
|
||||
* {@link LimitingResourceQueue}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<LimitingResourceQueueElement> getAssigned();
|
||||
|
||||
/**
|
||||
* Returns all {@link LimitingResourceQueueElement} that have not been assigned to
|
||||
* {@link LimitingResourceQueue} yet
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<LimitingResourceQueueElement> getUnassigned();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.daos;
|
||||
|
||||
import org.navalplanner.business.common.daos.GenericDAOHibernate;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* DAO for {@LimitingResourceQueueDAO}
|
||||
*
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*/
|
||||
@Repository
|
||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||
public class LimitingResourceQueueDAO extends
|
||||
GenericDAOHibernate<LimitingResourceQueue, Long> implements
|
||||
ILimitingResourceQueueDAO {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.daos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Criteria;
|
||||
import org.hibernate.criterion.Order;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.navalplanner.business.common.daos.GenericDAOHibernate;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* DAO for {@LimitingResourceQueueElementDAO}
|
||||
*
|
||||
* @author Diego Pino García <dpino@igalia.com>
|
||||
*/
|
||||
@Repository
|
||||
@Scope(BeanDefinition.SCOPE_SINGLETON)
|
||||
public class LimitingResourceQueueElementDAO extends
|
||||
GenericDAOHibernate<LimitingResourceQueueElement, Long> implements
|
||||
ILimitingResourceQueueElementDAO {
|
||||
|
||||
@Override
|
||||
public List<LimitingResourceQueueElement> getAll() {
|
||||
return list(LimitingResourceQueueElement.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<LimitingResourceQueueElement> getAssigned() {
|
||||
Criteria criteria = getSession().createCriteria(LimitingResourceQueueElement.class);
|
||||
criteria.add(Restrictions.isNotNull("limitingResourceQueue"));
|
||||
criteria.addOrder(Order.asc("creationTimestamp"));
|
||||
return criteria.list();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<LimitingResourceQueueElement> getUnassigned() {
|
||||
Criteria criteria = getSession().createCriteria(LimitingResourceQueueElement.class);
|
||||
criteria.add(Restrictions.isNull("limitingResourceQueue"));
|
||||
criteria.addOrder(Order.asc("creationTimestamp"));
|
||||
return criteria.list();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -155,6 +155,8 @@ public abstract class DayAssignment extends BaseEntity {
|
|||
@OnCopy(Strategy.SHARE)
|
||||
private Resource resource;
|
||||
|
||||
private Boolean consolidated;
|
||||
|
||||
protected DayAssignment() {
|
||||
|
||||
}
|
||||
|
|
@ -180,6 +182,14 @@ public abstract class DayAssignment extends BaseEntity {
|
|||
return day;
|
||||
}
|
||||
|
||||
public void setConsolidated(Boolean consolidated) {
|
||||
this.consolidated = consolidated;
|
||||
}
|
||||
|
||||
public Boolean isConsolidated() {
|
||||
return consolidated == null ? false : consolidated;
|
||||
}
|
||||
|
||||
public static Comparator<DayAssignment> byDayComparator() {
|
||||
return new Comparator<DayAssignment>() {
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ package org.navalplanner.business.planner.entities;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
|
||||
|
|
@ -38,21 +39,18 @@ public class LimitingResourceQueueElement extends BaseEntity {
|
|||
|
||||
private Date earlierStartDateBecauseOfGantt;
|
||||
|
||||
public Date getEarlierStartDateBecauseOfGantt() {
|
||||
return earlierStartDateBecauseOfGantt;
|
||||
}
|
||||
private QueuePosition startQueuePosition;
|
||||
|
||||
public void setEarlierStartDateBecauseOfGantt(
|
||||
Date earlierStartDateBecauseOfGantt) {
|
||||
this.earlierStartDateBecauseOfGantt = earlierStartDateBecauseOfGantt;
|
||||
}
|
||||
private QueuePosition endQueuePosition;
|
||||
|
||||
public static LimitingResourceQueueElement create() {
|
||||
private long creationTimestamp;
|
||||
|
||||
public static LimitingResourceQueueElement create() {
|
||||
return create(new LimitingResourceQueueElement());
|
||||
}
|
||||
|
||||
protected LimitingResourceQueueElement() {
|
||||
|
||||
creationTimestamp = (new Date()).getTime();
|
||||
}
|
||||
|
||||
public ResourceAllocation<?> getResourceAllocation() {
|
||||
|
|
@ -71,4 +69,53 @@ public static LimitingResourceQueueElement create() {
|
|||
this.limitingResourceQueue = limitingResourceQueue;
|
||||
}
|
||||
|
||||
public LocalDate getStartDate() {
|
||||
return startQueuePosition.getDate();
|
||||
}
|
||||
|
||||
public void setStartDate(LocalDate date) {
|
||||
startQueuePosition.setDate(date);
|
||||
}
|
||||
|
||||
public int getStartHour() {
|
||||
return startQueuePosition.getHour();
|
||||
}
|
||||
|
||||
public void setStartHour(int hour) {
|
||||
startQueuePosition.setHour(hour);
|
||||
}
|
||||
|
||||
public LocalDate getEndDate() {
|
||||
return endQueuePosition.getDate();
|
||||
}
|
||||
|
||||
public void setEndDate(LocalDate date) {
|
||||
endQueuePosition.setDate(date);
|
||||
}
|
||||
|
||||
public int getEndHour() {
|
||||
return endQueuePosition.getHour();
|
||||
}
|
||||
|
||||
public void setEndHour(int hour) {
|
||||
endQueuePosition.setHour(hour);
|
||||
}
|
||||
|
||||
public Date getEarlierStartDateBecauseOfGantt() {
|
||||
return earlierStartDateBecauseOfGantt;
|
||||
}
|
||||
|
||||
public void setEarlierStartDateBecauseOfGantt(
|
||||
Date earlierStartDateBecauseOfGantt) {
|
||||
this.earlierStartDateBecauseOfGantt = earlierStartDateBecauseOfGantt;
|
||||
}
|
||||
|
||||
public long getCreationTimestamp() {
|
||||
return creationTimestamp;
|
||||
}
|
||||
|
||||
public void setCreationTimestamp(long creationTimestamp) {
|
||||
this.creationTimestamp = creationTimestamp;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities;
|
||||
|
||||
import static org.navalplanner.business.i18n.I18nHelper._;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class QueuePosition {
|
||||
|
||||
private LocalDate date;
|
||||
|
||||
private int hour = 0;
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(LocalDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public int getHour() {
|
||||
return hour;
|
||||
}
|
||||
|
||||
public void setHour(int hour) {
|
||||
Validate.isTrue(hour >= 0 && hour <= 23, _("Hour should be a value between 0 and 23"));
|
||||
this.hour = hour;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ import java.util.Set;
|
|||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.hibernate.validator.Min;
|
||||
import org.hibernate.validator.NotNull;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.calendars.entities.AvailabilityTimeLine;
|
||||
|
|
@ -300,9 +301,14 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
@OnCopy(Strategy.SHARE)
|
||||
private ResourcesPerDay resourcesPerDay;
|
||||
|
||||
private Integer intendedTotalHours;
|
||||
|
||||
private Set<DerivedAllocation> derivedAllocations = new HashSet<DerivedAllocation>();
|
||||
|
||||
private LimitingResourceQueueElement limitingResourceQueueElement;
|
||||
private Set<LimitingResourceQueueElement> limitingResourceQueueElements = new HashSet<LimitingResourceQueueElement>();
|
||||
|
||||
@Min(0)
|
||||
private int originalTotalAssignment = 0;
|
||||
|
||||
/**
|
||||
* Constructor for hibernate. Do not use!
|
||||
|
|
@ -361,6 +367,14 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
return task;
|
||||
}
|
||||
|
||||
public void setOriginalTotalAssigment(int originalTotalAssigment) {
|
||||
this.originalTotalAssignment = originalTotalAssigment;
|
||||
}
|
||||
|
||||
public int getOriginalTotalAssigment() {
|
||||
return originalTotalAssignment;
|
||||
}
|
||||
|
||||
public abstract ResourcesPerDayModification withDesiredResourcesPerDay(
|
||||
ResourcesPerDay resourcesPerDay);
|
||||
|
||||
|
|
@ -477,6 +491,7 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
removingAssignments(getAssignments(startInclusive, endExclusive));
|
||||
addingAssignments(assignmentsCreated);
|
||||
setResourcesPerDay(calculateResourcesPerDayFromAssignments());
|
||||
setOriginalTotalAssigment(getAssignedHours());
|
||||
}
|
||||
|
||||
protected abstract AvailabilityTimeLine getResourcesAvailability();
|
||||
|
|
@ -557,6 +572,10 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
assert isUnsatisfied();
|
||||
}
|
||||
|
||||
public boolean isLimiting() {
|
||||
return getLimitingResourceQueueElement() != null;
|
||||
}
|
||||
|
||||
public boolean isSatisfied() {
|
||||
return hasAssignments();
|
||||
}
|
||||
|
|
@ -568,6 +587,7 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
private void resetAssignmentsTo(List<T> assignments) {
|
||||
removingAssignments(getAssignments());
|
||||
addingAssignments(assignments);
|
||||
setOriginalTotalAssigment(getAssignedHours());
|
||||
}
|
||||
|
||||
protected final void addingAssignments(Collection<? extends T> assignments) {
|
||||
|
|
@ -665,6 +685,7 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
Validate.notNull(scenario);
|
||||
ResourceAllocation<T> copy = createCopy(scenario);
|
||||
copy.resourcesPerDay = resourcesPerDay;
|
||||
copy.originalTotalAssignment = originalTotalAssignment;
|
||||
copy.task = task;
|
||||
copy.assignmentFunction = assignmentFunction;
|
||||
return copy;
|
||||
|
|
@ -943,6 +964,7 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
switchToScenario(scenario);
|
||||
mergeAssignments(modifications);
|
||||
setResourcesPerDay(modifications.getResourcesPerDay());
|
||||
setOriginalTotalAssigment(modifications.getOriginalTotalAssigment());
|
||||
setWithoutApply(modifications.getAssignmentFunction());
|
||||
mergeDerivedAllocations(scenario, modifications.getDerivedAllocations());
|
||||
}
|
||||
|
|
@ -989,12 +1011,21 @@ public abstract class ResourceAllocation<T extends DayAssignment> extends
|
|||
}
|
||||
|
||||
public LimitingResourceQueueElement getLimitingResourceQueueElement() {
|
||||
return limitingResourceQueueElement;
|
||||
return (!limitingResourceQueueElements.isEmpty()) ? (LimitingResourceQueueElement) limitingResourceQueueElements.iterator().next() : null;
|
||||
}
|
||||
|
||||
public void setLimitingResourceQueueElement(
|
||||
LimitingResourceQueueElement limitingResourceQueueElement) {
|
||||
this.limitingResourceQueueElement = limitingResourceQueueElement;
|
||||
public void setLimitingResourceQueueElement(LimitingResourceQueueElement element) {
|
||||
limitingResourceQueueElements.clear();
|
||||
element.setResourceAllocation(this);
|
||||
limitingResourceQueueElements.add(element);
|
||||
}
|
||||
|
||||
public Integer getIntendedTotalHours() {
|
||||
return intendedTotalHours;
|
||||
}
|
||||
|
||||
public void setIntendedTotalHours(Integer intendedTotalHours) {
|
||||
this.intendedTotalHours = intendedTotalHours;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -58,6 +58,13 @@ public class SpecificResourceAllocation extends
|
|||
task));
|
||||
}
|
||||
|
||||
public static SpecificResourceAllocation create(Resource resource, Task task) {
|
||||
SpecificResourceAllocation result = create(new SpecificResourceAllocation(
|
||||
task));
|
||||
result.setResource(resource);
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@OnCopy(Strategy.SHARE)
|
||||
private Resource resource;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import java.util.Collection;
|
|||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
|
@ -43,6 +44,7 @@ import org.navalplanner.business.orders.entities.TaskSource;
|
|||
import org.navalplanner.business.planner.entities.DerivedAllocationGenerator.IWorkerFinder;
|
||||
import org.navalplanner.business.planner.entities.allocationalgorithms.HoursModification;
|
||||
import org.navalplanner.business.planner.entities.allocationalgorithms.ResourcesPerDayModification;
|
||||
import org.navalplanner.business.planner.entities.consolidations.Consolidation;
|
||||
import org.navalplanner.business.resources.daos.IResourceDAO;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
|
|
@ -90,6 +92,9 @@ public class Task extends TaskElement {
|
|||
|
||||
private Integer priority;
|
||||
|
||||
@Valid
|
||||
private Consolidation consolidation;
|
||||
|
||||
/**
|
||||
* Constructor for hibernate. Do not use!
|
||||
*/
|
||||
|
|
@ -122,6 +127,10 @@ public class Task extends TaskElement {
|
|||
.getTotalHours();
|
||||
}
|
||||
|
||||
public int getTotalHours() {
|
||||
return (getTaskSource() != null) ? getTaskSource().getTotalHours() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf() {
|
||||
return true;
|
||||
|
|
@ -133,10 +142,15 @@ public class Task extends TaskElement {
|
|||
}
|
||||
|
||||
public Set<ResourceAllocation<?>> getSatisfiedResourceAllocations() {
|
||||
List<ResourceAllocation<?>> filtered = ResourceAllocation
|
||||
.getSatisfied(resourceAllocations);
|
||||
return Collections.unmodifiableSet(new HashSet<ResourceAllocation<?>>(
|
||||
filtered));
|
||||
Set<ResourceAllocation<?>> result = new HashSet<ResourceAllocation<?>>();
|
||||
|
||||
if (isLimiting()) {
|
||||
result.addAll(getLimitingResourceAllocations());
|
||||
} else {
|
||||
result.addAll(ResourceAllocation
|
||||
.getSatisfied(resourceAllocations));
|
||||
}
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -144,19 +158,44 @@ public class Task extends TaskElement {
|
|||
return Collections.unmodifiableSet(resourceAllocations);
|
||||
}
|
||||
|
||||
public Set<ResourceAllocation<?>> getLimitingResourceAllocations() {
|
||||
Set<ResourceAllocation<?>> result = new HashSet<ResourceAllocation<?>>();
|
||||
for (ResourceAllocation<?> each: resourceAllocations) {
|
||||
if (each.isLimiting()) {
|
||||
result.add(each);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
public Set<ResourceAllocation<?>> getNonLimitingResourceAllocations() {
|
||||
Set<ResourceAllocation<?>> result = new HashSet<ResourceAllocation<?>>();
|
||||
for (ResourceAllocation<?> each: resourceAllocations) {
|
||||
if (!each.isLimiting()) {
|
||||
result.add(each);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
public boolean isLimiting() {
|
||||
// FIXME: Task is limiting if its resourceAllocation is associated with
|
||||
// a LimitingResourceQueueElement
|
||||
return false;
|
||||
return !(getLimitingResourceAllocations().isEmpty());
|
||||
}
|
||||
|
||||
public void addResourceAllocation(ResourceAllocation<?> resourceAllocation) {
|
||||
addResourceAllocation(resourceAllocation, true);
|
||||
}
|
||||
|
||||
public void addResourceAllocation(ResourceAllocation<?> resourceAllocation,
|
||||
boolean generateDayAssignments) {
|
||||
if (!resourceAllocation.getTask().equals(this)) {
|
||||
throw new IllegalArgumentException(
|
||||
"the resourceAllocation's task must be this task");
|
||||
}
|
||||
resourceAllocations.add(resourceAllocation);
|
||||
resourceAllocation.associateAssignmentsToResource();
|
||||
if (generateDayAssignments) {
|
||||
resourceAllocation.associateAssignmentsToResource();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeResourceAllocation(
|
||||
|
|
@ -395,6 +434,14 @@ public class Task extends TaskElement {
|
|||
|
||||
private void reassign(Scenario onScenario,
|
||||
AllocationModificationStrategy strategy) {
|
||||
if (isLimiting()) {
|
||||
Set<ResourceAllocation<?>> resourceAllocations = getSatisfiedResourceAllocations();
|
||||
ResourceAllocation<?> resourceAlloation = resourceAllocations
|
||||
.iterator().next();
|
||||
resourceAlloation.getLimitingResourceQueueElement()
|
||||
.setEarlierStartDateBecauseOfGantt(getStartDate());
|
||||
return;
|
||||
}
|
||||
List<ModifiedAllocation> copied = ModifiedAllocation.copy(onScenario,
|
||||
getSatisfiedResourceAllocations());
|
||||
List<ResourceAllocation<?>> toBeModified = ModifiedAllocation
|
||||
|
|
@ -486,13 +533,21 @@ public class Task extends TaskElement {
|
|||
return subcontractedTaskData;
|
||||
}
|
||||
|
||||
public void removeAllResourceAllocations() {
|
||||
public void removeAllSatisfiedResourceAllocations() {
|
||||
Set<ResourceAllocation<?>> resourceAllocations = getSatisfiedResourceAllocations();
|
||||
for (ResourceAllocation<?> resourceAllocation : resourceAllocations) {
|
||||
removeResourceAllocation(resourceAllocation);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAllResourceAllocations() {
|
||||
for (Iterator<ResourceAllocation<?>> i = resourceAllocations.iterator(); i
|
||||
.hasNext();) {
|
||||
ResourceAllocation<?> each = i.next();
|
||||
removeResourceAllocation(each);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSubcontracted() {
|
||||
return (subcontractedTaskData != null);
|
||||
}
|
||||
|
|
@ -534,4 +589,12 @@ public class Task extends TaskElement {
|
|||
this.priority = priority;
|
||||
}
|
||||
|
||||
public void setConsolidation(Consolidation consolidation) {
|
||||
this.consolidation = consolidation;
|
||||
}
|
||||
|
||||
public Consolidation getConsolidation() {
|
||||
return consolidation;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -438,7 +438,8 @@ public abstract class TaskElement extends BaseEntity {
|
|||
return "unassigned";
|
||||
}
|
||||
for (ResourceAllocation<?> resourceAllocation : getSatisfiedResourceAllocations()) {
|
||||
if (resourceAllocation.getResourcesPerDay().isZero()) {
|
||||
final ResourcesPerDay resourcesPerDay = resourceAllocation.getResourcesPerDay();
|
||||
if (resourcesPerDay != null && resourcesPerDay.isZero()) {
|
||||
return "partially-assigned";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
|
||||
/**
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
|
||||
public class CalculatedConsolidatedValue extends ConsolidatedValue {
|
||||
|
||||
private CalculatedConsolidation consolidation;
|
||||
|
||||
public static CalculatedConsolidatedValue create() {
|
||||
return create(new CalculatedConsolidatedValue());
|
||||
}
|
||||
|
||||
public static CalculatedConsolidatedValue create(LocalDate date,
|
||||
BigDecimal value,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
return create(new CalculatedConsolidatedValue(date, value,
|
||||
pendingConsolidatedHours));
|
||||
}
|
||||
|
||||
protected CalculatedConsolidatedValue(
|
||||
LocalDate date,
|
||||
BigDecimal value,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
super(date, value, pendingConsolidatedHours);
|
||||
}
|
||||
|
||||
protected CalculatedConsolidatedValue() {
|
||||
}
|
||||
|
||||
public void setConsolidation(CalculatedConsolidation consolidation) {
|
||||
this.consolidation = consolidation;
|
||||
}
|
||||
|
||||
public CalculatedConsolidation getConsolidation() {
|
||||
return consolidation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCalculated() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.navalplanner.business.advance.entities.IndirectAdvanceAssignment;
|
||||
import org.navalplanner.business.planner.entities.Task;
|
||||
|
||||
/**
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
|
||||
public class CalculatedConsolidation extends Consolidation {
|
||||
|
||||
private SortedSet<CalculatedConsolidatedValue> consolidatedValues = new TreeSet<CalculatedConsolidatedValue>(
|
||||
new ConsolidatedValueComparator());
|
||||
|
||||
private IndirectAdvanceAssignment indirectAdvanceAssignment;
|
||||
|
||||
public static CalculatedConsolidation create(Task task,
|
||||
IndirectAdvanceAssignment indirectAdvanceAssignment) {
|
||||
return create(new CalculatedConsolidation(task,
|
||||
indirectAdvanceAssignment));
|
||||
}
|
||||
|
||||
public static CalculatedConsolidation create(Task task,
|
||||
IndirectAdvanceAssignment indirectAdvanceAssignment,
|
||||
SortedSet<CalculatedConsolidatedValue> consolidatedValues) {
|
||||
return create(new CalculatedConsolidation(task,
|
||||
indirectAdvanceAssignment,
|
||||
consolidatedValues));
|
||||
}
|
||||
|
||||
protected CalculatedConsolidation() {
|
||||
|
||||
}
|
||||
|
||||
protected CalculatedConsolidation(Task task,
|
||||
IndirectAdvanceAssignment indirectAdvanceAssignment,
|
||||
SortedSet<CalculatedConsolidatedValue> consolidatedValues) {
|
||||
this(task, indirectAdvanceAssignment);
|
||||
this.setConsolidatedValues(consolidatedValues);
|
||||
}
|
||||
|
||||
public CalculatedConsolidation(Task task,
|
||||
IndirectAdvanceAssignment indirectAdvanceAssignment) {
|
||||
super(task);
|
||||
this.indirectAdvanceAssignment = indirectAdvanceAssignment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<ConsolidatedValue> getConsolidatedValues() {
|
||||
return new TreeSet<ConsolidatedValue>(consolidatedValues);
|
||||
}
|
||||
|
||||
public SortedSet<CalculatedConsolidatedValue> getCalculatedConsolidatedValues() {
|
||||
return consolidatedValues;
|
||||
}
|
||||
|
||||
public void setConsolidatedValues(
|
||||
SortedSet<CalculatedConsolidatedValue> consolidatedValues) {
|
||||
this.consolidatedValues = consolidatedValues;
|
||||
}
|
||||
|
||||
public void setIndirectAdvanceAssignment(
|
||||
IndirectAdvanceAssignment indirectAdvanceAssignment) {
|
||||
this.indirectAdvanceAssignment = indirectAdvanceAssignment;
|
||||
}
|
||||
|
||||
public IndirectAdvanceAssignment getIndirectAdvanceAssignment() {
|
||||
return indirectAdvanceAssignment;
|
||||
}
|
||||
|
||||
public void addConsolidatedValue(CalculatedConsolidatedValue value) {
|
||||
if (!consolidatedValues.contains(value)) {
|
||||
value.setConsolidation(this);
|
||||
this.consolidatedValues.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCalculated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
|
||||
/**
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
|
||||
public abstract class ConsolidatedValue extends BaseEntity {
|
||||
|
||||
private LocalDate date;
|
||||
private BigDecimal value;
|
||||
private Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours = new HashSet<PendingConsolidatedHoursPerResourceAllocation>();
|
||||
|
||||
public abstract boolean isCalculated();
|
||||
|
||||
protected ConsolidatedValue() {
|
||||
|
||||
}
|
||||
|
||||
protected ConsolidatedValue(
|
||||
LocalDate date,
|
||||
BigDecimal value,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
this.date = date;
|
||||
this.value = value;
|
||||
this.pendingConsolidatedHours = pendingConsolidatedHours;
|
||||
}
|
||||
|
||||
public void setValue(BigDecimal value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public BigDecimal getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setDate(LocalDate date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public LocalDate getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setPendingConsolidatedHours(Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
this.pendingConsolidatedHours = pendingConsolidatedHours;
|
||||
}
|
||||
|
||||
public Set<PendingConsolidatedHoursPerResourceAllocation> getPendingConsolidatedHours() {
|
||||
return pendingConsolidatedHours;
|
||||
}
|
||||
|
||||
public static Set<PendingConsolidatedHoursPerResourceAllocation> createPendingConsolidatedHours(
|
||||
LocalDate consolidatedDate,
|
||||
Collection<? extends ResourceAllocation> allocations) {
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours = new HashSet<PendingConsolidatedHoursPerResourceAllocation>();
|
||||
for (ResourceAllocation allocation : allocations) {
|
||||
pendingConsolidatedHours
|
||||
.add(PendingConsolidatedHoursPerResourceAllocation.create(
|
||||
consolidatedDate, allocation));
|
||||
}
|
||||
return pendingConsolidatedHours;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
public class ConsolidatedValueComparator implements
|
||||
Comparator<ConsolidatedValue> {
|
||||
|
||||
public ConsolidatedValueComparator() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(ConsolidatedValue arg0, ConsolidatedValue arg1) {
|
||||
if (arg1.getDate() == arg0.getDate()) {
|
||||
return 0;
|
||||
}
|
||||
if (arg1.getDate() == null) {
|
||||
return -1;
|
||||
}
|
||||
if (arg0.getDate() == null) {
|
||||
return 1;
|
||||
}
|
||||
return arg0.getDate().compareTo(arg1.getDate());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.util.SortedSet;
|
||||
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.entities.Task;
|
||||
|
||||
/**
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
public abstract class Consolidation extends BaseEntity {
|
||||
|
||||
public abstract SortedSet<? extends ConsolidatedValue> getConsolidatedValues();
|
||||
|
||||
public abstract boolean isCalculated();
|
||||
|
||||
private Task task;
|
||||
|
||||
protected Consolidation() {
|
||||
|
||||
}
|
||||
|
||||
protected Consolidation(Task task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public void setTask(Task task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
public Task getTask() {
|
||||
return task;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.advance.entities.AdvanceMeasurement;
|
||||
|
||||
/**
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
|
||||
public class NonCalculatedConsolidatedValue extends ConsolidatedValue {
|
||||
|
||||
private NonCalculatedConsolidation consolidation;
|
||||
|
||||
private AdvanceMeasurement advanceMeasurement;
|
||||
|
||||
public static NonCalculatedConsolidatedValue create() {
|
||||
return create(new NonCalculatedConsolidatedValue());
|
||||
}
|
||||
|
||||
public static NonCalculatedConsolidatedValue create(LocalDate date,
|
||||
BigDecimal value,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
return create(new NonCalculatedConsolidatedValue(date, value,
|
||||
pendingConsolidatedHours));
|
||||
}
|
||||
|
||||
public static NonCalculatedConsolidatedValue create(LocalDate date,
|
||||
BigDecimal value,
|
||||
AdvanceMeasurement advanceMeasurement,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
return create(new NonCalculatedConsolidatedValue(date, value,
|
||||
advanceMeasurement, pendingConsolidatedHours));
|
||||
}
|
||||
|
||||
protected NonCalculatedConsolidatedValue(LocalDate date, BigDecimal value,
|
||||
AdvanceMeasurement advanceMeasurement,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
this(date, value, pendingConsolidatedHours);
|
||||
this.advanceMeasurement = advanceMeasurement;
|
||||
}
|
||||
|
||||
protected NonCalculatedConsolidatedValue(
|
||||
LocalDate date,
|
||||
BigDecimal value,
|
||||
Set<PendingConsolidatedHoursPerResourceAllocation> pendingConsolidatedHours) {
|
||||
super(date, value, pendingConsolidatedHours);
|
||||
}
|
||||
|
||||
protected NonCalculatedConsolidatedValue() {
|
||||
}
|
||||
|
||||
public void setAdvanceMeasurement(AdvanceMeasurement advanceMeasurement) {
|
||||
this.advanceMeasurement = advanceMeasurement;
|
||||
}
|
||||
|
||||
public AdvanceMeasurement getAdvanceMeasurement() {
|
||||
return advanceMeasurement;
|
||||
}
|
||||
|
||||
public void setConsolidation(NonCalculatedConsolidation consolidation) {
|
||||
this.consolidation = consolidation;
|
||||
}
|
||||
|
||||
public NonCalculatedConsolidation getConsolidation() {
|
||||
return consolidation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCalculated() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.navalplanner.business.advance.entities.DirectAdvanceAssignment;
|
||||
import org.navalplanner.business.planner.entities.Task;
|
||||
|
||||
|
||||
/**
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
|
||||
public class NonCalculatedConsolidation extends Consolidation {
|
||||
|
||||
private SortedSet<NonCalculatedConsolidatedValue> consolidatedValues = new TreeSet<NonCalculatedConsolidatedValue>(
|
||||
new ConsolidatedValueComparator());
|
||||
|
||||
private DirectAdvanceAssignment directAdvanceAssignment;
|
||||
|
||||
public static NonCalculatedConsolidation create(Task task,
|
||||
DirectAdvanceAssignment directAdvanceAssignment) {
|
||||
return create(new NonCalculatedConsolidation(task,
|
||||
directAdvanceAssignment));
|
||||
}
|
||||
|
||||
public static NonCalculatedConsolidation create(Task task,
|
||||
DirectAdvanceAssignment directAdvanceAssignment,
|
||||
SortedSet<NonCalculatedConsolidatedValue> consolidatedValues) {
|
||||
return create(new NonCalculatedConsolidation(task,
|
||||
directAdvanceAssignment,
|
||||
consolidatedValues));
|
||||
}
|
||||
|
||||
protected NonCalculatedConsolidation() {
|
||||
|
||||
}
|
||||
|
||||
protected NonCalculatedConsolidation(Task task,
|
||||
DirectAdvanceAssignment directAdvanceAssignment,
|
||||
SortedSet<NonCalculatedConsolidatedValue> consolidatedValues) {
|
||||
this(task, directAdvanceAssignment);
|
||||
this.setConsolidatedValues(consolidatedValues);
|
||||
}
|
||||
|
||||
public NonCalculatedConsolidation(Task task,
|
||||
DirectAdvanceAssignment directAdvanceAssignment) {
|
||||
super(task);
|
||||
this.directAdvanceAssignment = directAdvanceAssignment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SortedSet<ConsolidatedValue> getConsolidatedValues() {
|
||||
return new TreeSet<ConsolidatedValue>(consolidatedValues);
|
||||
}
|
||||
|
||||
public SortedSet<NonCalculatedConsolidatedValue> getNonCalculatedConsolidatedValues() {
|
||||
return consolidatedValues;
|
||||
}
|
||||
|
||||
public void setConsolidatedValues(
|
||||
SortedSet<NonCalculatedConsolidatedValue> consolidatedValues) {
|
||||
this.consolidatedValues = consolidatedValues;
|
||||
}
|
||||
|
||||
public void setDirectAdvanceAssignment(
|
||||
DirectAdvanceAssignment directAdvanceAssignment) {
|
||||
this.directAdvanceAssignment = directAdvanceAssignment;
|
||||
}
|
||||
|
||||
public DirectAdvanceAssignment getDirectAdvanceAssignment() {
|
||||
return directAdvanceAssignment;
|
||||
}
|
||||
|
||||
public void addConsolidatedValue(NonCalculatedConsolidatedValue value) {
|
||||
if (!consolidatedValues.contains(value)) {
|
||||
value.setConsolidation(this);
|
||||
this.consolidatedValues.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCalculated() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.business.planner.entities.consolidations;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.hibernate.validator.NotNull;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.entities.DayAssignment;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
|
||||
/**
|
||||
* Represents the number of hours per {@link ResourceAllocation} that are not
|
||||
* consolidated.
|
||||
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
|
||||
*/
|
||||
|
||||
public class PendingConsolidatedHoursPerResourceAllocation extends BaseEntity {
|
||||
|
||||
private Integer pendingConsolidatedHours;
|
||||
|
||||
private ResourceAllocation<?> resourceAllocation;
|
||||
|
||||
public static PendingConsolidatedHoursPerResourceAllocation create(
|
||||
LocalDate consolidatedDate,
|
||||
ResourceAllocation<?> resourceAllocation) {
|
||||
return create(new PendingConsolidatedHoursPerResourceAllocation(
|
||||
consolidatedDate,
|
||||
resourceAllocation));
|
||||
}
|
||||
|
||||
public static PendingConsolidatedHoursPerResourceAllocation create(
|
||||
Integer pendingConsolidatedHours,
|
||||
ResourceAllocation<?> resourceAllocation) {
|
||||
return create(new PendingConsolidatedHoursPerResourceAllocation(
|
||||
pendingConsolidatedHours, resourceAllocation));
|
||||
}
|
||||
|
||||
protected PendingConsolidatedHoursPerResourceAllocation(
|
||||
LocalDate consolidatedDate,
|
||||
ResourceAllocation<?> resourceAllocation) {
|
||||
this.setPendingConsolidatedHours(calculatePendingConsolidatedHours(
|
||||
consolidatedDate, resourceAllocation
|
||||
.getAssignments()));
|
||||
this.setResourceAllocation(resourceAllocation);
|
||||
}
|
||||
|
||||
protected PendingConsolidatedHoursPerResourceAllocation(
|
||||
Integer pendingConsolidatedHours,
|
||||
ResourceAllocation<?> resourceAllocation) {
|
||||
this.setPendingConsolidatedHours(pendingConsolidatedHours);
|
||||
this.setResourceAllocation(resourceAllocation);
|
||||
}
|
||||
|
||||
protected PendingConsolidatedHoursPerResourceAllocation() {
|
||||
|
||||
}
|
||||
|
||||
private Integer calculatePendingConsolidatedHours(LocalDate consolidatedDate,
|
||||
Collection<? extends DayAssignment> assignments) {
|
||||
int result = 0;
|
||||
for (DayAssignment dayAssignment : assignments) {
|
||||
if ((dayAssignment.getDay().toDateTimeAtStartOfDay()
|
||||
.compareTo(consolidatedDate.toDateTimeAtStartOfDay())) > 0) {
|
||||
dayAssignment.setConsolidated(true);
|
||||
result += dayAssignment.getHours();
|
||||
}
|
||||
}
|
||||
return new Integer(result);
|
||||
}
|
||||
|
||||
public void setPendingConsolidatedHours(Integer pendingConsolidatedHours) {
|
||||
this.pendingConsolidatedHours = pendingConsolidatedHours;
|
||||
}
|
||||
|
||||
@NotNull(message = "pending consolidated hours not specified")
|
||||
public Integer getPendingConsolidatedHours() {
|
||||
return pendingConsolidatedHours;
|
||||
}
|
||||
|
||||
public void setResourceAllocation(ResourceAllocation<?> resourceAllocation) {
|
||||
this.resourceAllocation = resourceAllocation;
|
||||
}
|
||||
|
||||
@NotNull(message = "resource allocation not specified")
|
||||
public ResourceAllocation<?> getResourceAllocation() {
|
||||
return resourceAllocation;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -157,8 +157,10 @@ public class ResourceDAO extends IntegrationEntityDAO<Resource> implements
|
|||
private List<Resource> findRelatedToSpecific(List<Task> taskElements) {
|
||||
List<Resource> list = getSession()
|
||||
.createQuery(
|
||||
"SELECT DISTINCT specificAllocation.resource FROM SpecificResourceAllocation specificAllocation "
|
||||
+ " WHERE specificAllocation.task IN(:taskElements)")
|
||||
"SELECT DISTINCT specificAllocation.resource "
|
||||
+ "FROM SpecificResourceAllocation specificAllocation "
|
||||
+ "WHERE specificAllocation.task IN(:taskElements) "
|
||||
+ "and specificAllocation.specificDaysAssignment IS NOT EMPTY")
|
||||
.setParameterList(
|
||||
"taskElements",
|
||||
taskElements).list();
|
||||
|
|
|
|||
|
|
@ -84,6 +84,26 @@ public class Criterion extends IntegrationEntity implements ICriterion {
|
|||
return result;
|
||||
}
|
||||
|
||||
public static List<Criterion> sortByTypeAndName(Collection<Criterion> criterions) {
|
||||
List<Criterion> result = new ArrayList<Criterion>(criterions);
|
||||
Collections.sort(result, new Comparator<Criterion>() {
|
||||
|
||||
@Override
|
||||
public int compare(Criterion o1, Criterion o2) {
|
||||
if (o1.getName() == null || o1.getType().getName() == null) {
|
||||
return 1;
|
||||
}
|
||||
if (o2.getName() == null || o2.getType().getName() == null) {
|
||||
return -1;
|
||||
}
|
||||
String name1 = o1.getType().getName() + " " + o1.getName();
|
||||
String name2 = o2.getType().getName() + " " + o2.getName();
|
||||
return name1.compareTo(name2);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public void updateUnvalidated(String name, Boolean active) {
|
||||
|
||||
if (!StringUtils.isBlank(name)) {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@
|
|||
package org.navalplanner.business.resources.entities;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
|
|
@ -36,8 +36,8 @@ public class LimitingResourceQueue extends BaseEntity {
|
|||
|
||||
private Resource resource;
|
||||
|
||||
private Set<LimitingResourceQueueElement> limitingResourceQueueElements =
|
||||
new HashSet<LimitingResourceQueueElement>();
|
||||
private SortedSet<LimitingResourceQueueElement> limitingResourceQueueElements =
|
||||
new TreeSet<LimitingResourceQueueElement>(new LimitingResourceQueueElementComparator());
|
||||
|
||||
public static LimitingResourceQueue create() {
|
||||
return create(new LimitingResourceQueue());
|
||||
|
|
@ -64,8 +64,8 @@ public class LimitingResourceQueue extends BaseEntity {
|
|||
limitingResourceQueueElements.remove(element);
|
||||
}
|
||||
|
||||
public Set<LimitingResourceQueueElement> getLimitingResourceQueueElements() {
|
||||
return Collections.unmodifiableSet(limitingResourceQueueElements);
|
||||
public SortedSet<LimitingResourceQueueElement> getLimitingResourceQueueElements() {
|
||||
return Collections.unmodifiableSortedSet(limitingResourceQueueElements);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.navalplanner.business.resources.entities;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
public class LimitingResourceQueueElementComparator implements
|
||||
Comparator<LimitingResourceQueueElement> {
|
||||
|
||||
@Override
|
||||
public int compare(LimitingResourceQueueElement arg0,
|
||||
LimitingResourceQueueElement arg1) {
|
||||
final int deltaHour = arg0.getStartHour() - arg1.getStartHour();
|
||||
if (deltaHour != 0) {
|
||||
return deltaHour / Math.abs(deltaHour);
|
||||
}
|
||||
if (arg0.getStartDate() == null) {
|
||||
return -1;
|
||||
}
|
||||
if (arg1.getStartDate() == null) {
|
||||
return 1;
|
||||
}
|
||||
return arg0.getStartDate().compareTo(arg1.getStartDate());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ public class Worker extends Resource {
|
|||
}
|
||||
|
||||
public String getName() {
|
||||
return firstName + " " + surname;
|
||||
return getSurname() + ", " + getFirstName();
|
||||
}
|
||||
|
||||
@NotEmpty(message="worker's NIF not specified")
|
||||
|
|
|
|||
|
|
@ -76,6 +76,9 @@
|
|||
<value>
|
||||
org/navalplanner/business/externalcompanies/entities/ExternalCompanies.hbm.xml
|
||||
</value>
|
||||
<value>
|
||||
org/navalplanner/business/planner/entities/AdvanceConsolidations.hbm.xml
|
||||
</value>
|
||||
<value>
|
||||
org/navalplanner/business/scenarios/entities/Scenarios.hbm.xml
|
||||
</value>
|
||||
|
|
|
|||
|
|
@ -50,12 +50,30 @@
|
|||
<key column="ADVANCE_ASSIGNMENT_ID" />
|
||||
<one-to-many class="org.navalplanner.business.advance.entities.AdvanceMeasurement"></one-to-many>
|
||||
</set>
|
||||
|
||||
<set name="nonCalculatedConsolidations"
|
||||
cascade="none"
|
||||
inverse="true"
|
||||
access="field">
|
||||
<key column="DIR_ADVANCE_ASSIGNMENT_ID" />
|
||||
<one-to-many class="org.navalplanner.business.planner.entities.consolidations.NonCalculatedConsolidation" />
|
||||
</set>
|
||||
|
||||
</joined-subclass>
|
||||
|
||||
<joined-subclass name="IndirectAdvanceAssignment">
|
||||
<key column="ADVANCE_ASSIGNMENT_ID"></key>
|
||||
|
||||
<many-to-one name="orderElement" class="org.navalplanner.business.orders.entities.OrderElement" column="INDIRECT_ORDER_ELEMENT_ID"/>
|
||||
|
||||
<set name="calculatedConsolidations"
|
||||
cascade="none"
|
||||
inverse="true"
|
||||
access="field">
|
||||
<key column="IND_ADVANCE_ASSIGNMENT_ID" />
|
||||
<one-to-many class="org.navalplanner.business.planner.entities.consolidations.CalculatedConsolidation" />
|
||||
</set>
|
||||
|
||||
</joined-subclass>
|
||||
|
||||
</class>
|
||||
|
|
@ -73,6 +91,12 @@
|
|||
<property name="value" scale="2" access="field" />
|
||||
<many-to-one name="advanceAssignment" class="AdvanceAssignment" column="ADVANCE_ASSIGNMENT_ID" access="field" />
|
||||
<property name="communicationDate" access="field" />
|
||||
|
||||
<set name="nonCalculatedConsolidatedValues" access="field" cascade="none" inverse="true">
|
||||
<key column="ADVANCE_MEASUREMENT_ID" />
|
||||
<one-to-many class="org.navalplanner.business.planner.entities.consolidations.NonCalculatedConsolidatedValue" />
|
||||
</set>
|
||||
|
||||
</class>
|
||||
|
||||
<class name="AdvanceAssignmentTemplate">
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
<property name="generateCodeForTypesOfWorkHours" not-null="true" />
|
||||
<property name="generateCodeForMaterialCategories" not-null="true" />
|
||||
<property name="generateCodeForUnitTypes" not-null="true" />
|
||||
<property name="expandCompanyPlanningViewCharts" not-null="true" />
|
||||
<property name="expandOrderPlanningViewCharts" not-null="true" />
|
||||
|
||||
</class>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
<?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">
|
||||
<hibernate-mapping package="org.navalplanner.business.planner.entities.consolidations" default-access="field">
|
||||
|
||||
<class name="ConsolidatedValue">
|
||||
<id name="id" column="id" type="long" access="property">
|
||||
<generator class="hilo">
|
||||
<param name="max_lo">100</param>
|
||||
</generator>
|
||||
</id>
|
||||
<discriminator column="CONSOLIDATED_VALUE_TYPE" type="string"/>
|
||||
<version name="version" access="property" type="long" />
|
||||
|
||||
<property name="date" access="field" type="org.joda.time.contrib.hibernate.PersistentLocalDate" />
|
||||
<property name="value" scale="2" access="field" />
|
||||
|
||||
<set name="pendingConsolidatedHours" table="PENDING_CONSOLIDATED_HOURS">
|
||||
<key column="PENDING_HOURS_ID"/>
|
||||
<composite-element class="org.navalplanner.business.planner.entities.consolidations.PendingConsolidatedHoursPerResourceAllocation">
|
||||
<property name="pendingConsolidatedHours"/>
|
||||
<many-to-one name="resourceAllocation" class="org.navalplanner.business.planner.entities.ResourceAllocation" column="RESOURCE_ALLOCATION_ID" access="field" />
|
||||
</composite-element>
|
||||
</set>
|
||||
|
||||
<subclass name="NonCalculatedConsolidatedValue" discriminator-value="NonCalculated">
|
||||
<many-to-one name="consolidation" class="NonCalculatedConsolidation" column="CONSOLIDATION_ID" access="field" />
|
||||
<many-to-one name="advanceMeasurement" class="org.navalplanner.business.advance.entities.AdvanceMeasurement" column="ADVANCE_MEASUREMENT_ID" access="field" />
|
||||
</subclass>
|
||||
|
||||
<subclass name="CalculatedConsolidatedValue" discriminator-value="Calculated">
|
||||
<many-to-one name="consolidation" class="CalculatedConsolidation" column="CONSOLIDATION_ID" access="field" />
|
||||
</subclass>
|
||||
|
||||
</class>
|
||||
|
||||
<class name="Consolidation">
|
||||
<id name="id" column="id" type="long" access="property">
|
||||
<generator class="foreign">
|
||||
<param name="property">task</param>
|
||||
</generator>
|
||||
</id>
|
||||
<discriminator column="CONSOLIDATION_TYPE" type="string"/>
|
||||
<version name="version" access="property" type="long" />
|
||||
|
||||
<one-to-one name="task" class="org.navalplanner.business.planner.entities.Task" constrained="true"/>
|
||||
|
||||
<subclass name="NonCalculatedConsolidation" discriminator-value="NonCalculated">
|
||||
|
||||
<many-to-one name="directAdvanceAssignment" column="DIR_ADVANCE_ASSIGNMENT_ID" access="field"
|
||||
class="org.navalplanner.business.advance.entities.DirectAdvanceAssignment" />
|
||||
|
||||
<set name="consolidatedValues"
|
||||
access="field"
|
||||
cascade="all,delete-orphan"
|
||||
inverse="true"
|
||||
sort="org.navalplanner.business.planner.entities.consolidations.ConsolidatedValueComparator">
|
||||
<key column="CONSOLIDATION_ID" />
|
||||
<one-to-many class="org.navalplanner.business.planner.entities.consolidations.NonCalculatedConsolidatedValue" />
|
||||
</set>
|
||||
|
||||
</subclass>
|
||||
|
||||
<subclass name="CalculatedConsolidation" discriminator-value="Calculated">
|
||||
|
||||
<many-to-one name="indirectAdvanceAssignment" column="IND_ADVANCE_ASSIGNMENT_ID" access="field"
|
||||
class="org.navalplanner.business.advance.entities.IndirectAdvanceAssignment"/>
|
||||
|
||||
<set name="consolidatedValues"
|
||||
access="field"
|
||||
cascade="all,delete-orphan"
|
||||
inverse="true"
|
||||
sort="org.navalplanner.business.planner.entities.consolidations.ConsolidatedValueComparator">
|
||||
<key column="CONSOLIDATION_ID" />
|
||||
<one-to-many class="org.navalplanner.business.planner.entities.consolidations.CalculatedConsolidatedValue" />
|
||||
</set>
|
||||
|
||||
</subclass>
|
||||
|
||||
</class>
|
||||
|
||||
</hibernate-mapping>
|
||||
|
|
@ -14,6 +14,10 @@
|
|||
|
||||
<property name="resourcesPerDay" type="org.navalplanner.business.planner.entities.hibernate.ResourcesPerDayType" />
|
||||
|
||||
<property name="intendedTotalHours" column="intended_total_hours" />
|
||||
|
||||
<property name="originalTotalAssignment" access="field"/>
|
||||
|
||||
<many-to-one class="Task" name="task" column="TASK" />
|
||||
|
||||
<many-to-one class="AssignmentFunction" name="assignmentFunction"
|
||||
|
|
@ -25,7 +29,10 @@
|
|||
<one-to-many class="DerivedAllocation"/>
|
||||
</set>
|
||||
|
||||
<one-to-one name="limitingResourceQueueElement" property-ref="resourceAllocation" cascade="all" />
|
||||
<set name="limitingResourceQueueElements" cascade="all-delete-orphan" inverse="true">
|
||||
<key column="RESOURCE_ALLOCATION_ID" />
|
||||
<one-to-many class="LimitingResourceQueueElement"/>
|
||||
</set>
|
||||
|
||||
<joined-subclass name="SpecificResourceAllocation" table="specific_resource_allocation">
|
||||
<key column="RESOURCE_ALLOCATION_ID" />
|
||||
|
|
@ -67,8 +74,8 @@
|
|||
natural-id could be used for that but was discarded due to:
|
||||
https://forum.hibernate.org/viewtopic.php?p=2372348
|
||||
-->
|
||||
<many-to-one name="resourceAllocation" column="RESOURCE_ALLOCATION_ID" not-null="true"/>
|
||||
<many-to-one name="scenario" not-null="true"/>
|
||||
<many-to-one name="resourceAllocation" column="RESOURCE_ALLOCATION_ID"/>
|
||||
<many-to-one name="scenario" />
|
||||
<set name="dayAssignments" cascade="all-delete-orphan">
|
||||
<key column="SPECIFIC_CONTAINER_ID" />
|
||||
<one-to-many class="SpecificDayAssignment"/>
|
||||
|
|
@ -87,8 +94,8 @@
|
|||
natural-id could be used for that but was discarded due to:
|
||||
https://forum.hibernate.org/viewtopic.php?p=2372348
|
||||
-->
|
||||
<many-to-one name="resourceAllocation" column="RESOURCE_ALLOCATION_ID" not-null="true"/>
|
||||
<many-to-one name="scenario" not-null="true"/>
|
||||
<many-to-one name="resourceAllocation" column="RESOURCE_ALLOCATION_ID"/>
|
||||
<many-to-one name="scenario" />
|
||||
<set name="dayAssignments" cascade="all-delete-orphan">
|
||||
<key column="GENERIC_CONTAINER_ID" />
|
||||
<one-to-many class="GenericDayAssignment"/>
|
||||
|
|
@ -115,6 +122,7 @@
|
|||
</set>
|
||||
</class>
|
||||
|
||||
<!-- LimitingResourceQueueElement -->
|
||||
<class name="LimitingResourceQueueElement" table="limiting_resource_queue_element">
|
||||
<id name="id" type="long" access="property">
|
||||
<generator class="hilo">
|
||||
|
|
@ -129,6 +137,18 @@
|
|||
|
||||
<property name="earlierStartDateBecauseOfGantt" column="EARLIER_START_DATE_BECAUSE_OF_GANTT" />
|
||||
|
||||
<property name="creationTimestamp" column="CREATION_TIMESTAMP" />
|
||||
|
||||
<component name="startQueuePosition" class="org.navalplanner.business.planner.entities.QueuePosition">
|
||||
<property name="date" column="START_DATE" type="org.joda.time.contrib.hibernate.PersistentLocalDate" />
|
||||
<property name="hour" column="START_HOUR" />
|
||||
</component>
|
||||
|
||||
<component name="endQueuePosition" class="org.navalplanner.business.planner.entities.QueuePosition">
|
||||
<property name="date" column="END_DATE" type="org.joda.time.contrib.hibernate.PersistentLocalDate" />
|
||||
<property name="hour" column="END_HOUR" />
|
||||
</component>
|
||||
|
||||
</class>
|
||||
|
||||
<!-- DayAssignment -->
|
||||
|
|
@ -144,6 +164,8 @@
|
|||
|
||||
<property name="hours" not-null="true"/>
|
||||
|
||||
<property name="consolidated" access="field"/>
|
||||
|
||||
<property name="day" type="org.joda.time.contrib.hibernate.PersistentLocalDate" not-null="true"/>
|
||||
|
||||
<many-to-one name="resource" class="org.navalplanner.business.resources.entities.Resource"
|
||||
|
|
@ -157,10 +179,10 @@
|
|||
|
||||
<!-- GenericDayAssignment -->
|
||||
<subclass name="GenericDayAssignment" discriminator-value="GENERIC_DAY">
|
||||
<many-to-one name="container" column="GENERIC_CONTAINER_ID" not-null="true"/>
|
||||
<many-to-one name="container" column="GENERIC_CONTAINER_ID" />
|
||||
</subclass>
|
||||
<subclass name="DerivedDayAssignment" discriminator-value="DERIVED_DAY">
|
||||
<many-to-one name="container" column="DERIVED_CONTAINER_ID" not-null="true"/>
|
||||
<many-to-one name="container" column="DERIVED_CONTAINER_ID" />
|
||||
</subclass>
|
||||
</class>
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@
|
|||
</property>
|
||||
<property name="constraintDate" />
|
||||
</component>
|
||||
|
||||
<one-to-one name="consolidation" class="org.navalplanner.business.planner.entities.consolidations.Consolidation"
|
||||
cascade="all"/>
|
||||
|
||||
<set name="resourceAllocations" cascade="all-delete-orphan">
|
||||
<key column="TASK" />
|
||||
<one-to-many class="ResourceAllocation" />
|
||||
|
|
|
|||
|
|
@ -78,7 +78,8 @@
|
|||
|
||||
<many-to-one name="resource" column="RESOURCE_ID" not-null="false" unique="true" />
|
||||
|
||||
<set name="limitingResourceQueueElements" cascade="all-delete-orphan" inverse="true" >
|
||||
<set name="limitingResourceQueueElements" cascade="all-delete-orphan" inverse="true"
|
||||
sort="org.navalplanner.business.resources.entities.LimitingResourceQueueElementComparator">
|
||||
<key column="LIMITING_RESOURCE_QUEUE_ID" not-null="true" />
|
||||
<one-to-many class="org.navalplanner.business.planner.entities.LimitingResourceQueueElement" />
|
||||
</set>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import static org.hamcrest.CoreMatchers.nullValue;
|
|||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
|
@ -608,8 +607,8 @@ public class BaseCalendarTest {
|
|||
assertThat(calendar.getOwnExceptions().size(), equalTo(2));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNotAllowCreateExceptionsInThePast() {
|
||||
@Test
|
||||
public void testAllowCreateExceptionsInThePast() {
|
||||
BaseCalendar calendar = createBasicCalendar();
|
||||
|
||||
LocalDate pastMonth = (new LocalDate()).minusMonths(1);
|
||||
|
|
@ -619,28 +618,26 @@ public class BaseCalendarTest {
|
|||
calendar.addExceptionDay(exceptionDay);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNotAllowRemoveExceptionsInThePast() {
|
||||
@Test
|
||||
public void testAllowRemoveExceptionsInThePast() {
|
||||
BaseCalendar calendar = createBasicCalendar();
|
||||
|
||||
LocalDate pastMonth = (new LocalDate()).minusMonths(1);
|
||||
CalendarException exceptionDay = CalendarException.create(pastMonth, 0,
|
||||
createCalendarExceptionType());
|
||||
|
||||
calendar.addExceptionDay(exceptionDay);
|
||||
calendar.removeExceptionDay(pastMonth);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotAllowSetExpiringDateInThePast() {
|
||||
public void testAllowSetExpiringDateInThePast() {
|
||||
BaseCalendar calendar = createBasicCalendar();
|
||||
|
||||
calendar.newVersion((new LocalDate()).plusDays(1));
|
||||
|
||||
LocalDate pastWeek = (new LocalDate()).minusWeeks(1);
|
||||
try {
|
||||
calendar.setExpiringDate(pastWeek);
|
||||
fail("It should throw an exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
|
||||
}
|
||||
calendar.setExpiringDate(pastWeek);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -663,8 +660,8 @@ public class BaseCalendarTest {
|
|||
nullValue());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNotAllowNewVersionOnCurrentDate() {
|
||||
@Test
|
||||
public void testAllowNewVersionOnCurrentDate() {
|
||||
BaseCalendar calendar = createBasicCalendar();
|
||||
|
||||
calendar.newVersion(new LocalDate());
|
||||
|
|
@ -697,8 +694,8 @@ public class BaseCalendarTest {
|
|||
equalTo(currentDate.plusWeeks(2)));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNotAllowSetValidFromInThePast() {
|
||||
@Test
|
||||
public void testAllowSetValidFromInThePast() {
|
||||
BaseCalendar calendar = createBasicCalendar();
|
||||
|
||||
LocalDate currentDate = new LocalDate();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.navalplanner.business.test.planner.daos;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
|
||||
import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.navalplanner.business.planner.daos.ILimitingResourceQueueDAO;
|
||||
import org.navalplanner.business.planner.daos.ILimitingResourceQueueElementDAO;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
|
||||
BUSINESS_SPRING_CONFIG_TEST_FILE })
|
||||
/**
|
||||
*
|
||||
* @author Diego Pino Garcia <dpino@igalia.com>
|
||||
*
|
||||
*/
|
||||
@Transactional
|
||||
public class LimitingResourceQueueElementDAOTest {
|
||||
|
||||
@Autowired
|
||||
private ILimitingResourceQueueDAO limitingResourceQueueDAO;
|
||||
|
||||
@Autowired
|
||||
private ILimitingResourceQueueElementDAO limitingResourceQueueElementDAO;
|
||||
|
||||
@Test
|
||||
public void testInSpringContainer() {
|
||||
assertNotNull(limitingResourceQueueDAO);
|
||||
}
|
||||
|
||||
private LimitingResourceQueueElement createValidLimitingResourceQueueElement() {
|
||||
return LimitingResourceQueueElement.create();
|
||||
}
|
||||
|
||||
private LimitingResourceQueue createValidLimitingResourceQueue() {
|
||||
return LimitingResourceQueue.create();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSaveLimitingResourceQueue() {
|
||||
LimitingResourceQueue limitingResourceQueue = createValidLimitingResourceQueue();
|
||||
limitingResourceQueueDAO.save(limitingResourceQueue);
|
||||
assertTrue(limitingResourceQueueDAO.exists(limitingResourceQueue.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveLimitingResourceQueue() throws InstanceNotFoundException {
|
||||
LimitingResourceQueue limitingResourceQueue = createValidLimitingResourceQueue();
|
||||
limitingResourceQueueDAO.save(limitingResourceQueue);
|
||||
limitingResourceQueueDAO.remove(limitingResourceQueue.getId());
|
||||
assertFalse(limitingResourceQueueDAO.exists(limitingResourceQueue.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListLimitingResourceQueue() {
|
||||
int previous = limitingResourceQueueDAO.list(LimitingResourceQueue.class).size();
|
||||
|
||||
LimitingResourceQueue limitingResourceQueue1 = createValidLimitingResourceQueue();
|
||||
limitingResourceQueueDAO.save(limitingResourceQueue1);
|
||||
LimitingResourceQueue limitingResourceQueue2 = createValidLimitingResourceQueue();
|
||||
limitingResourceQueueDAO.save(limitingResourceQueue1);
|
||||
limitingResourceQueueDAO.save(limitingResourceQueue2);
|
||||
|
||||
List<LimitingResourceQueue> list = limitingResourceQueueDAO
|
||||
.list(LimitingResourceQueue.class);
|
||||
assertEquals(previous + 2, list.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLimitingResourceQueueHasElements() {
|
||||
LimitingResourceQueueElement element = createValidLimitingResourceQueueElement();
|
||||
LimitingResourceQueue queue = createValidLimitingResourceQueue();
|
||||
queue.addLimitingResourceQueueElement(element);
|
||||
limitingResourceQueueDAO.save(queue);
|
||||
assertTrue(!limitingResourceQueueElementDAO.getAssigned().isEmpty());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,27 +28,43 @@ import static org.hamcrest.CoreMatchers.equalTo;
|
|||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE;
|
||||
import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.navalplanner.business.orders.entities.HoursGroup;
|
||||
import org.navalplanner.business.orders.entities.Order;
|
||||
import org.navalplanner.business.orders.entities.OrderLine;
|
||||
import org.navalplanner.business.orders.entities.SchedulingDataForVersion;
|
||||
import org.navalplanner.business.orders.entities.TaskSource;
|
||||
import org.navalplanner.business.planner.daos.ITaskElementDAO;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.planner.entities.SpecificResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.Task;
|
||||
import org.navalplanner.business.planner.entities.TaskElement;
|
||||
import org.navalplanner.business.scenarios.entities.OrderVersion;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE,
|
||||
BUSINESS_SPRING_CONFIG_TEST_FILE })
|
||||
@Transactional
|
||||
public class TaskTest {
|
||||
|
||||
@Autowired
|
||||
private ITaskElementDAO taskElementDAO;
|
||||
|
||||
private static final OrderVersion mockedOrderVersion = mockOrderVersion();
|
||||
|
||||
public static final OrderVersion mockOrderVersion() {
|
||||
|
|
@ -58,6 +74,7 @@ public class TaskTest {
|
|||
}
|
||||
|
||||
private Task task;
|
||||
|
||||
private HoursGroup hoursGroup;
|
||||
|
||||
public TaskTest() {
|
||||
|
|
@ -165,6 +182,11 @@ public class TaskTest {
|
|||
assertThat(task.getDaysDuration(), equalTo(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param task
|
||||
* @param hours
|
||||
* @return
|
||||
*/
|
||||
private SpecificResourceAllocation stubResourceAllocationWithAssignedHours(
|
||||
Task task,
|
||||
int hours) {
|
||||
|
|
@ -180,4 +202,26 @@ public class TaskTest {
|
|||
return resourceAllocation;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsLimiting() {
|
||||
LimitingResourceQueueElement element = LimitingResourceQueueElement.create();
|
||||
Task task = createValidTask();
|
||||
SpecificResourceAllocation resourceAllocation = SpecificResourceAllocation.create(task);
|
||||
resourceAllocation.setLimitingResourceQueueElement(element);
|
||||
task.addResourceAllocation(resourceAllocation);
|
||||
taskElementDAO.save(task);
|
||||
|
||||
assertTrue(task.getLimitingResourceAllocations().size() == 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNonLimiting() {
|
||||
Task task = createValidTask();
|
||||
SpecificResourceAllocation resourceAllocation = SpecificResourceAllocation.create(task);
|
||||
task.addResourceAllocation(resourceAllocation);
|
||||
taskElementDAO.save(task);
|
||||
|
||||
assertTrue(task.getNonLimitingResourceAllocations().size() == 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -84,6 +84,9 @@
|
|||
<value>
|
||||
org/navalplanner/business/externalcompanies/entities/ExternalCompanies.hbm.xml
|
||||
</value>
|
||||
<value>
|
||||
org/navalplanner/business/planner/entities/AdvanceConsolidations.hbm.xml
|
||||
</value>
|
||||
<value>
|
||||
org/navalplanner/business/scenarios/entities/Scenarios.hbm.xml
|
||||
</value>
|
||||
|
|
|
|||
|
|
@ -196,19 +196,6 @@ public abstract class BaseCalendarEditionController extends
|
|||
return baseCalendarModel.isDerived();
|
||||
}
|
||||
|
||||
public boolean isDateValidFromPast() {
|
||||
if (!isEditing()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Date dateValidFrom = baseCalendarModel.getDateValidFrom();
|
||||
if (dateValidFrom != null) {
|
||||
return isPast(dateValidFrom);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isPast(Date date) {
|
||||
LocalDate localDate = new LocalDate(date);
|
||||
LocalDate currentLocalDate = new LocalDate();
|
||||
|
|
@ -262,9 +249,7 @@ public abstract class BaseCalendarEditionController extends
|
|||
|
||||
});
|
||||
|
||||
if (isDateValidFromPast()) {
|
||||
hoursIntbox.setDisabled(true);
|
||||
} else if (baseCalendarModel.isDerived()
|
||||
if (baseCalendarModel.isDerived()
|
||||
&& baseCalendarModel.isDefault(day)) {
|
||||
hoursIntbox.setDisabled(true);
|
||||
}
|
||||
|
|
@ -302,10 +287,6 @@ public abstract class BaseCalendarEditionController extends
|
|||
|
||||
});
|
||||
|
||||
if (isDateValidFromPast()) {
|
||||
defaultCheckbox.setDisabled(true);
|
||||
}
|
||||
|
||||
defaultListcell.appendChild(defaultCheckbox);
|
||||
item.appendChild(defaultListcell);
|
||||
}
|
||||
|
|
@ -474,19 +455,6 @@ public abstract class BaseCalendarEditionController extends
|
|||
return baseCalendarModel.getHoursOfDay();
|
||||
}
|
||||
|
||||
public boolean isSelectedDateFromPast() {
|
||||
Date selectedDay = baseCalendarModel.getSelectedDay();
|
||||
if (selectedDay != null) {
|
||||
return isPast(selectedDay);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isNotSelectedDateFromPast() {
|
||||
return !isSelectedDateFromPast();
|
||||
}
|
||||
|
||||
public void createException() {
|
||||
Combobox exceptionTypes = (Combobox) window.getFellow("exceptionTypes");
|
||||
CalendarExceptionType type = (CalendarExceptionType) exceptionTypes
|
||||
|
|
@ -515,13 +483,6 @@ public abstract class BaseCalendarEditionController extends
|
|||
} else {
|
||||
Clients.closeErrorBox(dateboxEndDate);
|
||||
}
|
||||
if (startDate.compareTo(new Date()) <= 0) {
|
||||
throw new WrongValueException(
|
||||
dateboxStartDate,
|
||||
_("Exception start date should be greater than current date"));
|
||||
} else {
|
||||
Clients.closeErrorBox(dateboxStartDate);
|
||||
}
|
||||
if (startDate.compareTo(endDate) > 0) {
|
||||
throw new WrongValueException(
|
||||
dateboxEndDate,
|
||||
|
|
@ -694,9 +655,7 @@ public abstract class BaseCalendarEditionController extends
|
|||
LocalDate validFrom = baseCalendarModel.getValidFrom(calendarData);
|
||||
if ((validFrom == null)
|
||||
|| (!baseCalendarModel.getLastCalendarData().equals(
|
||||
calendarData))
|
||||
|| (validFrom.compareTo(
|
||||
new LocalDate()) <= 0)) {
|
||||
calendarData))) {
|
||||
result.setDisabled(true);
|
||||
}
|
||||
return result;
|
||||
|
|
@ -743,6 +702,10 @@ public abstract class BaseCalendarEditionController extends
|
|||
return baseCalendarModel.isLastVersion();
|
||||
}
|
||||
|
||||
public boolean isFirstVersion() {
|
||||
return baseCalendarModel.isFirstVersion();
|
||||
}
|
||||
|
||||
public void goToDate(Date date) {
|
||||
setSelectedDay(date);
|
||||
|
||||
|
|
@ -903,9 +866,6 @@ public abstract class BaseCalendarEditionController extends
|
|||
reloadDayInformation();
|
||||
}
|
||||
});
|
||||
if (isSelectedDateFromPast()) {
|
||||
result.setDisabled(true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -956,13 +916,6 @@ public abstract class BaseCalendarEditionController extends
|
|||
} else {
|
||||
Clients.closeErrorBox(dateboxEndDate);
|
||||
}
|
||||
if (startDate.compareTo(new Date()) <= 0) {
|
||||
throw new WrongValueException(
|
||||
dateboxStartDate,
|
||||
_("Exception start date should be greater than current date"));
|
||||
} else {
|
||||
Clients.closeErrorBox(dateboxStartDate);
|
||||
}
|
||||
if (startDate.compareTo(endDate) > 0) {
|
||||
throw new WrongValueException(
|
||||
dateboxEndDate,
|
||||
|
|
|
|||
|
|
@ -432,6 +432,14 @@ public class BaseCalendarModel implements IBaseCalendarModel {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFirstVersion() {
|
||||
if (getBaseCalendar() != null) {
|
||||
return getBaseCalendar().isFirstVersion(selectedDate);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (getBaseCalendar() != null) {
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@ import org.zkoss.zul.SimpleTreeNode;
|
|||
*/
|
||||
public class BaseCalendarsTreeModel extends SimpleTreeModel {
|
||||
|
||||
private static Map<BaseCalendar, List<BaseCalendar>> relationParentChildren = new HashMap<BaseCalendar, List<BaseCalendar>>();
|
||||
|
||||
public BaseCalendarsTreeModel(BaseCalendarTreeRoot root) {
|
||||
super(createRootNodeAndDescendants(root, root.getRootCalendars(), root
|
||||
.getDerivedCalendars()));
|
||||
|
|
@ -47,65 +45,55 @@ public class BaseCalendarsTreeModel extends SimpleTreeModel {
|
|||
BaseCalendarTreeRoot root, List<BaseCalendar> rootCalendars,
|
||||
List<BaseCalendar> derivedCalendars) {
|
||||
|
||||
fillHashParentChildren(rootCalendars, derivedCalendars);
|
||||
|
||||
return new SimpleTreeNode(root, asNodes(rootCalendars));
|
||||
Map<BaseCalendar, List<BaseCalendar>> parentChildren = createRelationParentChildren(
|
||||
rootCalendars, derivedCalendars);
|
||||
return new SimpleTreeNode(root, asNodes(parentChildren, rootCalendars));
|
||||
}
|
||||
|
||||
private static List<SimpleTreeNode> asNodes(List<BaseCalendar> baseCalendars) {
|
||||
private static List<SimpleTreeNode> asNodes(
|
||||
Map<BaseCalendar, List<BaseCalendar>> relationParentChildren,
|
||||
List<BaseCalendar> baseCalendars) {
|
||||
if (baseCalendars == null) {
|
||||
return new ArrayList<SimpleTreeNode>();
|
||||
}
|
||||
|
||||
ArrayList<SimpleTreeNode> result = new ArrayList<SimpleTreeNode>();
|
||||
for (BaseCalendar baseCalendar : baseCalendars) {
|
||||
result.add(asNode(baseCalendar));
|
||||
result.add(asNode(relationParentChildren, baseCalendar));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static SimpleTreeNode asNode(BaseCalendar baseCalendar) {
|
||||
private static SimpleTreeNode asNode(
|
||||
Map<BaseCalendar, List<BaseCalendar>> relationParentChildren,
|
||||
BaseCalendar baseCalendar) {
|
||||
List<BaseCalendar> children = relationParentChildren.get(baseCalendar);
|
||||
return new SimpleTreeNode(baseCalendar, asNodes(children));
|
||||
return new SimpleTreeNode(baseCalendar, asNodes(relationParentChildren,
|
||||
children));
|
||||
}
|
||||
|
||||
private static void fillHashParentChildren(
|
||||
private static Map<BaseCalendar, List<BaseCalendar>> createRelationParentChildren(
|
||||
List<BaseCalendar> rootCalendars,
|
||||
List<BaseCalendar> derivedCalendars) {
|
||||
Map<BaseCalendar, List<BaseCalendar>> result = new HashMap<BaseCalendar, List<BaseCalendar>>();
|
||||
for (BaseCalendar root : rootCalendars) {
|
||||
relationParentChildren.put(root, new ArrayList<BaseCalendar>());
|
||||
result.put(root, new ArrayList<BaseCalendar>());
|
||||
}
|
||||
|
||||
for (BaseCalendar derived : derivedCalendars) {
|
||||
BaseCalendar parent = derived.getParent();
|
||||
List<BaseCalendar> siblings = relationParentChildren.get(parent);
|
||||
List<BaseCalendar> siblings = result.get(parent);
|
||||
|
||||
if (siblings == null) {
|
||||
siblings = new ArrayList<BaseCalendar>();
|
||||
siblings.add(derived);
|
||||
relationParentChildren.put(parent, siblings);
|
||||
result.put(parent, siblings);
|
||||
} else {
|
||||
siblings.add(derived);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf(Object node) {
|
||||
if (node == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SimpleTreeNode simpleTreeNode = (SimpleTreeNode) node;
|
||||
BaseCalendar baseCalendar = (BaseCalendar) simpleTreeNode.getData();
|
||||
|
||||
List<BaseCalendar> children = relationParentChildren.get(baseCalendar);
|
||||
if (children == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return children.isEmpty();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ public interface IBaseCalendarModel {
|
|||
|
||||
boolean isLastVersion();
|
||||
|
||||
boolean isFirstVersion();
|
||||
|
||||
String getName();
|
||||
|
||||
LocalDate getValidFrom(CalendarData calendarData);
|
||||
|
|
|
|||
|
|
@ -346,4 +346,24 @@ public class ConfigurationController extends GenericForwardComposer {
|
|||
|
||||
}
|
||||
|
||||
public void setExpandCompanyPlanningViewCharts(
|
||||
Boolean expandCompanyPlanningViewCharts) {
|
||||
configurationModel
|
||||
.setExpandCompanyPlanningViewCharts(expandCompanyPlanningViewCharts);
|
||||
}
|
||||
|
||||
public Boolean isExpandCompanyPlanningViewCharts() {
|
||||
return configurationModel.isExpandCompanyPlanningViewCharts();
|
||||
}
|
||||
|
||||
public void setExpandOrderPlanningViewCharts(
|
||||
Boolean expandOrderPlanningViewCharts) {
|
||||
configurationModel
|
||||
.setExpandOrderPlanningViewCharts(expandOrderPlanningViewCharts);
|
||||
}
|
||||
|
||||
public Boolean isExpandOrderPlanningViewCharts() {
|
||||
return configurationModel.isExpandOrderPlanningViewCharts();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -339,4 +339,38 @@ public class ConfigurationModel implements IConfigurationModel {
|
|||
orderSequences.remove(orderSequence);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpandCompanyPlanningViewCharts(
|
||||
Boolean expandCompanyPlanningViewCharts) {
|
||||
if (configuration != null) {
|
||||
configuration
|
||||
.setExpandCompanyPlanningViewCharts(expandCompanyPlanningViewCharts);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isExpandCompanyPlanningViewCharts() {
|
||||
if (configuration == null) {
|
||||
return null;
|
||||
}
|
||||
return configuration.isExpandCompanyPlanningViewCharts();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExpandOrderPlanningViewCharts(
|
||||
Boolean expandOrderPlanningViewCharts) {
|
||||
if (configuration != null) {
|
||||
configuration
|
||||
.setExpandOrderPlanningViewCharts(expandOrderPlanningViewCharts);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean isExpandOrderPlanningViewCharts() {
|
||||
if (configuration == null) {
|
||||
return null;
|
||||
}
|
||||
return configuration.isExpandOrderPlanningViewCharts();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -197,11 +197,12 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
|
|||
subItem(_("Company view"), "/planner/index.zul;company_scheduling","01-introducion.html"),
|
||||
subItem(_("General resource allocation"),"/planner/index.zul;company_load","01-introducion.html#id1"),
|
||||
subItem(_("Orders list"), "/planner/index.zul;orders_list","01-introducion.html#id2"),
|
||||
// FIX: Temporary hidden in main menu
|
||||
// subItem(_("Limiting resources"),"/planner/index.zul;limiting_resources","01-introducion.html"),
|
||||
subItem(_("Templates list"), "/templates/templates.zul", ""),
|
||||
subItem(_("Subcontracted tasks list"), "/subcontract/subcontractedTasks.zul", ""),
|
||||
subItem(_("Report advances"), "/subcontract/reportAdvances.zul", ""),
|
||||
subItem(_("Transfer orders between scenarios"), "/scenarios/transferOrders.zul", ""));
|
||||
|
||||
topItem(_("Resources"), "/resources/worker/worker.zul", "",
|
||||
subItem(_("Workers List"), "/resources/worker/worker.zul","05-recursos.html#xesti-n-de-traballadores"),
|
||||
subItem(_("Machines List"), "/resources/machine/machines.zul","05-recursos.html#xesti-n-de-m-quinas"),
|
||||
|
|
|
|||
|
|
@ -76,6 +76,15 @@ public interface IConfigurationModel {
|
|||
void removeOrderSequence(OrderSequence orderSequence)
|
||||
throws IllegalArgumentException;
|
||||
|
||||
void setExpandCompanyPlanningViewCharts(
|
||||
Boolean expandCompanyPlanningViewCharts);
|
||||
|
||||
Boolean isExpandCompanyPlanningViewCharts();
|
||||
|
||||
void setExpandOrderPlanningViewCharts(Boolean expandOrderPlanningViewCharts);
|
||||
|
||||
Boolean isExpandOrderPlanningViewCharts();
|
||||
|
||||
/*
|
||||
* Final conversation steps
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import static org.navalplanner.web.I18nHelper._;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
|
@ -134,10 +135,13 @@ public class BandboxMultipleSearch extends HtmlMacroComponent {
|
|||
}
|
||||
|
||||
private void pickElementFromListAndCloseBandbox() {
|
||||
final Object object = getSelectedItem().getValue();
|
||||
if (multipleFiltersFinder.isValidNewFilter(object)) {
|
||||
addSelectedElement(object);
|
||||
clearListbox();
|
||||
if(getSelectedItem() != null) {
|
||||
final Object object = getSelectedItem().getValue();
|
||||
if (multipleFiltersFinder.isValidNewFilter(object)) {
|
||||
addSelectedElement(object);
|
||||
clearListbox();
|
||||
listbox.setModel(getSubModel());
|
||||
}
|
||||
}
|
||||
bandbox.close();
|
||||
}
|
||||
|
|
@ -238,7 +242,12 @@ public class BandboxMultipleSearch extends HtmlMacroComponent {
|
|||
}
|
||||
|
||||
private Listitem getSelectedItem() {
|
||||
return (Listitem) listbox.getSelectedItems().iterator().next();
|
||||
try {
|
||||
return (Listitem) listbox.getSelectedItems().iterator().next();
|
||||
}
|
||||
catch (NoSuchElementException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setDisabled(boolean disabled) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.common.components.finders;
|
||||
|
||||
import static org.navalplanner.web.I18nHelper._;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.navalplanner.business.common.IOnTransaction;
|
||||
import org.navalplanner.business.resources.daos.ICriterionDAO;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public class CriterionMultipleFiltersFinder extends MultipleFiltersFinder {
|
||||
|
||||
@Autowired
|
||||
private ICriterionDAO criterionDAO;
|
||||
|
||||
private static final List<Criterion> criterionList = new ArrayList<Criterion>();
|
||||
|
||||
private IFilterEnum criterionFilterEnum = new IFilterEnum() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return _("criterion");
|
||||
}
|
||||
};
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public void init() {
|
||||
getAdHocTransactionService()
|
||||
.runOnReadOnlyTransaction(new IOnTransaction<Void>() {
|
||||
@Override
|
||||
public Void execute() {
|
||||
loadCriteria();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
private void loadCriteria() {
|
||||
criterionList.clear();
|
||||
criterionList.addAll(criterionDAO.getAll());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FilterPair> getFirstTenFilters() {
|
||||
Iterator<Criterion> iteratorCriterion = criterionList.iterator();
|
||||
while(iteratorCriterion.hasNext() && getListMatching().size() < 10) {
|
||||
Criterion criterion = iteratorCriterion.next();
|
||||
getListMatching().add(new FilterPair(
|
||||
criterionFilterEnum, criterion.getName(), criterion));
|
||||
}
|
||||
return getListMatching();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FilterPair> getMatching(String filter) {
|
||||
getListMatching().clear();
|
||||
if ((filter != null) && (!filter.isEmpty())) {
|
||||
filter = StringUtils.deleteWhitespace(filter.toLowerCase());
|
||||
searchInCriteria(filter);
|
||||
}
|
||||
addNoneFilter();
|
||||
return getListMatching();
|
||||
|
||||
}
|
||||
private void searchInCriteria(String filter) {
|
||||
for(Criterion criterion : criterionList) {
|
||||
String name = StringUtils.deleteWhitespace(
|
||||
criterion.getName().toLowerCase());
|
||||
if(name.contains(filter)) {
|
||||
getListMatching().add(new FilterPair(
|
||||
criterionFilterEnum, criterion.getName(), criterion));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addNoneFilter() {
|
||||
getListMatching().add(
|
||||
new FilterPair(OrderElementFilterEnum.None,
|
||||
OrderElementFilterEnum.None.toString(), null));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.common.components.finders;
|
||||
|
||||
import static org.navalplanner.web.I18nHelper._;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.navalplanner.business.common.IOnTransaction;
|
||||
import org.navalplanner.business.resources.daos.IWorkerDAO;
|
||||
import org.navalplanner.business.resources.entities.Worker;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
public class WorkerMultipleFiltersFinder extends MultipleFiltersFinder {
|
||||
|
||||
@Autowired
|
||||
private IWorkerDAO workerDAO;
|
||||
|
||||
private static final List<Worker> workerList = new ArrayList<Worker>();
|
||||
|
||||
private IFilterEnum workerFilterEnum = new IFilterEnum() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return _("worker");
|
||||
}
|
||||
};
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public void init() {
|
||||
getAdHocTransactionService()
|
||||
.runOnReadOnlyTransaction(new IOnTransaction<Void>() {
|
||||
@Override
|
||||
public Void execute() {
|
||||
loadWorkers();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
private void loadWorkers() {
|
||||
workerList.clear();
|
||||
workerList.addAll(workerDAO.getAll());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FilterPair> getFirstTenFilters() {
|
||||
Iterator<Worker> iteratorWorker = workerList.iterator();
|
||||
while(iteratorWorker.hasNext() && getListMatching().size() < 10) {
|
||||
Worker worker = iteratorWorker.next();
|
||||
getListMatching().add(new FilterPair(
|
||||
workerFilterEnum, worker.getShortDescription(), worker));
|
||||
}
|
||||
return getListMatching();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FilterPair> getMatching(String filter) {
|
||||
getListMatching().clear();
|
||||
if ((filter != null) && (!filter.isEmpty())) {
|
||||
filter = StringUtils.deleteWhitespace(filter.toLowerCase());
|
||||
searchInWorkers(filter);
|
||||
}
|
||||
addNoneFilter();
|
||||
return getListMatching();
|
||||
|
||||
}
|
||||
private void searchInWorkers(String filter) {
|
||||
boolean limited = (filter.length() < 3);
|
||||
for(Worker worker : workerList) {
|
||||
String name = StringUtils.deleteWhitespace(
|
||||
worker.getShortDescription().toLowerCase());
|
||||
if(name.contains(filter)) {
|
||||
getListMatching().add(new FilterPair(
|
||||
workerFilterEnum, worker.getShortDescription(), worker));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addNoneFilter() {
|
||||
getListMatching().add(
|
||||
new FilterPair(OrderElementFilterEnum.None,
|
||||
OrderElementFilterEnum.None.toString(), null));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.limitingresources;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.orders.entities.Order;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.planner.entities.TaskElement;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
|
||||
import org.zkoss.ganttz.util.Interval;
|
||||
|
||||
public interface ILimitingResourceQueueModel {
|
||||
|
||||
void initGlobalView(boolean filterByResources);
|
||||
|
||||
void initGlobalView(Order filterBy, boolean filterByResources);
|
||||
|
||||
List<LimitingResourceQueue> getLimitingResourceQueues();
|
||||
|
||||
Interval getViewInterval();
|
||||
|
||||
ZoomLevel calculateInitialZoomLevel();
|
||||
|
||||
Order getOrderByTask(TaskElement task);
|
||||
|
||||
boolean userCanRead(Order order, String loginName);
|
||||
|
||||
List<LimitingResourceQueueElement> getUnassignedLimitingResourceQueueElements();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.limitingresources;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.zkoss.ganttz.TaskComponent;
|
||||
import org.zkoss.ganttz.data.Dependency;
|
||||
import org.zkoss.ganttz.data.DependencyType;
|
||||
import org.zkoss.ganttz.data.Task;
|
||||
import org.zkoss.ganttz.data.constraint.Constraint;
|
||||
import org.zkoss.ganttz.data.constraint.Constraint.IConstraintViolationListener;
|
||||
import org.zkoss.zk.au.out.AuInvoke;
|
||||
import org.zkoss.zk.ui.ext.AfterCompose;
|
||||
import org.zkoss.zul.Div;
|
||||
import org.zkoss.zul.impl.XulElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Francisco Javier Moran Rúa <jmoran@igalia.com>
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
public class LimitingDependencyComponent extends XulElement implements
|
||||
AfterCompose {
|
||||
|
||||
private Div source;
|
||||
|
||||
private Div destination;
|
||||
|
||||
private DependencyType type;
|
||||
|
||||
// private Dependency dependency;
|
||||
|
||||
private IConstraintViolationListener<Date> violationListener;
|
||||
|
||||
public LimitingDependencyComponent(Div source, Div destination) {
|
||||
Validate.notNull(source);
|
||||
Validate.notNull(destination);
|
||||
// Validate.isTrue(source.getTask() == dependency.getSource());
|
||||
// Validate.isTrue(destination.getTask() ==
|
||||
// dependency.getDestination());
|
||||
// this.type = dependency.getType();
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
// this.dependency = dependency;
|
||||
violationListener = new IConstraintViolationListener<Date>() {
|
||||
|
||||
@Override
|
||||
public void constraintViolated(Constraint<Date> constraint,
|
||||
Date value) {
|
||||
// TODO mark graphically dependency as violated
|
||||
}
|
||||
};
|
||||
// this.dependency.addConstraintViolationListener(violationListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompose() {
|
||||
PropertyChangeListener listener = new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
redrawDependency();
|
||||
}
|
||||
};
|
||||
// this.source.getTask().addFundamentalPropertiesChangeListener(listener);
|
||||
// this.destination.getTask().addFundamentalPropertiesChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the idTaskOrig
|
||||
*/
|
||||
public String getIdTaskOrig() {
|
||||
return source.getUuid();
|
||||
}
|
||||
|
||||
public void setIdTaskOrig(String idTaskOrig) {
|
||||
this.source = findTaskComponent(idTaskOrig);
|
||||
|
||||
}
|
||||
|
||||
private TaskComponent findTaskComponent(String idTaskOrig) {
|
||||
return (TaskComponent) getFellow(idTaskOrig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the idTaskEnd
|
||||
*/
|
||||
public String getIdTaskEnd() {
|
||||
return destination.getUuid();
|
||||
}
|
||||
|
||||
public void setIdTaskEnd(String idTaskEnd) {
|
||||
this.destination = findTaskComponent(idTaskEnd);
|
||||
}
|
||||
|
||||
public void zoomChanged() {
|
||||
redrawDependency();
|
||||
}
|
||||
|
||||
public void redrawDependency() {
|
||||
response("zoomChanged", new AuInvoke(this, "draw"));
|
||||
}
|
||||
|
||||
public boolean contains(Task task) {
|
||||
return false;
|
||||
// Task sourceTask = getSource().getTask();
|
||||
// Task destinationTask = getDestination().getTask();
|
||||
// return task.equals(sourceTask) || task.equals(destinationTask);
|
||||
}
|
||||
|
||||
public Div getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public Div getDestination() {
|
||||
return destination;
|
||||
}
|
||||
|
||||
// public Dependency getDependency() {
|
||||
// return dependency;
|
||||
// }
|
||||
|
||||
public DependencyType getDependencyType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public boolean hasSameSourceAndDestination(Dependency dependency) {
|
||||
return false;
|
||||
// Task sourceTask = source.getTask();
|
||||
// Task destinationTask = destination.getTask();
|
||||
// return sourceTask.equals(dependency.getSource())
|
||||
// && destinationTask.equals(dependency.getDestination());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.limitingresources;
|
||||
|
||||
import static org.zkoss.ganttz.i18n.I18nHelper._;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.zkoss.ganttz.DependencyList;
|
||||
import org.zkoss.ganttz.FunctionalityExposedForExtensions;
|
||||
import org.zkoss.ganttz.GanttPanel;
|
||||
import org.zkoss.ganttz.TaskComponent;
|
||||
import org.zkoss.ganttz.data.Dependency;
|
||||
import org.zkoss.ganttz.data.DependencyType;
|
||||
import org.zkoss.ganttz.data.Task;
|
||||
import org.zkoss.ganttz.timetracker.TimeTracker;
|
||||
import org.zkoss.ganttz.timetracker.TimeTrackerComponent;
|
||||
import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener;
|
||||
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
|
||||
import org.zkoss.ganttz.util.ComponentsFinder;
|
||||
import org.zkoss.ganttz.util.MenuBuilder;
|
||||
import org.zkoss.ganttz.util.MenuBuilder.ItemAction;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.ext.AfterCompose;
|
||||
import org.zkoss.zul.Div;
|
||||
import org.zkoss.zul.Menupopup;
|
||||
import org.zkoss.zul.impl.XulElement;
|
||||
|
||||
/**
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
public class LimitingDependencyList extends XulElement implements AfterCompose {
|
||||
|
||||
private final class ChangeTypeAction implements
|
||||
ItemAction<LimitingDependencyComponent> {
|
||||
private final DependencyType type;
|
||||
|
||||
private ChangeTypeAction(DependencyType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(final LimitingDependencyComponent choosen,
|
||||
Event event) {
|
||||
// context.changeType(choosen.getDependency(), type);
|
||||
}
|
||||
}
|
||||
|
||||
private final class DependencyVisibilityToggler implements
|
||||
PropertyChangeListener {
|
||||
private final Task source;
|
||||
private final Task destination;
|
||||
private final LimitingDependencyComponent dependencyComponent;
|
||||
|
||||
private DependencyVisibilityToggler(Task source, Task destination,
|
||||
LimitingDependencyComponent dependencyComponent) {
|
||||
this.source = source;
|
||||
this.destination = destination;
|
||||
this.dependencyComponent = dependencyComponent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (!evt.getPropertyName().equals("visible")) {
|
||||
return;
|
||||
}
|
||||
if (dependencyMustBeVisible() != isDependencyNowVisible()) {
|
||||
toggleDependencyExistence(dependencyMustBeVisible());
|
||||
}
|
||||
}
|
||||
|
||||
void toggleDependencyExistence(boolean visible) {
|
||||
if (visible) {
|
||||
appendChild(dependencyComponent);
|
||||
addContextMenu(dependencyComponent);
|
||||
} else {
|
||||
removeChild(dependencyComponent);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isDependencyNowVisible() {
|
||||
return dependencyComponent.getParent() != null;
|
||||
}
|
||||
|
||||
boolean dependencyMustBeVisible() {
|
||||
return source.isVisible() && destination.isVisible();
|
||||
}
|
||||
}
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(DependencyList.class);
|
||||
|
||||
private transient IZoomLevelChangedListener listener;
|
||||
|
||||
private final FunctionalityExposedForExtensions<?> context;
|
||||
|
||||
public LimitingDependencyList(FunctionalityExposedForExtensions<?> context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private List<LimitingDependencyComponent> getLimitingDependencyComponents() {
|
||||
List<Object> children = getChildren();
|
||||
return ComponentsFinder.findComponentsOfType(
|
||||
LimitingDependencyComponent.class, children);
|
||||
}
|
||||
|
||||
void addDependencyComponent(
|
||||
final LimitingDependencyComponent dependencyComponent) {
|
||||
Div source = dependencyComponent.getSource();
|
||||
Div destination = dependencyComponent.getDestination();
|
||||
// DependencyVisibilityToggler visibilityToggler = new
|
||||
// DependencyVisibilityToggler(
|
||||
// source.getTask(), destination.getTask(), dependencyComponent);
|
||||
// source.getTask().addVisibilityPropertiesChangeListener(
|
||||
// visibilityToggler);
|
||||
// destination.getTask().addVisibilityPropertiesChangeListener(
|
||||
// visibilityToggler);
|
||||
// boolean dependencyMustBeVisible = visibilityToggler
|
||||
// .dependencyMustBeVisible();
|
||||
// visibilityToggler.toggleDependencyExistence(dependencyMustBeVisible);
|
||||
// if (dependencyMustBeVisible) {
|
||||
// dependencyComponent.redrawDependency();
|
||||
// }
|
||||
}
|
||||
|
||||
private void addContextMenu(LimitingDependencyComponent dependencyComponent) {
|
||||
dependencyComponent.setContext(getContextMenu());
|
||||
}
|
||||
|
||||
private GanttPanel getGanttPanel() {
|
||||
return (GanttPanel) getParent();
|
||||
}
|
||||
|
||||
public void setDependencyComponents(
|
||||
List<LimitingDependencyComponent> dependencyComponents) {
|
||||
for (LimitingDependencyComponent dependencyComponent : dependencyComponents) {
|
||||
addDependencyComponent(dependencyComponent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompose() {
|
||||
if (listener == null) {
|
||||
listener = new IZoomLevelChangedListener() {
|
||||
@Override
|
||||
public void zoomLevelChanged(ZoomLevel detailLevel) {
|
||||
if (!isInPage()) {
|
||||
return;
|
||||
}
|
||||
for (LimitingDependencyComponent dependencyComponent : getLimitingDependencyComponents()) {
|
||||
dependencyComponent.zoomChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
// getTimeTracker().addZoomListener(listener);
|
||||
}
|
||||
// addContextMenu();
|
||||
}
|
||||
|
||||
private boolean isInPage() {
|
||||
return getParent() != null && getGanttPanel() != null
|
||||
&& getGanttPanel().getParent() != null;
|
||||
}
|
||||
|
||||
private TimeTracker getTimeTracker() {
|
||||
return getTimeTrackerComponent().getTimeTracker();
|
||||
}
|
||||
|
||||
private void addContextMenu() {
|
||||
for (LimitingDependencyComponent dependencyComponent : getLimitingDependencyComponents()) {
|
||||
addContextMenu(dependencyComponent);
|
||||
}
|
||||
}
|
||||
|
||||
private Menupopup contextMenu;
|
||||
|
||||
private Menupopup getContextMenu() {
|
||||
if (contextMenu == null) {
|
||||
MenuBuilder<LimitingDependencyComponent> contextMenuBuilder = MenuBuilder
|
||||
.on(getPage(), getLimitingDependencyComponents()).item(_("Erase"),
|
||||
"/common/img/ico_borrar.png",
|
||||
new ItemAction<LimitingDependencyComponent>() {
|
||||
@Override
|
||||
public void onEvent(
|
||||
final LimitingDependencyComponent choosen,
|
||||
Event event) {
|
||||
// context
|
||||
// .removeDependency(choosen.getDependency());
|
||||
}
|
||||
});
|
||||
contextMenuBuilder.item(_("Set End-Start"), null,
|
||||
new ChangeTypeAction(
|
||||
DependencyType.END_START));
|
||||
|
||||
contextMenuBuilder.item(_("Set Start-Start"), null,
|
||||
new ChangeTypeAction(
|
||||
DependencyType.START_START));
|
||||
|
||||
contextMenuBuilder.item(_("Set End-End"), null,
|
||||
new ChangeTypeAction(
|
||||
DependencyType.END_END));
|
||||
|
||||
contextMenu = contextMenuBuilder.create();
|
||||
|
||||
}
|
||||
return contextMenu;
|
||||
}
|
||||
|
||||
private TimeTrackerComponent getTimeTrackerComponent() {
|
||||
return getGanttPanel().getTimeTrackerComponent();
|
||||
}
|
||||
|
||||
public void redrawDependenciesConnectedTo(TaskComponent taskComponent) {
|
||||
redrawDependencyComponents(getDependencyComponentsConnectedTo(taskComponent));
|
||||
}
|
||||
|
||||
private List<LimitingDependencyComponent> getDependencyComponentsConnectedTo(
|
||||
TaskComponent taskComponent) {
|
||||
ArrayList<LimitingDependencyComponent> result = new ArrayList<LimitingDependencyComponent>();
|
||||
List<LimitingDependencyComponent> dependencies = getLimitingDependencyComponents();
|
||||
for (LimitingDependencyComponent dependencyComponent : dependencies) {
|
||||
if (dependencyComponent.getSource().equals(taskComponent)
|
||||
|| dependencyComponent.getDestination().equals(
|
||||
taskComponent)) {
|
||||
result.add(dependencyComponent);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void redrawDependencies() {
|
||||
redrawDependencyComponents(getLimitingDependencyComponents());
|
||||
}
|
||||
|
||||
public void redrawDependencyComponents(
|
||||
List<LimitingDependencyComponent> dependencyComponents) {
|
||||
for (LimitingDependencyComponent dependencyComponent : dependencyComponents) {
|
||||
dependencyComponent.redrawDependency();
|
||||
}
|
||||
}
|
||||
|
||||
public void taskRemoved(Task task) {
|
||||
for (LimitingDependencyComponent dependencyComponent : LimitingDependencyList.this
|
||||
.getLimitingDependencyComponents()) {
|
||||
if (dependencyComponent.contains(task)) {
|
||||
this.removeChild(dependencyComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(Dependency dependency) {
|
||||
for (LimitingDependencyComponent dependencyComponent : LimitingDependencyList.this
|
||||
.getLimitingDependencyComponents()) {
|
||||
if (dependencyComponent.hasSameSourceAndDestination(dependency)) {
|
||||
this.removeChild(dependencyComponent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.limitingresources;
|
||||
|
||||
import static org.navalplanner.web.I18nHelper._;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.navalplanner.business.orders.daos.IOrderDAO;
|
||||
import org.navalplanner.business.orders.daos.IOrderElementDAO;
|
||||
import org.navalplanner.business.orders.entities.Order;
|
||||
import org.navalplanner.business.orders.entities.OrderElement;
|
||||
import org.navalplanner.business.planner.daos.ILimitingResourceQueueElementDAO;
|
||||
import org.navalplanner.business.planner.daos.IResourceAllocationDAO;
|
||||
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.Task;
|
||||
import org.navalplanner.business.planner.entities.TaskElement;
|
||||
import org.navalplanner.business.resources.daos.IResourceDAO;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.navalplanner.business.users.daos.IOrderAuthorizationDAO;
|
||||
import org.navalplanner.business.users.daos.IUserDAO;
|
||||
import org.navalplanner.business.users.entities.OrderAuthorization;
|
||||
import org.navalplanner.business.users.entities.OrderAuthorizationType;
|
||||
import org.navalplanner.business.users.entities.User;
|
||||
import org.navalplanner.business.users.entities.UserRole;
|
||||
import org.navalplanner.web.security.SecurityUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.zkoss.ganttz.data.resourceload.TimeLineRole;
|
||||
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
|
||||
import org.zkoss.ganttz.util.Interval;
|
||||
|
||||
@Component
|
||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||
public class LimitingResourceQueueModel implements ILimitingResourceQueueModel {
|
||||
|
||||
@Autowired
|
||||
private IResourceDAO resourcesDAO;
|
||||
|
||||
@Autowired
|
||||
private IOrderElementDAO orderElementDAO;
|
||||
|
||||
@Autowired
|
||||
private IOrderDAO orderDAO;
|
||||
|
||||
@Autowired
|
||||
private IResourceAllocationDAO resourceAllocationDAO;
|
||||
|
||||
@Autowired
|
||||
private IUserDAO userDAO;
|
||||
|
||||
@Autowired
|
||||
private IOrderAuthorizationDAO orderAuthorizationDAO;
|
||||
|
||||
@Autowired
|
||||
private ILimitingResourceQueueElementDAO limitingResourceQueueElementDAO;
|
||||
|
||||
private List<LimitingResourceQueue> limitingResourceQueues = new ArrayList<LimitingResourceQueue>();
|
||||
|
||||
private Interval viewInterval;
|
||||
|
||||
private Order filterBy;
|
||||
|
||||
private boolean filterByResources = true;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void initGlobalView(boolean filterByResources) {
|
||||
filterBy = null;
|
||||
this.filterByResources = filterByResources;
|
||||
doGlobalView();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void initGlobalView(Order filterBy, boolean filterByResources) {
|
||||
this.filterBy = orderDAO.findExistingEntity(filterBy.getId());
|
||||
this.filterByResources = filterByResources;
|
||||
doGlobalView();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Order getOrderByTask(TaskElement task) {
|
||||
return orderElementDAO
|
||||
.loadOrderAvoidingProxyFor(task.getOrderElement());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public boolean userCanRead(Order order, String loginName) {
|
||||
if (SecurityUtils.isUserInRole(UserRole.ROLE_READ_ALL_ORDERS)
|
||||
|| SecurityUtils.isUserInRole(UserRole.ROLE_EDIT_ALL_ORDERS)) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
User user = userDAO.findByLoginName(loginName);
|
||||
for (OrderAuthorization authorization : orderAuthorizationDAO
|
||||
.listByOrderUserAndItsProfiles(order, user)) {
|
||||
if (authorization.getAuthorizationType() == OrderAuthorizationType.READ_AUTHORIZATION
|
||||
|| authorization.getAuthorizationType() == OrderAuthorizationType.WRITE_AUTHORIZATION) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (InstanceNotFoundException e) {
|
||||
// this case shouldn't happen, because it would mean that there
|
||||
// isn't a logged user
|
||||
// anyway, if it happenned we don't allow the user to pass
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void doGlobalView() {
|
||||
limitingResourceQueues = calculateLimitingResourceQueues();
|
||||
if (!limitingResourceQueues.isEmpty()) {
|
||||
// Build interval
|
||||
// viewInterval =
|
||||
// LimitingResourceQueue.getIntervalFrom(limitingResourceQueues);
|
||||
viewInterval = new Interval(new Date(), plusFiveYears(new Date()));
|
||||
} else {
|
||||
viewInterval = new Interval(new Date(), plusFiveYears(new Date()));
|
||||
}
|
||||
}
|
||||
|
||||
private Date plusFiveYears(Date date) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.add(Calendar.YEAR, 5);
|
||||
return calendar.getTime();
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueue> calculateLimitingResourceQueues() {
|
||||
List<LimitingResourceQueue> result = new ArrayList<LimitingResourceQueue>();
|
||||
result.addAll(groupsFor(resourcesToShow()));
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Resource> resourcesToShow() {
|
||||
if (filter()) {
|
||||
return resourcesForActiveTasks();
|
||||
} else {
|
||||
return allLimitingResources();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean filter() {
|
||||
return filterBy != null;
|
||||
}
|
||||
|
||||
private List<Resource> resourcesForActiveTasks() {
|
||||
return Resource.sortByName(resourcesDAO
|
||||
.findResourcesRelatedTo(justTasks(filterBy
|
||||
.getAllChildrenAssociatedTaskElements())));
|
||||
}
|
||||
|
||||
private List<Task> justTasks(Collection<? extends TaskElement> tasks) {
|
||||
List<Task> result = new ArrayList<Task>();
|
||||
for (TaskElement taskElement : tasks) {
|
||||
if (taskElement instanceof Task) {
|
||||
result.add((Task) taskElement);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Resource> allLimitingResources() {
|
||||
List<Resource> result = Resource.sortByName(resourcesDAO
|
||||
.getAllLimitingResources());
|
||||
for (Resource each : result) {
|
||||
each.getLimitingResourceQueue().getLimitingResourceQueueElements()
|
||||
.size();
|
||||
limitingResourceQueues.add(each.getLimitingResourceQueue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private TimeLineRole<BaseEntity> getCurrentTimeLineRole(BaseEntity entity) {
|
||||
return new TimeLineRole<BaseEntity>(entity);
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueue> groupsFor(List<Resource> allResources) {
|
||||
List<LimitingResourceQueue> result = new ArrayList<LimitingResourceQueue>();
|
||||
for (Resource resource : allResources) {
|
||||
LimitingResourceQueue group = resource.getLimitingResourceQueue();
|
||||
result.add(group);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void initializeIfNeeded(
|
||||
Map<Order, List<ResourceAllocation<?>>> result, Order order) {
|
||||
if (!result.containsKey(order)) {
|
||||
result.put(order, new ArrayList<ResourceAllocation<?>>());
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Map<Order, List<ResourceAllocation<?>>> byOrder(
|
||||
Collection<ResourceAllocation<?>> allocations) {
|
||||
Map<Order, List<ResourceAllocation<?>>> result = new HashMap<Order, List<ResourceAllocation<?>>>();
|
||||
for (ResourceAllocation<?> resourceAllocation : allocations) {
|
||||
if ((resourceAllocation.isSatisfied())
|
||||
&& (resourceAllocation.getTask() != null)) {
|
||||
OrderElement orderElement = resourceAllocation.getTask()
|
||||
.getOrderElement();
|
||||
Order order = orderElementDAO
|
||||
.loadOrderAvoidingProxyFor(orderElement);
|
||||
initializeIfNeeded(result, order);
|
||||
result.get(order).add(resourceAllocation);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private List<GenericResourceAllocation> onlyGeneric(
|
||||
List<ResourceAllocation<?>> sortedByStartDate) {
|
||||
return ResourceAllocation.getOfType(GenericResourceAllocation.class,
|
||||
sortedByStartDate);
|
||||
}
|
||||
|
||||
public static String getName(Collection<? extends Criterion> criterions,
|
||||
Task task) {
|
||||
String prefix = task.getName();
|
||||
return (prefix + " :: " + getName(criterions));
|
||||
}
|
||||
|
||||
public static String getName(Collection<? extends Criterion> criterions) {
|
||||
if (criterions.isEmpty()) {
|
||||
return _("[generic all workers]");
|
||||
}
|
||||
String[] names = new String[criterions.size()];
|
||||
int i = 0;
|
||||
for (Criterion criterion : criterions) {
|
||||
names[i++] = criterion.getName();
|
||||
}
|
||||
return (Arrays.toString(names));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<LimitingResourceQueue> getLimitingResourceQueues() {
|
||||
return limitingResourceQueues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Interval getViewInterval() {
|
||||
return viewInterval;
|
||||
}
|
||||
|
||||
public ZoomLevel calculateInitialZoomLevel() {
|
||||
Interval interval = getViewInterval();
|
||||
return ZoomLevel.getDefaultZoomByDates(new LocalDate(interval
|
||||
.getStart()), new LocalDate(interval.getFinish()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly=true)
|
||||
public List<LimitingResourceQueueElement> getUnassignedLimitingResourceQueueElements() {
|
||||
List<LimitingResourceQueueElement> result = limitingResourceQueueElementDAO
|
||||
.getUnassigned();
|
||||
for (LimitingResourceQueueElement each : result) {
|
||||
limitingResourceQueueElementDAO.reattach(each);
|
||||
each.getResourceAllocation().getTask().getName();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galic
|
||||
* ia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.limitingresources;
|
||||
|
||||
import static org.navalplanner.web.I18nHelper._;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.common.exceptions.ValidationException;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.zkoss.ganttz.IDatesMapper;
|
||||
import org.zkoss.ganttz.timetracker.TimeTracker;
|
||||
import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener;
|
||||
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
|
||||
import org.zkoss.ganttz.util.MenuBuilder;
|
||||
import org.zkoss.ganttz.util.MenuBuilder.ItemAction;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.ext.AfterCompose;
|
||||
import org.zkoss.zul.Div;
|
||||
import org.zkoss.zul.impl.XulElement;
|
||||
|
||||
/**
|
||||
* This class wraps ResourceLoad data inside an specific HTML Div component.
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
public class LimitingResourcesComponent extends XulElement implements
|
||||
AfterCompose {
|
||||
|
||||
public static LimitingResourcesComponent create(TimeTracker timeTracker,
|
||||
LimitingResourceQueue limitingResourceQueue) {
|
||||
return new LimitingResourcesComponent(timeTracker,
|
||||
limitingResourceQueue);
|
||||
}
|
||||
|
||||
private final LimitingResourceQueue limitingResourceQueue;
|
||||
private final TimeTracker timeTracker;
|
||||
private transient IZoomLevelChangedListener zoomChangedListener;
|
||||
private List<Div> queueElementDivs = new ArrayList<Div>();
|
||||
|
||||
private LimitingResourcesComponent(final TimeTracker timeTracker,
|
||||
final LimitingResourceQueue limitingResourceQueue) {
|
||||
this.limitingResourceQueue = limitingResourceQueue;
|
||||
this.timeTracker = timeTracker;
|
||||
createChildren(limitingResourceQueue, timeTracker.getMapper());
|
||||
zoomChangedListener = new IZoomLevelChangedListener() {
|
||||
|
||||
@Override
|
||||
public void zoomLevelChanged(ZoomLevel detailLevel) {
|
||||
getChildren().clear();
|
||||
createChildren(limitingResourceQueue, timeTracker.getMapper());
|
||||
invalidate();
|
||||
}
|
||||
};
|
||||
this.timeTracker.addZoomListener(zoomChangedListener);
|
||||
}
|
||||
|
||||
private void createChildren(LimitingResourceQueue limitingResourceQueue,
|
||||
IDatesMapper mapper) {
|
||||
List<Div> divs = createDivsForQueueElements(mapper,
|
||||
limitingResourceQueue.getLimitingResourceQueueElements());
|
||||
if (divs != null) {
|
||||
for (Div div : divs) {
|
||||
appendChild(div);
|
||||
}
|
||||
queueElementDivs.addAll(divs);
|
||||
}
|
||||
}
|
||||
|
||||
public String getResourceName() {
|
||||
return limitingResourceQueue.getResource().getName();
|
||||
}
|
||||
|
||||
private static List<Div> createDivsForQueueElements(
|
||||
IDatesMapper datesMapper,
|
||||
Set<LimitingResourceQueueElement> list) {
|
||||
List<Div> result = new ArrayList<Div>();
|
||||
|
||||
for (LimitingResourceQueueElement queueElement : list) {
|
||||
validateQueueElement(queueElement);
|
||||
result.add(createDivForQueueElement(datesMapper, queueElement));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void validateQueueElement(
|
||||
LimitingResourceQueueElement queueElement) {
|
||||
if ((queueElement.getStartDate() == null)
|
||||
|| (queueElement.getStartDate() == null)) {
|
||||
throw new ValidationException(_("Invalid queue element"));
|
||||
}
|
||||
}
|
||||
|
||||
private void appendMenu(Div divElement) {
|
||||
if (divElement.getPage() != null) {
|
||||
MenuBuilder<Div> menuBuilder = MenuBuilder.on(divElement.getPage(),
|
||||
queueElementDivs);
|
||||
menuBuilder.item(_("Unassign"), "/common/img/ico_borrar.png",
|
||||
new ItemAction<Div>() {
|
||||
@Override
|
||||
public void onEvent(Div choosen, Event event) {
|
||||
unnasign(choosen);
|
||||
}
|
||||
});
|
||||
divElement.setContext(menuBuilder.createWithoutSettingContext());
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Implement real unnasign operation
|
||||
private void unnasign(Div choosen) {
|
||||
choosen.detach();
|
||||
}
|
||||
|
||||
private static Div createDivForQueueElement(IDatesMapper datesMapper,
|
||||
LimitingResourceQueueElement queueElement) {
|
||||
Div result = new Div();
|
||||
result.setClass("queue-element");
|
||||
|
||||
result.setTooltiptext(queueElement.getLimitingResourceQueue()
|
||||
.getResource().getName());
|
||||
|
||||
result.setLeft(forCSS(getStartPixels(datesMapper, queueElement)));
|
||||
result.setWidth(forCSS(getWidthPixels(datesMapper, queueElement)));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int getWidthPixels(IDatesMapper datesMapper,
|
||||
LimitingResourceQueueElement loadPeriod) {
|
||||
LocalDate start = loadPeriod.getStartDate();
|
||||
LocalDate end = loadPeriod.getEndDate();
|
||||
return datesMapper
|
||||
.toPixels(toMilliseconds(end) - toMilliseconds(start));
|
||||
}
|
||||
|
||||
private static long toMilliseconds(LocalDate localDate) {
|
||||
return localDate.toDateMidnight().getMillis();
|
||||
}
|
||||
|
||||
private static String forCSS(int pixels) {
|
||||
return String.format("%dpx", pixels);
|
||||
}
|
||||
|
||||
private static int getStartPixels(IDatesMapper datesMapper,
|
||||
LimitingResourceQueueElement queueElement) {
|
||||
return datesMapper.toPixels(queueElement.getStartDate().toDateMidnight()
|
||||
.toDate());
|
||||
}
|
||||
|
||||
private void appendContextMenus() {
|
||||
for (Div each : queueElementDivs) {
|
||||
appendMenu(each);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompose() {
|
||||
appendContextMenus();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,227 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.limitingresources;
|
||||
|
||||
import static org.navalplanner.web.I18nHelper._;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.navalplanner.business.orders.entities.Order;
|
||||
import org.navalplanner.business.planner.entities.LimitingResourceQueueElement;
|
||||
import org.navalplanner.business.planner.entities.TaskElement;
|
||||
import org.navalplanner.web.limitingresources.LimitingResourcesPanel.IToolbarCommand;
|
||||
import org.navalplanner.web.planner.order.BankHolidaysMarker;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.zkoss.ganttz.resourceload.IFilterChangedListener;
|
||||
import org.zkoss.ganttz.timetracker.TimeTracker;
|
||||
import org.zkoss.ganttz.timetracker.zoom.SeveralModificators;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.event.EventListener;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zk.ui.util.Composer;
|
||||
import org.zkoss.zul.Button;
|
||||
import org.zkoss.zul.Checkbox;
|
||||
import org.zkoss.zul.Label;
|
||||
import org.zkoss.zul.Messagebox;
|
||||
import org.zkoss.zul.Row;
|
||||
import org.zkoss.zul.RowRenderer;
|
||||
|
||||
/**
|
||||
* Controller for limiting resources view
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
@Component
|
||||
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
|
||||
public class LimitingResourcesController implements Composer {
|
||||
|
||||
@Autowired
|
||||
private ILimitingResourceQueueModel limitingResourceQueueModel;
|
||||
|
||||
private List<IToolbarCommand> commands = new ArrayList<IToolbarCommand>();
|
||||
|
||||
private Order filterBy;
|
||||
|
||||
private org.zkoss.zk.ui.Component parent;
|
||||
|
||||
private LimitingResourcesPanel limitingResourcesPanel;
|
||||
|
||||
private TimeTracker timeTracker;
|
||||
|
||||
private final LimitingResourceQueueElementsRenderer limitingResourceQueueElementsRenderer =
|
||||
new LimitingResourceQueueElementsRenderer();
|
||||
|
||||
private transient IFilterChangedListener filterChangedListener;
|
||||
|
||||
public LimitingResourcesController() {
|
||||
}
|
||||
|
||||
public void add(IToolbarCommand... commands) {
|
||||
Validate.noNullElements(commands);
|
||||
this.commands.addAll(Arrays.asList(commands));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAfterCompose(org.zkoss.zk.ui.Component comp) throws Exception {
|
||||
this.parent = comp;
|
||||
reload();
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
// by default show the task by resources
|
||||
boolean filterByResources = true;
|
||||
reload(filterByResources);
|
||||
}
|
||||
|
||||
private void reload(boolean filterByResources) {
|
||||
try {
|
||||
if (filterBy == null) {
|
||||
limitingResourceQueueModel.initGlobalView(filterByResources);
|
||||
} else {
|
||||
limitingResourceQueueModel.initGlobalView(filterBy,
|
||||
filterByResources);
|
||||
}
|
||||
timeTracker = buildTimeTracker();
|
||||
limitingResourcesPanel = buildLimitingResourcesPanel();
|
||||
addListeners();
|
||||
|
||||
this.parent.getChildren().clear();
|
||||
this.parent.appendChild(limitingResourcesPanel);
|
||||
limitingResourcesPanel.afterCompose();
|
||||
addCommands(limitingResourcesPanel);
|
||||
} catch (IllegalArgumentException e) {
|
||||
try {
|
||||
e.printStackTrace();
|
||||
Messagebox.show(_("Limiting resources error") + e, _("Error"),
|
||||
Messagebox.OK, Messagebox.ERROR);
|
||||
} catch (InterruptedException o) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addListeners() {
|
||||
filterChangedListener = new IFilterChangedListener() {
|
||||
|
||||
@Override
|
||||
public void filterChanged(boolean filter) {
|
||||
onApplyFilter(filter);
|
||||
}
|
||||
};
|
||||
// this.limitingResourcesPanel.addFilterListener(filterChangedListener);
|
||||
}
|
||||
|
||||
public void onApplyFilter(boolean filterByResources) {
|
||||
limitingResourcesPanel.clearComponents();
|
||||
reload(filterByResources);
|
||||
}
|
||||
|
||||
private void addCommands(LimitingResourcesPanel limitingResourcesPanel) {
|
||||
limitingResourcesPanel.add(commands.toArray(new IToolbarCommand[0]));
|
||||
}
|
||||
|
||||
private TimeTracker buildTimeTracker() {
|
||||
return timeTracker = new TimeTracker(limitingResourceQueueModel
|
||||
.getViewInterval(), limitingResourceQueueModel
|
||||
.calculateInitialZoomLevel(), SeveralModificators.create(),
|
||||
SeveralModificators.create(new BankHolidaysMarker()), parent);
|
||||
}
|
||||
|
||||
private LimitingResourcesPanel buildLimitingResourcesPanel() {
|
||||
LimitingResourcesPanel result = new LimitingResourcesPanel(
|
||||
limitingResourceQueueModel.getLimitingResourceQueues(),
|
||||
timeTracker);
|
||||
result.setVariable("limitingResourcesController", this, true);
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<LimitingResourceQueueElement> getUnassignedLimitingResourceQueueElements() {
|
||||
return limitingResourceQueueModel.getUnassignedLimitingResourceQueueElements();
|
||||
}
|
||||
|
||||
public void filterBy(Order order) {
|
||||
this.filterBy = order;
|
||||
}
|
||||
|
||||
public LimitingResourceQueueElementsRenderer getLimitingResourceQueueElementsRenderer() {
|
||||
return limitingResourceQueueElementsRenderer;
|
||||
}
|
||||
|
||||
private class LimitingResourceQueueElementsRenderer implements RowRenderer {
|
||||
|
||||
@Override
|
||||
public void render(Row row, Object data) throws Exception {
|
||||
LimitingResourceQueueElement element = (LimitingResourceQueueElement) data;
|
||||
|
||||
row.appendChild(label(getTaskName(element)));
|
||||
row.appendChild(label(getOrderName(element)));
|
||||
row.appendChild(assignButton(element));
|
||||
row.appendChild(automaticQueueing(element));
|
||||
}
|
||||
|
||||
private Button assignButton(final LimitingResourceQueueElement element) {
|
||||
Button result = new Button();
|
||||
result.setLabel("Assign");
|
||||
result.setTooltiptext(_("Assign to queue"));
|
||||
result.addEventListener(Events.ON_CLICK, new EventListener() {
|
||||
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
// FIXME: assign element to queue
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
private Checkbox automaticQueueing(final LimitingResourceQueueElement element) {
|
||||
Checkbox result = new Checkbox();
|
||||
result.setTooltiptext(_("Select for automatic queuing"));
|
||||
return result;
|
||||
}
|
||||
|
||||
private Label label(String value) {
|
||||
return new Label(value);
|
||||
}
|
||||
|
||||
private TaskElement getTask(LimitingResourceQueueElement element) {
|
||||
return element.getResourceAllocation().getTask();
|
||||
}
|
||||
|
||||
private String getTaskName(LimitingResourceQueueElement element) {
|
||||
return getTask(element).getName();
|
||||
}
|
||||
|
||||
private Order getOrder(LimitingResourceQueueElement element) {
|
||||
return limitingResourceQueueModel.getOrderByTask(getTask(element));
|
||||
}
|
||||
|
||||
private String getOrderName(LimitingResourceQueueElement element) {
|
||||
return getOrder(element).getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.limitingresources;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.zkoss.ganttz.util.MutableTreeModel;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.HtmlMacroComponent;
|
||||
import org.zkoss.zul.Div;
|
||||
import org.zkoss.zul.Label;
|
||||
import org.zkoss.zul.Popup;
|
||||
import org.zkoss.zul.Treecell;
|
||||
import org.zkoss.zul.Treechildren;
|
||||
import org.zkoss.zul.Treeitem;
|
||||
import org.zkoss.zul.TreeitemRenderer;
|
||||
import org.zkoss.zul.Treerow;
|
||||
import org.zkoss.zul.api.Tree;
|
||||
|
||||
public class LimitingResourcesLeftPane extends HtmlMacroComponent {
|
||||
|
||||
private MutableTreeModel<LimitingResourceQueue> modelForTree;
|
||||
private final LimitingResourcesList limitingResourcesList;
|
||||
|
||||
public LimitingResourcesLeftPane(
|
||||
MutableTreeModel<LimitingResourceQueue> treeModel,
|
||||
LimitingResourcesList resourceLoadList) {
|
||||
this.limitingResourcesList = resourceLoadList;
|
||||
this.modelForTree = treeModel;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterCompose() {
|
||||
super.afterCompose();
|
||||
getContainerTree().setModel(modelForTree);
|
||||
getContainerTree().setTreeitemRenderer(getRendererForTree());
|
||||
}
|
||||
|
||||
private TreeitemRenderer getRendererForTree() {
|
||||
return new TreeitemRenderer() {
|
||||
@Override
|
||||
public void render(Treeitem item, Object data)
|
||||
throws Exception {
|
||||
LimitingResourceQueue line = (LimitingResourceQueue) data;
|
||||
item.setOpen(false);
|
||||
item.setValue(line);
|
||||
|
||||
Treerow row = new Treerow();
|
||||
Treecell cell = new Treecell();
|
||||
Component component = createComponent(line);
|
||||
item.appendChild(row);
|
||||
row.appendChild(cell);
|
||||
cell.appendChild(component);
|
||||
}
|
||||
|
||||
private Component createComponent(LimitingResourceQueue line) {
|
||||
return isTopLevel(line) ? createFirstLevel(line)
|
||||
: createSecondLevel(line);
|
||||
}
|
||||
|
||||
private boolean isTopLevel(LimitingResourceQueue line) {
|
||||
int[] path = modelForTree.getPath(modelForTree.getRoot(), line);
|
||||
return path.length == 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void collapse(LimitingResourceQueue line) {
|
||||
// unnecesary
|
||||
limitingResourcesList.collapse(line);
|
||||
}
|
||||
|
||||
private void expand(LimitingResourceQueue line,
|
||||
List<LimitingResourceQueue> closed) {
|
||||
// unnecesary
|
||||
// limitingResourcesList.expand(line, closed);
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueue> calculatedClosedItems(Treeitem item) {
|
||||
List<LimitingResourceQueue> result = new ArrayList<LimitingResourceQueue>();
|
||||
Treechildren treeChildren = item.getTreechildren();
|
||||
if (treeChildren != null) {
|
||||
List<Treeitem> myTreeItems = (List<Treeitem>) treeChildren
|
||||
.getChildren();
|
||||
Iterator<Treeitem> iterator = myTreeItems.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Treeitem child = (Treeitem) iterator.next();
|
||||
if (!child.isOpen()) {
|
||||
result.addAll(getLineChildrenBy(child));
|
||||
} else {
|
||||
result.addAll(calculatedClosedItems(child));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<LimitingResourceQueue> getLineChildrenBy(Treeitem item) {
|
||||
List<LimitingResourceQueue> result = new ArrayList<LimitingResourceQueue>();
|
||||
LimitingResourceQueue line = getLineByTreeitem(item);
|
||||
return result;
|
||||
}
|
||||
|
||||
private LimitingResourceQueue getLineByTreeitem(Treeitem child) {
|
||||
LimitingResourceQueue line = null;
|
||||
try {
|
||||
line = (LimitingResourceQueue) child.getValue();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
private Tree getContainerTree() {
|
||||
return (Tree) getFellow("loadsTree");
|
||||
}
|
||||
|
||||
private Component createFirstLevel(LimitingResourceQueue principal) {
|
||||
Div result = createLabelWithName(principal);
|
||||
result.setSclass("firstlevel");
|
||||
return result;
|
||||
}
|
||||
|
||||
private Component createSecondLevel(LimitingResourceQueue loadTimeLine) {
|
||||
Div result = createLabelWithName(loadTimeLine);
|
||||
result.setSclass("secondlevel");
|
||||
return result;
|
||||
}
|
||||
|
||||
private Div createLabelWithName(LimitingResourceQueue principal) {
|
||||
Div result = new Div();
|
||||
Label label = new Label();
|
||||
final String conceptName = principal.getResource().getName();
|
||||
label.setValue(conceptName);
|
||||
result.appendChild(label);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static Popup createPopup(Div parent, String originalValue) {
|
||||
Popup result = new Popup();
|
||||
result.appendChild(new Label(originalValue));
|
||||
parent.appendChild(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.limitingresources;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.zkoss.ganttz.timetracker.TimeTracker;
|
||||
import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener;
|
||||
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
|
||||
import org.zkoss.ganttz.util.MutableTreeModel;
|
||||
import org.zkoss.zk.au.out.AuInvoke;
|
||||
import org.zkoss.zk.ui.HtmlMacroComponent;
|
||||
import org.zkoss.zk.ui.ext.AfterCompose;
|
||||
|
||||
/**
|
||||
* Component to include a list of ResourceLoads inside the ResourcesLoadPanel.
|
||||
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
||||
*/
|
||||
public class LimitingResourcesList extends HtmlMacroComponent implements
|
||||
AfterCompose {
|
||||
|
||||
private final IZoomLevelChangedListener zoomListener;
|
||||
|
||||
private Map<LimitingResourceQueue, LimitingResourcesComponent> fromTimeLineToComponent = new HashMap<LimitingResourceQueue, LimitingResourcesComponent>();
|
||||
|
||||
private final MutableTreeModel<LimitingResourceQueue> timelinesTree;
|
||||
|
||||
private List<LimitingResourcesComponent> limitingResourcesComponents = new ArrayList<LimitingResourcesComponent>();
|
||||
|
||||
public LimitingResourcesList(TimeTracker timeTracker,
|
||||
MutableTreeModel<LimitingResourceQueue> timelinesTree) {
|
||||
this.timelinesTree = timelinesTree;
|
||||
zoomListener = adjustTimeTrackerSizeListener();
|
||||
timeTracker.addZoomListener(zoomListener);
|
||||
LimitingResourceQueue current = timelinesTree.getRoot();
|
||||
List<LimitingResourceQueue> toInsert = new ArrayList<LimitingResourceQueue>();
|
||||
fill(timelinesTree, current, toInsert);
|
||||
insertAsComponents(timeTracker, toInsert);
|
||||
}
|
||||
|
||||
private void fill(MutableTreeModel<LimitingResourceQueue> timelinesTree,
|
||||
LimitingResourceQueue current, List<LimitingResourceQueue> result) {
|
||||
final int length = timelinesTree.getChildCount(current);
|
||||
for (int i = 0; i < length; i++) {
|
||||
LimitingResourceQueue child = timelinesTree.getChild(current, i);
|
||||
result.add(child);
|
||||
fill(timelinesTree, child, result);
|
||||
}
|
||||
}
|
||||
|
||||
private IZoomLevelChangedListener adjustTimeTrackerSizeListener() {
|
||||
return new IZoomLevelChangedListener() {
|
||||
|
||||
@Override
|
||||
public void zoomLevelChanged(ZoomLevel detailLevel) {
|
||||
response(null, new AuInvoke(LimitingResourcesList.this,
|
||||
"adjustTimeTrackerSize"));
|
||||
response(null, new AuInvoke(LimitingResourcesList.this,
|
||||
"adjustResourceLoadRows"));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void insertAsComponents(TimeTracker timetracker,
|
||||
List<LimitingResourceQueue> children) {
|
||||
for (LimitingResourceQueue LimitingResourceQueue : children) {
|
||||
LimitingResourcesComponent component = LimitingResourcesComponent
|
||||
.create(timetracker, LimitingResourceQueue);
|
||||
limitingResourcesComponents.add(component);
|
||||
appendChild(component);
|
||||
fromTimeLineToComponent.put(LimitingResourceQueue, component);
|
||||
}
|
||||
}
|
||||
|
||||
public void collapse(LimitingResourceQueue line) {
|
||||
}
|
||||
|
||||
private LimitingResourcesComponent getComponentFor(LimitingResourceQueue l) {
|
||||
LimitingResourcesComponent resourceLoadComponent = fromTimeLineToComponent
|
||||
.get(l);
|
||||
return resourceLoadComponent;
|
||||
}
|
||||
|
||||
public void expand(LimitingResourceQueue line,
|
||||
List<LimitingResourceQueue> closed) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompose() {
|
||||
super.afterCompose();
|
||||
for (LimitingResourcesComponent each : limitingResourcesComponents) {
|
||||
each.afterCompose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.limitingresources;
|
||||
|
||||
import static org.zkoss.ganttz.i18n.I18nHelper._;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.navalplanner.business.resources.daos.IResourceDAO;
|
||||
import org.navalplanner.business.resources.entities.LimitingResourceQueue;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.zkoss.ganttz.timetracker.TimeTracker;
|
||||
import org.zkoss.ganttz.timetracker.TimeTrackerComponent;
|
||||
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
|
||||
import org.zkoss.ganttz.util.ComponentsFinder;
|
||||
import org.zkoss.ganttz.util.MutableTreeModel;
|
||||
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
|
||||
import org.zkoss.ganttz.util.script.IScriptsRegister;
|
||||
import org.zkoss.zk.au.out.AuInvoke;
|
||||
import org.zkoss.zk.ui.Component;
|
||||
import org.zkoss.zk.ui.HtmlMacroComponent;
|
||||
import org.zkoss.zk.ui.event.Event;
|
||||
import org.zkoss.zk.ui.event.EventListener;
|
||||
import org.zkoss.zk.ui.event.Events;
|
||||
import org.zkoss.zul.Button;
|
||||
import org.zkoss.zul.Div;
|
||||
import org.zkoss.zul.ListModel;
|
||||
import org.zkoss.zul.Listbox;
|
||||
import org.zkoss.zul.Separator;
|
||||
import org.zkoss.zul.SimpleListModel;
|
||||
|
||||
public class LimitingResourcesPanel extends HtmlMacroComponent {
|
||||
|
||||
public interface IToolbarCommand {
|
||||
public void doAction();
|
||||
|
||||
public String getLabel();
|
||||
|
||||
public String getImage();
|
||||
}
|
||||
|
||||
private TimeTrackerComponent timeTrackerComponent;
|
||||
|
||||
private LimitingResourcesLeftPane leftPane;
|
||||
|
||||
private LimitingResourcesList limitingResourcesList;
|
||||
|
||||
private List<LimitingResourceQueue> limitingResourceQueues = new ArrayList<LimitingResourceQueue>();
|
||||
|
||||
private MutableTreeModel<LimitingResourceQueue> treeModel;
|
||||
|
||||
private TimeTracker timeTracker;
|
||||
|
||||
// private LimitingDependencyList dependencyList;
|
||||
|
||||
// private WeakReferencedListeners<IFilterChangedListener> zoomListeners =
|
||||
// WeakReferencedListeners.create();
|
||||
|
||||
private Listbox listZoomLevels;
|
||||
|
||||
@Autowired
|
||||
IResourceDAO resourcesDAO;
|
||||
|
||||
private static final String filterResources = _("Filter by resources");
|
||||
private static final String filterCriterions = _("Filter by criterions");
|
||||
private boolean filterbyResources = true;
|
||||
|
||||
public LimitingResourcesPanel(List<LimitingResourceQueue> groups,
|
||||
TimeTracker timeTracker) {
|
||||
init(groups, timeTracker);
|
||||
|
||||
}
|
||||
|
||||
public void init(List<LimitingResourceQueue> groups, TimeTracker timeTracker) {
|
||||
this.limitingResourceQueues = groups;
|
||||
this.timeTracker = timeTracker;
|
||||
treeModel = createModelForTree();
|
||||
timeTrackerComponent = timeTrackerForResourcesLoadPanel(timeTracker);
|
||||
limitingResourcesList = new LimitingResourcesList(timeTracker,
|
||||
treeModel);
|
||||
leftPane = new LimitingResourcesLeftPane(treeModel,
|
||||
limitingResourcesList);
|
||||
registerNeededScripts();
|
||||
}
|
||||
|
||||
public ListModel getFilters() {
|
||||
String[] filters = new String[] { filterResources, filterCriterions };
|
||||
return new SimpleListModel(filters);
|
||||
}
|
||||
|
||||
public void setFilter(String filterby) {
|
||||
if (filterby.equals(filterResources)) {
|
||||
this.filterbyResources = true;
|
||||
} else {
|
||||
this.filterbyResources = false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getFilter() {
|
||||
return filterbyResources;
|
||||
}
|
||||
|
||||
public ListModel getZoomLevels() {
|
||||
return new SimpleListModel(ZoomLevel.values());
|
||||
}
|
||||
|
||||
public void setZoomLevel(final ZoomLevel zoomLevel) {
|
||||
timeTracker.setZoomLevel(zoomLevel);
|
||||
}
|
||||
|
||||
public void zoomIncrease() {
|
||||
timeTracker.zoomIncrease();
|
||||
}
|
||||
|
||||
public void zoomDecrease() {
|
||||
timeTracker.zoomDecrease();
|
||||
}
|
||||
|
||||
public void add(final IToolbarCommand... commands) {
|
||||
Component toolbar = getToolbar();
|
||||
Separator separator = getSeparator();
|
||||
for (IToolbarCommand c : commands) {
|
||||
toolbar.insertBefore(asButton(c), separator);
|
||||
}
|
||||
}
|
||||
|
||||
private Button asButton(final IToolbarCommand c) {
|
||||
Button result = new Button();
|
||||
result.addEventListener(Events.ON_CLICK, new EventListener() {
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
c.doAction();
|
||||
}
|
||||
});
|
||||
if (!StringUtils.isEmpty(c.getImage())) {
|
||||
result.setImage(c.getImage());
|
||||
result.setTooltiptext(c.getLabel());
|
||||
} else {
|
||||
result.setLabel(c.getLabel());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Separator getSeparator() {
|
||||
List<Component> children = getToolbar().getChildren();
|
||||
Separator separator = ComponentsFinder.findComponentsOfType(
|
||||
Separator.class, children).get(0);
|
||||
return separator;
|
||||
}
|
||||
|
||||
private Component getToolbar() {
|
||||
Component toolbar = getFellow("toolbar");
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
private void registerNeededScripts() {
|
||||
// getScriptsRegister().register(ScriptsRequiredByResourceLoadPanel.class);
|
||||
}
|
||||
|
||||
private IScriptsRegister getScriptsRegister() {
|
||||
return OnZKDesktopRegistry.getLocatorFor(IScriptsRegister.class)
|
||||
.retrieve();
|
||||
}
|
||||
|
||||
private MutableTreeModel<LimitingResourceQueue> createModelForTree() {
|
||||
MutableTreeModel<LimitingResourceQueue> result = MutableTreeModel
|
||||
.create(LimitingResourceQueue.class);
|
||||
for (LimitingResourceQueue LimitingResourceQueue : this.limitingResourceQueues) {
|
||||
result.addToRoot(LimitingResourceQueue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private TimeTrackerComponent timeTrackerForResourcesLoadPanel(
|
||||
TimeTracker timeTracker) {
|
||||
return new TimeTrackerComponent(timeTracker) {
|
||||
@Override
|
||||
protected void scrollHorizontalPercentage(int pixelsDisplacement) {
|
||||
response("", new AuInvoke(limitingResourcesList,
|
||||
"adjustScrollHorizontalPosition", pixelsDisplacement
|
||||
+ ""));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompose() {
|
||||
|
||||
super.afterCompose();
|
||||
|
||||
// Insert resourcesList left pane component
|
||||
getFellow("insertionPointLeftPanel").appendChild(leftPane);
|
||||
leftPane.afterCompose();
|
||||
|
||||
// Insert timetracker watermarks and limitingResourcesQueues
|
||||
getFellow("insertionPointRightPanel").appendChild(timeTrackerComponent);
|
||||
getFellow("insertionPointRightPanel")
|
||||
.appendChild(limitingResourcesList);
|
||||
limitingResourcesList.afterCompose();
|
||||
|
||||
Div source = new Div();
|
||||
Div destination = new Div();
|
||||
|
||||
LimitingDependencyComponent limitingDependencyComponent = new LimitingDependencyComponent(
|
||||
source, destination);
|
||||
|
||||
LimitingDependencyList dependencyList = new LimitingDependencyList(null);
|
||||
dependencyList.addDependencyComponent(limitingDependencyComponent);
|
||||
|
||||
getFellow("insertionPointRightPanel").appendChild(dependencyList);
|
||||
|
||||
dependencyList.afterCompose();
|
||||
|
||||
// Insert timetracker headers
|
||||
TimeTrackerComponent timeTrackerHeader = createTimeTrackerHeader();
|
||||
getFellow("insertionPointTimetracker").appendChild(timeTrackerHeader);
|
||||
|
||||
timeTrackerHeader.afterCompose();
|
||||
timeTrackerComponent.afterCompose();
|
||||
listZoomLevels = (Listbox) getFellow("listZoomLevels");
|
||||
listZoomLevels.setSelectedIndex(timeTracker.getDetailLevel().ordinal());
|
||||
}
|
||||
|
||||
public void clearComponents() {
|
||||
getFellow("insertionPointLeftPanel").getChildren().clear();
|
||||
getFellow("insertionPointRightPanel").getChildren().clear();
|
||||
getFellow("insertionPointTimetracker").getChildren().clear();
|
||||
}
|
||||
|
||||
private TimeTrackerComponent createTimeTrackerHeader() {
|
||||
return new TimeTrackerComponent(
|
||||
timeTracker) {
|
||||
|
||||
@Override
|
||||
protected void scrollHorizontalPercentage(int pixelsDisplacement) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,365 @@
|
|||
/*
|
||||
* This file is part of NavalPlan
|
||||
*
|
||||
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
|
||||
* Desenvolvemento Tecnolóxico de Galicia
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.navalplanner.web.limitingresources;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.navalplanner.business.planner.entities.DayAssignment;
|
||||
import org.navalplanner.business.planner.entities.GenericResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.ResourceAllocation;
|
||||
import org.navalplanner.business.planner.entities.SpecificDayAssignment;
|
||||
import org.navalplanner.business.resources.daos.IResourceDAO;
|
||||
import org.navalplanner.business.resources.entities.Criterion;
|
||||
import org.navalplanner.business.resources.entities.CriterionCompounder;
|
||||
import org.navalplanner.business.resources.entities.ICriterion;
|
||||
import org.navalplanner.business.resources.entities.Resource;
|
||||
import org.zkoss.ganttz.data.limitingresource.QueueTask;
|
||||
import org.zkoss.ganttz.data.resourceload.LoadLevel;
|
||||
|
||||
interface QueueTaskGeneratorFactory {
|
||||
QueueTaskGenerator create(ResourceAllocation<?> allocation);
|
||||
}
|
||||
|
||||
|
||||
abstract class QueueTaskGenerator {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(QueueTaskGenerator.class);
|
||||
|
||||
public static QueueTaskGeneratorFactory onResource(Resource resource) {
|
||||
return new OnResourceFactory(resource);
|
||||
}
|
||||
|
||||
public static QueueTaskGeneratorFactory onResourceSatisfying(
|
||||
Resource resource, Collection<Criterion> criterions) {
|
||||
return new OnResourceFactory(resource, criterions);
|
||||
}
|
||||
|
||||
private static class OnResourceFactory implements
|
||||
QueueTaskGeneratorFactory {
|
||||
|
||||
private final Resource resource;
|
||||
|
||||
private final ICriterion criterion;
|
||||
|
||||
public OnResourceFactory(Resource resource) {
|
||||
this(resource, Collections.<Criterion> emptyList());
|
||||
}
|
||||
|
||||
public OnResourceFactory(Resource resource,
|
||||
Collection<Criterion> criterionsToSatisfy) {
|
||||
Validate.notNull(resource);
|
||||
this.resource = resource;
|
||||
this.criterion = CriterionCompounder.buildAnd(criterionsToSatisfy)
|
||||
.getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueueTaskGenerator create(ResourceAllocation<?> allocation) {
|
||||
return new QueueTaskGeneratorOnResource(resource, allocation,
|
||||
criterion);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static QueueTaskGeneratorFactory onCriterion(
|
||||
final Criterion criterion, final IResourceDAO resourcesDAO) {
|
||||
return new QueueTaskGeneratorFactory() {
|
||||
|
||||
@Override
|
||||
public QueueTaskGenerator create(ResourceAllocation<?> allocation) {
|
||||
return new QueueTaskGeneratorOnCriterion(criterion,
|
||||
allocation, findResources(criterion, resourcesDAO));
|
||||
}
|
||||
|
||||
private List<Resource> findResources(final Criterion criterion,
|
||||
final IResourceDAO resourcesDAO) {
|
||||
return resourcesDAO
|
||||
.findSatisfyingCriterionsAtSomePoint(Collections
|
||||
.singletonList(criterion));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected final LocalDate start;
|
||||
protected final LocalDate end;
|
||||
|
||||
private List<ResourceAllocation<?>> allocationsOnInterval = new ArrayList<ResourceAllocation<?>>();
|
||||
|
||||
protected QueueTaskGenerator(LocalDate start,
|
||||
LocalDate end, List<ResourceAllocation<?>> allocationsOnInterval) {
|
||||
Validate.notNull(start);
|
||||
Validate.notNull(end);
|
||||
Validate.notNull(allocationsOnInterval);
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.allocationsOnInterval = ResourceAllocation
|
||||
.getSatisfied(allocationsOnInterval);
|
||||
}
|
||||
|
||||
public List<QueueTaskGenerator> join(QueueTaskGenerator next) {
|
||||
if (!overlaps(next)) {
|
||||
return stripEmpty(this, next);
|
||||
}
|
||||
if (isIncluded(next)) {
|
||||
return stripEmpty(this.until(next.start), intersect(next), this
|
||||
.from(next.end));
|
||||
}
|
||||
assert overlaps(next) && !isIncluded(next);
|
||||
return stripEmpty(this.until(next.start), intersect(next), next
|
||||
.from(end));
|
||||
}
|
||||
|
||||
protected List<ResourceAllocation<?>> getAllocationsOnInterval() {
|
||||
return allocationsOnInterval;
|
||||
}
|
||||
|
||||
private List<QueueTaskGenerator> stripEmpty(
|
||||
QueueTaskGenerator... generators) {
|
||||
List<QueueTaskGenerator> result = new ArrayList<QueueTaskGenerator>();
|
||||
for (QueueTaskGenerator loadPeriodGenerator : generators) {
|
||||
if (!loadPeriodGenerator.isEmpty()) {
|
||||
result.add(loadPeriodGenerator);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isEmpty() {
|
||||
return start.equals(end);
|
||||
}
|
||||
|
||||
protected abstract QueueTaskGenerator create(LocalDate start,
|
||||
LocalDate end, List<ResourceAllocation<?>> allocationsOnInterval);
|
||||
|
||||
private QueueTaskGenerator intersect(QueueTaskGenerator other) {
|
||||
return create(max(this.start, other.start),
|
||||
min(this.end, other.end), plusAllocations(other));
|
||||
}
|
||||
|
||||
private static LocalDate max(LocalDate l1, LocalDate l2) {
|
||||
return l1.compareTo(l2) < 0 ? l2 : l1;
|
||||
}
|
||||
|
||||
private static LocalDate min(LocalDate l1, LocalDate l2) {
|
||||
return l1.compareTo(l2) < 0 ? l1 : l2;
|
||||
}
|
||||
|
||||
private List<ResourceAllocation<?>> plusAllocations(
|
||||
QueueTaskGenerator other) {
|
||||
List<ResourceAllocation<?>> result = new ArrayList<ResourceAllocation<?>>();
|
||||
result.addAll(allocationsOnInterval);
|
||||
result.addAll(other.allocationsOnInterval);
|
||||
return result;
|
||||
}
|
||||
|
||||
private QueueTaskGenerator from(LocalDate newStart) {
|
||||
return create(newStart, end,
|
||||
allocationsOnInterval);
|
||||
}
|
||||
|
||||
private QueueTaskGenerator until(LocalDate newEnd) {
|
||||
return create(start, newEnd,
|
||||
allocationsOnInterval);
|
||||
}
|
||||
|
||||
boolean overlaps(QueueTaskGenerator other) {
|
||||
return (start.compareTo(other.end) < 0 && other.start
|
||||
.compareTo(this.end) < 0);
|
||||
}
|
||||
|
||||
private boolean isIncluded(QueueTaskGenerator other) {
|
||||
return other.start.compareTo(start) >= 0
|
||||
&& other.end.compareTo(end) <= 0;
|
||||
}
|
||||
|
||||
public QueueTask build() {
|
||||
return new QueueTask(start, end, getTotalWorkHours(),
|
||||
getHoursAssigned(), new LoadLevel(
|
||||
calculateLoadPercentage()));
|
||||
}
|
||||
|
||||
protected abstract int getTotalWorkHours();
|
||||
|
||||
private int calculateLoadPercentage() {
|
||||
final int totalResourceWorkHours = getTotalWorkHours();
|
||||
int assigned = getHoursAssigned();
|
||||
if (totalResourceWorkHours == 0) {
|
||||
return assigned == 0 ? 0 : Integer.MAX_VALUE;
|
||||
}
|
||||
double proportion = assigned / (double) totalResourceWorkHours;
|
||||
return new BigDecimal(proportion).scaleByPowerOfTen(2).intValue();
|
||||
}
|
||||
|
||||
protected abstract int getHoursAssigned();
|
||||
|
||||
protected final int sumAllocations() {
|
||||
int sum = 0;
|
||||
for (ResourceAllocation<?> resourceAllocation : allocationsOnInterval) {
|
||||
sum += getAssignedHoursFor(resourceAllocation);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
protected abstract int getAssignedHoursFor(
|
||||
ResourceAllocation<?> resourceAllocation);
|
||||
|
||||
public LocalDate getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public LocalDate getEnd() {
|
||||
return end;
|
||||
}
|
||||
}
|
||||
|
||||
class QueueTaskGeneratorOnResource extends QueueTaskGenerator {
|
||||
|
||||
private Resource resource;
|
||||
|
||||
private final ICriterion criterion;
|
||||
|
||||
QueueTaskGeneratorOnResource(Resource resource, LocalDate start,
|
||||
LocalDate end, List<ResourceAllocation<?>> allocationsOnInterval,
|
||||
ICriterion criterion) {
|
||||
super(start, end, allocationsOnInterval);
|
||||
this.resource = resource;
|
||||
this.criterion = criterion;
|
||||
}
|
||||
|
||||
QueueTaskGeneratorOnResource(Resource resource,
|
||||
ResourceAllocation<?> initial, ICriterion criterion) {
|
||||
super(initial.getStartDate(), initial.getEndDate(), Arrays.<ResourceAllocation<?>> asList(initial));
|
||||
this.resource = resource;
|
||||
this.criterion = criterion;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QueueTaskGenerator create(LocalDate start, LocalDate end,
|
||||
List<ResourceAllocation<?>> allocationsOnInterval) {
|
||||
return new QueueTaskGeneratorOnResource(resource, start, end,
|
||||
allocationsOnInterval, criterion);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getTotalWorkHours() {
|
||||
return resource.getTotalWorkHours(start, end, criterion);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getAssignedHoursFor(ResourceAllocation<?> resourceAllocation) {
|
||||
return resourceAllocation.getAssignedHours(resource, start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHoursAssigned() {
|
||||
return sumAllocations();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class QueueTaskGeneratorOnCriterion extends QueueTaskGenerator {
|
||||
|
||||
private final Criterion criterion;
|
||||
private final List<Resource> resourcesSatisfyingCriterionAtSomePoint;
|
||||
|
||||
public QueueTaskGeneratorOnCriterion(Criterion criterion,
|
||||
ResourceAllocation<?> allocation,
|
||||
List<Resource> resourcesSatisfyingCriterionAtSomePoint) {
|
||||
this(criterion, allocation.getStartDate(), allocation.getEndDate(),
|
||||
Arrays.<ResourceAllocation<?>> asList(allocation),
|
||||
resourcesSatisfyingCriterionAtSomePoint);
|
||||
}
|
||||
|
||||
public QueueTaskGeneratorOnCriterion(Criterion criterion,
|
||||
LocalDate startDate, LocalDate endDate,
|
||||
List<ResourceAllocation<?>> allocations,
|
||||
List<Resource> resourcesSatisfyingCriterionAtSomePoint) {
|
||||
super(startDate, endDate, allocations);
|
||||
this.criterion = criterion;
|
||||
this.resourcesSatisfyingCriterionAtSomePoint = resourcesSatisfyingCriterionAtSomePoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected QueueTaskGenerator create(LocalDate start, LocalDate end,
|
||||
List<ResourceAllocation<?>> allocationsOnInterval) {
|
||||
QueueTaskGeneratorOnCriterion result = new QueueTaskGeneratorOnCriterion(
|
||||
criterion, start, end, allocationsOnInterval,
|
||||
resourcesSatisfyingCriterionAtSomePoint);
|
||||
result.specificByResourceCached = specificByResourceCached;
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<GenericResourceAllocation> genericAllocationsOnInterval() {
|
||||
return ResourceAllocation.getOfType(GenericResourceAllocation.class,
|
||||
getAllocationsOnInterval());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getAssignedHoursFor(ResourceAllocation<?> resourceAllocation) {
|
||||
return resourceAllocation.getAssignedHours(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getTotalWorkHours() {
|
||||
int sum = 0;
|
||||
for (Resource resource : resourcesSatisfyingCriterionAtSomePoint) {
|
||||
sum += resource.getTotalWorkHours(start, end, criterion);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHoursAssigned() {
|
||||
return sumAllocations();
|
||||
}
|
||||
|
||||
private Map<Resource, List<SpecificDayAssignment>> specificByResourceCached = new HashMap<Resource, List<SpecificDayAssignment>>();
|
||||
|
||||
private List<SpecificDayAssignment> getSpecificOrderedAssignmentsFor(
|
||||
Resource resource) {
|
||||
if (!specificByResourceCached.containsKey(resource)) {
|
||||
specificByResourceCached.put(resource, DayAssignment
|
||||
.specific(DayAssignment.orderedByDay(resource
|
||||
.getAssignments())));
|
||||
}
|
||||
return specificByResourceCached.get(resource);
|
||||
}
|
||||
|
||||
private int sum(List<SpecificDayAssignment> specific) {
|
||||
int result = 0;
|
||||
for (SpecificDayAssignment s : specific) {
|
||||
result += s.getHours();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -62,7 +62,7 @@ public interface IManageOrderElementAdvancesModel {
|
|||
|
||||
public boolean isReadOnlyAdvanceMeasurements();
|
||||
|
||||
public void cleanAdvance();
|
||||
public void cleanAdvance(DirectAdvanceAssignment advance);
|
||||
|
||||
public boolean isPrecisionValid(AdvanceMeasurement advanceMeasurement);
|
||||
|
||||
|
|
@ -99,4 +99,13 @@ public interface IManageOrderElementAdvancesModel {
|
|||
public boolean isQualityForm(AdvanceAssignment advance);
|
||||
|
||||
public boolean lessThanPreviousMeasurements();
|
||||
|
||||
public boolean hasConsolidatedAdvances(AdvanceAssignment advance);
|
||||
|
||||
public boolean hasConsolidatedAdvances(AdvanceMeasurement advanceMeasurement);
|
||||
|
||||
public boolean findIndirectConsolidation(
|
||||
AdvanceMeasurement advanceMeasurement);
|
||||
|
||||
public void resetAdvanceAssignment();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.joda.time.LocalDate;
|
||||
|
|
@ -164,17 +165,33 @@ public class ManageOrderElementAdvancesController extends
|
|||
return orderElementModel.getOrderElement();
|
||||
}
|
||||
|
||||
private void resetAdvancesGrid() {
|
||||
manageOrderElementAdvancesModel.resetAdvanceAssignment();
|
||||
this.indexSelectedItem = -1;
|
||||
reloadAdvances();
|
||||
}
|
||||
|
||||
private void reloadAdvances() {
|
||||
Util.reloadBindings(self);
|
||||
if (indexSelectedItem > -1) {
|
||||
editAdvances.setSelectedItem(editAdvances
|
||||
.getItemAtIndex(indexSelectedItem));
|
||||
editAdvances.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
private Listbox editAdvances;
|
||||
|
||||
public void prepareEditAdvanceMeasurements(Listitem selectedItem) {
|
||||
AdvanceAssignment advanceAssignment = (AdvanceAssignment) selectedItem
|
||||
.getValue();
|
||||
if (advanceAssignment.getAdvanceType() != null) {
|
||||
validateListAdvanceMeasurement();
|
||||
manageOrderElementAdvancesModel
|
||||
validateListAdvanceMeasurement();
|
||||
manageOrderElementAdvancesModel
|
||||
.prepareEditAdvanceMeasurements(advanceAssignment);
|
||||
this.indexSelectedItem = editAdvances.getIndexOfItem(editAdvances.getSelectedItem());
|
||||
Util.reloadBindings(self);
|
||||
this.indexSelectedItem = editAdvances.getIndexOfItem(editAdvances
|
||||
.getSelectedItem());
|
||||
reloadAdvances();
|
||||
} else {
|
||||
Component comboAdvanceType = selectedItem.getFirstChild()
|
||||
.getFirstChild();
|
||||
|
|
@ -187,14 +204,12 @@ public class ManageOrderElementAdvancesController extends
|
|||
|
||||
public void goToCreateLineAdvanceAssignment() {
|
||||
manageOrderElementAdvancesModel.addNewLineAdvaceAssignment();
|
||||
manageOrderElementAdvancesModel.prepareEditAdvanceMeasurements(null);
|
||||
this.indexSelectedItem = -1;
|
||||
Util.reloadBindings(self);
|
||||
resetAdvancesGrid();
|
||||
}
|
||||
|
||||
public void goToCreateLineAdvanceMeasurement() {
|
||||
manageOrderElementAdvancesModel.addNewLineAdvaceMeasurement();
|
||||
Util.reloadBindings(self);
|
||||
reloadAdvances();
|
||||
}
|
||||
|
||||
public void goToRemoveLineAdvanceAssignment(){
|
||||
|
|
@ -204,7 +219,7 @@ public class ManageOrderElementAdvancesController extends
|
|||
.getValue();
|
||||
manageOrderElementAdvancesModel
|
||||
.removeLineAdvanceAssignment(advanceAssignment);
|
||||
Util.reloadBindings(self);
|
||||
reloadAdvances();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -218,7 +233,7 @@ public class ManageOrderElementAdvancesController extends
|
|||
if (advanceMeasurement != null) {
|
||||
manageOrderElementAdvancesModel
|
||||
.removeLineAdvanceMeasurement(advanceMeasurement);
|
||||
Util.reloadBindings(self);
|
||||
reloadAdvances();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -306,8 +321,9 @@ public class ManageOrderElementAdvancesController extends
|
|||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
setMaxValue(listItem,comboAdvanceTypes);
|
||||
cleanFields();
|
||||
cleanFields(advance);
|
||||
setPercentage();
|
||||
resetAdvancesGrid();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -351,7 +367,7 @@ public class ManageOrderElementAdvancesController extends
|
|||
|
||||
private void appendDecimalBoxMaxValue(final Listitem listItem,
|
||||
boolean isQualityForm) {
|
||||
AdvanceAssignment advanceAssignment = (AdvanceAssignment) listItem
|
||||
final AdvanceAssignment advanceAssignment = (AdvanceAssignment) listItem
|
||||
.getValue();
|
||||
Decimalbox maxValue = new Decimalbox();
|
||||
maxValue.setScale(2);
|
||||
|
|
@ -379,15 +395,23 @@ public class ManageOrderElementAdvancesController extends
|
|||
|
||||
@Override
|
||||
public void set(BigDecimal value) {
|
||||
directAdvanceAssignment.setMaxValue(value);
|
||||
if (!manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advanceAssignment)) {
|
||||
directAdvanceAssignment.setMaxValue(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
maxValue.addEventListener(Events.ON_CHANGE,
|
||||
new EventListener() {
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
setPercentage();
|
||||
Util.reloadBindings(self);
|
||||
if (manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advanceAssignment)) {
|
||||
showMessagesConsolidation(1);
|
||||
} else {
|
||||
setPercentage();
|
||||
reloadAdvances();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -531,7 +555,7 @@ public class ManageOrderElementAdvancesController extends
|
|||
} else {
|
||||
selectedAdvances.remove(advance);
|
||||
}
|
||||
Util.reloadBindings(self);
|
||||
reloadAdvances();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -548,9 +572,18 @@ public class ManageOrderElementAdvancesController extends
|
|||
removeButton.addEventListener(Events.ON_CLICK, new EventListener() {
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
manageOrderElementAdvancesModel
|
||||
if (manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advance)) {
|
||||
showMessagesConsolidation(1);
|
||||
} else {
|
||||
manageOrderElementAdvancesModel
|
||||
.removeLineAdvanceAssignment(advance);
|
||||
Util.reloadBindings(self);
|
||||
if (indexSelectedItem == editAdvances
|
||||
.getIndexOfItem(listItem)) {
|
||||
indexSelectedItem = -1;
|
||||
}
|
||||
reloadAdvances();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -589,12 +622,14 @@ public class ManageOrderElementAdvancesController extends
|
|||
Listitem item = (Listitem) comp.getParent().getParent();
|
||||
DirectAdvanceAssignment advance = (DirectAdvanceAssignment) item
|
||||
.getValue();
|
||||
if (value == null) {
|
||||
((Decimalbox) comp).setValue(advance.getMaxValue());
|
||||
((Decimalbox) comp).invalidate();
|
||||
throw new WrongValueException(
|
||||
comp,
|
||||
_("The max value must be not empty"));
|
||||
if (!manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advance)) {
|
||||
if (value == null) {
|
||||
((Decimalbox) comp).setValue(advance.getMaxValue());
|
||||
((Decimalbox) comp).invalidate();
|
||||
throw new WrongValueException(comp,
|
||||
_("The max value must be not empty"));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -651,7 +686,6 @@ public class ManageOrderElementAdvancesController extends
|
|||
((Decimalbox) value.getFirstChild()).invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Chart chart;
|
||||
|
|
@ -695,29 +729,47 @@ public class ManageOrderElementAdvancesController extends
|
|||
}
|
||||
}
|
||||
|
||||
private void cleanFields(){
|
||||
this.manageOrderElementAdvancesModel.cleanAdvance();
|
||||
Util.reloadBindings(self);
|
||||
private void cleanFields(DirectAdvanceAssignment advance) {
|
||||
this.manageOrderElementAdvancesModel
|
||||
.cleanAdvance((DirectAdvanceAssignment) advance);
|
||||
}
|
||||
|
||||
private void setReportGlobalAdvance(final Listitem item){
|
||||
for(int i=0; i< editAdvances.getChildren().size(); i++){
|
||||
if(editAdvances.getChildren().get(i) instanceof Listitem){
|
||||
Listitem listItem = (Listitem) editAdvances.getChildren().get(i);
|
||||
Listcell celdaSpread = (Listcell) listItem.getChildren().get(5);
|
||||
Radio radioSpread = ((Radio)celdaSpread.getFirstChild());
|
||||
if(!radioSpread.isDisabled()){
|
||||
radioSpread.setChecked(false);
|
||||
((AdvanceAssignment) listItem.getValue())
|
||||
.setReportGlobalAdvance(false);
|
||||
boolean spread = true;
|
||||
if (!radioSpreadIsConsolidated()) {
|
||||
for (int i = 0; i < editAdvances.getChildren().size(); i++) {
|
||||
if (editAdvances.getChildren().get(i) instanceof Listitem) {
|
||||
Listitem listItem = (Listitem) editAdvances.getChildren()
|
||||
.get(i);
|
||||
Listcell celdaSpread = (Listcell) listItem.getChildren()
|
||||
.get(5);
|
||||
Radio radioSpread = ((Radio) celdaSpread.getFirstChild());
|
||||
if (!radioSpread.isDisabled()) {
|
||||
radioSpread.setChecked(false);
|
||||
((AdvanceAssignment) listItem.getValue())
|
||||
.setReportGlobalAdvance(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
spread = false;
|
||||
}
|
||||
Listcell celdaSpread = (Listcell) item.getChildren().get(5);
|
||||
((Radio)celdaSpread.getFirstChild()).setChecked(true);
|
||||
((AdvanceAssignment) item.getValue()).setReportGlobalAdvance(true);
|
||||
((Radio) celdaSpread.getFirstChild()).setChecked(spread);
|
||||
((AdvanceAssignment) item.getValue()).setReportGlobalAdvance(spread);
|
||||
}
|
||||
|
||||
private boolean radioSpreadIsConsolidated() {
|
||||
for (AdvanceAssignment advance : getAdvanceAssignments()) {
|
||||
if ((advance.getReportGlobalAdvance())
|
||||
&& (manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advance))) {
|
||||
showMessagesConsolidation(1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean validateDataForm(){
|
||||
return ((validateListAdvanceAssignment())
|
||||
|
|
@ -845,7 +897,12 @@ public class ManageOrderElementAdvancesController extends
|
|||
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
updatesValue(value);
|
||||
if (manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advanceMeasurement)) {
|
||||
showMessagesConsolidation(2);
|
||||
} else {
|
||||
updatesValue(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -859,9 +916,11 @@ public class ManageOrderElementAdvancesController extends
|
|||
|
||||
@Override
|
||||
public void set(BigDecimal value) {
|
||||
advanceMeasurement.setValue(value);
|
||||
Util.reloadBindings(chart);
|
||||
Util.reloadBindings(editAdvances);
|
||||
if (!manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advanceMeasurement)) {
|
||||
advanceMeasurement.setValue(value);
|
||||
reloadAdvances();
|
||||
}
|
||||
}
|
||||
});
|
||||
value.setConstraint(checkValidValue());
|
||||
|
|
@ -883,7 +942,7 @@ public class ManageOrderElementAdvancesController extends
|
|||
private void appendDateboxDate(final Listitem listitem) {
|
||||
final AdvanceMeasurement advanceMeasurement = (AdvanceMeasurement) listitem
|
||||
.getValue();
|
||||
Datebox date = new Datebox();
|
||||
final Datebox date = new Datebox();
|
||||
|
||||
Listcell listcell = new Listcell();
|
||||
listcell.appendChild(date);
|
||||
|
|
@ -894,7 +953,12 @@ public class ManageOrderElementAdvancesController extends
|
|||
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
setCurrentDate(listitem);
|
||||
if (manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advanceMeasurement)) {
|
||||
showMessagesConsolidation(2);
|
||||
} else {
|
||||
setCurrentDate(listitem);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -912,10 +976,13 @@ public class ManageOrderElementAdvancesController extends
|
|||
|
||||
@Override
|
||||
public void set(Date value) {
|
||||
advanceMeasurement.setDate(new LocalDate(value));
|
||||
manageOrderElementAdvancesModel
|
||||
if (!manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advanceMeasurement)) {
|
||||
advanceMeasurement.setDate(new LocalDate(value));
|
||||
manageOrderElementAdvancesModel
|
||||
.sortListAdvanceMeasurement();
|
||||
Util.reloadBindings(self);
|
||||
reloadAdvances();
|
||||
}
|
||||
}
|
||||
});
|
||||
date.setConstraint(checkValidDate());
|
||||
|
|
@ -927,7 +994,9 @@ public class ManageOrderElementAdvancesController extends
|
|||
public void validate(Component comp, Object value)
|
||||
throws WrongValueException {
|
||||
AdvanceMeasurement advanceMeasurement = getAdvanceMeasurementByComponent(comp);
|
||||
if (advanceMeasurement != null) {
|
||||
if ((advanceMeasurement != null)
|
||||
&& (!manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advanceMeasurement))) {
|
||||
advanceMeasurement.setValue((BigDecimal) value);
|
||||
if (((BigDecimal) value) == null) {
|
||||
throw new WrongValueException(
|
||||
|
|
@ -977,29 +1046,32 @@ public class ManageOrderElementAdvancesController extends
|
|||
public void validate(Component comp, Object value)
|
||||
throws WrongValueException {
|
||||
AdvanceMeasurement advanceMeasurement = getAdvanceMeasurementByComponent(comp);
|
||||
if (((Date) value) == null) {
|
||||
advanceMeasurement.setDate(null);
|
||||
throw new WrongValueException(
|
||||
comp,
|
||||
_("The date is not valid, the date must be not empty"));
|
||||
} else {
|
||||
if (!manageOrderElementAdvancesModel
|
||||
.isDistinctValidDate((Date) value,
|
||||
advanceMeasurement)) {
|
||||
if ((!manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advanceMeasurement))) {
|
||||
if (((Date) value) == null) {
|
||||
advanceMeasurement.setDate(null);
|
||||
throw new WrongValueException(
|
||||
comp,
|
||||
_("The date is not valid, the date must be unique for this advanced assignment"));
|
||||
}
|
||||
if (advanceMeasurement != null) {
|
||||
advanceMeasurement.setDate(new LocalDate(
|
||||
(Date) value));
|
||||
manageOrderElementAdvancesModel
|
||||
.sortListAdvanceMeasurement();
|
||||
if (manageOrderElementAdvancesModel
|
||||
.lessThanPreviousMeasurements()) {
|
||||
_("The date is not valid, the date must be not empty"));
|
||||
} else {
|
||||
if (!manageOrderElementAdvancesModel
|
||||
.isDistinctValidDate((Date) value,
|
||||
advanceMeasurement)) {
|
||||
throw new WrongValueException(
|
||||
comp,
|
||||
_("Value is not valid, the value must be greater than the value of the previous advances."));
|
||||
_("The date is not valid, the date must be unique for this advanced assignment"));
|
||||
}
|
||||
if (advanceMeasurement != null) {
|
||||
advanceMeasurement.setDate(new LocalDate(
|
||||
(Date) value));
|
||||
manageOrderElementAdvancesModel
|
||||
.sortListAdvanceMeasurement();
|
||||
if (manageOrderElementAdvancesModel
|
||||
.lessThanPreviousMeasurements()) {
|
||||
throw new WrongValueException(
|
||||
comp,
|
||||
_("Value is not valid, the value must be greater than the value of the previous advances."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1016,9 +1088,14 @@ public class ManageOrderElementAdvancesController extends
|
|||
removeButton.addEventListener(Events.ON_CLICK, new EventListener() {
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
manageOrderElementAdvancesModel
|
||||
if (manageOrderElementAdvancesModel
|
||||
.hasConsolidatedAdvances(advance)) {
|
||||
showMessagesConsolidation(2);
|
||||
} else {
|
||||
manageOrderElementAdvancesModel
|
||||
.removeLineAdvanceMeasurement(advance);
|
||||
Util.reloadBindings(self);
|
||||
reloadAdvances();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -1047,4 +1124,19 @@ public class ManageOrderElementAdvancesController extends
|
|||
manageOrderElementAdvancesModel.refreshChangesFromOrderElement();
|
||||
}
|
||||
|
||||
private void showMessagesConsolidation(int opcion) {
|
||||
String message = "";
|
||||
switch (opcion) {
|
||||
case 1:
|
||||
message = _("This advance can not be changed or removed, because it has got consolidated advances. It is needed removing the consolidation on all its advances.");
|
||||
break;
|
||||
case 2:
|
||||
message = _("This advance measurement can not be changed or removed, because it is consolidated. It is needed removing its consolidation.");
|
||||
break;
|
||||
}
|
||||
if (!StringUtils.isBlank(message)) {
|
||||
messagesForUser.showMessage(Level.ERROR, message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ import java.math.RoundingMode;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
|
|
@ -51,6 +53,8 @@ import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
|||
import org.navalplanner.business.orders.daos.IOrderElementDAO;
|
||||
import org.navalplanner.business.orders.entities.OrderElement;
|
||||
import org.navalplanner.business.orders.entities.OrderLineGroup;
|
||||
import org.navalplanner.business.planner.entities.consolidations.CalculatedConsolidatedValue;
|
||||
import org.navalplanner.business.planner.entities.consolidations.CalculatedConsolidation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
|
|
@ -176,10 +180,22 @@ public class ManageOrderElementAdvancesModel implements
|
|||
private void forceLoadAdvanceAssignmentsAndMeasurements() {
|
||||
for (DirectAdvanceAssignment each : orderElement
|
||||
.getDirectAdvanceAssignments()) {
|
||||
each.getAdvanceMeasurements().size();
|
||||
forceLoadAdvanceConsolidatedValues(each);
|
||||
each.getNonCalculatedConsolidation().size();
|
||||
}
|
||||
if (orderElement instanceof OrderLineGroup) {
|
||||
((OrderLineGroup) orderElement).getIndirectAdvanceAssignments().size();
|
||||
for (IndirectAdvanceAssignment each : ((OrderLineGroup) orderElement)
|
||||
.getIndirectAdvanceAssignments()) {
|
||||
each.getCalculatedConsolidation().size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void forceLoadAdvanceConsolidatedValues(
|
||||
DirectAdvanceAssignment advance) {
|
||||
for (AdvanceMeasurement measurement : advance.getAdvanceMeasurements()) {
|
||||
measurement.getNonCalculatedConsolidatedValues().size();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -302,18 +318,18 @@ public class ManageOrderElementAdvancesModel implements
|
|||
}
|
||||
|
||||
@Override
|
||||
public void cleanAdvance(){
|
||||
if (this.advanceAssignment != null) {
|
||||
this.advanceAssignment.setReportGlobalAdvance(false);
|
||||
List<AdvanceMeasurement> listAdvanceMeasurements = new ArrayList<AdvanceMeasurement>(
|
||||
this.advanceAssignment.getAdvanceMeasurements());
|
||||
for (AdvanceMeasurement advanceMeasurement : listAdvanceMeasurements) {
|
||||
advanceMeasurement.setValue(BigDecimal.ZERO);
|
||||
advanceMeasurement.setDate(null);
|
||||
}
|
||||
public void cleanAdvance(DirectAdvanceAssignment advanceAssignment) {
|
||||
if (advanceAssignment != null) {
|
||||
advanceAssignment.setReportGlobalAdvance(false);
|
||||
advanceAssignment.getAdvanceMeasurements().clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetAdvanceAssignment() {
|
||||
this.advanceAssignment = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void confirmSave() throws InstanceNotFoundException,
|
||||
|
|
@ -561,6 +577,50 @@ public class ManageOrderElementAdvancesModel implements
|
|||
return xymodel;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public boolean hasConsolidatedAdvances(AdvanceAssignment advance) {
|
||||
if (advance instanceof DirectAdvanceAssignment) {
|
||||
if ((advance.getReportGlobalAdvance())
|
||||
&& (!((DirectAdvanceAssignment) advance)
|
||||
.getNonCalculatedConsolidation().isEmpty())) {
|
||||
return true;
|
||||
}
|
||||
return (!((DirectAdvanceAssignment) advance).isFake())
|
||||
&& (containsAnyConsolidatedAdvanceMeasurement((DirectAdvanceAssignment) advance));
|
||||
|
||||
} else {
|
||||
return ((advance.getReportGlobalAdvance()) && (!((IndirectAdvanceAssignment) advance)
|
||||
.getCalculatedConsolidation().isEmpty()));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean containsAnyConsolidatedAdvanceMeasurement(
|
||||
DirectAdvanceAssignment advance) {
|
||||
Iterator<AdvanceMeasurement> iterator = advance
|
||||
.getAdvanceMeasurements().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (hasConsolidatedAdvances(iterator.next())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public boolean hasConsolidatedAdvances(
|
||||
AdvanceMeasurement advanceMeasurement) {
|
||||
|
||||
if (advanceMeasurement.isNewObject() || isIndirectAdvanceAssignment) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!advanceMeasurement.getNonCalculatedConsolidatedValues().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
return findIndirectConsolidation(advanceMeasurement);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public boolean isQualityForm(AdvanceAssignment advance) {
|
||||
|
|
@ -569,4 +629,69 @@ public class ManageOrderElementAdvancesModel implements
|
|||
return advanceType.isQualityForm();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public boolean findIndirectConsolidation(
|
||||
AdvanceMeasurement advanceMeasurement) {
|
||||
|
||||
AdvanceAssignment advance = advanceMeasurement.getAdvanceAssignment();
|
||||
if ((orderElement != null) && (orderElement.getParent() != null) && (advance instanceof DirectAdvanceAssignment)) {
|
||||
|
||||
List<String> types = new ArrayList<String>();
|
||||
|
||||
types.add(advance.getAdvanceType().getUnitName());
|
||||
if (advance.getReportGlobalAdvance()) {
|
||||
types.add(PredefinedAdvancedTypes.CHILDREN.getTypeName());
|
||||
}
|
||||
|
||||
Set<IndirectAdvanceAssignment> indirects = getSpreadIndirectAdvanceAssignmentWithSameType(
|
||||
orderElement, types);
|
||||
|
||||
for (IndirectAdvanceAssignment indirect : indirects) {
|
||||
if (findConsolidatedAdvance(indirect
|
||||
.getCalculatedConsolidation(), advanceMeasurement)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Set<IndirectAdvanceAssignment> getSpreadIndirectAdvanceAssignmentWithSameType(
|
||||
OrderElement orderElement, List<String> types) {
|
||||
|
||||
orderElementDAO.reattach(orderElement);
|
||||
Set<IndirectAdvanceAssignment> result = new HashSet<IndirectAdvanceAssignment>();
|
||||
|
||||
for (IndirectAdvanceAssignment indirect : orderElement
|
||||
.getIndirectAdvanceAssignments()) {
|
||||
if ((indirect.getReportGlobalAdvance())
|
||||
&& (types.contains(indirect.getAdvanceType().getUnitName()))) {
|
||||
result.add(indirect);
|
||||
}
|
||||
}
|
||||
|
||||
OrderElement parent = orderElement.getParent();
|
||||
if (parent != null) {
|
||||
result.addAll(getSpreadIndirectAdvanceAssignmentWithSameType(
|
||||
parent, types));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean findConsolidatedAdvance(
|
||||
Set<CalculatedConsolidation> consolidations,
|
||||
AdvanceMeasurement advance) {
|
||||
for (CalculatedConsolidation consolidation : consolidations) {
|
||||
for (CalculatedConsolidatedValue value : consolidation
|
||||
.getCalculatedConsolidatedValues()) {
|
||||
if (value.getDate().compareTo(advance.getDate()) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
|
|||
InputElement codeBox = (InputElement)
|
||||
((Treecell)row.getChildren().get(1)).getChildren().get(0);
|
||||
InputElement nameBox = (InputElement)
|
||||
((Treecell)row.getChildren().get(2)).getChildren().get(1);
|
||||
((Treecell)row.getChildren().get(2)).getChildren().get(0);
|
||||
InputElement hoursBox = (InputElement)
|
||||
((Treecell)row.getChildren().get(3)).getChildren().get(0);
|
||||
InputElement initDateBox = (InputElement)
|
||||
|
|
@ -423,30 +423,13 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
|
|||
|
||||
@Override
|
||||
protected void addDescriptionCell(OrderElement element) {
|
||||
addTaskNumberCell(element);
|
||||
addTaskNameCell(element);
|
||||
}
|
||||
|
||||
private void addTaskNumberCell(final OrderElement orderElementForThisRow) {
|
||||
private void addTaskNameCell(final OrderElement orderElementForThisRow) {
|
||||
int[] path = getModel().getPath(orderElementForThisRow);
|
||||
String cssClass = "depth_" + path.length;
|
||||
|
||||
Label taskNumber = new Label(pathAsString(path));
|
||||
taskNumber.setSclass("tasknumber");
|
||||
taskNumber.addEventListener(Events.ON_DOUBLE_CLICK,
|
||||
new EventListener() {
|
||||
|
||||
@Override
|
||||
public void onEvent(Event event) throws Exception {
|
||||
IOrderElementModel model = orderModel
|
||||
.getOrderElementModel(orderElementForThisRow);
|
||||
orderElementController.openWindow(model);
|
||||
// Util.reloadBindings(tree);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// TODO It would be needed to expand the width for the numbers
|
||||
// to make it ready for 2 and 3 digit numbers
|
||||
Textbox textBox = Util.bind(new Textbox(),
|
||||
new Util.Getter<String>() {
|
||||
|
||||
|
|
@ -464,7 +447,7 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
|
|||
if (readOnly) {
|
||||
textBox.setDisabled(true);
|
||||
}
|
||||
addCell(cssClass, taskNumber, textBox);
|
||||
addCell(cssClass, textBox);
|
||||
registerKeyboardListener(textBox);
|
||||
}
|
||||
|
||||
|
|
@ -584,6 +567,7 @@ public class OrderElementTreeController extends TreeController<OrderElement> {
|
|||
notifyDateboxCantBeCreated(dateboxName, currentOrderElement
|
||||
.getCode());
|
||||
}
|
||||
registerFocusEvent(dinamicDatebox.getDateTextBox());
|
||||
addCell(cell);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -266,7 +266,12 @@ public abstract class AllocationRow {
|
|||
|
||||
public void setResourcesPerDay(ResourcesPerDay resourcesPerDay) {
|
||||
this.resourcesPerDay = resourcesPerDay;
|
||||
resourcesPerDayInput.setValue(this.resourcesPerDay.getAmount());
|
||||
resourcesPerDayInput.setValue(getAmount(resourcesPerDay));
|
||||
}
|
||||
|
||||
private BigDecimal getAmount(ResourcesPerDay resourcesPerDay) {
|
||||
return (resourcesPerDay != null) ? resourcesPerDay.getAmount()
|
||||
: new BigDecimal(0);
|
||||
}
|
||||
|
||||
public void setTemporal(ResourceAllocation<?> last) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue