Author: bpoussin Date: 2012-05-26 19:31:16 +0200 (Sat, 26 May 2012) New Revision: 162 Url: http://chorem.org/repositories/revision/chorem/162 Log: creation de nouveau dashboard pour separer les infos entre project et financial (reduction de la taille du tableau) Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardProfitability.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacationByEmployee.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardWorkingProjectDaysByEmployee.jsp Modified: trunk/chorem-entities/src/main/java/org/chorem/ChoremClient.java trunk/chorem-entities/src/main/xmi/chorem-model.properties trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/DashboardAction.java trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardProject.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacation.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacationAsked.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/hr.jsp Modified: trunk/chorem-entities/src/main/java/org/chorem/ChoremClient.java =================================================================== --- trunk/chorem-entities/src/main/java/org/chorem/ChoremClient.java 2012-05-25 16:22:13 UTC (rev 161) +++ trunk/chorem-entities/src/main/java/org/chorem/ChoremClient.java 2012-05-26 17:31:16 UTC (rev 162) @@ -5,6 +5,8 @@ import org.apache.commons.lang3.StringUtils; import org.chorem.entities.Attachment; +import org.chorem.entities.Configuration; +import org.chorem.entities.ConfigurationImpl; import org.chorem.entities.ContactDetails; import org.nuiton.util.ApplicationConfig; @@ -150,4 +152,27 @@ List<ContactDetails> contactDetails = result.getAll(); return contactDetails; } + + protected String configId; + public Configuration getConfiguration() { + if (configId == null) { + configId = findByQuery(new WikittyQueryMaker().exteq(Configuration.EXT_CONFIGURATION).end()); + } + + // on utilise le restore pour utilise le cache wikitty, il n'y a + // qu'une instance de cet objet + Configuration config = restore(Configuration.class, configId); + + if (config == null) { + // pas retrouve, on en cree un nouveau + // TODO poussin 20120524 dans le futur faire une interface pour recalculer/modifier les valeurs + config = new ConfigurationImpl(); + config.setDailyHoursWorked(6); + config.setDailyReturn(420); + store(config); + } + + return config; + } + } Modified: trunk/chorem-entities/src/main/xmi/chorem-model.properties =================================================================== --- trunk/chorem-entities/src/main/xmi/chorem-model.properties 2012-05-25 16:22:13 UTC (rev 161) +++ trunk/chorem-entities/src/main/xmi/chorem-model.properties 2012-05-26 17:31:16 UTC (rev 162) @@ -1,4 +1,4 @@ -org.chorem.entities.Configration.class.tagvalue.version=1.0 +org.chorem.entities.Configration.class.tagvalue.version=2.0 org.chorem.entities.Project.class.tagvalue.version=5.0 org.chorem.entities.Project.class.tagvalue.toString=%Project.name|noname$s org.chorem.entities.Project.class.tagvalue.sortOrder=Project.name @@ -54,7 +54,7 @@ org.chorem.entities.Evaluation.class.tagvalue.toString=%PersonSkill.evaluator$s %Evaluation.level|nolevel$s org.chorem.entities.Evaluation.class.tagvalue.sortOrder=Evaluation.level org.chorem.entities.Evaluation.class.tagvalue.preload=Evaluation.evaluator -org.chorem.entities.Vacation.class.tagvalue.version=7q.0 +org.chorem.entities.Vacation.class.tagvalue.version=8.0 org.chorem.entities.Vacation.class.tagvalue.toString=%Interval.employee$s %Interval.beginDate$tF-%Interval.endDate$tF %Vacation.type|notype$s org.chorem.entities.Vacation.class.tagvalue.preload=Vacation.employee org.chorem.entities.Vacation.class.tagvalue.sortOrder=Interval.beginDate,Interval.endDate,Vacation.type @@ -65,7 +65,7 @@ org.chorem.entities.Touch.class.tagvalue.sortOrder=Interval.beginDate desc,Touch.type,Touch.goal org.chorem.entities.Touch.attribute.goal.tagvalue.subtype=text/rst org.chorem.entities.Touch.attribute.type.tagvalue.choiceQuery=SELECT Touch.type WHERE extension=Touch -org.chorem.entities.Attachment.class.tagvalue.version=5.0 +org.chorem.entities.Attachment.class.tagvalue.version=6.0 org.chorem.entities.Attachment.class.tagvalue.toString=%Attachment.name|noname$s (%Attachment.mimetype|notype$s) %Attachment.date$tF org.chorem.entities.Attachment.class.tagvalue.sortOrder=Attachment.name,Attachment.mimetype,Attachment.date org.chorem.entities.Quotation.class.tagvalue.version=9.0 Modified: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/DashboardAction.java =================================================================== --- trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/DashboardAction.java 2012-05-25 16:22:13 UTC (rev 161) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/DashboardAction.java 2012-05-26 17:31:16 UTC (rev 162) @@ -1,19 +1,28 @@ package org.chorem.webmotion.actions; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Calendar; import java.util.Collection; +import java.util.Date; import java.util.EnumSet; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; +import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.ChoremClient; import org.chorem.entities.Attachment; import org.chorem.entities.Configuration; import org.chorem.entities.ConfigurationImpl; +import org.chorem.entities.Employee; import org.chorem.entities.Invoice; import org.chorem.entities.Quotation; import org.chorem.entities.QuotationStatus; @@ -24,6 +33,8 @@ import org.chorem.entities.VacationStatus; import org.debux.webmotion.server.WebMotionController; import org.debux.webmotion.server.render.Render; +import org.nuiton.util.ObjectUtil; +import org.nuiton.wikitty.entities.Element; import org.nuiton.wikitty.query.WikittyQuery; import org.nuiton.wikitty.query.WikittyQueryMaker; import org.nuiton.wikitty.query.WikittyQueryParser; @@ -42,6 +53,142 @@ /** to use log facility, just put in your code: log.info(\"...\"); */ static private Log log = LogFactory.getLog(DashboardAction.class); + /** + * Permet de decore une map dont toutes les valeurs manquant lorsqu'on les + * demandent sont initialise avec l'objet passe dans le constructeur. + * L'objet initialise est pousse dans la map avant d'etre retourne. + * + * TODO poussin 20120526 move this class to nuiton-utils + * + * @param <K> + * @param <V> + */ + static public class MapWithDefault<K, V> implements Map<K, V> { + protected Map<K, V> map; + protected Object defaultValue; + protected Collection args; + + /** + * L'objet par default utilise est l'objet passe en parametre s'il n'est + * pas clonable ou un clone de l'objet s'il est clonable. + * @param map la map a decore + * @param defaultValue la valeur par default + */ + public MapWithDefault(Map<K, V> map, V defaultValue) { + this.map = map; + this.defaultValue = defaultValue; + } + + /** + * L'objet par defaut est construit via le constructeur de la classe + * passe en parametre prenant les arguments args. + * @param map la map a decore + * @param defaultValue la class de la valeur par defaut + * @param args les arguments du construteur pour la classe + */ + public MapWithDefault(Map<K, V> map, Class<V> defaultValue, Object... args) { + this.map = map; + this.defaultValue = defaultValue; + if (ArrayUtils.isNotEmpty(args)) { + this.args = Arrays.asList(args); + } + } + + /** + * Get new instance of defaultValue if defaultValue is clonable or + * return directly defaultValue otherwize. + * @return + */ + protected V getDefaultValue() { + try { + Object result = defaultValue; + if (defaultValue instanceof Class) { + if (args == null) { + result = ((Class)defaultValue).newInstance(); + } else { + result = ObjectUtil.newInstance(((Class)defaultValue), args, true); + } + } else if (defaultValue instanceof Cloneable) { + result = ObjectUtil.clone(((Cloneable)defaultValue)); + } + return (V)result; + } catch (Exception eee) { + throw new RuntimeException(eee); + } + } + + // on surcharge le get pour creer automatiquement les objets + @Override + public V get(Object key) { + V result = map.get(key); + if (result == null) { + result = getDefaultValue(); + put((K)key, result); + } + return result; + } + + public int size() { + return map.size(); + } + + public boolean isEmpty() { + return map.isEmpty(); + } + + public boolean containsKey(Object key) { + return map.containsKey(key); + } + + public boolean containsValue(Object value) { + return map.containsValue(value); + } + + public V put(K key, V value) { + return map.put(key, value); + } + + public V remove(Object key) { + return map.remove(key); + } + + public void putAll(Map<? extends K, ? extends V> m) { + map.putAll(m); + } + + public void clear() { + map.clear(); + } + + public Set<K> keySet() { + return map.keySet(); + } + + public Collection<V> values() { + return map.values(); + } + + public Set<Entry<K, V>> entrySet() { + return map.entrySet(); + } + } + + +// static public class TaskInfoMap extends HashMap<String, TaskInfo> { +// // on surcharge le get pour creer automatiquement les objets +// @Override +// public TaskInfo get(Object key) { +// TaskInfo result = super.get(key); +// if (result == null) { +// result = new TaskInfo(); +// result.id = (String)key; +// put(result.id, result); +// } +// return result; +// } +// }; + + protected <E> Map<String, List<Attachment>> prepareAttachment(ChoremClient client, Collection<E> ids) { // recherche des attachments de chaque quotation trouvee WikittyQuery attachmentQuery = new WikittyQueryMaker().and() @@ -67,6 +214,35 @@ return attachments; } + /** + * return le nombre de jour entre 2 dates. Les demi-journées doivent etre + * posée jusqu'à 12h00 + * + * @param v + * @return + */ + public double computeVacationDays(Vacation v) { + Date endDate = v.getEndDate(); + if (0 == DateUtils.getFragmentInSeconds(endDate, Calendar.DATE)) { + // on rajoute un jour pour que les vances du 01/01/2012 au 01/01/2012 + // represente bien un jour plein + endDate = DateUtils.addDays(endDate, 1); + } + long end = endDate.getTime(); + long begin = v.getBeginDate().getTime(); + + double result = (end - begin) / (1000.0 * 3600.0 * 24.0); + return result; + } + + public double computeWorkingDays(ChoremClient client, Time t) { + Configuration config = client.getConfiguration(); + long workingTime = t.getEndDate().getTime() - t.getBeginDate().getTime(); + double result = workingTime / (1000.0 * 3600.0 * config.getDailyHoursWorked()); // N heures de travail par jour + return result; + } + + //////////////////////////////////////////////////////////////////////////// // // C O N T A C T @@ -94,35 +270,16 @@ EnumSet<QuotationStatus> status, String jspRender, String title, boolean computeTask) { // recherche de la configuration pour les calcules - Configuration config = client.findByQuery(Configuration.class, - new WikittyQueryMaker().rTrue().end()); - if (config == null) { - // pas retrouve, on en cree un nouveau - // TODO poussin 20120524 dans le futur faire une interface pour recalculer/modifier les valeurs - config = new ConfigurationImpl(); - config.setDailyHoursWorked(6); - config.setDailyReturn(420); - client.store(config); - } + Configuration config = client.getConfiguration(); - // recuperation des quotations en fonction de leur status - // TODO poussin 20120525 lorsque wikitty supportera la methode parse sur - // WikittyQueryMaker l'utiliser au lieu de ce qui suit pour simplifier - // voir: http://www.nuiton.org/issues/2105 - WikittyQueryMaker quotationQueryMaker = new WikittyQueryMaker(); - - // si besoin on ajoute le filtre demande par l'utilisateur - if (StringUtils.isNotBlank(query)) { - WikittyQuery filter = WikittyQueryParser.parse(query); - quotationQueryMaker.and().condition(filter.getCondition()); - } - - WikittyQuery quotationQuery = quotationQueryMaker + WikittyQuery quotationQuery = new WikittyQueryMaker().and() + .parse(query) .containsOne(Quotation.FQ_FIELD_QUOTATION_STATUS, status) .end(); - WikittyQueryResult<Quotation> result = client.findAllByQuery(Quotation.class, quotationQuery); + WikittyQueryResult<Quotation> result = + client.findAllByQuery(Quotation.class, quotationQuery); // recherche des attachments de chaque quotation trouvee Map<String, List<Attachment>> attachments = @@ -132,7 +289,8 @@ // si besoin recherche le nombre de tache ouvert et ferme // key: quotation id - Map<String, TaskInfo> taskInfos = new TaskInfoMap(); + Map<String, TaskInfo> taskInfos = new MapWithDefault<String, TaskInfo>( + new HashMap<String, TaskInfo>(), TaskInfo.class); int opened = 0; int closed = 0; @@ -167,13 +325,11 @@ } } - long workingTime = 0; for (Time t : timeResult) { Task task = t.getTask(true); String id = task.getQuotation(); - workingTime += t.getEndDate().getTime() - t.getBeginDate().getTime(); TaskInfo info = taskInfos.get(id); - info.workingDays += workingTime / (1000 * 3600 * config.getDailyHoursWorked()); // N heures de travail par jour + info.workingDays += computeWorkingDays(client, t); } } @@ -230,9 +386,7 @@ return quotationFilter(client, query, status, jsp, title, true); } - static public class TaskInfo { - /** id de la quotation */ - public String id; + static public class TaskInfo implements Cloneable { /** nombre de tache ouverte (scheduled ou started) */ public int opened; /** nombre de tache ferme (finished ou closed) */ @@ -250,6 +404,11 @@ /** profit reel pour ce projet */ public double realProfit; + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + public int getOpened() { return opened; } @@ -316,20 +475,6 @@ } - static public class TaskInfoMap extends HashMap<String, TaskInfo> { - // on surcharge le get pour creer automatiquement les objets - @Override - public TaskInfo get(Object key) { - TaskInfo result = super.get(key); - if (result == null) { - result = new TaskInfo(); - result.id = (String)key; - put(result.id, result); - } - return result; - } - }; - //////////////////////////////////////////////////////////////////////////// // // F I N A N C I A L @@ -338,18 +483,8 @@ public Render invoice(ChoremClient client, String query) { // recuperation des factures - // TODO poussin 20120525 lorsque wikitty supportera la methode parse sur - // WikittyQueryMaker l'utiliser au lieu de ce qui suit pour simplifier - // voir: http://www.nuiton.org/issues/2105 - WikittyQueryMaker invoiceQueryMaker = new WikittyQueryMaker(); - - // si besoin on ajoute le filtre demande par l'utilisateur - if (StringUtils.isNotBlank(query)) { - WikittyQuery filter = WikittyQueryParser.parse(query); - invoiceQueryMaker.and().condition(filter.getCondition()); - } - - WikittyQuery invoiceQuery = invoiceQueryMaker + WikittyQuery invoiceQuery = new WikittyQueryMaker().and() + .parse(query) .exteq(Invoice.EXT_INVOICE) .end(); @@ -383,6 +518,13 @@ ); } + public Render profitability(ChoremClient client, String query) { + EnumSet<QuotationStatus> status = EnumSet.range(QuotationStatus.STARTED, QuotationStatus.CLOSED); + String jsp = "dashboardProfitability.jsp"; + String title = "Profitability"; + return quotationFilter(client, query, status, jsp, title, true); + } + //////////////////////////////////////////////////////////////////////////// // // H R @@ -391,39 +533,93 @@ public Render vacationFilter(ChoremClient client, String query, String jspRender, EnumSet<VacationStatus> status) { // recuperation des vacances en fonction de leur status - // TODO poussin 20120525 lorsque wikitty supportera la methode parse sur - // WikittyQueryMaker l'utiliser au lieu de ce qui suit pour simplifier - // voir: http://www.nuiton.org/issues/2105 - WikittyQueryMaker vacationQueryMaker = new WikittyQueryMaker(); - - // si besoin on ajoute le filtre demande par l'utilisateur - if (StringUtils.isNotBlank(query)) { - WikittyQuery filter = WikittyQueryParser.parse(query); - vacationQueryMaker.and().condition(filter.getCondition()); - } - - WikittyQuery vacationQuery = vacationQueryMaker + WikittyQuery vacationQuery = new WikittyQueryMaker().and() + .parse(query) .containsOne(Vacation.FQ_FIELD_VACATION_STATUS, status) .end(); WikittyQueryResult<Vacation> vacations = client.findAllByQuery(Vacation.class, vacationQuery); + Map<String, Double> days = new HashMap<String, Double>(); + for (Vacation v : vacations) { + double d = computeVacationDays(v); + days.put(v.getWikittyId(), d); + } + return renderView(jspRender, - "vacations", vacations.getAll() + "vacations", vacations.getAll(), + "days", days ); } + /** + * Les vacances demandees par des employes non encore validee. + * @param client + * @param query + * @return + */ public Render vacationAsked(ChoremClient client, String query) { return vacationFilter(client, query, "dashboardVacationAsked.jsp", EnumSet.of(VacationStatus.ASKED)); } + /** + * Les vacances validees + * @param client + * @param query + * @return + */ public Render vacation(ChoremClient client, String query) { return vacationFilter(client, query, "dashboardVacation.jsp", EnumSet.of(VacationStatus.ACCEPTED)); } + public Render vacationByEmployee(ChoremClient client, String query) { + WikittyQuery vacationQuery = new WikittyQueryMaker().and() + .parse(query) + .eq(Vacation.FQ_FIELD_VACATION_STATUS, VacationStatus.ACCEPTED) + .end(); + WikittyQueryResult<Vacation> vacations = + client.findAllByQuery(Vacation.class, vacationQuery); + + Map<Employee, Double> days = new MapWithDefault<Employee, Double>( + new HashMap<Employee, Double>(), Double.valueOf(0)); + for(Vacation v : vacations) { + Employee e = v.getEmployee(false); + double d = days.get(e) + computeVacationDays(v); + days.put(e, d); + } + + return renderView("dashboardVacationByEmployee.jsp", + "vacationByEmployee", days + ); + } + /** + * Bilan du nombre de jour travaille sur des projets client depuis le 01/01 par employer de la + * societe par defaut (Configuration.defaultCompany) + */ + public Render workingProjectDaysByEmployee(ChoremClient client, String query) { + WikittyQuery vacationQuery = new WikittyQueryMaker().and() + .parse(query) + .exteq(Time.EXT_TIME) + .end(); + + WikittyQueryResult<Time> times = + client.findAllByQuery(Time.class, vacationQuery); + + Map<Employee, Double> days = new MapWithDefault<Employee, Double>( + new HashMap<Employee, Double>(), Double.valueOf(0)); + for(Time t : times) { + Employee e = t.getEmployee(false); + double d = days.get(e) + computeWorkingDays(client, t); + days.put(e, d); + } + + return renderView("dashboardWorkingProjectDaysByEmployee.jsp", + "workingProjectDaysByEmployee", days + ); + } } Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardProfitability.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardProfitability.jsp (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardProfitability.jsp 2012-05-26 17:31:16 UTC (rev 162) @@ -0,0 +1,48 @@ +<%@page contentType="text/html" pageEncoding="UTF-8"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + +<h1>${title}</h1> + +<table class="table table-striped table-bordered table-condensed"> + <thead> + <tr> + <th>Project</th> + <th>Type</th> + <th>Description</th> + <th>estimated days</th> + <th>Amount</th> + <th>working days</th> + <th>Hoped price day</th> + <th>Real price day</th> + <th>Hoped profit</th> + <th>Real profit</th> + <th>Status</th> + <th>Attchment</th> + </tr> + </thead> + <c:forEach var="q" items="${quotations}"> + <tbody> + <tr> + <td><a href="<c:url value="/wikitty/Project/view/${q.project}"/>">${q.getProject(false).getName()}</a></td> + <td>${q.type}</td> + <td><a href="<c:url value="/wikitty/Quotation/view/${q.wikittyId}"/>">${q.description}</a></td> + <td>${q.estimatedDays}</td> + <td>${q.amount}</td> + <td>${taskInfos.get(q.wikittyId).workingDays}</td> + <td>${taskInfos.get(q.wikittyId).hopedPriceDay}</td> + <td>${taskInfos.get(q.wikittyId).realPriceDay}</td> + <td>${taskInfos.get(q.wikittyId).hopedProfit}</td> + <td>${taskInfos.get(q.wikittyId).realProfit}</td> + <td>${q.status}</td> + <td>${attachments.get(q.wikittyId)}</td> + </tr> + </tbody> + </c:forEach> +</table> + +<dl class="dl-horizontal"> + <dt>Total amount</dt><dd>${amount}</dd> + <dt>Total hoped profit</dt><dd>${hopedProfit}</dd> + <dt>Total real profit</dt><dd>${realProfit}</dd> + <dt>Profit discordance</dt><dd>${realProfit - hopedProfit}</dd> +</dl> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardProject.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardProject.jsp 2012-05-25 16:22:13 UTC (rev 161) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardProject.jsp 2012-05-26 17:31:16 UTC (rev 162) @@ -15,10 +15,6 @@ <th>working days</th> <th>task opened</th> <th>task closed</th> - <th>Hoped price day</th> - <th>Real price day</th> - <th>Hoped profit</th> - <th>Real profit</th> <th>Amount</th> <th>Status</th> <th>Attchment</th> @@ -36,10 +32,6 @@ <td>${taskInfos.get(q.wikittyId).workingDays}</td> <td>${taskInfos.get(q.wikittyId).opened}</td> <td>${taskInfos.get(q.wikittyId).closed}</td> - <td>${taskInfos.get(q.wikittyId).hopedPriceDay}</td> - <td>${taskInfos.get(q.wikittyId).realPriceDay}</td> - <td>${taskInfos.get(q.wikittyId).hopedProfit}</td> - <td>${taskInfos.get(q.wikittyId).realProfit}</td> <td>${q.amount}</td> <td>${q.status}</td> <td>${attachments.get(q.wikittyId)}</td> @@ -51,9 +43,6 @@ <dl class="dl-horizontal"> <dt>Total amount</dt><dd>${amount}</dd> - <dt>Total hoped profit</dt><dd>${hopedProfit}</dd> - <dt>Total real profit</dt><dd>${realProfit}</dd> - <dt>Profit discordance</dt><dd>${realProfit - hopedProfit}</dd> <dt>Total task opened</dt><dd>${opened}</dd> <dt>Total task closed</dt><dd>${closed}</dd> </dl> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacation.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacation.jsp 2012-05-25 16:22:13 UTC (rev 161) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacation.jsp 2012-05-26 17:31:16 UTC (rev 162) @@ -11,6 +11,7 @@ <th>Employee</th> <th>Begin date</th> <th>End date</th> + <th>Days</th> <th>Type</th> <th>Description</th> </tr> @@ -21,6 +22,7 @@ <td><a href="<c:url value="/wikitty/Employee/view/${q.employee}"/>">${q.getEmployee(false)}</a></td> <td><a href="<c:url value="/wikitty/Vacation/view/${q.wikittyId}"/>">${q.beginDate}</a></td> <td>${q.endDate}</td> + <td>${days.get(q.wikittyId)}</td> <td>${q.type}</td> <td>${q.description}</td> </tr> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacationAsked.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacationAsked.jsp 2012-05-25 16:22:13 UTC (rev 161) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacationAsked.jsp 2012-05-26 17:31:16 UTC (rev 162) @@ -9,6 +9,7 @@ <th>Employee</th> <th>Begin date</th> <th>End date</th> + <th>Days</th> <th>Type</th> <th>Description</th> </tr> @@ -19,6 +20,7 @@ <td><a href="<c:url value="/wikitty/Employee/view/${q.employee}"/>">${q.getEmployee(false)}</a></td> <td><a href="<c:url value="/wikitty/Vacation/view/${q.wikittyId}"/>">${q.beginDate}</a></td> <td>${q.endDate}</td> + <td>${days.get(q.wikittyId)}</td> <td>${q.type}</td> <td>${q.description}</td> </tr> Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacationByEmployee.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacationByEmployee.jsp (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardVacationByEmployee.jsp 2012-05-26 17:31:16 UTC (rev 162) @@ -0,0 +1,12 @@ +<%@page contentType="text/html" pageEncoding="UTF-8"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + +<h1>Vacances par employe</h1> + +<ul> + <c:forEach var="q" items="${vacationByEmployee.keySet()}"> + + <li><strong>${q}:</strong> <span>${vacationByEmployee.get(q)}</span></li> + + </c:forEach> +</ul> Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardWorkingProjectDaysByEmployee.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardWorkingProjectDaysByEmployee.jsp (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardWorkingProjectDaysByEmployee.jsp 2012-05-26 17:31:16 UTC (rev 162) @@ -0,0 +1,10 @@ +<%@page contentType="text/html" pageEncoding="UTF-8"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + +<h1>Jour de travail sur des projets client par employe</h1> + +<ul> + <c:forEach var="q" items="${workingProjectDaysByEmployee.keySet()}"> + <li><strong>${q}:</strong> <span>${workingProjectDaysByEmployee.get(q)}</span></li> + </c:forEach> +</ul> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial.jsp 2012-05-25 16:22:13 UTC (rev 161) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial.jsp 2012-05-26 17:31:16 UTC (rev 162) @@ -8,3 +8,4 @@ </form> <jsp:include page="/fragment/dashboard/invoice?query=${query}"/> +<jsp:include page="/fragment/dashboard/profitability?query=${query}"/> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/hr.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/hr.jsp 2012-05-25 16:22:13 UTC (rev 161) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/hr.jsp 2012-05-26 17:31:16 UTC (rev 162) @@ -9,3 +9,5 @@ <jsp:include page="/fragment/dashboard/vacationAsked?query=${query}"/> <jsp:include page="/fragment/dashboard/vacation?query=${query}"/> +<jsp:include page="/fragment/dashboard/vacationByEmployee?query=${query}"/> +<jsp:include page="/fragment/dashboard/workingProjectDaysByEmployee?query=${query}"/>