You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by er...@apache.org on 2011/11/23 20:56:03 UTC

svn commit: r1205554 - in /ofbiz/trunk/specialpurpose/projectmgr: entitydef/entitymodel.xml script/org/ofbiz/project/ProjectServices.xml

Author: erwan
Date: Wed Nov 23 19:56:03 2011
New Revision: 1205554

URL: http://svn.apache.org/viewvc?rev=1205554&view=rev
Log:
A patch from Youssef Khaye - OFBIZ-4584 - improve proect manager service by using entity-views instead of loops

Modified:
    ofbiz/trunk/specialpurpose/projectmgr/entitydef/entitymodel.xml
    ofbiz/trunk/specialpurpose/projectmgr/script/org/ofbiz/project/ProjectServices.xml

Modified: ofbiz/trunk/specialpurpose/projectmgr/entitydef/entitymodel.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/projectmgr/entitydef/entitymodel.xml?rev=1205554&r1=1205553&r2=1205554&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/projectmgr/entitydef/entitymodel.xml (original)
+++ ofbiz/trunk/specialpurpose/projectmgr/entitydef/entitymodel.xml Wed Nov 23 19:56:03 2011
@@ -252,6 +252,168 @@ under the License.
     </relation>
   </view-entity>
 
+  <view-entity entity-name="ProjectPhaseTaskAssignmentView"
+    package-name="org.ofbiz.specialpurpose.project">
+    <description>This view is used to deduct project's status from its children tasks status and
+        to deduct the status of a task depending on its assigned resources and time entries</description>
+    <member-entity entity-alias="WEP" entity-name="WorkEffort"/><!--project -->
+    <member-entity entity-alias="WEPH" entity-name="WorkEffort"/><!-- phase -->
+    <member-entity entity-alias="WET" entity-name="WorkEffort"/><!-- task -->
+    <member-entity entity-alias="PAS" entity-name="WorkEffortPartyAssignment"/> <!-- Party assigned -->
+    <member-entity entity-alias="TE" entity-name="TimeEntry"/>
+
+    <alias entity-alias="WEP" field="workEffortId" name="projectId" group-by="true"/>
+    <alias entity-alias="WEPH" field="workEffortId" name="phaseId" group-by="true"/>
+    <alias entity-alias="WET" field="workEffortId" name="taskId" group-by="true"/>
+    <alias entity-alias="WET" field="currentStatusId" name="taskStatusId" group-by="true"/>
+    <alias entity-alias="PAS" field="partyId" name="resourceCount" function="count-distinct"/>
+    <alias entity-alias="TE" field="timeEntryId" name="entriesCount" function="count-distinct"/>
+    
+    <view-link entity-alias="WEP" rel-entity-alias="WEPH" rel-optional="true">
+      <key-map field-name="workEffortId" rel-field-name="workEffortParentId"/>
+    </view-link>
+    <view-link entity-alias="WEPH" rel-entity-alias="WET" rel-optional="true">
+      <key-map field-name="workEffortId" rel-field-name="workEffortParentId"/>
+    </view-link>
+    <view-link entity-alias="WET" rel-entity-alias="PAS" rel-optional="true">
+      <key-map field-name="workEffortId" />
+    </view-link>
+        <view-link entity-alias="WET" rel-entity-alias="TE" rel-optional="true">
+      <key-map field-name="workEffortId" />
+    </view-link>
+  </view-entity>
+
+  <view-entity entity-name="ProjectPhaseTaskSummaryView"
+    package-name="org.ofbiz.specialpurpose.project">
+    <description>Retrieve actual, estimated start and end dates, priority, planned hours</description>
+
+    <member-entity entity-alias="WEP" entity-name="WorkEffort"/><!--project -->
+    <member-entity entity-alias="WEPH" entity-name="WorkEffort"/><!-- phase -->
+    <member-entity entity-alias="WET" entity-name="WorkEffort"/><!-- task -->
+    <member-entity entity-alias="TE" entity-name="TimeEntry"/><!-- to get actualStartDate from declared times-->
+    <member-entity entity-alias="SKL" entity-name="WorkEffortSkillStandard"/> <!-- for planned hours -->
+
+    <alias entity-alias="WEP" field="workEffortId" name="projectId" group-by="true"/>
+    <alias entity-alias="WEPH" field="workEffortId" name="phaseId" group-by="true"/>
+    <alias entity-alias="WET" field="workEffortId" name="taskId" group-by="true"/>
+
+    <!-- get minimum for start dates -->
+    <alias entity-alias="WET" name="estimatedStartDate" function="min"/>
+    <alias entity-alias="WET" name="actualStartDate" function="min"/>
+    <alias entity-alias="TE" field="fromDate" name="actualEntryStartDate" function="min"/>
+
+    <!-- and maximum for completion dates -->
+    <alias entity-alias="WET" name="estimatedCompletionDate" function="max"/>
+    <alias entity-alias="WET" name="actualCompletionDate" function="max"/>
+    <alias entity-alias="TE" field="fromDate" name="actualEntryCompletionDate" function="max"/>
+
+    <!-- get the sum of planned and actual hours -->
+    <alias entity-alias="SKL" field="estimatedDuration" name="plannedHours" function="sum"/>
+    <!-- get the minimum priority -->
+    <alias entity-alias="WET" field="priority" name="priority" function="min"/>
+
+    <view-link entity-alias="WEP" rel-entity-alias="WEPH" rel-optional="true">
+      <key-map field-name="workEffortId" rel-field-name="workEffortParentId"/>
+    </view-link>
+    <view-link entity-alias="WEPH" rel-entity-alias="WET" rel-optional="true">
+      <key-map field-name="workEffortId" rel-field-name="workEffortParentId"/>
+    </view-link>
+    <view-link entity-alias="WET" rel-entity-alias="SKL" rel-optional="true">
+      <key-map field-name="workEffortId" />
+    </view-link>
+    <view-link entity-alias="WET" rel-entity-alias="TE" rel-optional="true">
+      <key-map field-name="workEffortId" />
+    </view-link>
+  </view-entity>
+
+  <view-entity entity-name="ProjectPhaseTaskActualHoursView"
+    package-name="org.ofbiz.specialpurpose.project">
+    <description>prepare actual hours total per project, phase or task,
+        this view is used by another view that do sums</description>
+    <member-entity entity-alias="WEP" entity-name="WorkEffort"/><!--project -->
+    <member-entity entity-alias="WEPH" entity-name="WorkEffort"/><!-- phase -->
+    <member-entity entity-alias="WET" entity-name="WorkEffort"/><!-- task -->
+    <member-entity entity-alias="TE" entity-name="TimeEntry"/>
+    <member-entity entity-alias="TS" entity-name="Timesheet"/>
+    <member-entity entity-alias="PR" entity-name="PartyRate"/>
+
+    <alias entity-alias="WEP" field="workEffortId" name="projectId" group-by="true"/>
+    <alias entity-alias="WEPH" field="workEffortId" name="phaseId" group-by="true"/>
+    <alias entity-alias="WET" field="workEffortId" name="taskId" group-by="true"/>
+    <alias entity-alias="TE" name="timeEntryId" group-by="true"/>
+    <alias entity-alias="TE" name="hours" group-by="true"/>
+    <alias entity-alias="TE" name="invoiceId" group-by="true"/>
+    <alias entity-alias="PR" name="partyId" group-by="true"/>
+    <alias entity-alias="PR" name="percentageUsed" function="max"/>
+
+    <view-link entity-alias="WEP" rel-entity-alias="WEPH" rel-optional="true">
+      <key-map field-name="workEffortId" rel-field-name="workEffortParentId"/>
+    </view-link>
+    <view-link entity-alias="WEPH" rel-entity-alias="WET" rel-optional="true">
+      <key-map field-name="workEffortId" rel-field-name="workEffortParentId"/>
+    </view-link>
+    <view-link entity-alias="WET" rel-entity-alias="TE" rel-optional="true">
+      <key-map field-name="workEffortId" />
+    </view-link>
+    <view-link entity-alias="TE" rel-entity-alias="TS" rel-optional="true">
+      <key-map field-name="timesheetId" />
+    </view-link>
+    <view-link entity-alias="TE" rel-entity-alias="PR" rel-optional="true">
+      <key-map field-name="rateTypeId"/>
+      <entity-condition>
+        <condition-list>
+            <condition-expr entity-alias="TS" field-name="partyId" rel-entity-alias="PR" rel-field-name="partyId"/>
+            <condition-expr entity-alias="PR" field-name="fromDate" operator="less-equals" rel-entity-alias="TE" rel-field-name="fromDate"/>
+            <condition-list combine="or">
+                <condition-expr entity-alias="PR" field-name="thruDate" operator="equals" value=""/>
+                <condition-expr entity-alias="PR" field-name="thruDate" operator="greater-equals" rel-entity-alias="TE" rel-field-name="fromDate"/>
+            </condition-list>
+        </condition-list>
+    </entity-condition>
+    </view-link>
+  </view-entity>
+
+  <view-entity entity-name="ProjectPhaseTaskActualRatedHoursView"
+    package-name="org.ofbiz.specialpurpose.project">
+    <description>get total actual hour for which there is a valid partyRate that can be applicable</description>
+    <member-entity entity-alias="PPAH" entity-name="ProjectPhaseTaskActualHoursView"/>
+
+    <alias entity-alias="PPAH" name="projectId" group-by="true"/>
+    <alias entity-alias="PPAH" name="phaseId" group-by="true"/>
+    <alias entity-alias="PPAH" name="taskId" group-by="true"/>
+    <alias entity-alias="PPAH" name="invoiceId" group-by="true"/>
+    <alias entity-alias="PPAH" name="totalOriginalHours" field="hours" function="sum"/>
+    <alias name="totalRatedHours" function="sum">
+        <complex-alias operator="/">
+            <complex-alias operator="*">
+                <complex-alias-field entity-alias="PPAH" field="hours"/>
+                <complex-alias-field entity-alias="PPAH" field="percentageUsed"/>
+            </complex-alias>
+            <complex-alias-field entity-alias="" field="" value="100"/>
+        </complex-alias>
+    </alias>
+
+    <entity-condition>
+        <condition-expr entity-alias="PPAH" field-name="percentageUsed" operator="not-equals" value=""/>
+    </entity-condition>
+  </view-entity>
+
+  <view-entity entity-name="ProjectPhaseTaskActualNotRatedHoursView"
+    package-name="org.ofbiz.specialpurpose.project">
+    <description>get total actual hour for which there is NO valid partyRate applicable</description>
+    <member-entity entity-alias="PPAH" entity-name="ProjectPhaseTaskActualHoursView"/>
+
+    <alias entity-alias="PPAH" name="projectId" group-by="true"/>
+    <alias entity-alias="PPAH" name="phaseId" group-by="true"/>
+    <alias entity-alias="PPAH" name="taskId" group-by="true"/>
+        <alias entity-alias="PPAH" name="invoiceId" group-by="true"/>
+    <alias entity-alias="PPAH" name="totalOriginalHours" field="hours" function="sum"/>
+
+    <entity-condition>
+        <condition-expr entity-alias="PPAH" field-name="percentageUsed" operator="equals" value=""/>
+    </entity-condition>
+  </view-entity>
+
   <view-entity entity-name="TimesheetAndTimeEntry"
     package-name="org.ofbiz.specialpurpose.project"
     title="Time entry for Timesheets, time entries always have a timesheet and are always for one day only and recording the hours for one person which is defined on the timesheet. A timesheet will always have at least one time entry.">

