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 -->