r352 - in trunk/chorem-webmotion/src/main: java/org/chorem/webmotion/actions/project resources webapp/WEB-INF/jsp webapp/js
Author: meynier Date: 2013-06-28 16:53:52 +0200 (Fri, 28 Jun 2013) New Revision: 352 Url: http://chorem.org/projects/chorem/repository/revisions/352 Log: Corrected dashboard for new model and added the multi-project dashboard Added: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/project/QuotationCalculation.java trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardMultiProject.jsp Modified: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/project/DashboardProjectAction.java trunk/chorem-webmotion/src/main/resources/mapping trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/decorator.jsp trunk/chorem-webmotion/src/main/webapp/js/chorem.js trunk/chorem-webmotion/src/main/webapp/js/jquery.fn.gantt.js Modified: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/project/DashboardProjectAction.java =================================================================== --- trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/project/DashboardProjectAction.java 2013-06-28 14:35:50 UTC (rev 351) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/project/DashboardProjectAction.java 2013-06-28 14:53:52 UTC (rev 352) @@ -19,6 +19,7 @@ import org.debux.webmotion.server.call.Call; import org.debux.webmotion.server.render.Render; import org.chorem.entities.Closed; +import org.chorem.entities.Interval; import org.chorem.entities.Quotation; import org.chorem.entities.Project; import org.chorem.entities.Task; @@ -55,14 +56,14 @@ .end(); projectResult = client.findAllByQuery(Project.class, projectQuery); - + //Fetch the quotations form the project (if there is one) if(projectResult.size() != 0) { for(Project project : projectResult.getAll()) { WikittyQuery quotationQuery = null; WikittyQueryMaker wqm = new WikittyQueryMaker(); - - + + if(quotationFilter.equals("Devis ouverts")) { wqm.and() .eq(Quotation.ELEMENT_FIELD_QUOTATION_PROJECT, project) @@ -71,17 +72,17 @@ else { wqm.eq(Quotation.ELEMENT_FIELD_QUOTATION_PROJECT, project); } - + quotationQuery = wqm.end(); - + quotationQuery.addSortDescending(Quotation.ELEMENT_FIELD_INTERVAL_BEGINDATE); quotationResult = client.findAllByQuery(Quotation.class, quotationQuery); - - + + } - + } - + //Fetch the tasks form the quotations (if there are some) if(quotationResult != null) { String customClass = ""; @@ -89,16 +90,16 @@ WikittyQuery taskQuery = new WikittyQueryMaker() .eq(Task.ELEMENT_FIELD_TASK_QUOTATION, quote) .end(); - + taskResult = client.findAllByQuery(Task.class, taskQuery); taskMap.put(quote, taskResult.getAll()); - + } - + } - + } - + if(projectResult == null) { return renderView("dashboardSingleProject.jsp", "title", "Tableau de bord projet", "projects", null,"quotations",null); @@ -110,34 +111,69 @@ } else { return renderView("dashboardSingleProject.jsp", - "title", "Tableau de bord projet", "projects", projectResult.getAll(), - "quotations", quotationResult.getAll(), "taskMap", taskMap, "extensions", - Extensions.extensions); + "title", "Tableau de bord projet", "projects", projectResult.getAll(), + "quotations", quotationResult.getAll(), "taskMap", taskMap, "extensions", + Extensions.extensions); } } + public Render multiProjectFilter(ChoremClient client, Date from, Date to) { + System.out.println(from + "," + to); + if(from != null && to != null) { + WikittyQueryMaker quotationQueryMaker = new WikittyQueryMaker(); + WikittyQuery quotationQuery = quotationQueryMaker.or() + .bw(Interval.FQ_FIELD_INTERVAL_BEGINDATE, from, to) + .bw(Interval.FQ_FIELD_INTERVAL_ENDDATE, from, to) + .end(); + WikittyQueryResult<Quotation> result = + client.findAllByQuery(Quotation.class, quotationQuery); + + Collection<Quotation> quotations = result.getAll(); + + HashMap<Quotation, QuotationCalculation> calculations = new HashMap<Quotation, QuotationCalculation>(); + for(Quotation q : quotations) { + calculations.put(q, new QuotationCalculation(q, client)); + } + + return renderView("dashboardMultiProject.jsp", + "title", "Tableau de bord projets", + "quotations", quotations, + "calculations", calculations); + } + else { + return renderView("dashboardMultiProject.jsp", + "title", "Tableau de bord projets"); + } + + } + + + public Render requestProject(ChoremClient client, String project_id, String quotationFilter) { return projectFilter(client, project_id, quotationFilter); } - + public Render requestMultiProject(ChoremClient client, Date from, Date to) { + return multiProjectFilter(client, from, to); + } + public Render getGanttInfo(ChoremClient client, String id) { Wikitty wikitty = client.restore(id); - WikittyQuery quotationQuery = new WikittyQueryMaker() + WikittyQuery quotationQuery = new WikittyQueryMaker() .ideq(id) .end(); - Quotation quotation = client.findByQuery(Quotation.class, quotationQuery); - - - + Quotation quotation = client.findByQuery(Quotation.class, quotationQuery); + + + WikittyQuery taskQuery = new WikittyQueryMaker() .eq(Task.ELEMENT_FIELD_TASK_QUOTATION, quotation) .end(); - + WikittyQueryResult<Task> taskResult = client.findAllByQuery(Task.class, taskQuery); String customClass = ""; List<JTask> lTask = new ArrayList<JTask>(); for(Task t : taskResult.getAll()) { - + if(t.getStatus().equals("SCHEDULED")) { customClass = "ganttBlue"; } @@ -150,25 +186,25 @@ else if(t.getStatus().equals("CLOSED")) { customClass = "ganttGrey"; } - + Values[] v = null; - if(t.getReestimatedEnd() != null) - v= new Values[2]; - else + //if(t.getReestimatedEnd() != null) + // v= new Values[2]; + //else v = new Values[1]; v[0] = new Values(t.getBeginDate(), t.getEndDate(), t.getName(), customClass); - if(t.getReestimatedEnd() != null) - v[1]= new Values(t.getEndDate(), t.getReestimatedEnd(), "Reestimated end", "ganttOrange"); - - JTask jt = new JTask(t.getName(), t.getDescription(), v); - + //if(t.getReestimatedEnd() != null) + // v[1]= new Values(t.getEndDate(), t.getReestimatedEnd(), "Reestimated end", "ganttOrange"); + + JTask jt = new JTask(t.getName(), t.getDescription(), t.getWikittyId(),t.getPrice(), t.getEstimatedDays(), v); + lTask.add(jt); } - + Collections.sort(lTask); String dateStart = "/Date(" + quotation.getBeginDate().getTime() + ")/"; String dateEnd = "/Date(" + quotation.getEndDate().getTime() + ")/"; - + HashMap<String,String> dateMap = new HashMap<String,String>(); dateMap.put("sendingDate", "Draft"); dateMap.put("postedDate", "Sent"); @@ -180,7 +216,7 @@ dateMap.put("closedDate", "Closed"); dateMap.put("rejectedDate", "Rejected"); dateMap.put("cancelledDate", "Cancelled"); - + Iterator i = dateMap.entrySet().iterator(); HashMap<String,String> extDate = new HashMap<String,String>(); while(i.hasNext()) { @@ -191,12 +227,12 @@ "/Date(" + ((Date) (wikitty.getFieldAsObject(me.getValue(), me.getKey()))).getTime() +")/"); } } - + JRender data = new JRender(lTask, extDate, dateStart, dateEnd); - return renderJSON("data", data); - } - - + return renderJSON("data", data); + } + + private class JRender { private List<JTask> source; private String dateStart; @@ -209,23 +245,29 @@ this.extDate = extDate; } } - + private class JTask implements Comparable { private String name; private String desc; private Values[] values; private String status; - public JTask(String name, String desc, Values[] values) { + private String wikittyId; + private float price; + private double estimatedDays; + public JTask(String name, String desc, String wikittyId,float price, double estimatedDays, Values[] values) { this.name = name; this.desc = desc; this.values = values; + this.wikittyId = wikittyId; + this.price = price; + this.estimatedDays = estimatedDays; } @Override public int compareTo(Object task) { - + return values[0].compareTo(((JTask)task).values[0]); } - + } private class Values implements Comparable{ private String from; @@ -240,19 +282,19 @@ } @Override public int compareTo(Object o) { - + return from.compareTo(((Values)o).from); } - + } - + private class QuotationSorter<T> implements Comparator { @Override public int compare(Object q1, Object q2) { - + return ((Quotation)q1).getBeginDate().compareTo(((Quotation)q2).getBeginDate()); } - + } } Added: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/project/QuotationCalculation.java =================================================================== --- trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/project/QuotationCalculation.java (rev 0) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/project/QuotationCalculation.java 2013-06-28 14:53:52 UTC (rev 352) @@ -0,0 +1,94 @@ +package org.chorem.webmotion.actions.project; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; + +import org.chorem.ChoremClient; +import org.chorem.entities.Interval; +import org.chorem.entities.Quotation; +import org.chorem.entities.Task; +import org.chorem.entities.Time; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryMaker; +import org.nuiton.wikitty.query.WikittyQueryResult; + +public class QuotationCalculation { + + private Quotation q; + private ChoremClient client; + private static final int SEC_PER_HOUR = 3600; + private static final int WORKING_HOURS_PER_DAY = 7; + + public QuotationCalculation(Quotation q, ChoremClient client) { + this.q = q; + this.client = client; + } + public double tjm() { + double amount = q.getAmount(); + double nbDays = q.getEstimatedDays(); + + return amount/nbDays; + + } + + private double getSecondPeriod(Date start, Date end) { + return end.getTime()-start.getTime(); + } + + public double realDays() { + //test if quotation is finished + if(q.getExtensionNames().contains("Closed")) { + //TODO calcul grâce aux objets Time + WikittyQuery taskQuery = new WikittyQueryMaker() + .eq(Task.ELEMENT_FIELD_TASK_QUOTATION, q) + .end(); + + WikittyQueryResult<Task> result = + client.findAllByQuery(Task.class, taskQuery); + Collection<Time> times = new ArrayList<Time>(); + for(Task t : result.getAll()) { + WikittyQuery timeQuery = new WikittyQueryMaker() + .eq(Time.ELEMENT_FIELD_TIME_TASK, q) + .end(); + WikittyQueryResult timeResult = client.findAllByQuery(Time.class, timeQuery); + System.out.println("RESULT : " + timeResult); + times.addAll(timeResult.getAll()); + } + System.out.println(times); + double totalTime = 0; + for(Time t : times) { + totalTime += getSecondPeriod(t.getBeginDate(), t.getEndDate()); + } + return (totalTime / SEC_PER_HOUR) / WORKING_HOURS_PER_DAY; + } + else { + //nbDays + otherdays + WikittyQuery taskQuery = new WikittyQueryMaker() + .eq(Task.ELEMENT_FIELD_TASK_QUOTATION, q) + .end(); + + WikittyQueryResult<Task> result = + client.findAllByQuery(Task.class, taskQuery); + + double totalDayExt = 0; + for(Task t : result.getAll()) { + totalDayExt += t.getDayExtension(); + } + return q.getEstimatedDays() + totalDayExt; + + } + } + + public double deltaDays() { + return q.getEstimatedDays() - realDays(); + } + + public double realTjm() { + double amount = q.getAmount(); + double nbDays = realDays(); + + return amount/nbDays; + } + +} Modified: trunk/chorem-webmotion/src/main/resources/mapping =================================================================== --- trunk/chorem-webmotion/src/main/resources/mapping 2013-06-28 14:35:50 UTC (rev 351) +++ trunk/chorem-webmotion/src/main/resources/mapping 2013-06-28 14:53:52 UTC (rev 352) @@ -69,6 +69,7 @@ * /sales/funnel/json/{method} action:sales.SalesAction.{method} * /sales/funnel/json/{method}/{id} action:sales.SalesAction.{method} * /project action:project.DashboardProjectAction.requestProject +* /project/multi action:project.DashboardProjectAction.requestMultiProject * /project/json/getExtension/{extensionName}/{id} action:project.QuotationStatusAction.getExtension * /project/json/getGanttInfo/{id} action:project.DashboardProjectAction.getGanttInfo * /crm/account/{id} action:crm.AccountAction.view Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardMultiProject.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardMultiProject.jsp (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardMultiProject.jsp 2013-06-28 14:53:52 UTC (rev 352) @@ -0,0 +1,97 @@ +<%-- + #%L + Chorem webmotion + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2011 - 2012 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@page contentType="text/html" pageEncoding="UTF-8"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="f"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%> +<%@ taglib uri="/WEB-INF/wikitty.tld" prefix="w"%> + + +<link rel="stylesheet" href="<c:url value='/css/jquery.fn.gantt.css'/>" /> +<h1>${title}</h1> +<form class="well form-inline" method="GET" id="projectSearch"> + + <div class="control-group"> + <div class="controls" style="display: inline"> +<!-- + <script> + $(function() { + $("#project_text") + .autocompleteByExtension( + { + source : "/chorem/wikitty-json/search?extension=Project", + minLength : 2, + select : function(event, ui) { + $("#project_text").val( + ui.item.label); + $("#project_hidden") + .val(ui.item.id); + $("#project_hidden").change() + return false; + } + }); + }); + </script> + --> + From : <input type="text" name="from" id="from" class="datepicker" /> + to : <input type="text" name="to" id="to" class="datepicker" /> + <input type="submit"/> + </div> + </div> + +</form> + +<table class="table table-striped table-bordered table-condensed"> + <thead> + <tr> + <th>Client</th> + <th>Projet</th> + <th>Montant</th> + <th>NbJour</th> + <th>TJM</th> + <th>NbJourReel</th> + <th>delta jour</th> + <th>tjm reel</th> + + </tr> + </thead> + <c:forEach var="q" items="${quotations}"> + <tbody> + <tr> + <td><w:display wikitty="${q.wikitty}" fqfield="Quotation.customer" label=""/></td> + <td><w:display wikitty="${q.wikitty}" fqfield="Quotation.project" label=""/> + <a href="<c:url value="/wikitty/edit/${q.wikittyId}"/>"><i + class="icon-pencil icon-black"></i></a> + </td> + <td class="currency"><w:display wikitty="${q.wikitty}" fqfield="Quotation.amount" label=""/></td> + <td class="number"><w:display wikitty="${q.wikitty}" fqfield="Quotation.estimatedDays" label=""/></td> + <td class="number">${calculations[q].tjm()}</td> + <td class="number">${calculations[q].realDays()}</td> + <td class="number">${calculations[q].deltaDays()}</td> + <td class="number">${calculations[q].realTjm()}</td> + </tr> + </tbody> + </c:forEach> +</table> + + Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/decorator.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/decorator.jsp 2013-06-28 14:35:50 UTC (rev 351) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/decorator.jsp 2013-06-28 14:53:52 UTC (rev 352) @@ -102,6 +102,7 @@ <li><a href="<c:url value="/wikitty/Project/search"/>"><i class="icon-th-list icon-black"></i> All projects</a></li> <li><a href="<c:url value="/wikitty/Project/edit/new"/>"><i class="icon-plus icon-black"></i> Add project</a></li> <li><a href="<c:url value="/project"/>"><i class="icon-th-list icon-black"></i> Dashboard project</a></li> + <li><a href="<c:url value="/project/multi"/>"><i class="icon-th-list icon-black"></i> Dashboard multi-project</a></li> <li class="divider"></li> <li>Propale</li> <li><a href="<c:url value="/wikitty/Quotation/search"/>"><i class="icon-th-list icon-black"></i> All quotations</a></li> Modified: trunk/chorem-webmotion/src/main/webapp/js/chorem.js =================================================================== --- trunk/chorem-webmotion/src/main/webapp/js/chorem.js 2013-06-28 14:35:50 UTC (rev 351) +++ trunk/chorem-webmotion/src/main/webapp/js/chorem.js 2013-06-28 14:53:52 UTC (rev 352) @@ -775,7 +775,7 @@ minScale: "days", itemsPerPage: 10, onItemClick: function(data) { - alert("Item clicked - show some details"); + window.location ="wikitty/edit/" + this.source[0].wikittyId; }, onAddClick: function(dt, rowId) { alert("Empty space clicked - add an item!"); Modified: trunk/chorem-webmotion/src/main/webapp/js/jquery.fn.gantt.js =================================================================== --- trunk/chorem-webmotion/src/main/webapp/js/jquery.fn.gantt.js 2013-06-28 14:35:50 UTC (rev 351) +++ trunk/chorem-webmotion/src/main/webapp/js/jquery.fn.gantt.js 2013-06-28 14:53:52 UTC (rev 352) @@ -45,6 +45,7 @@ waitText: "Please wait...", onItemClick: function (data) { return; }, onAddClick: function (data) { return; }, + onTaskClick: function (data) { return; }, onRender: function() { return; }, scrollToToday: true, dateStart:null, @@ -334,10 +335,12 @@ mover : function (e) { console.log("hint"); var hint; + var str; if($(this).attr("over") == 'text') - hint = $('<div class="fn-gantt-hint"/>').html($(this).text()); + str = $(this).text(); else - hint = $('<div class="fn-gantt-hint"/>').html($(this).attr("over")); + str = $(this).attr("over"); + hint = $('<div class="fn-gantt-hint"/>').html(str); $("body").append(hint); hint.css("left", e.pageX); hint.css("top", e.pageY); @@ -995,7 +998,7 @@ // **Progress Bar** // Return an element representing a progress of position within // the entire chart - createProgressBar: function (days, cls, desc, label, dataObj) { + createProgressBar: function (days, cls, desc, label,price, estimatedDays, dataObj) { var cellWidth = tools.getCellSize(); var barMarg = tools.getProgressBarMargin() || 0; @@ -1007,10 +1010,21 @@ .data("dataObj", dataObj); //if (desc) { - bar.mouseover(core.mover) + bar.mouseover(function (e) { + console.log("hint"); + var hint; + var str; + + hint = $('<div class="fn-gantt-hint"/>').html(label + " :<br/>" + + desc + "<br/>Price : " + price + "<br />Estimated days : " + estimatedDays); + $("body").append(hint); + hint.css("left", e.pageX); + hint.css("top", e.pageY); + hint.show(); + }) .mouseout(core.mout) .mousemove(core.mmove) - .attr('over', 'text'); + .attr('over', 'task'); //} bar.click(function (e) { e.stopPropagation(); @@ -1156,6 +1170,8 @@ day.customClass ? day.customClass : "", entry.desc ? entry.desc : "", day.label ? day.label : "", + entry.price ? entry.price : "", + entry.estimatedDays ? entry.estimatedDays : "", day.dataObj ? day.dataObj : null ); @@ -1199,6 +1215,8 @@ day.customClass ? day.customClass : "", entry.desc ? entry.desc : "", day.label ? day.label : "", + ntry.price ? entry.price : "", + entry.estimatedDays ? entry.estimatedDays : "", day.dataObj ? day.dataObj : null ); @@ -1239,6 +1257,8 @@ day.customClass ? day.customClass : "", entry.desc ? entry.desc : "", day.label ? day.label : "", + entry.price ? entry.price : "", + entry.estimatedDays ? entry.estimatedDays : "", day.dataObj ? day.dataObj : null ); @@ -1265,6 +1285,8 @@ day.customClass ? day.customClass : "", entry.desc ? entry.desc : "", day.label ? day.label : "", + entry.price ? entry.price : "", + entry.estimatedDays ? entry.estimatedDays : "", day.dataObj ? day.dataObj : null );
participants (1)
-
meynier@users.chorem.org