Modified: ofbiz/trunk/specialpurpose/projectmgr/script/org/ofbiz/project/ProjectServices.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/projectmgr/script/org/ofbiz/project/ProjectServices.xml?rev=1205554&r1=1205553&r2=1205554&view=diff
==============================================================================
--- ofbiz/trunk/specialpurpose/projectmgr/script/org/ofbiz/project/ProjectServices.xml (original)
+++ ofbiz/trunk/specialpurpose/projectmgr/script/org/ofbiz/project/ProjectServices.xml Wed Nov 23 19:56:03 2011
@@ -707,24 +707,8 @@
         <set field="highInfo.createdDate" from-field="project.createdDate"/>
         <set field="highInfo.parentProjectId" from-field="project.workEffortParentId"/>
         <!-- loop through the related phases and tasks -->
-        <get-related value-field="project" relation-name="ChildWorkEffort" list="phases"/>
-        <if-not-empty field="phases">
-            <iterate entry="phase" list="phases">
-                <get-related value-field="phase" relation-name="ChildWorkEffort" list="tasks"/>
-                <if-not-empty field="tasks">
-                    <iterate entry="lowInfo" list="tasks">
-                        <if-compare field="lowInfo.currentStatusId" value="PTS_COMPLETED" operator="not-equals">
-                            <if-compare field="lowInfo.currentStatusId" value="PTS_CANCELLED" operator="not-equals">
-                                <set field="allTaskStatus" value="notComplete"/>
-                            </if-compare>
-                        </if-compare>
-                        <call-simple-method method-name="combineInfo"/>
-                        <call-simple-method method-name="getHours" xml-resource="component://workeffort/script/org/ofbiz/workeffort/workeffort/WorkEffortSimpleServices.xml"/>
-                    </iterate>
-                </if-not-empty>
-            </iterate>
-        </if-not-empty>
-        
+        <call-simple-method method-name="combineInfo"/>
+
         <!-- get e-mail address -->
         <entity-and list="emailAddresses" entity-name="WorkEffortContactMechView">
             <field-map field-name="workEffortId" from-field="highInfo.projectId"/>
