You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ha...@apache.org on 2011/07/05 10:15:37 UTC

svn commit: r1142915 [11/28] - in /ofbiz/trunk/specialpurpose: ./ scrum/ scrum/config/ scrum/data/ scrum/data/helpdata/ scrum/data/hookscripts/ scrum/documents/ scrum/dtd/ scrum/entitydef/ scrum/lib/ scrum/patches/ scrum/script/ scrum/script/org/ scrum...

Added: ofbiz/trunk/specialpurpose/scrum/templates/CompletedBacklogNotification.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/templates/CompletedBacklogNotification.ftl?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/templates/CompletedBacklogNotification.ftl (added)
+++ ofbiz/trunk/specialpurpose/scrum/templates/CompletedBacklogNotification.ftl Tue Jul  5 08:15:32 2011
@@ -0,0 +1,37 @@
+<#--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+        <title>${title}</title>
+    </head>
+    <body>
+        <p>Hello ${person.firstName?if_exists} ${person.lastName?if_exists},</p>
+        <p>Your backlog <b>${custRequest.description?if_exists} [${custRequest.custRequestId}]</b> <#if informationMap.workEffortId?has_content>in sprint <b>${informationMap.workEffortName?if_exists} [${informationMap.workEffortId?if_exists}]</b></#if> 
+            <#if informationMap.productId?has_content>of the product <b>${informationMap.internalName?if_exists} [${informationMap.productId?if_exists}]</#if></b> has been completed.
+        <br />
+        <br />
+        <#if custRequest.fromPartyId == partyIdTo>
+        The complete information about this sprint can be found <a href="${StringUtil.wrapString(baseSecureUrl?if_exists)}/scrum/control/ViewProdBacklogItem?custRequestId=${custRequest.custRequestId?if_exists}">here.....</a>
+        <br /><br />
+        </#if>
+        Regards.<br /><br />
+        Thank you for your business.
+    </body>
+</html>

Propchange: ofbiz/trunk/specialpurpose/scrum/templates/CompletedBacklogNotification.ftl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/templates/CompletedBacklogNotification.ftl
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/templates/CompletedBacklogNotification.ftl
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/scrum/templates/ReviewedBacklogNotification.ftl
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/templates/ReviewedBacklogNotification.ftl?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/templates/ReviewedBacklogNotification.ftl (added)
+++ ofbiz/trunk/specialpurpose/scrum/templates/ReviewedBacklogNotification.ftl Tue Jul  5 08:15:32 2011
@@ -0,0 +1,38 @@
+<#--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+        <title>${title}</title>
+    </head>
+    <body>
+        <p>Hello ${person.firstName?if_exists} ${person.lastName?if_exists},</p>
+        <p>Your backlog <b>${custRequest.description?if_exists} [${custRequest.custRequestId}]</b> 
+        <#if informationMap.workEffortId?has_content>has been added to sprint <b>${informationMap.workEffortName?if_exists} [${informationMap.workEffortId?if_exists}]</b></#if><br /> 
+            <#if informationMap.productId?has_content>The related product: <b>${informationMap.internalName?if_exists} [${informationMap.productId?if_exists}]</#if></b>.
+        <br />
+        <br />
+        <#if custRequest.fromPartyId == partyIdTo>
+        The complete information about this sprint can be found <a href="${StringUtil.wrapString(baseSecureUrl?if_exists)}/scrum/control/ViewProdBacklogItem?custRequestId=${custRequest.custRequestId?if_exists}">here.....</a>
+        <br /><br />
+        </#if>
+        Regards.<br /><br />
+        Thank you for your business.
+    </body>
+</html>

Propchange: ofbiz/trunk/specialpurpose/scrum/templates/ReviewedBacklogNotification.ftl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/templates/ReviewedBacklogNotification.ftl
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/templates/ReviewedBacklogNotification.ftl
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/scrum/testdef/scrumTests.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/testdef/scrumTests.xml?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/testdef/scrumTests.xml (added)
+++ ofbiz/trunk/specialpurpose/scrum/testdef/scrumTests.xml Tue Jul  5 08:15:32 2011
@@ -0,0 +1,52 @@
+<test-suite suite-name="scrumtests"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/test-suite.xsd">
+
+        <test-case case-name="scrum-tests">
+            <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/ScrumTests.xml"/>
+        </test-case>
+        <test-case case-name="productBacklog-tests">
+             <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/ProductBacklogTest.xml"/>
+        </test-case>
+        <test-case case-name="scrumProject-tests">
+             <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/ScrumProjectTests.xml"/>
+        </test-case>
+        <test-case case-name="project-tests">
+             <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/ProjectTests.xml"/>
+        </test-case>
+        <test-case case-name="sprint-tests">
+             <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/SprintTests.xml"/>
+        </test-case>
+        <test-case case-name="sprintBacklog-tests">
+             <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/SprintBacklogTests.xml"/>
+        </test-case>
+        <test-case case-name="dailyMeetingMinute-tests">
+             <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/DailyMeetingMinuteTests.xml"/>
+        </test-case>
+        <test-case case-name="product-tests">
+             <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/ProductTest.xml"/>
+        </test-case>
+        <test-case case-name="task-test">
+            <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/TaskTests.xml"/>
+        </test-case>
+        <test-case case-name="myWork-test">
+            <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/MyWorkTests.xml"/>
+        </test-case>
+        <test-case case-name="timesheet-test">
+            <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/TimesheetTests.xml"/>
+        </test-case>
+        <!-- test-case case-name="qa-tests">
+             <simple-method-test location="component://scrum/script/org/ofbiz/scrum/test/QATests.xml"/>
+        </test-case-->
+        
+        <!-- Tests data load -->
+        <test-case case-name="scrum-type-data">
+            <entity-xml action="load" entity-xml-url="component://scrum/data/scrumTypeData.xml"/>
+        </test-case>
+        <test-case case-name="scrum-security-data">
+            <entity-xml action="load" entity-xml-url="component://scrum/data/scrumSecurityData.xml"/>
+        </test-case>
+        <test-case case-name="scrum-demo-data">
+            <entity-xml action="load" entity-xml-url="component://scrum/data/scrumDemoData.xml"/>
+        </test-case>
+</test-suite>

