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 |
Free forum by Nabble | Edit this page |