@@ -799,18 +783,7 @@
             <set field="highInfo.scopeEnumId" from-field="phase.scopeEnumId"/>
 
             <!-- loop through the related tasks and combine information -->
-            <get-related value-field="phase" relation-name="ChildWorkEffort" list="tasks"/>
-            <if-not-empty field="tasks">
-                <iterate entry="lowInfo" list="tasks">
-                    <if-compare field="lowInfo.currentStatusId" value="PTS_COMPLETED" operator="not-equals">
-                        <if-compare field="lowInfo.currentStatusId" value="PTS_CANCELLED" operator="not-equals">
-                            <set field="allTaskStatus" value="notComplete"/>
-                        </if-compare>
-                    </if-compare>
-                    <call-simple-method method-name="combineInfo"/>
-                    <call-simple-method method-name="getHours" xml-resource="component://workeffort/script/org/ofbiz/workeffort/workeffort/WorkEffortSimpleServices.xml"/>
-                </iterate>
-            </if-not-empty>
+            <call-simple-method method-name="combineInfo"/>
 
             <!-- merge estimated and actual dates -->
             <call-simple-method method-name="createDates"/>
@@ -894,8 +867,6 @@
         <set field="highInfo.scopeEnumId" from-field="lowInfo.scopeEnumId"/>
         <set field="highInfo.workEffortParentId" from-field="lowInfo.workEffortParentId"/>
         <call-simple-method method-name="combineInfo"/>