Propchange: ofbiz/trunk/specialpurpose/scrum/testdef/scrumTests.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/testdef/scrumTests.xml
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/testdef/scrumTests.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/controller.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/controller.xml?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/controller.xml (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/controller.xml Tue Jul  5 08:15:32 2011
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<site-conf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/site-conf.xsd">
+    <include location="component://common/webcommon/WEB-INF/common-controller.xml" />
+    <include location="component://humanres/webapp/humanres/WEB-INF/controller.xml" />
+    <include
+        location="component://workeffort/webapp/workeffort/WEB-INF/controller.xml" />
+    <description>scrum Component Site Configuration File</description>
+    <handler name="service-multi" type="request"
+        class="org.ofbiz.webapp.event.ServiceMultiEventHandler" />
+
+    <request-map uri="main">
+        <security https="false" auth="false" />
+        <response name="success" type="view" value="main" />
+    </request-map>
+    <request-map uri="demotest">
+        <security https="false" auth="false"/>
+        <event type="simple" invoke="setNewDemoUser" path="component://scrum/script/org/ofbiz/scrum/ScrumEvents.xml" />
+        <response name="success" type="url" value="../scrum/control/main" />
+        <response name="error" type="view" value="main" />
+    </request-map>
+
+    <view-map name="main" type="screen" page="component://scrum/widget/demotest/DemotestScreen.xml#main" />
+</site-conf>
\ No newline at end of file

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/controller.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/controller.xml
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/controller.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml Tue Jul  5 08:15:32 2011
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app>
+	<display-name>Open For Business - scrum Component</display-name>
+	<description>scrum Component of the Open For Business Project
+	</description>
+
+	<context-param>
+		<param-name>webSiteId</param-name>
+		<param-value>scrumSite</param-value>
+		<description>A unique ID used to look up the WebSite entity
+		</description>
+	</context-param>
+	<context-param>
+		<param-name>localDispatcherName</param-name>
+		<param-value>scrum</param-value>
+		<description>A unique name used to identify/recognize the local
+			dispatcher for the Service Engine</description>
+	</context-param>
+	<context-param>
+		<param-name>entityDelegatorName</param-name>
+		<param-value>default</param-value>
+		<description>The Name of the Entity Delegator to use, defined in
+			entityengine.xml</description>
+	</context-param>
+	<context-param>
+		<param-name>mainDecoratorLocation</param-name>
+		<param-value>component://scrum/widget/demotest/DemotestScreen.xml
+		</param-value>
+		<description>The location of the main-decorator screen to use for this
+			webapp; referred to as a context variable in screen def XML files.
+		</description>
+	</context-param>
+	<context-param>
+		<param-name>widgetVerbose</param-name>
+		<param-value>false</param-value>
+		<description>Enable widget boundary comments. See
+			org.ofbiz.widget.ModelWidget.widgetBoundaryCommentsEnabled().
+		</description>
+	</context-param>
+	<context-param>
+		<param-name>compressHTML</param-name>
+		<param-value>false</param-value>
+		<description>Remove unnecessary whitespace from HTML output.
+		</description>
+	</context-param>
+
+	<filter>
+		<filter-name>ContextFilter</filter-name>
+		<display-name>ContextFilter</display-name>
+		<filter-class>org.ofbiz.webapp.control.ContextFilter</filter-class>
+		<init-param>
+			<param-name>disableContextSecurity</param-name>
+			<param-value>N</param-value>
+		</init-param>
+		<init-param>
+			<param-name>allowedPaths</param-name>
+			<param-value>/error:/control:/select:/index.html:/index.jsp:/default.html:/default.jsp:/images:/includes/maincss.css
+			</param-value>
+		</init-param>
+		<init-param>
+			<param-name>errorCode</param-name>
+			<param-value>403</param-value>
+		</init-param>
+		<init-param>
+			<param-name>redirectPath</param-name>
+			<param-value>/control/main</param-value>
+		</init-param>
+	</filter>
+	<filter-mapping>
+		<filter-name>ContextFilter</filter-name>
+		<url-pattern>/*</url-pattern>
+	</filter-mapping>
+
+	<listener>
+		<listener-class>org.ofbiz.webapp.control.ControlEventListener
+		</listener-class>
+	</listener>
+	<listener>
+		<listener-class>org.ofbiz.webapp.control.LoginEventListener
+		</listener-class>
+	</listener>
+	<!--
+		NOTE: not all app servers support mounting implementations of the
+		HttpSessionActivationListener interface
+	-->
+	<!--
+		<listener><listener-class>org.ofbiz.webapp.control.ControlActivationEventListener</listener-class></listener>
+	-->
+
+	<servlet>
+		<servlet-name>ControlServlet</servlet-name>
+		<display-name>ControlServlet</display-name>
+		<description>Main Control Servlet</description>
+		<servlet-class>org.ofbiz.webapp.control.ControlServlet</servlet-class>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+	<servlet-mapping>
+		<servlet-name>ControlServlet</servlet-name>
+		<url-pattern>/control/*</url-pattern>
+	</servlet-mapping>
+
+	<session-config>
+		<session-timeout>60</session-timeout><!-- in minutes -->
+	</session-config>
+
+	<welcome-file-list>
+		<welcome-file>index.jsp</welcome-file>
+		<welcome-file>index.html</welcome-file>
+		<welcome-file>index.htm</welcome-file>
+	</welcome-file-list>
+</web-app>
\ No newline at end of file

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/WEB-INF/web.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/error/error.jsp
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/demotest/error/error.jsp?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/demotest/error/error.jsp (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/demotest/error/error.jsp Tue Jul  5 08:15:32 2011
@@ -0,0 +1,34 @@
+<%@ page import="org.ofbiz.base.util.*" %>
+<html>
+<head>
+<title>Open For Business Message</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+
+<% String errorMsg = (String) request.getAttribute("_ERROR_MESSAGE_"); %>
+
+<body bgcolor="#FFFFFF">
+<div align="center">
+  <br/>
+  <table width="100%" border="1" height="200">
+    <tr>
+      <td>
+        <table width="100%" border="0" height="200">
+          <tr bgcolor="#CC6666">
+            <td height="45">
+              <div align="center"><font face="Verdana, Arial, Helvetica, sans-serif" size="4" color="#FFFFFF"><b>:ERROR MESSAGE:</b></font></div>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <div align="left"><font face="Verdana, Arial, Helvetica, sans-serif" size="2"><%=UtilFormatOut.replaceString(errorMsg, "\n", "<br/>")%></font></div>
+            </td>
+          </tr>
+        </table>
+      </td>
+    </tr>
+  </table>
+</div>
+<div align="center"></div>
+</body>
+</html>
\ No newline at end of file

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/error/error.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/error/error.jsp
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/error/error.jsp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/index.jsp
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/demotest/index.jsp?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/demotest/index.jsp (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/demotest/index.jsp Tue Jul  5 08:15:32 2011
@@ -0,0 +1 @@
+<%response.sendRedirect("control/main");%>
\ No newline at end of file

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/index.jsp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/index.jsp
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/demotest/index.jsp
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy Tue Jul  5 08:15:32 2011
@@ -0,0 +1,137 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import java.sql.*;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import net.fortuna.ical4j.model.DateTime;
+import org.ofbiz.base.util.*;
+import org.ofbiz.entity.condition.*;
+import sun.util.calendar.LocalGregorianCalendar.Date;
+
+def module = "AddProductBacklogItem.groovy";
+
+// find cust request and items
+def performFindInMap = [:];
+performFindInMap.entityName = "CustRequestAndCustRequestItem";
+def inputFields = [:];
+
+if(parameters.statusId == null){
+    parameters.statusId = "";
+}else if("Any".equals(parameters.statusId)){
+    parameters.statusId = "";
+}
+inputFields.putAll(parameters);
+inputFields.custRequestTypeId = "RF_PROD_BACKLOG";
+performFindInMap.inputFields = inputFields;
+performFindInMap.orderBy = "sequenceNum";
+def performFindResults = dispatcher.runSync("performFind", performFindInMap);
+def custRequestAndItems = performFindResults.listIt.getCompleteList();
+performFindResults.listIt.close();
+
+// prepare cust request item list [cust request and item Map]
+def countSequence = 1;
+def custRequestAndCustRequestItems = [];
+custRequestAndItems.each() { custRequestAndItem ->
+    def tempCustRequestAndItem = [:];
+    tempCustRequestAndItem.putAll(custRequestAndItem);
+    tempCustRequestAndItem.sequenceNum = countSequence;
+    tempCustRequestAndItem.realSequenceNum = custRequestAndItem.sequenceNum;
+    // if custRequest has task then get Actual Hours
+    custWorkEffortList = delegator.findByAnd("CustRequestWorkEffort",["custRequestId" : custRequestAndItem.custRequestId]);
+    if (custWorkEffortList) {
+        actualHours = 0.00;
+        custWorkEffortList.each() { custWorkEffortMap ->
+            result = dispatcher.runSync("getScrumActualHour", ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
+            actualHours += result.actualHours;
+        }
+        if(actualHours) {
+            tempCustRequestAndItem.actualHours = actualHours;
+        } else {
+            tempCustRequestAndItem.actualHours = null;
+        }
+    } else {
+        tempCustRequestAndItem.actualHours = null;
+    }
+    custRequestAndCustRequestItems.add(tempCustRequestAndItem);
+    countSequence ++;
+}
+
+if ("N".equals(parameters.sequence)) { // re-order category list item
+    custRequestAndCustRequestItems = UtilMisc.sortMaps(custRequestAndCustRequestItems, ["parentCustRequestId"]);
+}
+//set status back for display in Find screen
+if("".equals(parameters.statusId)){
+    parameters.statusId = "Any";
+}
+context.custRequestAndCustRequestItems = custRequestAndCustRequestItems;
+
+// unplanned backlog item list
+
+productId = parameters.productId;
+
+conditionList = [];
+orConditionList = [];
+mainConditionList = [];
+
+conditionList.add(EntityCondition.makeCondition("custRequestTypeId", EntityOperator.EQUALS, "RF_UNPLAN_BACKLOG"));
+conditionList.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, parameters.productId));
+
+orConditionList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "CRQ_ACCEPTED"));
+orConditionList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "CRQ_REOPENED"));
+
+orConditions = EntityCondition.makeCondition(orConditionList, EntityOperator.OR);
+conditions = EntityCondition.makeCondition(conditionList, EntityOperator.AND);
+
+mainConditionList.add(orConditions);
+mainConditionList.add(conditions);
+mainConditions = EntityCondition.makeCondition(mainConditionList, EntityOperator.AND);
+
+unplannedList = delegator.findList("CustRequestAndCustRequestItem", mainConditions, ["custRequestId", "sequenceNum", "statusId", "description", "estimatedMilliSeconds", "custRequestName", "parentCustRequestId"] as Set, ["sequenceNum"], null, false);
+
+def countSequenceUnplanned = 1;
+def unplanBacklogItems = [];
+unplannedList.each() { unplannedItem ->
+    def tempUnplanned = [:];
+    tempUnplanned.putAll(unplannedItem);
+    tempUnplanned.sequenceNum = countSequenceUnplanned;
+    tempUnplanned.realSequenceNum = unplannedItem.sequenceNum;
+    // if custRequest has task then get Actual Hours
+    unplanCustWorkEffortList = delegator.findByAnd("CustRequestWorkEffort",["custRequestId" : unplannedItem.custRequestId]);
+    if (unplanCustWorkEffortList) {
+        actualHours = 0.00;
+        unplanCustWorkEffortList.each() { custWorkEffortMap ->
+            result = dispatcher.runSync("getScrumActualHour", ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
+            actualHours += result.actualHours;
+        }
+        if(actualHours) {
+            tempUnplanned.actualHours = actualHours;
+        } else {
+            tempUnplanned.actualHours = null;
+        }
+    } else {
+        tempUnplanned.actualHours = null;
+    }
+    unplanBacklogItems.add(tempUnplanned);
+    countSequenceUnplanned ++;
+}
+if ("N".equals(parameters.UnplannedSequence)) { // re-order category list item
+    unplanBacklogItems = UtilMisc.sortMaps(unplanBacklogItems, ["parentCustRequestId"]);
+}
+context.unplanBacklogItems = unplanBacklogItems;

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddProductBacklogItem.groovy
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy Tue Jul  5 08:15:32 2011
@@ -0,0 +1,56 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements.  See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership.  The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License.  You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied.  See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+import java.util.*;
+import org.ofbiz.base.util.Debug;
+
+partyId = parameters.partyId
+// get existing task that no assign
+projectSprintBacklogAndTaskList = [];
+projectAndTaskList = delegator.findByAnd("ProjectSprintBacklogAndTask", ["sprintTypeId" : "SCRUM_SPRINT","taskCurrentStatusId" : "STS_CREATED"], ["taskId DESC"]);
+projectAndTaskList.each { projectAndTaskMap ->
+userLoginId = userLogin.partyId;
+    projectId = projectAndTaskMap.projectId;
+    partyAssignmentProjectList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : projectId, "partyId" : partyId]);
+    partyAssignmentProjectMap = partyAssignmentProjectList[0];
+        // if this userLoginId is a member of project
+        if (partyAssignmentProjectMap) {
+            sprintId = projectAndTaskMap.sprintId;
+            partyAssignmentSprintList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : sprintId, "partyId" : partyId]);
+            partyAssignmentSprintMap = partyAssignmentSprintList[0];
+            // if this userLoginId is a member of sprint
+            if (partyAssignmentSprintMap) {
+                workEffortId = projectAndTaskMap.taskId;
+                partyAssignmentTaskList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : workEffortId]);
+                partyAssignmentTaskMap = partyAssignmentTaskList[0];
+                // if the task do not assigned
+                if (!partyAssignmentTaskMap) {
+                    projectSprintBacklogAndTaskList.add(projectAndTaskMap);
+                    // if the task do not assigned and assigned with custRequestTypeId = RF_SCRUM_MEETINGS
+                    } else {
+                        custRequestTypeId = projectAndTaskMap.custRequestTypeId;
+                        backlogStatusId = projectAndTaskMap.backlogStatusId;
+                        if (custRequestTypeId.equals("RF_SCRUM_MEETINGS") && backlogStatusId.equals("CRQ_REVIEWED")) {
+                            projectSprintBacklogAndTaskList.add(projectAndTaskMap);
+                           }
+                     }
+                }
+            }
+    }
+context.projectSprintBacklogAndTaskList = projectSprintBacklogAndTaskList;
\ No newline at end of file

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/AddResourceTaskParty.groovy
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy Tue Jul  5 08:15:32 2011
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.ofbiz.base.util.*;
+import org.ofbiz.entity.condition.*;
+
+def module = "BacklogNotifications.groovy";
+
+custRequest = delegator.findByPrimaryKey("CustRequest", ["custRequestId" : custRequestId]);
+person = delegator.findByPrimaryKey("PartyNameView", ["partyId" : partyIdTo]);
+informationMap = [:];
+informationMap.internalName = null;
+informationMap.productId = null;
+informationMap.workEffortName = null;
+informationMap.workEffortId = null;
+
+//check in sprint
+andExprs = [EntityCondition.makeCondition("workEffortTypeId", EntityOperator.EQUALS, "SCRUM_SPRINT"),
+            EntityCondition.makeCondition("custRequestId", EntityOperator.EQUALS, custRequestId)];
+backlogCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
+backlogList = delegator.findList("ProductBacklog", backlogCond, ["productId", "workEffortId", "custRequestId"] as Set ,null ,null, false);
+if (backlogList) {
+    product = delegator.findByPrimaryKey("Product", ["productId" : backlogList[0].productId]);
+    sprint = delegator.findByPrimaryKey("WorkEffort", ["workEffortId" : backlogList[0].workEffortId]);
+    informationMap.internalName = product.internalName;
+    informationMap.productId = product.productId;
+    informationMap.workEffortName = sprint.workEffortName;
+    informationMap.workEffortId = sprint.workEffortId;
+} else {
+    andExprs = [EntityCondition.makeCondition("custRequestId", EntityOperator.EQUALS, custRequestId)];
+    backlogCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
+    backlogList = delegator.findList("ProductBacklog", backlogCond, ["productId", "workEffortId", "custRequestId"] as Set ,null ,null, false);
+    if (backlogList) {
+        if (backlogList[0].productId) {
+            product = delegator.findByPrimaryKey("Product", ["productId" : backlogList[0].productId]);
+            informationMap.internalName = product.internalName;
+            informationMap.productId = product.productId;
+        }
+    }
+}
+// check backlog removed from sprint.
+removedFromSprint = false;
+if ("CRQ_ACCEPTED".equals(custRequest.statusId)) {
+    custStatusList = custRequest.getRelated("CustRequestStatus", ["-custRequestStatusId"]);
+    if (custStatusList.size() > 2 && "CRQ_REVIEWED".equals(custStatusList[1].statusId)) {
+        removedFromSprint = true;
+        }
+    }
+
+context.custRequest = custRequest;
+context.person = person;
+context.informationMap = informationMap;
+context.removedFromSprint = removedFromSprint;

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/BacklogNotifications.groovy
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy Tue Jul  5 08:15:32 2011
@@ -0,0 +1,484 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.*;
+import java.lang.*;
+import org.ofbiz.base.util.*;
+import org.ofbiz.entity.*;
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilDateTime;
+import org.ofbiz.entity.util.*;
+import org.ofbiz.entity.condition.*;
+import org.ofbiz.webapp.website.WebSiteWorker;
+import java.sql.Timestamp;
+
+uiLabelMap = UtilProperties.getResourceBundleMap("scrumUiLabels", locale);
+partyId = parameters.partyId;
+if (!partyId) {
+    partyId = parameters.userLogin.partyId;
+}
+
+// show the requested timesheet, otherwise the current , if not exist create
+timesheet = null;
+timesheetId = parameters.timesheetId;
+if (timesheetId) {
+    timesheet = delegator.findByPrimaryKey("Timesheet", ["timesheetId" : timesheetId]);
+    partyId = timesheet.partyId; // use the party from this timesheet
+} else {
+    // make sure because of timezone changes, not a duplicate timesheet is created
+    midweek = UtilDateTime.addDaysToTimestamp(UtilDateTime.getWeekStart(UtilDateTime.nowTimestamp()),3);
+    entryExprs = EntityCondition.makeCondition([
+        EntityCondition.makeCondition("fromDate", EntityComparisonOperator.LESS_THAN, midweek),
+        EntityCondition.makeCondition("thruDate", EntityComparisonOperator.GREATER_THAN, midweek),
+        EntityCondition.makeCondition("partyId", EntityComparisonOperator.EQUALS, partyId)
+        ], EntityOperator.AND);
+    entryIterator = delegator.find("Timesheet", entryExprs, null, null, null, null);
+    timesheet = entryIterator.next();
+    entryIterator.close();
+    if (timesheet == null) {
+        result = dispatcher.runSync("createProjectTimesheet", ["userLogin" : parameters.userLogin, "partyId" : partyId]);
+        if (result && result.timesheetId) {
+            timesheet = delegator.findByPrimaryKey("Timesheet", ["timesheetId" : result.timesheetId]);
+        }
+    }
+}
+if (!timesheet) return;
+context.timesheet = timesheet;
+context.weekNumber = UtilDateTime.weekNumber(timesheet.fromDate);
+
+// get the user names
+context.partyNameView = delegator.findByPrimaryKey("PartyNameView",["partyId" : partyId]);
+// get the default rate for this person
+rateTypes = EntityUtil.filterByDate(delegator.findByAnd("PartyRate", ["partyId" : partyId, "defaultRate" : "Y"]));
+if (rateTypes) {
+    context.defaultRateTypeId = rateTypes[0].rateTypeId;
+}
+
+entries = [];
+entry = ["timesheetId" : timesheet.timesheetId];
+leaveEntry = ["timesheetId" : timesheet.timesheetId];
+taskTotal = 0.00;
+planTotal = 0.00;
+leaveTaskTotal = 0.00;
+leavePlanTotal = 0.00;
+day0Total = 0.00; day1Total=0.00; day2Total=0.00; day3Total=0.00; day4Total=0.00; day5Total=0.00; day6Total=0.00;
+pDay0Total = 0.00; pDay1Total=0.00; pDay2Total=0.00; pDay3Total=0.00; pDay4Total=0.00; pDay5Total=0.00; pDay6Total=0.00;
+pHours = 0.00;
+timeEntry = null;
+lastTimeEntry = null;
+emplLeaveEntry = null;
+lastEmplLeaveEntry = null;
+
+// retrieve work effort data when the workeffortId has changed.
+void retrieveWorkEffortData() {
+        // get the planned number of hours
+        entryWorkEffort = lastTimeEntry.getRelatedOne("WorkEffort");
+        if (entryWorkEffort) {
+            plannedHours = entryWorkEffort.getRelated("WorkEffortSkillStandard");
+            pHours = 0.00;
+            plannedHours.each { plannedHour ->
+                if (plannedHour.estimatedDuration) {
+                    pHours += plannedHour.estimatedDuration;
+                }
+            }
+            estimatedHour =  0.00;
+            
+            estimatedMilliSeconds = entryWorkEffort.estimatedMilliSeconds
+            if (estimatedMilliSeconds > 0) 
+                estimatedHour = estimatedMilliSeconds/3600000;
+            entry.plannedHours = estimatedHour;
+            //entry.plannedHours = pHours;
+            planHours = 0.0;
+            planHours = lastTimeEntry.planHours;
+            lastTimeEntryOfTasks = delegator.findByAnd("TimeEntry", ["workEffortId" : lastTimeEntry.workEffortId, "partyId" : partyId], ["-fromDate"]);
+            if (lastTimeEntryOfTasks.size() != 0) lastTimeEntry = lastTimeEntryOfTasks[0];
+            if (planHours < 1) {
+                planHours = estimatedHour;
+            }
+            entry.planHours = lastTimeEntry.planHours;
+            actualHours = entryWorkEffort.getRelated("TimeEntry");
+            aHours = 0.00;
+            actualHours.each { actualHour ->
+                if (actualHour.hours) {
+                    aHours += actualHour.hours;
+                }
+            }
+            entry.actualHours = aHours;
+            // get party assignment data to be able to set the task to complete
+            workEffortPartyAssigns = EntityUtil.filterByDate(entryWorkEffort.getRelatedByAnd("WorkEffortPartyAssignment", ["partyId" : partyId]));
+            if (workEffortPartyAssigns) {
+                workEffortPartyAssign = workEffortPartyAssigns[0];
+                entry.fromDate = workEffortPartyAssign.getTimestamp("fromDate");
+                entry.roleTypeId = workEffortPartyAssign.roleTypeId;
+                if ("SCAS_COMPLETED".equals(workEffortPartyAssign.statusId)) {
+                    entry.checkComplete = "Y";
+                    
+                }
+            } else {
+                if ("STS_COMPLETED".equals(entryWorkEffort.currentStatusId)) {
+                    entry.checkComplete = "Y";
+                }
+            }
+
+            // get project/phase information
+            entry.workEffortId = entryWorkEffort.workEffortId;
+            entry.workEffortName = entryWorkEffort.workEffortName;
+            result = dispatcher.runSync("getProjectInfoFromTask", ["userLogin" : parameters.userLogin,"taskId" : entryWorkEffort.workEffortId]);
+                entry.phaseId = result.phaseId;
+                entry.phaseName = result.phaseName;
+                entry.projectId = result.projectId;
+                entry.projectName = result.projectName;
+                entry.taskWbsId = result.taskWbsId;
+
+        }
+        entry.acualTotal = taskTotal;
+        entry.planTotal = planTotal;
+        //Drop Down Lists
+        if (entry.checkComplete != "Y") {
+            if (aHours > 0.00)
+                entries.add(entry);
+        } else {
+                entries.add(entry);
+        }
+        // start new entry
+        taskTotal = 0.00;
+        planTotal = 0.00;
+        entry = ["timesheetId" : timesheet.timesheetId];
+}
+
+timeEntries = timesheet.getRelated("TimeEntry", ["workEffortId", "rateTypeId", "fromDate"]);
+te = timeEntries.iterator();
+while (te.hasNext()) {
+    // only fill lastTimeEntry when not the first time
+    if (timeEntry!=void) {
+        lastTimeEntry = timeEntry;
+    }
+    timeEntry = te.next();
+
+    if (lastTimeEntry &&
+            (!lastTimeEntry.workEffortId.equals(timeEntry.workEffortId) ||
+            !lastTimeEntry.rateTypeId.equals(timeEntry.rateTypeId))) {
+            retrieveWorkEffortData();
+        }
+    if (timeEntry.hours) {
+        dayNumber = "d" + (timeEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
+        hours = timeEntry.hours.doubleValue();
+        entry.put(String.valueOf(dayNumber), hours);
+        if (dayNumber.equals("d0")) day0Total += hours;
+        if (dayNumber.equals("d1")) day1Total += hours;
+        if (dayNumber.equals("d2")) day2Total += hours;
+        if (dayNumber.equals("d3")) day3Total += hours;
+        if (dayNumber.equals("d4")) day4Total += hours;
+        if (dayNumber.equals("d5")) day5Total += hours;
+        if (dayNumber.equals("d6")) day6Total += hours;
+        taskTotal += hours;
+    }
+    if (timeEntry.planHours) {
+        dayNumber = "pd" + (timeEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
+        planHours = timeEntry.planHours.doubleValue();
+        entry.put(String.valueOf(dayNumber), planHours);
+        if (dayNumber.equals("pd0")) pDay0Total += planHours;
+        if (dayNumber.equals("pd1")) pDay1Total += planHours;
+        if (dayNumber.equals("pd2")) pDay2Total += planHours;
+        if (dayNumber.equals("pd3")) pDay3Total += planHours;
+        if (dayNumber.equals("pd4")) pDay4Total += planHours;
+        if (dayNumber.equals("pd5")) pDay5Total += planHours;
+        if (dayNumber.equals("pd6")) pDay6Total += planHours;
+        planTotal += planHours;
+
+    }
+    entry.rateTypeId = timeEntry.rateTypeId;
+}
+//retrieve Empl Leave data.
+void retrieveEmplLeaveData() {
+        if (lastEmplLeaveEntry) {
+            //service get Hours
+            inputMap = [:];
+            inputMap.userLogin = parameters.userLogin;
+            inputMap.partyId = lastEmplLeaveEntry.partyId;
+            inputMap.leaveTypeId = lastEmplLeaveEntry.leaveTypeId;
+            inputMap.fromDate = lastEmplLeaveEntry.fromDate;
+            result = dispatcher.runSync("getPartyLeaveHoursForDate", inputMap);
+            if (result.hours) {
+                leaveEntry.plannedHours = result.hours;
+                leaveEntry.planHours =  result.hours;
+            }
+            if (lastEmplLeaveEntry.leaveStatus == "LEAVE_APPROVED") {
+                leaveEntry.checkComplete = "Y";
+            }
+            leaveEntry.partyId = lastEmplLeaveEntry.partyId;
+            leaveEntry.leaveTypeId = lastEmplLeaveEntry.leaveTypeId;
+            leaveEntry.leavefromDate = lastEmplLeaveEntry.fromDate;
+            leaveEntry.leavethruDate = lastEmplLeaveEntry.thruDate;
+            leaveEntry.description = lastEmplLeaveEntry.description;
+        }
+        leaveEntry.acualTotal = leaveTaskTotal;
+        leaveEntry.planHours = leavePlanTotal;
+        leaveEntry.actualHours = leaveTaskTotal;
+        //Drop Down Lists
+        entries.add(leaveEntry);
+        // start new leaveEntry
+        leaveTaskTotal = 0.00;
+        leavePlanTotal = 0.00;
+        leaveEntry = ["timesheetId" : timesheet.timesheetId];
+   }
+
+// define condition
+findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
+leaveExprs = [];
+leaveExprs.add(EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN_EQUAL_TO, timesheet.fromDate));
+leaveExprs.add(EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, timesheet.thruDate));
+leaveExprs.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId));
+emplLeave = delegator.find("EmplLeave", EntityCondition.makeCondition(leaveExprs, EntityOperator.AND), null, null, null, findOpts);
+
+while ((emplLeaveMap = emplLeave.next())) {
+    if (emplLeaveEntry!=void) {
+        lastEmplLeaveEntry = emplLeaveEntry;
+    }
+    
+    emplLeaveEntry = emplLeaveMap;
+    
+    if (lastEmplLeaveEntry && (
+            !lastEmplLeaveEntry.leaveTypeId.equals(emplLeaveEntry.leaveTypeId) ||
+            !lastEmplLeaveEntry.partyId.equals(emplLeaveEntry.partyId))) {
+            retrieveEmplLeaveData();
+        }
+    input = [:];
+    input.userLogin = parameters.userLogin;
+    input.partyId = emplLeaveEntry.partyId;
+    input.leaveTypeId = emplLeaveEntry.leaveTypeId;
+    input.fromDate = emplLeaveEntry.fromDate;
+    resultHours = dispatcher.runSync("getPartyLeaveHoursForDate", input);
+    
+    if (resultHours.hours) {
+        leaveDayNumber = "d" + (emplLeaveEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
+        inputMap = [:];
+        inputMap.userLogin = parameters.userLogin;
+        inputMap.partyId = emplLeaveEntry.partyId;
+        inputMap.leaveTypeId = emplLeaveEntry.leaveTypeId;
+        inputMap.fromDate = emplLeaveEntry.fromDate;
+        resultHours = dispatcher.runSync("getPartyLeaveHoursForDate", inputMap);
+        leaveHours = resultHours.hours.doubleValue();
+        leaveEntry.put(String.valueOf(leaveDayNumber), leaveHours);
+        if (leaveDayNumber.equals("d0")) day0Total += leaveHours;
+        if (leaveDayNumber.equals("d1")) day1Total += leaveHours;
+        if (leaveDayNumber.equals("d2")) day2Total += leaveHours;
+        if (leaveDayNumber.equals("d3")) day3Total += leaveHours;
+        if (leaveDayNumber.equals("d4")) day4Total += leaveHours;
+        if (leaveDayNumber.equals("d5")) day5Total += leaveHours;
+        if (leaveDayNumber.equals("d6")) day6Total += leaveHours;
+        leaveTaskTotal += leaveHours;
+    }
+    if (resultHours.hours) {
+        leavePlanDay = "pd" + (emplLeaveEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
+        inputMap = [:];
+        inputMap.userLogin = parameters.userLogin;
+        inputMap.partyId = emplLeaveEntry.partyId;
+        inputMap.leaveTypeId = emplLeaveEntry.leaveTypeId;
+        inputMap.fromDate = emplLeaveEntry.fromDate;
+        resultPlanHours = dispatcher.runSync("getPartyLeaveHoursForDate", inputMap);
+        leavePlanHours = resultPlanHours.hours.doubleValue();
+        leaveEntry.put(String.valueOf(leavePlanDay), leavePlanHours);
+        if (leavePlanDay.equals("pd0")) pDay0Total += leavePlanHours;
+        if (leavePlanDay.equals("pd1")) pDay1Total += leavePlanHours;
+        if (leavePlanDay.equals("pd2")) pDay2Total += leavePlanHours;
+        if (leavePlanDay.equals("pd3")) pDay3Total += leavePlanHours;
+        if (leavePlanDay.equals("pd4")) pDay4Total += leavePlanHours;
+        if (leavePlanDay.equals("pd5")) pDay5Total += leavePlanHours;
+        if (leavePlanDay.equals("pd6")) pDay6Total += leavePlanHours;
+        leavePlanTotal += leavePlanHours;
+    }
+    leaveEntry.rateTypeId = "STANDARD";
+}
+emplLeave.close();
+
+if (timeEntry) {
+    lastTimeEntry = timeEntry;
+    retrieveWorkEffortData();
+    }
+if (emplLeaveEntry) {
+    lastEmplLeaveEntry = emplLeaveEntry;
+    retrieveEmplLeaveData();
+    }
+
+// add empty lines if timesheet not completed
+if (!timesheet.statusId.equals("TIMESHEET_COMPLETED")) {
+    for (c=0; c < 3; c++) { // add empty lines
+        entries.add(["timesheetId" : timesheet.timesheetId]);
+    }
+}
+
+// add the totals line if at least one entry
+if (timeEntry || emplLeaveEntry) {
+    entry = ["timesheetId" : timesheet.timesheetId];
+    entry.d0 = day0Total;
+    entry.d1 = day1Total;
+    entry.d2 = day2Total;
+    entry.d3 = day3Total;
+    entry.d4 = day4Total;
+    entry.d5 = day5Total;
+    entry.d6 = day6Total;
+    entry.pd0 = pDay0Total;
+    entry.pd1 = pDay1Total;
+    entry.pd2 = pDay2Total;
+    entry.pd3 = pDay3Total;
+    entry.pd4 = pDay4Total;
+    entry.pd5 = pDay5Total;
+    entry.pd6 = pDay6Total;
+    entry.phaseName = uiLabelMap.ScrumTotals;
+    entry.workEffortId = "Totals";
+    entry.total = day0Total + day1Total + day2Total + day3Total + day4Total + day5Total + day6Total;
+    entries.add(entry);
+}
+context.timeEntries = entries;
+// get all timesheets of this user, including the planned hours
+timesheetsDb = delegator.findByAnd("Timesheet", ["partyId" : partyId], ["fromDate DESC"]);
+timesheets = new LinkedList();
+timesheetsDb.each { timesheetDb ->
+    //get hours from EmplLeave;
+    findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
+    leaveExprsList = [];
+    leaveExprsList.add(EntityCondition.makeCondition("fromDate", EntityOperator.GREATER_THAN_EQUAL_TO, timesheetDb.fromDate));
+    leaveExprsList.add(EntityCondition.makeCondition("fromDate", EntityOperator.LESS_THAN_EQUAL_TO, timesheetDb.thruDate));
+    leaveExprsList.add(EntityCondition.makeCondition("partyId", EntityOperator.EQUALS, partyId));
+    emplLeaveList = delegator.find("EmplLeave", EntityCondition.makeCondition(leaveExprsList, EntityOperator.AND), null, null, null, findOpts);
+    leaveHours = 0.00;
+    
+    while ((emplLeaveMap = emplLeaveList.next())) {
+        emplLeaveEntry = emplLeaveMap;
+        inputData = [:];
+        inputData.userLogin = parameters.userLogin;
+        inputData.partyId = emplLeaveEntry.partyId;
+        inputData.leaveTypeId = emplLeaveEntry.leaveTypeId;
+        inputData.fromDate = emplLeaveEntry.fromDate;
+        resultHour = dispatcher.runSync("getPartyLeaveHoursForDate", inputData);
+        if (resultHour) {
+            leaveActualHours = resultHour.hours.doubleValue();
+            leaveHours += leaveActualHours;
+        }
+    }
+    //get hours from TimeEntry;
+    timesheet = [:];
+    timesheet.putAll(timesheetDb);
+    entries = timesheetDb.getRelated("TimeEntry");
+    hours = 0.00;
+    entries.each { timeEntry ->
+        if (timeEntry.hours) {
+            hours += timeEntry.hours.doubleValue();
+        }
+    }
+    timesheet.weekNumber = UtilDateTime.weekNumber(timesheetDb.fromDate);
+    timesheet.hours = hours + leaveHours;
+    timesheets.add(timesheet);
+    emplLeaveList.close();
+}
+context.timesheets = timesheets;
+
+// get existing task that no assign
+taskList=[];
+projectSprintBacklogAndTaskList = [];
+backlogIndexList = [];
+projectAndTaskList = delegator.findByAnd("ProjectSprintBacklogAndTask", ["sprintTypeId" : "SCRUM_SPRINT","taskCurrentStatusId" : "STS_CREATED"], ["projectName ASC","taskActualStartDate DESC"]);
+projectAndTaskList.each { projectAndTaskMap ->
+userLoginId = userLogin.partyId;
+    sprintId = projectAndTaskMap.sprintId;
+    workEffortList = delegator.findByAnd("WorkEffortAndProduct", ["workEffortId" : projectAndTaskMap.projectId]);
+    backlogIndexList.add(workEffortList[0].productId);
+	
+    partyAssignmentSprintList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : sprintId, "partyId" : userLoginId]);
+    partyAssignmentSprintMap = partyAssignmentSprintList[0];
+    // if this userLoginId is a member of sprint
+    if (partyAssignmentSprintMap) {
+        workEffortId = projectAndTaskMap.taskId;
+        partyAssignmentTaskList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : workEffortId]);
+        partyAssignmentTaskMap = partyAssignmentTaskList[0];
+        // if the task do not assigned
+        if (partyAssignmentTaskMap) {
+            custRequestTypeId = projectAndTaskMap.custRequestTypeId;
+			backlogStatusId = projectAndTaskMap.backlogStatusId;
+			if (custRequestTypeId.equals("RF_SCRUM_MEETINGS") && backlogStatusId.equals("CRQ_REVIEWED")) {
+				projectSprintBacklogAndTaskList.add(projectAndTaskMap);
+			   }
+            } else {
+					projectSprintBacklogAndTaskList.add(0,projectAndTaskMap);
+             }
+        }
+    }
+
+// for unplanned taks.
+unplanList=[];
+if (backlogIndexList) {
+    backlogIndex = new HashSet(backlogIndexList);
+    custRequestList = delegator.findByAnd("CustRequest", ["custRequestTypeId" : "RF_UNPLAN_BACKLOG","statusId" : "CRQ_REVIEWED"],["custRequestDate DESC"]);
+    if (custRequestList) {
+        custRequestList.each { custRequestMap ->
+            custRequestItemList = custRequestMap.getRelated("CustRequestItem");
+			custRequestItem =  
+			productOut = custRequestItemList[0].productId;
+			product = delegator.findByPrimaryKey("Product", ["productId" : productOut]);
+            backlogIndex.each { backlogProduct ->
+                productId = backlogProduct
+                if (productId.equals(productOut)) {
+                    custRequestWorkEffortList = delegator.findByAnd("CustRequestWorkEffort", ["custRequestId" : custRequestItemList[0].custRequestId]);
+                    custRequestWorkEffortList.each { custRequestWorkEffortMap ->
+                        partyAssignmentTaskList = delegator.findByAnd("WorkEffortPartyAssignment", ["workEffortId" : custRequestWorkEffortMap.workEffortId]);
+                        partyAssignmentTaskMap = partyAssignmentTaskList[0];
+                        // if the task do not assigned
+                        if (!partyAssignmentTaskMap) {
+                            result = [:];
+                            workEffortMap = delegator.findByPrimaryKey("WorkEffort", ["workEffortId" : custRequestWorkEffortMap.workEffortId]);
+                            result.description = custRequestMap.description;
+                            result.productName = product.internalName;
+                            result.taskId = workEffortMap.workEffortId;
+                            result.taskName = workEffortMap.workEffortName;
+							result.custRequestTypeId = custRequestMap.custRequestTypeId;
+							result.taskTypeId = workEffortMap.workEffortTypeId;
+                            unplanList.add(result);
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+projectSprintBacklogAndTaskList = UtilMisc.sortMaps(projectSprintBacklogAndTaskList, ["projectName","sprintName","-taskTypeId","custRequestId"]);
+projectSprintBacklogAndTaskList.each { projectSprintBacklogAndTaskMap ->
+	blTypeId = projectSprintBacklogAndTaskMap.custRequestTypeId;
+	if (blTypeId == "RF_SCRUM_MEETINGS"){
+		taskList.add(projectSprintBacklogAndTaskMap);
+	}
+}
+projectSprintBacklogAndTaskList = UtilMisc.sortMaps(projectSprintBacklogAndTaskList, ["-projectName","sprintName","-taskTypeId","custRequestId"]);
+projectSprintBacklogAndTaskList.each { projectSprintBacklogAndTaskMap ->
+	blTypeId = projectSprintBacklogAndTaskMap.custRequestTypeId;
+	if (blTypeId == "RF_PROD_BACKLOG"){
+		taskList.add(0,projectSprintBacklogAndTaskMap);
+	}
+}
+unplanList = UtilMisc.sortMaps(unplanList,["-productName","-taskTypeId","custRequestId"]);
+unplanList.each { unplanMap->
+		taskList.add(0,unplanMap);
+}
+context.taskList = taskList;
+
+// notification context
+webSiteId = WebSiteWorker.getWebSiteId(request);
+context.webSiteId = webSiteId;

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditDailyHourReport.groovy
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy Tue Jul  5 08:15:32 2011
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.*;
+import java.lang.*;
+import org.ofbiz.base.util.*;
+import org.ofbiz.entity.*;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilDateTime;
+import org.ofbiz.entity.util.*;
+import org.ofbiz.entity.condition.*;
+import java.sql.Timestamp;
+
+uiLabelMap = UtilProperties.getResourceBundleMap("scrumUiLabels", locale);
+
+partyId = parameters.partyId;
+if (!partyId) {
+    partyId = parameters.userLogin.partyId;
+}
+
+// show the requested timesheet, otherwise the current , if not exist create
+timesheet = null;
+timesheetId = parameters.timesheetId;
+if (timesheetId) {
+    timesheet = delegator.findByPrimaryKey("Timesheet", ["timesheetId" : timesheetId]);
+    partyId = timesheet.partyId; // use the party from this timesheet
+} else {
+    // make sure because of timezone changes, not a duplicate timesheet is created
+    midweek = UtilDateTime.addDaysToTimestamp(UtilDateTime.getWeekStart(UtilDateTime.nowTimestamp()),3);
+    entryExprs = EntityCondition.makeCondition([
+        EntityCondition.makeCondition("fromDate", EntityComparisonOperator.LESS_THAN, midweek),
+        EntityCondition.makeCondition("thruDate", EntityComparisonOperator.GREATER_THAN, midweek),
+        EntityCondition.makeCondition("partyId", EntityComparisonOperator.EQUALS, partyId)
+        ], EntityOperator.AND);
+    entryIterator = delegator.find("Timesheet", entryExprs, null, null, null, null);
+    timesheet = entryIterator.next();
+    entryIterator.close();
+    if (timesheet == null) {
+        result = dispatcher.runSync("createProjectTimesheet", ["userLogin" : parameters.userLogin, "partyId" : partyId]);
+        if (result && result.timesheetId) {
+            timesheet = delegator.findByPrimaryKey("Timesheet", ["timesheetId" : result.timesheetId]);
+        }
+    }
+}
+if (!timesheet) return;
+context.timesheet = timesheet;
+context.weekNumber = UtilDateTime.weekNumber(timesheet.fromDate);
+
+// get the user names
+context.partyNameView = delegator.findByPrimaryKey("PartyNameView",["partyId" : partyId]);
+// get the default rate for this person
+rateTypes = EntityUtil.filterByDate(delegator.findByAnd("PartyRate", ["partyId" : partyId, "defaultRate" : "Y"]));
+if (rateTypes) {
+    context.defaultRateTypeId = rateTypes[0].rateTypeId;
+}
+
+entries = [];
+entry = ["timesheetId" : timesheet.timesheetId];
+taskTotal = 0.00;
+day0Total = 0.00; day1Total=0.00; day2Total=0.00; day3Total=0.00; day4Total=0.00; day5Total=0.00; day6Total=0.00;
+pHours = 0.00;
+timeEntry = null;
+lastTimeEntry = null;
+
+// retrieve work effort data when the workeffortId has changed.
+void retrieveWorkEffortData() {
+        // get the planned number of hours
+        entryWorkEffort = lastTimeEntry.getRelatedOne("WorkEffort");
+        if (entryWorkEffort) {
+            plannedHours = entryWorkEffort.getRelated("WorkEffortSkillStandard");
+            pHours = 0.00;
+            plannedHours.each { plannedHour ->
+                if (plannedHour.estimatedDuration) {
+                    pHours += plannedHour.estimatedDuration;
+                }
+            }
+            entry.plannedHours = pHours;
+            actualHours = entryWorkEffort.getRelated("TimeEntry");
+            aHours = 0.00;
+            actualHours.each { actualHour ->
+                if (actualHour.hours) {
+                    aHours += actualHour.hours;
+                }
+            }
+            entry.actualHours = aHours;
+            // get party assignment data to be able to set the task to complete
+            workEffortPartyAssigns = EntityUtil.filterByDate(entryWorkEffort.getRelatedByAnd("WorkEffortPartyAssignment", ["partyId" : partyId]));
+            if (workEffortPartyAssigns) {
+                workEffortPartyAssign = workEffortPartyAssigns[0];
+                entry.fromDate = workEffortPartyAssign.getTimestamp("fromDate");
+                entry.roleTypeId = workEffortPartyAssign.roleTypeId;
+                if ("PAS_COMPLETED".equals(workEffortPartyAssign.statusId)) {
+                    entry.checkComplete = "Y";
+                }
+            }
+
+            // get project/phase information
+            entry.workEffortId = entryWorkEffort.workEffortId;
+            entry.workEffortName = entryWorkEffort.workEffortName;
+            result = dispatcher.runSync("getProjectIdAndNameFromTask", ["userLogin" : parameters.userLogin,"taskId" : entryWorkEffort.workEffortId]);
+                entry.sprintId = result.phaseId;
+                entry.sprintName = result.phaseName;
+                entry.projectId = result.projectId;
+                entry.projectName = result.projectName;
+                entry.taskWbsId = result.taskWbsId;
+
+        }
+        entry.total = taskTotal;
+        //Drop Down Lists
+        entries.add(entry);
+        // start new entry
+        taskTotal = 0.00;
+        entry = ["timesheetId" : timesheet.timesheetId];
+}
+
+timeEntries = timesheet.getRelated("TimeEntry", ["workEffortId", "rateTypeId", "fromDate"]);
+te = timeEntries.iterator();
+while (te.hasNext()) {
+    // only fill lastTimeEntry when not the first time
+    if (timeEntry!=void) {
+        lastTimeEntry = timeEntry;
+    }
+    timeEntry = te.next();
+
+    if (lastTimeEntry &&
+            (!lastTimeEntry.workEffortId.equals(timeEntry.workEffortId) ||
+            !lastTimeEntry.rateTypeId.equals(timeEntry.rateTypeId))) {
+            retrieveWorkEffortData();
+        }
+    if (timeEntry.hours) {
+        dayNumber = "d" + (timeEntry.fromDate.getTime() - timesheet.fromDate.getTime()) / (24*60*60*1000);
+        hours = timeEntry.hours.doubleValue();
+        entry.put(String.valueOf(dayNumber), hours);
+        if (dayNumber.equals("d0")) day0Total += hours;
+        if (dayNumber.equals("d1")) day1Total += hours;
+        if (dayNumber.equals("d2")) day2Total += hours;
+        if (dayNumber.equals("d3")) day3Total += hours;
+        if (dayNumber.equals("d4")) day4Total += hours;
+        if (dayNumber.equals("d5")) day5Total += hours;
+        if (dayNumber.equals("d6")) day6Total += hours;
+        taskTotal += hours;
+    }
+    entry.rateTypeId = timeEntry.rateTypeId;
+}
+
+if (timeEntry) {
+    lastTimeEntry = timeEntry;
+    retrieveWorkEffortData();
+    }
+
+// add empty lines if timesheet not completed
+if (!timesheet.statusId.equals("TIMESHEET_COMPLETED")) {
+    for (c=0; c < 3; c++) { // add empty lines
+        entries.add(["timesheetId" : timesheet.timesheetId]);
+    }
+}
+
+// add the totals line if at least one entry
+if (timeEntry) {
+    entry = ["timesheetId" : timesheet.timesheetId];
+    entry.d0 = day0Total;
+    entry.d1 = day1Total;
+    entry.d2 = day2Total;
+    entry.d3 = day3Total;
+    entry.d4 = day4Total;
+    entry.d5 = day5Total;
+    entry.d6 = day6Total;
+    entry.phaseName = uiLabelMap.ScrumTotals;
+    entry.workEffortId = "Totals";
+    entry.total = day0Total + day1Total + day2Total + day3Total + day4Total + day5Total + day6Total;
+    entries.add(entry);
+}
+context.timeEntries = entries;
+// get all timesheets of this user, including the planned hours
+timesheetsDb = delegator.findByAnd("Timesheet", ["partyId" : partyId], ["fromDate DESC"]);
+timesheets = new LinkedList();
+timesheetsDb.each { timesheetDb ->
+    timesheet = [:];
+    timesheet.putAll(timesheetDb);
+    entries = timesheetDb.getRelated("TimeEntry");
+    hours = 0.00;
+    entries.each { timeEntry ->
+        if (timeEntry.hours) {
+            hours += timeEntry.hours.doubleValue();
+        }
+    }
+    timesheet.weekNumber = UtilDateTime.weekNumber(timesheetDb.fromDate);
+    timesheet.hours = hours;
+    timesheets.add(timesheet);
+}
+context.timesheets = timesheets;

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/EditWeekTimesheet.groovy
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy Tue Jul  5 08:15:32 2011
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.*;
+import java.lang.*;
+import javolution.util.FastList;
+import org.ofbiz.base.util.*;
+import org.ofbiz.entity.*;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilValidate;
+import org.ofbiz.base.util.UtilDateTime;
+import org.ofbiz.entity.util.*;
+import org.ofbiz.entity.condition.*;
+import java.sql.Timestamp;
+
+productId =parameters.productId;
+custRequestList=[];
+backlogList=[];
+custRequestList = delegator.findByAnd("CustRequestItem", ["productId" : productId]);
+custRequestList.each { custRequestListMap ->
+    custRequestId=custRequestListMap.custRequestId;
+    exprBldr = FastList.newInstance();
+    exprBldr.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "CRQ_REOPENED"));
+    exprBldr.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, "CRQ_REVIEWED"));
+    andExprs = FastList.newInstance();
+    andExprs.add(EntityCondition.makeCondition("custRequestId", EntityOperator.EQUALS, custRequestId));
+    andExprs.add(EntityCondition.makeCondition(exprBldr, EntityOperator.OR));
+    custRequestTypeCond = EntityCondition.makeCondition(andExprs, EntityOperator.AND);
+    orderBy = ["custRequestTypeId"];
+    productBacklogList = delegator.findList("CustRequest", custRequestTypeCond, null,orderBy ,null, false);
+    productBacklogList.each { productBacklogMap ->
+        productBackId = productBacklogMap.custRequestId;
+        taskBacklogList = delegator.findByAnd("CustRequestWorkEffort", ["custRequestId" : productBackId]);
+        int countImplTask=0, countImplTaskComplete=0, countInstallTask=0, countInstallTaskComplete=0, countErrTask=0, countErrTaskComplete=0, countTestTask=0;
+        taskBacklogList.each { taskBacklogMap ->
+            taskId = taskBacklogMap.workEffortId;
+            
+            task = delegator.findByPrimaryKey("WorkEffort", ["workEffortId" : taskId]);
+            if (task.workEffortTypeId == "SCRUM_TASK_IMPL") {
+                countImplTask+=1;
+                if ( task.currentStatusId == "STS_COMPLETED" || task.currentStatusId == "STS_CANCELLED") {
+                    countImplTaskComplete+=1;
+                }
+            }
+            else if (task.workEffortTypeId == "SCRUM_TASK_INST") {
+                countInstallTask+=1;
+                if ( task.currentStatusId == "STS_COMPLETED" || task.currentStatusId == "STS_CANCELLED") {
+                    countInstallTaskComplete+=1;
+                }
+            }
+            else if (task.workEffortTypeId == "SCRUM_TASK_ERROR") {
+                countErrTask+=1;
+                if ( task.currentStatusId == "STS_COMPLETED" || task.currentStatusId == "STS_CANCELLED") {
+                    countErrTaskComplete+=1;
+                }
+            }
+            else if (task.workEffortTypeId == "SCRUM_TASK_TEST" || task.currentStatusId == "STS_CANCELLED") {
+                countTestTask+=1;
+            }
+        }
+        if ((countImplTask > 0 || countErrTask > 0 || countInstallTask > 0) && countImplTask == countImplTaskComplete 
+            && countInstallTask == countInstallTaskComplete && countErrTask == countErrTaskComplete && countTestTask > 0) {
+            productBacklogMap = productBacklogMap.getAllFields();
+            backlogList.add(productBacklogMap);
+        }
+    }
+}
+if (backlogList) {
+    backlogList = UtilMisc.sortMaps(backlogList, ["-custRequestName"])
+    context.backlogList = backlogList;
+}
+

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindBacklogItem.groovy
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy?rev=1142915&view=auto
==============================================================================
--- ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy (added)
+++ ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy Tue Jul  5 08:15:32 2011
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.sql.*;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import net.fortuna.ical4j.model.DateTime;
+import org.ofbiz.base.util.*;
+import org.ofbiz.entity.condition.*;
+import sun.util.calendar.LocalGregorianCalendar.Date;
+
+def module = "FindProductBacklogItem.groovy";
+
+// list planned and unplanned backlog
+conditionBacklogList = [];
+orConditionBacklogList = [];
+mainConditionBacklogList = [];
+orConditionsBacklog =  null;
+parameters.custRequestTypeId = parameters.custRequestTypeId ?: "Any";
+description = parameters.description;
+custRequestId = parameters.custRequestId;
+orderBy = "custRequestDate";
+
+if ((parameters.billed != null)||(parameters.parentCustRequestId != null)||(parameters.description != null)
+    ||(parameters.fromPartyId != null)||(parameters.custRequestDate != null)||(parameters.custRequestId != null)||(viewIndex > 0)) {
+    if(UtilValidate.isNotEmpty(parameters.productId)){
+        conditionBacklogList.add(EntityCondition.makeCondition("productId", EntityOperator.EQUALS, parameters.productId));
+    }
+    if("Any".equals(parameters.custRequestTypeId)){
+        orConditionBacklogList.add(EntityCondition.makeCondition("custRequestTypeId", EntityOperator.EQUALS, "RF_UNPLAN_BACKLOG"));
+        orConditionBacklogList.add(EntityCondition.makeCondition("custRequestTypeId", EntityOperator.EQUALS, "RF_PROD_BACKLOG"));
+        orConditionsBacklog = EntityCondition.makeCondition(orConditionBacklogList, EntityOperator.OR);
+    }else{
+        conditionBacklogList.add(EntityCondition.makeCondition("custRequestTypeId", EntityOperator.EQUALS, parameters.custRequestTypeId));
+    }
+    
+    if(UtilValidate.isEmpty(parameters.billed)){
+    	orConditionBacklogList.add(EntityCondition.makeCondition("billed", EntityOperator.EQUALS, "Y"));
+    	orConditionBacklogList.add(EntityCondition.makeCondition("billed", EntityOperator.EQUALS, "N"));
+    	orConditionsBacklog = EntityCondition.makeCondition(orConditionBacklogList, EntityOperator.OR);
+    }else{
+    	conditionBacklogList.add(EntityCondition.makeCondition("billed", EntityOperator.EQUALS, parameters.billed));
+    }
+    
+    if(!"Any".equals(parameters.statusId)){
+        orderBy = "sequenceNum";
+        conditionBacklogList.add(EntityCondition.makeCondition("statusId", EntityOperator.EQUALS, parameters.statusId));
+    }
+    
+    if(UtilValidate.isNotEmpty(parameters.parentCustRequestId)){
+    	conditionBacklogList.add(EntityCondition.makeCondition("parentCustRequestId", EntityOperator.EQUALS, parameters.parentCustRequestId));
+    }
+    if(UtilValidate.isNotEmpty(parameters.description)){
+    	conditionBacklogList.add(EntityCondition.makeCondition("description", EntityOperator.LIKE, "%" + description + "%"));
+    }
+    
+    if(UtilValidate.isNotEmpty(parameters.fromPartyId)){
+    	conditionBacklogList.add(EntityCondition.makeCondition("fromPartyId", EntityOperator.LIKE, "%" + parameters.fromPartyId + "%"));
+    }
+    
+    if (UtilValidate.isNotEmpty(parameters.custRequestDate)){
+    	fromDate = parameters.custRequestDate;
+    	fromDate = fromDate + " " + "00:00:00.000";
+    	conditionBacklogList.add(EntityCondition.makeCondition("custRequestDate", EntityOperator.GREATER_THAN_EQUAL_TO, Timestamp.valueOf(fromDate)));
+    	thruDate = parameters.custRequestDate;
+    	thruDate = thruDate + " " + "23:59:59.999";
+    	conditionBacklogList.add(EntityCondition.makeCondition("custRequestDate", EntityOperator.LESS_THAN_EQUAL_TO, Timestamp.valueOf(thruDate)));
+    }
+    
+    if(UtilValidate.isNotEmpty(parameters.custRequestId)){
+    	conditionBacklogList.add(EntityCondition.makeCondition("custRequestId", EntityOperator.LIKE, custRequestId + "%"));
+    }
+    
+    conditionsBacklog = EntityCondition.makeCondition(conditionBacklogList, EntityOperator.AND);
+    
+    if(UtilValidate.isNotEmpty(orConditionsBacklog)){
+        mainConditionBacklogList.add(orConditionsBacklog);
+    }
+    
+    mainConditionBacklogList.add(conditionsBacklog);
+    mainConditionsBacklog = EntityCondition.makeCondition(mainConditionBacklogList, EntityOperator.AND);
+    
+    backlogList = delegator.findList("CustRequestAndCustRequestItem", mainConditionsBacklog, ["custRequestId","custRequestTypeId", "sequenceNum", "statusId", "description", "estimatedMilliSeconds", "custRequestName", "parentCustRequestId","productId","billed","custRequestDate","fromPartyId"] as Set, ["-custRequestTypeId",orderBy], null, false);
+    def countSequenceBacklog = 1;
+    def backlogItems = [];
+    backlogList.each() { backlogItem ->
+        def tempBacklog = [:];
+        tempBacklog.putAll(backlogItem);
+        tempBacklog.sequenceNum = countSequenceBacklog;
+        tempBacklog.realSequenceNum = backlogItem.sequenceNum;
+        // if custRequest has task then get Actual Hours
+        backlogCustWorkEffortList = delegator.findByAnd("CustRequestWorkEffort",["custRequestId" : backlogItem.custRequestId]);
+        if (backlogCustWorkEffortList) {
+            actualHours = 0.00;
+            backlogCustWorkEffortList.each() { custWorkEffortMap ->
+                result = dispatcher.runSync("getScrumActualHour", ["taskId" : custWorkEffortMap.workEffortId,"partyId" : null, "userLogin" : userLogin]);
+                actualHours += result.actualHours;
+            }
+            if(actualHours) {
+                tempBacklog.actualHours = actualHours;
+            } else {
+                tempBacklog.actualHours = null;
+            }
+        } else {
+            tempBacklog.actualHours = null;
+        }
+        backlogItems.add(tempBacklog);
+        countSequenceBacklog ++;
+    }
+    
+    //re-order category list item
+    if ("N".equals(parameters.sequence)) {
+        backlogItems = UtilMisc.sortMaps(backlogItems, ["parentCustRequestId"]);
+    }
+    context.backlogItems = backlogItems;
+}

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: ofbiz/trunk/specialpurpose/scrum/webapp/scrum/WEB-INF/actions/FindProductBacklogItem.groovy
------------------------------------------------------------------------------
    svn:mime-type = text/plain