Author: meynier Date: 2013-07-08 14:03:44 +0200 (Mon, 08 Jul 2013) New Revision: 360 Url: http://chorem.org/projects/chorem/repository/revisions/360 Log: Small changes on project dashboard for displaying alerts. Modified: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/project/DashboardProjectAction.java trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardMultiProject.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardSingleProject.jsp trunk/chorem-webmotion/src/main/webapp/css/jquery.fn.gantt.css 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-07-03 15:30:35 UTC (rev 359) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/project/DashboardProjectAction.java 2013-07-08 12:03:44 UTC (rev 360) @@ -67,7 +67,7 @@ HashMap<Project, List<Quotation>> quotations = new HashMap<Project, List<Quotation>>(); HashMap<Quotation, List<Task>> taskMap = new HashMap<Quotation, List<Task>>(); - HashMap<Quotation, List<String>> alertsMap = new HashMap<Quotation, List<String>>(); + HashMap<Task, String> alertsMap = new HashMap<Task, String>(); HashMap<Quotation, QuotationCalculation> calculations = new HashMap<Quotation, QuotationCalculation>(); HashMap<Task, TaskCalculation> taskCalc = new HashMap<Task, TaskCalculation>(); @@ -78,6 +78,7 @@ List<Task> tasks = fetchTasks(quotation, client); taskMap.put(quotation, tasks); + //Make the calculations for the tasks for(Task t : tasks) { TaskCalculation tc = new TaskCalculation(t, client); tc.setSrp(config.getDailyReturn()); @@ -85,7 +86,7 @@ taskCalc.put(t, tc); } taskMap.put(quotation, tasks); - alertsMap.put(quotation, getAlerts(client, quotation)); + alertsMap.putAll(getAlerts(client, quotation)); QuotationCalculation calc = new QuotationCalculation(quotation, client); calc.setSrp(config.getDailyReturn()); calc.calculate(); @@ -120,11 +121,11 @@ WikittyQueryResult<Task> taskResult = null; HashMap<Project, List<Quotation>> quotations = new HashMap<Project, List<Quotation>>(); HashMap<Quotation, List<Task>> taskMap = new HashMap<Quotation, List<Task>>(); - HashMap<Quotation, List<String>> alertsMap = new HashMap<Quotation, List<String>>(); + HashMap<Task, String> alertsMap = new HashMap<Task, String>(); HashMap<Quotation, QuotationCalculation> calculations = new HashMap<Quotation, QuotationCalculation>(); HashMap<Task, TaskCalculation> taskCalc = new HashMap<Task, TaskCalculation>(); - //Fetch the project from the id + //Fetch the projects from the id or the filter WikittyQueryMaker projectQueryMaker = new WikittyQueryMaker(); if(id != null && !id.equals("")) projectQueryMaker.ideq(id); @@ -138,7 +139,7 @@ (new WikittyQueryMaker()).exteq(Configuration.EXT_CONFIGURATION).end() ).get(0); - //Fetch the quotations form the project (if there is one) + //Fetch the quotations from the projects if(projectResult.size() != 0) { for(Project project : projectResult.getAll()) { WikittyQuery quotationQuery = null; @@ -173,19 +174,15 @@ taskCalc.put(t, tc); } - alertsMap.put(quote, getAlerts(client, quote)); + alertsMap.putAll(getAlerts(client, quote)); QuotationCalculation calc = new QuotationCalculation(quote, client); calc.setSrp(config.getDailyReturn()); calc.calculate(); calculations.put(quote, calc); } - } - - } - } return renderView("dashboardSingleProject.jsp", "locale", client.getUserLocale(), @@ -207,44 +204,53 @@ WikittyQuery taskQuery = new WikittyQueryMaker() .eq(Task.ELEMENT_FIELD_TASK_QUOTATION, q) .end(); + + taskQuery.addSortAscending(Quotation.ELEMENT_FIELD_INTERVAL_BEGINDATE); WikittyQueryResult taskResult = client.findAllByQuery(Task.class, taskQuery); return taskResult.getAll(); } - private List<String> getAlerts(ChoremClient client, Quotation q) { + private HashMap<Task, String> getAlerts(ChoremClient client, Quotation q) { List<Task> tasks = fetchTasks(q, client); Calendar now = new GregorianCalendar(); - List<String> messages = new ArrayList<String>(); + HashMap<Task, String> messages = new HashMap<Task, String>(); for(Task t : tasks) { if(t.getBeginDate() != null && t.getEndDate() != null) { + String str = "<h4>Warning</h4>"; + boolean alert = false; //Test if the statuses are correct if(t.getStatus().equalsIgnoreCase("Scheduled")) { if(t.getBeginDate().before(now.getTime())) { - System.out.println("should be started"); - messages.add( "Task " + t.getName() + " should be started"); + alert = true; + str += "Task " + t.getName() + " should be started"; } } else if(t.getStatus().equalsIgnoreCase("Started")) { if(t.getBeginDate().after(now.getTime())) { - System.out.println("started in advance"); - messages.add( "Task " + t.getName() + " has been started in advance"); + alert = true; + str += "Task " + t.getName() + " has been started in advance"; } else if(t.getEndDate().before(now.getTime())) { - System.out.println("should be ended"); - messages.add( "Task " + t.getName() + " should have ended by now"); + alert = true; + str += "Task " + t.getName() + " should have ended by now"; } } else if(t.getStatus().equalsIgnoreCase("Finished")) { if(t.getEndDate().after(now.getTime())) { - System.out.println("finished in advance"); - messages.add( "Task " + t.getName() + " has been finished in advance"); + alert = true; + str += "Task " + t.getName() + " has been finished in advance"; } } + if(alert) { + messages.put(t,str); + } + } } + return messages; } @@ -271,6 +277,9 @@ WikittyQuery quotationQuery = quotationQueryMaker.or() .bw(Interval.FQ_FIELD_INTERVAL_BEGINDATE, from, to) .bw(Interval.FQ_FIELD_INTERVAL_ENDDATE, from, to) + .and() + .le(Interval.FQ_FIELD_INTERVAL_BEGINDATE, from) + .ge(Interval.FQ_FIELD_INTERVAL_ENDDATE, to) .end(); WikittyQueryResult<Quotation> result = client.findAllByQuery(Quotation.class, quotationQuery); @@ -346,14 +355,17 @@ } Values[] v = null; - //if(t.getReestimatedEnd() != null) - // v= new Values[2]; - //else - v = new Values[1]; + if(t.getDayExtension() != 0) + v= new Values[2]; + else + v = new Values[1]; v[0] = new Values(t.getBeginDate(), t.getEndDate(), t.getName(), customClass, t.getWikittyId()); - //if(t.getReestimatedEnd() != null) - // v[1]= new Values(t.getEndDate(), t.getReestimatedEnd(), "Reestimated end", "ganttOrange"); - + if(t.getDayExtension() != 0) { + GregorianCalendar newEnd = new GregorianCalendar(); + newEnd.setTime(t.getEndDate()); + newEnd.add(Calendar.DAY_OF_YEAR, (int) t.getDayExtension()); + v[1]= new Values(t.getEndDate(), newEnd.getTime(), "Reestimated end", "ganttOrange", t.getWikittyId()); + } JTask jt = new JTask(t.getName(), t.getDescription(), t.getWikittyId(),t.getPrice(), t.getEstimatedDays(), v); lTask.add(jt); @@ -449,12 +461,12 @@ } - private class QuotationSorter<T> implements Comparator { + private class IntervalSorter<T extends Interval> implements Comparator { @Override public int compare(Object q1, Object q2) { - return ((Quotation)q1).getBeginDate().compareTo(((Quotation)q2).getBeginDate()); + return ((T)q1).getBeginDate().compareTo(((T)q2).getBeginDate()); } } Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardMultiProject.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardMultiProject.jsp 2013-07-03 15:30:35 UTC (rev 359) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardMultiProject.jsp 2013-07-08 12:03:44 UTC (rev 360) @@ -27,6 +27,7 @@ <%@ taglib uri="/WEB-INF/wikitty.tld" prefix="w"%> <f:setLocale value="${locale}"/> + <link rel="stylesheet" href="<c:url value='/css/jquery.fn.gantt.css'/>" /> <h1>${title}</h1> <form class="well form-inline" method="GET" id="projectSearch"> @@ -69,13 +70,13 @@ <td class="number"><w:display wikitty="${q.wikitty}" fqfield="Quotation.estimatedDays" label=""/></td> <td class="number"> <f:formatNumber type="number" - maxFractionDigits="2" value="${calculations[q].getTjm()}" /></td> + maxFractionDigits="2" value="${calculations[q].getAdr()}" /></td> <td class="number"> <f:formatNumber type="number" maxFractionDigits="2" value="${calculations[q].getRealDays()}" /></td> <td class="number"> <f:formatNumber type="number" maxFractionDigits="2" value="${calculations[q].getDeltaDays()}" /></td> <td class="number"> <f:formatNumber type="number" - maxFractionDigits="2" value="${calculations[q].getRealTjm()}" /></td> + maxFractionDigits="2" value="${calculations[q].getRealAdr()}" /></td> <td class="currency"> <f:formatNumber type="currency" maxFractionDigits="2" value="${calculations[q].getExpectedProfit()}" /></td> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardSingleProject.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardSingleProject.jsp 2013-07-03 15:30:35 UTC (rev 359) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardSingleProject.jsp 2013-07-08 12:03:44 UTC (rev 360) @@ -81,7 +81,7 @@ <c:forEach var="p" items="${projects}"> <c:if test="${not empty quotations[p]}"> <h2 style="display: inline;">${p.name}</h2> - <a href="<c:url value="/wikitty/edit/${param.project_id}"/>"><i + <a href="<c:url value="/wikitty/edit/${p.wikittyId}"/>"><i class="icon-pencil icon-black"></i><small>edit</small></a> <p>${p.description}</p> @@ -101,7 +101,7 @@ <w:display wikitty="${q.wikitty}" fqfield="Interval.beginDate" label="" pattern="dd/MM/yyyy" /> au - <w:display wikitty="${q.wikitty}" fqfield="Interval.beginDate" + <w:display wikitty="${q.wikitty}" fqfield="Interval.endDate" label="" pattern="dd/MM/yyyy" /> <br />Statut : ${q.wikitty.extensionNames.toArray()[q.wikitty.extensionNames.size() @@ -121,8 +121,6 @@ <th>Gain/perte</th> </tr> </thead> - - <tbody> <tr> @@ -133,9 +131,9 @@ <td class="number"><w:display wikitty="${q.wikitty}" fqfield="Quotation.estimatedDays" label="" /></td> <td class="currency"><f:formatNumber type="currency" - maxFractionDigits="2" value="${calculations[q].getTjm()}" /></td> + maxFractionDigits="2" value="${calculations[q].getAdr()}" /></td> <td class="currency"><f:formatNumber type="currency" - maxFractionDigits="2" value="${calculations[q].getRealTjm()}" /></td> + maxFractionDigits="2" value="${calculations[q].getRealAdr()}" /></td> <td class="currency"><w:display wikitty="${q.wikitty}" fqfield="Quotation.amount" label="" /></td> <td class="currency"><f:formatNumber type="currency" @@ -148,66 +146,63 @@ - <c:forEach var="a" items="${alerts[q]}"> - <div class="alert-error alert"> - <div class="alert-block">${a}</div> - </div> - - </c:forEach> - <div class="gantt gantt-${q.wikittyId}" wikittyId="${q.wikittyId}" data=''>Pas de tâche</div> - - - <table class="table table-striped table-bordered table-condensed"> - <thead> - <tr> - <th>Nom</th> - <th>Montant</th> - <th>Jours estimés</th> - <th>Jours réels</th> - <th>Différence estimation/réel</th> - <th>TJM estimé</th> - <th>TJM réel</th> - <th>Gain attendu</th> - <th>Gain/perte</th> - </tr> - </thead> - <tbody> - <c:forEach items="${taskMap[q]}" var="task"> + <c:if test="${taskMap[q].size() != 0}"> + <table class="table table-striped table-bordered table-condensed"> + <thead> <tr> - <td><a href="<c:url value="/wikitty/view/${task.wikittyId}"/>"> - <w:display wikitty="${task.wikitty}" fqfield="Task.name" - label="" /></a></td> - <td><w:display wikitty="${task.wikitty}" - fqfield="Task.price" label="" /></td> - <td class="number"><w:display wikitty="${task.wikitty}" - fqfield="Task.estimatedDays" label="" /></td> - <td class="number"><f:formatNumber type="number" - maxFractionDigits="2" value="${taskCalc[task].getRealDays()}" /></td> - <td class="number"><f:formatNumber type="number" - maxFractionDigits="2" value="${taskCalc[task].getDeltaDays()}" /></td> - <td class="number"><f:formatNumber type="number" - maxFractionDigits="2" value="${taskCalc[task].getTjm()}" /></td> + <th>Nom</th> + <th>Montant</th> + <th>Jours estimés</th> + <th>Jours réels</th> + <th>Différence estimation/réel</th> + <th>TJM estimé</th> + <th>TJM réel</th> + <th>Gain attendu</th> + <th>Gain/perte</th> + </tr> + </thead> + <tbody> + <c:forEach items="${taskMap[q]}" var="task"> + <tr id="taskrow-${task.wikittyId}"> + <td <c:if test="${not empty alerts[task]}">class="task-alert"</c:if>><a + href="<c:url value="/wikitty/view/${task.wikittyId}"/>"> <w:display + wikitty="${task.wikitty}" fqfield="Task.name" label="" /></a> + <c:if test="${not empty alerts[task]}"> + <i class="icon-warning-sign" title="${alerts[task]}"></i> + </c:if> + + + <td><w:display wikitty="${task.wikitty}" + fqfield="Task.price" label="" /></td> + <td class="number"><w:display wikitty="${task.wikitty}" + fqfield="Task.estimatedDays" label="" /></td> + <td class="number"><f:formatNumber type="number" + maxFractionDigits="2" value="${taskCalc[task].getRealDays()}" /></td> + <td class="number"><f:formatNumber type="number" + maxFractionDigits="2" value="${taskCalc[task].getDeltaDays()}" /></td> + <td class="number"><f:formatNumber type="number" + maxFractionDigits="2" value="${taskCalc[task].getAdr()}" /></td> - <td class="number"><f:formatNumber type="number" - maxFractionDigits="2" value="${taskCalc[task].getRealTjm()}" /></td> + <td class="number"><f:formatNumber type="number" + maxFractionDigits="2" value="${taskCalc[task].getRealAdr()}" /></td> - <td class="currency"><f:formatNumber type="currency" - maxFractionDigits="2" - value="${taskCalc[task].getExpectedProfit()}" /></td> - <td class="currency"><f:formatNumber type="currency" - maxFractionDigits="2" - value="${taskCalc[task].getLossOrProfit()}" /></td> - </tr> + <td class="currency"><f:formatNumber type="currency" + maxFractionDigits="2" + value="${taskCalc[task].getExpectedProfit()}" /></td> + <td class="currency"><f:formatNumber type="currency" + maxFractionDigits="2" + value="${taskCalc[task].getLossOrProfit()}" /></td> + </tr> - </c:forEach> - </tbody> - </table> - + </c:forEach> + </tbody> + </table> + </c:if> </c:forEach> </c:if> Modified: trunk/chorem-webmotion/src/main/webapp/css/jquery.fn.gantt.css =================================================================== --- trunk/chorem-webmotion/src/main/webapp/css/jquery.fn.gantt.css 2013-07-03 15:30:35 UTC (rev 359) +++ trunk/chorem-webmotion/src/main/webapp/css/jquery.fn.gantt.css 2013-07-08 12:03:44 UTC (rev 360) @@ -28,9 +28,11 @@ width: 100%; } +.task-alert a { + color:red; +} - /* === LEFT PANEL === */ .fn-gantt .leftPanel { Modified: trunk/chorem-webmotion/src/main/webapp/js/chorem.js =================================================================== --- trunk/chorem-webmotion/src/main/webapp/js/chorem.js 2013-07-03 15:30:35 UTC (rev 359) +++ trunk/chorem-webmotion/src/main/webapp/js/chorem.js 2013-07-08 12:03:44 UTC (rev 360) @@ -756,6 +756,8 @@ $("#quotationFilter").change(function() { $("#projectSearch").submit(); }); + $(".task-alert").tooltip(); + function initgantt(id) { "use strict"; $.get(createUrl("/project/json/getGanttInfo/",id), @@ -776,7 +778,9 @@ window.location ="wikitty/edit/" + data; }, onAddClick: function(dt, rowId) { - alert("Empty space clicked - add an item!"); + var d = new Date(parseInt(dt,10)); + var str = d.getDay() +"/"+ d.getMonth() +"/"+ d.getFullYear(); + window.location ="wikitty/Task/edit/new?Interval.beginDate=" + str +"&Task.quotation=" + id; }, onRender: function() { if (window.console && typeof console.log === "function") { @@ -798,6 +802,6 @@ initgantt(div.attributes.wikittyid.nodeValue); } + - }); \ No newline at end of file Modified: trunk/chorem-webmotion/src/main/webapp/js/jquery.fn.gantt.js =================================================================== --- trunk/chorem-webmotion/src/main/webapp/js/jquery.fn.gantt.js 2013-07-03 15:30:35 UTC (rev 359) +++ trunk/chorem-webmotion/src/main/webapp/js/jquery.fn.gantt.js 2013-07-08 12:03:44 UTC (rev 360) @@ -384,8 +384,6 @@ entries.push('</div>'); } - - } }); ganttLeftPanel.append(entries.join("")); @@ -1224,7 +1222,7 @@ day.customClass ? day.customClass : "", entry.desc ? entry.desc : "", day.label ? day.label : "", - ntry.price ? entry.price : "", + entry.price ? entry.price : "", entry.estimatedDays ? entry.estimatedDays : "", day.dataObj ? day.dataObj : null );