-        <call-simple-method method-name="getHours" xml-resource="component://workeffort/script/org/ofbiz/workeffort/workeffort/WorkEffortSimpleServices.xml"/>
-        <set field="highInfo.currentStatusId" from-field="lowInfo.currentStatusId"/>
         <field-to-result field="highInfo" result-name="taskInfo"/>
     </simple-method>
 
@@ -1017,7 +988,255 @@
     </simple-method>
 
     <!-- Internal functions  -->
+    <simple-method method-name="combineStatusInfo" short-description="combine lower level status">
+        <!-- the status for a project or phase is
+         IN_PROGRESS if at least one task still in progress
+         COMPLETED if all task are either completed or cancelled
+         CREATED if other conditions does not apply
+         For a task the status is
+         IN_PROGRESS if it has at least one resource and at least a time entry
+         ASSIGNED if it has at least one resource but no time entry associated
+         -->
+        <entity-count count-field="tasksCount" entity-name="ProjectPhaseTaskAssignmentView">
+            <condition-list>
+                <condition-expr field-name="projectId" from-field="highInfo.projectId" ignore-if-empty="true"/>
+                <condition-expr field-name="phaseId" from-field="highInfo.phaseId" ignore-if-empty="true"/>
+                <condition-expr field-name="taskId" from-field="highInfo.taskId" ignore-if-empty="true"/>
+            </condition-list>
+        </entity-count>
+        <log level="info" message="related tasks count ====> ${tasksCount}"/>
+        <entity-count count-field="completedTasks" entity-name="ProjectPhaseTaskAssignmentView">
+            <condition-list>
+                <condition-expr field-name="projectId" from-field="highInfo.projectId" ignore-if-empty="true"/>
+                <condition-expr field-name="phaseId" from-field="highInfo.phaseId" ignore-if-empty="true"/>
+                <condition-expr field-name="taskId" from-field="highInfo.taskId" ignore-if-empty="true"/>
+            </condition-list>
+            <having-condition-list combine="or">
+            <condition-expr field-name="taskStatusId" operator="equals" value="PTS_COMPLETED"/>
+            <condition-expr field-name="taskStatusId" operator="equals" value="PTS_CANCELLED"/>
+        </having-condition-list>
+        </entity-count>
+        <log level="info" message="related completed tasks count ====> ${completedTasks}"/>
+        <entity-count count-field="assignedTasks" entity-name="ProjectPhaseTaskAssignmentView">
+            <condition-list>
+                <condition-expr field-name="projectId" from-field="highInfo.projectId" ignore-if-empty="true"/>
+                <condition-expr field-name="phaseId" from-field="highInfo.phaseId" ignore-if-empty="true"/>
+                <condition-expr field-name="taskId" from-field="highInfo.taskId" ignore-if-empty="true"/>
+            </condition-list>
+            <having-condition-list combine="and">
+            <condition-expr field-name="entriesCount" value="0"/>
+            <condition-expr field-name="resourceCount" operator="greater-equals" value="1"/>
+            <condition-expr field-name="taskStatusId" operator="not-equals" value="PTS_COMPLETED"/>
+            <condition-expr field-name="taskStatusId" operator="not-equals" value="PTS_CANCELLED"/>
+        </having-condition-list>
+        </entity-count>
+        <log level="info" message="related assigned tasks count ====> ${assignedTasks}"/>
+        <entity-count count-field="inprogressTasks" entity-name="ProjectPhaseTaskAssignmentView">
+            <condition-list>
+                <condition-expr field-name="projectId" from-field="highInfo.projectId" ignore-if-empty="true"/>
+                <condition-expr field-name="phaseId" from-field="highInfo.phaseId" ignore-if-empty="true"/>
+                <condition-expr field-name="taskId" from-field="highInfo.taskId" ignore-if-empty="true"/>
+            </condition-list>
+            <having-condition-list combine="and">
+                <condition-expr field-name="entriesCount" operator="greater-equals" value="1"/>
+                <condition-expr field-name="resourceCount" operator="greater-equals" value="1"/>
+                <condition-expr field-name="taskStatusId" operator="not-equals" value="PTS_COMPLETED"/>
+                <condition-expr field-name="taskStatusId" operator="not-equals" value="PTS_CANCELLED"/>
+            </having-condition-list>
+        </entity-count>
+        <log level="info" message="related in progress tasks count ====> ${inprogressTasks}"/>
+        <if>
+            <condition>
+                <or>
+                    <if-compare operator="greater" field="inprogressTasks" type="Long" value="0"/>
+                    <if-compare operator="greater" field="assignedTasks" type="Long" value="0"/>
+                </or>
+            </condition>
+            <then>
+                <set field="highInfo.currentStatusId" value="PTS_CREATED_IP"/>
+            </then>
+            <else>
+                <if>
+                    <condition>
+                        <if-compare-field operator="equals" field="completedTasks" to-field="tasksCount"/>
+                    </condition>
+                    <then>
+                        <set field="highInfo.currentStatusId" value="PTS_COMPLETED"/>
+                    </then>
+                    <else>
+                        <set field="highInfo.currentStatusId" value="PTS_CREATED"/>
+                    </else>
+                </if>
+            </else>
+        </if>
+    </simple-method>
+
+    <simple-method method-name="combineDatesAndPlannedHoursInfo" short-description="combine lower level start end dates and planned hours for a project, phase or task">
+        <entity-condition  entity-name="ProjectPhaseTaskSummaryView" list="summaryInfos">
+            <condition-list>
+                <condition-expr field-name="projectId" from-field="highInfo.projectId" ignore-if-empty="true"/>
+                <condition-expr field-name="phaseId" from-field="highInfo.phaseId" ignore-if-empty="true"/>
+                <condition-expr field-name="taskId" from-field="highInfo.taskId" ignore-if-empty="true"/>
+            </condition-list>
+            <select-field field-name="projectId"/>
+            <select-field field-name="estimatedStartDate"/>
+            <select-field field-name="actualEntryStartDate"/>
+            <select-field field-name="actualStartDate"/>
+            <select-field field-name="estimatedCompletionDate"/>
+            <select-field field-name="actualCompletionDate"/>
+            <select-field field-name="actualEntryCompletionDate"/>
+            <select-field field-name="plannedHours"/>
+            <select-field field-name="priority"/>
+        </entity-condition>
+
+        <first-from-list entry="summaryInfo" list="summaryInfos"/>
+        <set field="highInfo.estimatedStartDate" from-field="summaryInfo.estimatedStartDate"/>
+        <set field="highInfo.estimatedCompletionDate" from-field="summaryInfo.estimatedCompletionDate"/>
+        <set field="highInfo.actualStartDate" from-field="summaryInfo.actualStartDate"/>
+        <set field="highInfo.actualCompletionDate" from-field="summaryInfo.actualCompletionDate"/>
+        <set field="highInfo.priority" from-field="summaryInfo.priority"/>
+        <set field="highInfo.plannedHours" from-field="summaryInfo.plannedHours"/>
+        <!-- update actual start date by the min date form sub tasks associated entries 
+        (if before actualStartDate field) -->
+        <if-not-empty field="summaryInfo.actualEntryStartDate">
+            <if>
+                <condition>
+                    <or>
+                        <if-empty field="highInfo.actualStartDate"/>
+                        <if-compare-field field="highInfo.actualStartDate" operator="greater" type="Timestamp" to-field="summaryInfo.actualEntryStartDate"/>
+                    </or>
+                </condition>
+                <then>
+                    <set field="highInfo.actualStartDate" from-field="summaryInfo.actualEntryStartDate"/>
+                </then>
+            </if>
+        </if-not-empty>
+        <!-- update actual completion date by the max date form sub tasks associated entries 
+        (if after actualCompletionDate field) -->
+        <if-not-empty field="summaryInfo.actualEntryCompletionDate">
+            <if>
+                <condition>
+                    <or>
+                        <if-empty field="highInfo.actualCompletionDate"/>
+                        <if-compare-field field="highInfo.actualCompletionDate" operator="less" type="Timestamp" to-field="summaryInfo.actualEntryCompletionDate"/>
+                    </or>
+                </condition>
+                <then>
+                    <set field="highInfo.actualCompletionDate" from-field="summaryInfo.actualEntryCompletionDate"/>
+                </then>
+            </if>
+        </if-not-empty>
+    </simple-method>
+
     <simple-method method-name="combineInfo" short-description="combine lower level status, dates of tasks.">
