Author: bpoussin Date: 2012-08-21 18:42:04 +0200 (Tue, 21 Aug 2012) New Revision: 245 Url: http://chorem.org/repositories/revision/chorem/245 Log: creation d'un dashboard pour la page d'accueil Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardSummary.jsp Modified: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/DashboardAction.java trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/index.jsp trunk/chorem-webmotion/src/main/webapp/css/chorem.less trunk/chorem-webmotion/src/main/webapp/js/chorem.js 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-08-20 23:28:09 UTC (rev 244) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/DashboardAction.java 2012-08-21 16:42:04 UTC (rev 245) @@ -66,8 +66,12 @@ import java.util.Set; import javax.servlet.ServletContext; import org.apache.commons.lang3.StringUtils; +import org.chorem.entities.Interval; +import org.chorem.entities.Touch; import org.nuiton.util.DateUtil; import org.nuiton.wikitty.entities.Element; +import org.nuiton.wikitty.entities.Wikitty; +import org.nuiton.wikitty.query.conditions.Select; /** * @@ -83,6 +87,7 @@ static private Log log = LogFactory.getLog(DashboardAction.class); static final public String budgetDateFormat = "MM/yyyy"; + static final public String summaryDateFormat = "dd/MM/yyyy hh:mm"; /** * Permet de decore une map dont toutes les valeurs manquant lorsqu'on les @@ -313,6 +318,139 @@ //////////////////////////////////////////////////////////////////////////// // + // C O N T A C T + // + //////////////////////////////////////////////////////////////////////////// + + public Render summary(ChoremClient client) { + Date now = new Date(); + Date inOneWeek = DateUtils.addDays(now, 7); + Date firstDayYear = DateUtil.setFirstDayOfYear(now); + Date lastYearNow = DateUtils.addYears(now, -1); + Date lastYearFirstDay = DateUtil.setFirstDayOfYear(lastYearNow); + + String companyId = client.getConfiguration().getDefaultCompany(); + + // toutes les depenses depuis le debut de l'annee + WikittyQuery annualDebtQuery = new WikittyQueryMaker() + .select(Invoice.FQ_FIELD_INVOICE_AMOUNT, Aggregate.SUM) + .and() + .exteq(Invoice.EXT_INVOICE) + .bw(Invoice.FQ_FIELD_INVOICE_POSTEDDATE, firstDayYear, now) + .containsOne(Invoice.FQ_FIELD_INVOICE_CUSTOMER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .end().setLimit(WikittyQuery.MAX); + + // toutes les factures emises depuis le debut de l'annee + WikittyQuery annualIncomeQuery = new WikittyQueryMaker() + .select(Invoice.FQ_FIELD_INVOICE_AMOUNT, Aggregate.SUM) + .and() + .exteq(Invoice.EXT_INVOICE) + .bw(Invoice.FQ_FIELD_INVOICE_POSTEDDATE, firstDayYear, now) + .containsOne(Invoice.FQ_FIELD_INVOICE_SUPPLIER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .end(); + + // toutes les depenses depuis le debut de l'annee + WikittyQuery lastYearAnnualDebtQuery = new WikittyQueryMaker() + .select(Invoice.FQ_FIELD_INVOICE_AMOUNT, Aggregate.SUM) + .and() + .exteq(Invoice.EXT_INVOICE) + .bw(Invoice.FQ_FIELD_INVOICE_POSTEDDATE, lastYearFirstDay, lastYearNow) + .containsOne(Invoice.FQ_FIELD_INVOICE_CUSTOMER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .end().setLimit(WikittyQuery.MAX); + + // toutes les factures emises depuis le debut de l'annee + WikittyQuery lastYearAnnualIncomeQuery = new WikittyQueryMaker() + .select(Invoice.FQ_FIELD_INVOICE_AMOUNT, Aggregate.SUM) + .and() + .exteq(Invoice.EXT_INVOICE) + .bw(Invoice.FQ_FIELD_INVOICE_POSTEDDATE, lastYearFirstDay, lastYearNow) + .containsOne(Invoice.FQ_FIELD_INVOICE_SUPPLIER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .end(); + + + // les factures que notre societe doit payer au plus tard dans 7 jours + WikittyQuery invoiceDebtQuery = new WikittyQueryMaker() + .select(Invoice.FQ_FIELD_INVOICE_AMOUNT, Aggregate.SUM) + .and() + .exteq(Invoice.EXT_INVOICE) + .lt(Invoice.FQ_FIELD_INVOICE_EXPECTEDDATE, inOneWeek) + .isNull(Invoice.FQ_FIELD_INVOICE_PAYMENTDATE) + .containsOne(Invoice.FQ_FIELD_INVOICE_CUSTOMER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .end().setLimit(WikittyQuery.MAX); + + // les factures qu'auraient du payer nos clients (ils sont en retard) + WikittyQuery invoiceIncomeQuery = new WikittyQueryMaker() + .select(Invoice.FQ_FIELD_INVOICE_AMOUNT, Aggregate.SUM) + .and() + .exteq(Invoice.EXT_INVOICE) + .lt(Invoice.FQ_FIELD_INVOICE_EXPECTEDDATE, now) + .isNull(Invoice.FQ_FIELD_INVOICE_PAYMENTDATE) + .containsOne(Invoice.FQ_FIELD_INVOICE_SUPPLIER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .end(); + + // les contacts qui doivnet etre pris dans les 7 prochains jours + WikittyQuery touchQuery = new WikittyQueryMaker().and() + .exteq(Touch.EXT_TOUCH) + .lt(Interval.FQ_FIELD_INTERVAL_BEGINDATE, inOneWeek) + .isNull(Interval.FQ_FIELD_INTERVAL_ENDDATE) + .end().setLimit(0); + + WikittyQueryResult<Double>[] invoices = + client.findAllByQuery(Double.class, + invoiceDebtQuery, invoiceIncomeQuery, + annualDebtQuery, annualIncomeQuery, + lastYearAnnualDebtQuery, lastYearAnnualIncomeQuery); + + WikittyQueryResult<String> touchs = + client.findAllByQuery(touchQuery); + + // nombre de facture + int invoiceDebtNb = invoices[0].getTotalResult(); + // montant total de toutes les factures + double invoiceDebt = invoices[0].peek(); + + // nombre de facture + int invoiceIncomeNb = invoices[1].getTotalResult(); + // montant total de toutes les factures + double invoiceIncome = invoices[1].peek(); + + // montant total de toutes les factures + double annualDebt = invoices[2].peek(); + double annualIncome = invoices[3].peek(); + + // montant total de toutes les factures + double lastYearAnnualDebt = invoices[4].peek(); + double lastYearAnnualIncome = invoices[5].peek(); + + int touchNb = touchs.getTotalResult(); + + String touchQueryString = touchQuery.getCondition().toString(); + + return renderView("dashboardSummary.jsp", + "date", now, + "now", DateFormatUtils.format(now, summaryDateFormat), + "inOneWeek", DateFormatUtils.format(inOneWeek, summaryDateFormat), + "invoiceDebtNb", invoiceDebtNb, + "invoiceDebt", invoiceDebt, + "invoiceIncomeNb", invoiceIncomeNb, + "invoiceIncome", invoiceIncome, + "annualDebt", annualDebt, + "annualIncome", annualIncome, + "lastYearAnnualDebt", lastYearAnnualDebt, + "lastYearAnnualIncome", lastYearAnnualIncome, + "touchNb", touchNb, + "touchQueryString", touchQueryString + ); + } + + //////////////////////////////////////////////////////////////////////////// + // // P R O J E C T // //////////////////////////////////////////////////////////////////////////// Added: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardSummary.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardSummary.jsp (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardSummary.jsp 2012-08-21 16:42:04 UTC (rev 245) @@ -0,0 +1,56 @@ +<%-- + #%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="/WEB-INF/wikitty.tld" prefix="w"%> + +<div class="row"> + <div class="span1"> + <p class="calendar"> + <f:formatDate value="${date}" pattern="dd"/> + <span class="week">semaine <f:formatDate value="${date}" pattern="w"/></span> + <em><f:formatDate value="${date}" pattern="MMM"/></em> + </p> + </div> + <div class="span24"> + <ul> + <li>Il y a ${invoiceDebtNb} + <a href='<c:url value="/report?report=invoiceDebt&end=${inOneWeek}&query=Invoice.paymentDate=null"/>'> + factures à payer</a> pour un montant de + <f:formatNumber type="currency" value="${invoiceDebt}"/></li> + <li>Il y a ${invoiceIncomeNb} + <a href='<c:url value="/report?report=invoiceIncome&end=${now}&query=Invoice.paymentDate=null"/>'> + factures impayées</a> pour un montant de + <f:formatNumber type="currency" value="${invoiceIncome}"/></li> + <li>Il y a ${touchNb} <a href='<c:url value="/wikitty/search?query=${touchQueryString}"/>'> + contact à prendre</a></li> + </ul> + + <ul> + <li>Chiffre d'affaire: <strong><f:formatNumber type="currency" value="${annualIncome}"/></strong> (N-1: <strong><f:formatNumber type="currency" value="${lastYearAnnualIncome}"/></strong>) + <li>Dépenses: <strong><f:formatNumber type="currency" value="${annualDebt}"/></strong> (N-1: <strong><f:formatNumber type="currency" value="${lastYearAnnualDebt}"/></strong>) + <li>Bénéfice/perte: <strong><f:formatNumber type="currency" value="${annualIncome-annualDebt}"/></strong> (N-1: <strong><f:formatNumber type="currency" value="${lastYearAnnualIncome-lastYearAnnualDebt}"/></strong>) + </ul> + </div> +</div> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/index.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/index.jsp 2012-08-20 23:28:09 UTC (rev 244) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/index.jsp 2012-08-21 16:42:04 UTC (rev 245) @@ -25,3 +25,5 @@ <h1>Chorem</h1> Bienvenue sur Chorem, l'outil de gestion d'entreprise. + +<jsp:include page="/fragment/dashboard/summary"/> Modified: trunk/chorem-webmotion/src/main/webapp/css/chorem.less =================================================================== --- trunk/chorem-webmotion/src/main/webapp/css/chorem.less 2012-08-20 23:28:09 UTC (rev 244) +++ trunk/chorem-webmotion/src/main/webapp/css/chorem.less 2012-08-21 16:42:04 UTC (rev 245) @@ -38,6 +38,89 @@ text-align: right; } + +/* L'affiche du calendrier sur la page d'accueil */ +.calendar{ + margin:.25em 10px 10px 0; + padding-top:5px; + float:left; + width:80px; + background:#ededef; + background: -webkit-gradient(linear, left top, left bottom, from(#ededef), to(#ccc)); + background: -moz-linear-gradient(top, #ededef, #ccc); + font:bold 30px/60px Arial Black, Arial, Helvetica, sans-serif; + text-align:center; + color:#000; + text-shadow:#fff 0 1px 0; + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; + position:relative; + -moz-box-shadow:0 2px 2px #888; + -webkit-box-shadow:0 2px 2px #888; + box-shadow:0 2px 2px #888; +} + +.calendar span.week { + display:block; + font: 10px/20px Arial Black, Arial, Helvetica, sans-serif; +} + +.calendar:before, .calendar:after{ + content:''; + float:left; + position:absolute; + top:5px; + width:8px; + height:8px; + background:#111; + z-index:1; + -moz-border-radius:10px; + -webkit-border-radius:10px; + border-radius:10px; + -moz-box-shadow:0 1px 1px #fff; + -webkit-box-shadow:0 1px 1px #fff; + box-shadow:0 1px 1px #fff; +} +.calendar:before{left:11px;} +.calendar:after{right:11px;} + +.calendar em{ + display:block; + font:normal bold 11px/30px Arial, Helvetica, sans-serif; + color:#fff; + text-shadow:#00365a 0 -1px 0; + background:#04599a; + background:-webkit-gradient(linear, left top, left bottom, from(#04599a), to(#00365a)); + background:-moz-linear-gradient(top, #04599a, #00365a); + -moz-border-radius-bottomright:3px; + -webkit-border-bottom-right-radius:3px; + border-bottom-right-radius:3px; + -moz-border-radius-bottomleft:3px; + -webkit-border-bottom-left-radius:3px; + border-bottom-left-radius:3px; + border-top:1px solid #00365a; +} + +.calendar em:before, .calendar em:after{ + content:''; + float:left; + position:absolute; + top:-5px; + width:4px; + height:14px; + background:#dadada; + background:-webkit-gradient(linear, left top, left bottom, from(#f1f1f1), to(#aaa)); + background:-moz-linear-gradient(top, #f1f1f1, #aaa); + z-index:2; + -moz-border-radius:2px; + -webkit-border-radius:2px; + border-radius:2px; +} +.calendar em:before{left:13px;} +.calendar em:after{right:13px;} + +/* Les differents niveaux pour le tableau de budget*/ .categorylevel (@level) { margin-left: @level * 10px; } Modified: trunk/chorem-webmotion/src/main/webapp/js/chorem.js =================================================================== --- trunk/chorem-webmotion/src/main/webapp/js/chorem.js 2012-08-20 23:28:09 UTC (rev 244) +++ trunk/chorem-webmotion/src/main/webapp/js/chorem.js 2012-08-21 16:42:04 UTC (rev 245) @@ -21,13 +21,20 @@ * #L% */ +// tooltips utiliser pour le tableau budget, mais pas tres bien, car oblige +// de mettre hide a 1000. Le mieux serait d'avoir un tooltips (html) qui reste +// visible (et donc permet de cliquer sur les liens) si on va dessus' $(function() { $('.withTooltip').tooltip({trigger: 'hover', delay: { show: 0, hide: 1000 }}); }); +$(function () { + $.datepicker.setDefaults($.datepicker.regional['fr']); + $.timepicker.setDefaults($.timepicker.regional['fr']); +}); + // tout ce qui aura la classe datepicker servira a editer une date $(function() { - $( ".datepicker" ).datepicker($.datepicker.regional['fr']); $( ".datepicker" ).datepicker({ showWeek: true, firstDay: 1, @@ -37,7 +44,6 @@ // "option", "gotoCurrent", true ); }); $(function() { - $( ".timepicker" ).timepicker($.timepicker.regional['fr']); $( ".timepicker" ).timepicker({ showWeek: true, firstDay: 1, @@ -48,7 +54,6 @@ }); // tout ce qui aura la classe datetimepicker servira a editer une date avec heure $(function() { - $( ".datetimepicker" ).datetimepicker($.timepicker.regional['fr']); $( ".datetimepicker" ).datetimepicker({ showWeek: true, firstDay: 1,