+        <call-simple-method method-name="combineStatusInfo"/>
+        <call-simple-method method-name="combineDatesAndPlannedHoursInfo"/>
+        <call-simple-method method-name="combineActualHours"/>
+    </simple-method>
+    <simple-method method-name="combineActualHours" short-description="combine lower level Actual hours info.">
+        <!-- 
+        -to calculate actual hours : the declared number of hours in time entry should be multiplied by the 
+         max percentage declared in PartyRate if a valid party rate can be found for the party associated to a
+         the timesheet associated to this time entry and has the same rateType as this timeEntry 
+        -actualHoursOriginal is the total of hours in time entries without application of percentage declared in partyRate
+         -->
+
+        <!-- I- get timeEntries for which there is no rate  (originalHours)-->
+        <entity-condition list="notRatedValues" entity-name="ProjectPhaseTaskActualNotRatedHoursView">
+            <condition-list>
+                <condition-expr field-name="projectId" from-field="highInfo.projectId" ignore-if-empty="true"/>
+                <condition-expr field-name="phaseId" from-field="highInfo.phaseId" ignore-if-empty="true"/>
+                <condition-expr field-name="taskId" from-field="highInfo.taskId" ignore-if-empty="true"/>
+            </condition-list>
+            <select-field field-name="totalOriginalHours"/>
+        </entity-condition>
+        <first-from-list entry="notRatedValue" list="notRatedValues"/>
+        <set field="originalHours" from-field="notRatedValue.totalOriginalHours" type="Double"/>
+
+        <!-- II- get total for timeEntries having a partyRate that should be applied
+        before applying rate (totalOriginalHours)
+        after applying rate (totalRatedHours)-->
+        <entity-condition list="ratedValues" entity-name="ProjectPhaseTaskActualRatedHoursView">
+            <condition-list>
+                <condition-expr field-name="projectId" from-field="highInfo.projectId" ignore-if-empty="true"/>
+                <condition-expr field-name="phaseId" from-field="highInfo.phaseId" ignore-if-empty="true"/>
+                <condition-expr field-name="taskId" from-field="highInfo.taskId" ignore-if-empty="true"/>
+            </condition-list>
+            <select-field field-name="totalOriginalHours"/>
+            <select-field field-name="totalRatedHours"/>
+        </entity-condition>
+        <first-from-list list="ratedValues" entry="ratedValue"/>
+        <call-object-method method-name="getDouble" obj-field="ratedValue" ret-field="actualHours">
+            <string value="totalRatedHours"/>
+        </call-object-method>
+
+        <if-empty field="actualHours">
+            <set field="actualHours" from-field="originalHours"/>
+            <else>
+                <calculate field="actualHours" type="Double">
+                    <calcop operator="add" field="originalHours">
+                        <calcop operator="get" field="actualHours"/>
+                    </calcop>
+                </calculate>
+            </else>
+        </if-empty>
+
+        <if-empty field="originalHours">
+            <set field="originalActualHours" from-field="ratedValue.totalOriginalHours" type="Double"/>
+            <else>
+                <calculate field="originalActualHours" type="Double">
+                    <calcop operator="add" field="originalHours">
+                        <calcop operator="get" field="ratedValue.totalOriginalHours"/>
+                    </calcop>
+                </calculate>
+            </else>
+        </if-empty>
+
+        <set field="highInfo.originalActualHours" from-field="originalActualHours"/>
+        <set field="highInfo.actualHours" from-field="actualHours"/>
+        <!-- do the same but for non-billed hours -->
+        <!-- first get not rated hours -->
+        <entity-condition list="notRatedValues" entity-name="ProjectPhaseTaskActualNotRatedHoursView">
+            <condition-list>
+                <condition-expr field-name="projectId" from-field="highInfo.projectId" ignore-if-empty="true"/>
+                <condition-expr field-name="phaseId" from-field="highInfo.phaseId" ignore-if-empty="true"/>
+                <condition-expr field-name="taskId" from-field="highInfo.taskId" ignore-if-empty="true"/>
+                <condition-expr field-name="invoiceId" from-field="nullField"/>
+            </condition-list>
+            <select-field field-name="totalOriginalHours"/>
+        </entity-condition>
+        <first-from-list entry="notRatedValue" list="notRatedValues"/>
+        <set field="actualNonBilledHours" from-field="notRatedValue.totalOriginalHours" type="Double"/>
+        <!-- second get non billed for entries having an invoiceId -->
+        <entity-condition list="ratedValues" entity-name="ProjectPhaseTaskActualRatedHoursView">
+            <condition-list>
+                <condition-expr field-name="projectId" from-field="highInfo.projectId" ignore-if-empty="true"/>
+                <condition-expr field-name="phaseId" from-field="highInfo.phaseId" ignore-if-empty="true"/>
+                <condition-expr field-name="taskId" from-field="highInfo.taskId" ignore-if-empty="true"/>
+                <condition-expr field-name="invoiceId" from-field="nullField"/>
+            </condition-list>
+            <select-field field-name="totalOriginalHours"/>
+            <select-field field-name="totalRatedHours"/>
+        </entity-condition>
+        <first-from-list list="ratedValues" entry="ratedValue"/>
+        <call-object-method method-name="getDouble" obj-field="ratedValue" ret-field="actualHours">
+            <string value="totalOriginalHours"/>
+        </call-object-method>
+
+        <if-not-empty field="actualNonBilledHours">
+            <calculate field="actualNonBilledHours" type="Double">
+                <calcop operator="get" field="actualNonBilledHours">
+                    <calcop operator="add" field="actualHours"/>
+                </calcop>
+            </calculate>
+            <else>
+                <set field="actualNonBilledHours" from-field="totalOriginalHours" type="Double"/>
+            </else>
+        </if-not-empty>
+        <set field="highInfo.actualNonBilledHours" from-field="actualNonBilledHours" type="Double"/>
+    </simple-method>
+
+    <simple-method method-name="combineInfoOld" short-description="combine lower level status, dates of tasks.">
         <!-- in/output highInfo infoMap -->
         <!-- input lowInfo info map -->
         <!-- set the dates from the lower level tasks -->