Author: jcouteau Date: 2014-10-17 17:43:57 +0200 (Fri, 17 Oct 2014) New Revision: 438 Url: http://forge.chorem.org/projects/chorem/repository/revisions/438 Log: fixes #944 : [Financial] Reporting : - reporting on billing per year for an account - reporting on billing per year for a project Added: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/financial/AccountBillingReportAction.java trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/financial/ProjectBillingReportAction.java trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/accountBillingReport.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/projectBillingReport.jsp Modified: trunk/chorem-webmotion/src/main/resources/mapping trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/billingPerAccountReport.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/billingPerProjectReport.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/menu.jsp Copied: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/financial/AccountBillingReportAction.java (from rev 435, trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/sales/AccountSalesReportAction.java) =================================================================== --- trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/financial/AccountBillingReportAction.java (rev 0) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/financial/AccountBillingReportAction.java 2014-10-17 15:43:57 UTC (rev 438) @@ -0,0 +1,118 @@ +package org.chorem.webmotion.actions.financial; + +/* + * #%L + * Chorem :: webmotion + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 - 2014 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% + */ + +import org.chorem.ChoremClient; +import org.chorem.entities.Accepted; +import org.chorem.entities.FinancialTransaction; +import org.chorem.entities.Quotation; +import org.chorem.webmotion.actions.sales.SalesData; +import org.chorem.webmotion.actions.sales.SalesReportHelper; +import org.debux.webmotion.server.WebMotionController; +import org.debux.webmotion.server.render.Render; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryMaker; + +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * @author jcouteau <couteau@codelutin.com> + */ +public class AccountBillingReportAction extends WebMotionController { + + /** + * Rend le graphe des devis envoyés par mois + * + * @param client + * @return + */ + public Render billing(ChoremClient client, String account, String from, + String to) { + + if (null == from) { + from = String.valueOf(BillingReportHelper.getFirstYear(client)); + } + + if (null == to) { + to = String.valueOf(BillingReportHelper.getLastYear()); + } + + Map<Integer, SalesData> salesData = new LinkedHashMap<Integer, SalesData>(); + + List<Integer> listAllYears = BillingReportHelper.listAllYears(from, to); + + List<Integer> listAllYearsInChorem = BillingReportHelper.listAllYears(client); + + int previousYearValue = 0; + + for (Integer year:listAllYears){ + Date yearFirstDay = BillingReportHelper.getFirstDayOfYear(year); + Date yearLastDay = BillingReportHelper.getLastDayOfYear(year); + + SalesData yearData = new SalesData(); + + WikittyQuery projectQuery = new WikittyQueryMaker() + .select().sum(FinancialTransaction.FQ_FIELD_FINANCIALTRANSACTION_AMOUNT).where().and() + .eq(FinancialTransaction.FQ_FIELD_FINANCIALTRANSACTION_PAYER, account) + .bw(FinancialTransaction.FQ_FIELD_FINANCIALTRANSACTION_EMITTEDDATE, yearFirstDay, + yearLastDay) + .end(); + + Integer sales = client.findByQuery(Integer.class, projectQuery); + + //TODO JC 2012-01-26 Find a way to replace two queries into one. + WikittyQuery quotationsQuery = new WikittyQueryMaker().and() + .eq(FinancialTransaction.FQ_FIELD_FINANCIALTRANSACTION_PAYER, account) + .bw(FinancialTransaction.FQ_FIELD_FINANCIALTRANSACTION_EMITTEDDATE, yearFirstDay, + yearLastDay) + .end(); + + List<FinancialTransaction> quotations = client.findAllByQuery(FinancialTransaction.class, + quotationsQuery).getAll(); + + //Progression devis envoyés + int salesProgression = 0; + if (previousYearValue != 0){ + salesProgression = 100 * (sales - previousYearValue) / previousYearValue; + } + + previousYearValue = sales; + + yearData.setSales(sales); + yearData.setProgression(salesProgression); + yearData.setQuotations(quotations.size()); + + salesData.put(year, yearData); + } + + return renderView("financial/reports/accountBillingReport.jsp", + "data", salesData, + "allYears", listAllYearsInChorem, + "fromYear", from, + "toYear", to); + } +} Copied: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/financial/ProjectBillingReportAction.java (from rev 435, trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/sales/ProjectSalesReportAction.java) =================================================================== --- trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/financial/ProjectBillingReportAction.java (rev 0) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/financial/ProjectBillingReportAction.java 2014-10-17 15:43:57 UTC (rev 438) @@ -0,0 +1,118 @@ +package org.chorem.webmotion.actions.financial; + +/* + * #%L + * Chorem :: webmotion + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2011 - 2014 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% + */ + +import org.chorem.ChoremClient; +import org.chorem.entities.Accepted; +import org.chorem.entities.FinancialTransaction; +import org.chorem.entities.Quotation; +import org.chorem.webmotion.actions.sales.SalesData; +import org.chorem.webmotion.actions.sales.SalesReportHelper; +import org.debux.webmotion.server.WebMotionController; +import org.debux.webmotion.server.render.Render; +import org.nuiton.wikitty.query.WikittyQuery; +import org.nuiton.wikitty.query.WikittyQueryMaker; + +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * @author jcouteau <couteau@codelutin.com> + */ +public class ProjectBillingReportAction extends WebMotionController { + + /** + * Rend le graphe des devis envoyés par mois + * + * @param client + * @return + */ + public Render billing(ChoremClient client, String project, String from, + String to) { + + if (null == from) { + from = String.valueOf(BillingReportHelper.getFirstYear(client)); + } + + if (null == to) { + to = String.valueOf(BillingReportHelper.getLastYear()); + } + + Map<Integer, SalesData> salesData = new LinkedHashMap<Integer, SalesData>(); + + List<Integer> listAllYears = BillingReportHelper.listAllYears(from, to); + + List<Integer> listAllYearsInChorem = BillingReportHelper.listAllYears(client); + + int previousYearValue = 0; + + for (Integer year:listAllYears){ + Date yearFirstDay = BillingReportHelper.getFirstDayOfYear(year); + Date yearLastDay = BillingReportHelper.getLastDayOfYear(year); + + SalesData yearData = new SalesData(); + + WikittyQuery projectQuery = new WikittyQueryMaker() + .select().sum("FinancialTransaction.amount").where().and() + .eq(FinancialTransaction.FQ_FIELD_FINANCIALTRANSACTION_TARGET, project) + .bw(FinancialTransaction.FQ_FIELD_FINANCIALTRANSACTION_EMITTEDDATE, yearFirstDay, + yearLastDay) + .end(); + + Integer billing = client.findByQuery(Integer.class, projectQuery); + + //TODO JC 2012-01-22 Find a way to replace two queries into one. + WikittyQuery quotationsQuery = new WikittyQueryMaker().and() + .eq(FinancialTransaction.FQ_FIELD_FINANCIALTRANSACTION_TARGET, project) + .bw(FinancialTransaction.FQ_FIELD_FINANCIALTRANSACTION_EMITTEDDATE, yearFirstDay, + yearLastDay) + .end(); + + List<FinancialTransaction> quotations = client.findAllByQuery(FinancialTransaction.class, + quotationsQuery).getAll(); + + //Progression devis envoyés + int salesProgression = 0; + if (previousYearValue != 0){ + salesProgression = 100 * (billing - previousYearValue) / previousYearValue; + } + + previousYearValue = billing; + + yearData.setSales(billing); + yearData.setProgression(salesProgression); + yearData.setQuotations(quotations.size()); + + salesData.put(year, yearData); + } + + return renderView("financial/reports/projectBillingReport.jsp", + "data", salesData, + "allYears", listAllYearsInChorem, + "fromYear", from, + "toYear", to); + } +} Modified: trunk/chorem-webmotion/src/main/resources/mapping =================================================================== --- trunk/chorem-webmotion/src/main/resources/mapping 2014-10-17 14:54:24 UTC (rev 437) +++ trunk/chorem-webmotion/src/main/resources/mapping 2014-10-17 15:43:57 UTC (rev 438) @@ -108,7 +108,9 @@ PUT /financial/expenseAccounts/{expenseAccountId} action:financial.ExpenseAccountAction.saveExpenseAccount * /financial/report/billing action:financial.BillingReportAction.billing * /financial/report/billingPerProject action:financial.BillingPerProjectReportAction.billing +* /financial/report/billingPerProject/{project} action:financial.ProjectBillingReportAction.billing * /financial/report/billingPerAccount action:financial.BillingPerAccountReportAction.billing +* /financial/report/billingPerAccount/{account} action:financial.AccountBillingReportAction.billing * /billingMenu view:financial/reports/menu.jsp Copied: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/accountBillingReport.jsp (from rev 435, trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/accountSalesReport.jsp) =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/accountBillingReport.jsp (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/accountBillingReport.jsp 2014-10-17 15:43:57 UTC (rev 438) @@ -0,0 +1,122 @@ +<%-- + #%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-fluid"> + <div class="span2"> + <jsp:include page="/billingMenu"/> + </div> + + <div class="span10"> + <!-- Javascript to display graph --> + <script type="text/javascript"> + $(document).ready(function(){ + var sales = [ + <c:forEach var="entry" items="${data}" varStatus="counter"> + ['${entry.key}', ${entry.value.sales}] + <c:if test="${!counter.last}">, </c:if> + </c:forEach> + ]; + + var plot1 = $.jqplot ('sales', [sales], { + title:'Facturation par année', + seriesDefaults:{ + renderer:$.jqplot.BarRenderer, + rendererOptions: {fillToZero: true} + }, + axes:{ + xaxis:{ + pad: 0, + tickRenderer: $.jqplot.CanvasAxisTickRenderer , + tickOptions: { + angle: -30, + fontSize: '10pt' + }, + renderer: $.jqplot.CategoryAxisRenderer + }, + }, + highlighter: { + show: true, + tooltipAxes: 'y' + }, + cursor: { + show: false + }, + series:[ + <c:forEach var="entry" items="${data}" varStatus="counter"> + {label:${entry.key}}<c:if test="${!counter.last}">,</c:if> + </c:forEach>] + }); + + }); + </script> + + <h2>Facturation par année</h2> + + <form action="sales" method="get"> + <select name="from"> + <c:forEach var="entry" items="${allYears}" varStatus="counter"> + <option value="${entry}" <c:if test="${entry==fromYear}">selected</c:if>>${entry}</option> + </c:forEach> + </select> + <select name="to"> + <c:forEach var="entry" items="${allYears}" varStatus="counter"> + <option value="${entry}" ${entry == toYear ? 'selected' : ''} >${entry}</option> + </c:forEach> + </select> + <input type="submit" value="Rechercher"> + </form> + + <div id="sales" style="height:200px;"></div> + + + <table class="table table-striped table-bordered table-condensed"> + <thead> + <tr> + <th>Année</th> + <th>Facturation</th> + <th>Factures</th> + <th>€/factures</th> + <th>Progression</th> + </tr> + </thead> + <tbody> + <c:forEach var="year" items="${data}"> + <tr> + <td>${year.key}</td> + <td class="currency">${year.value.sales}</td> + <td>${year.value.quotations}</td> + <td class="currency">${year.value.mean}</td> + <td class="percent">${year.value.progression} %</td> + </tr> + </c:forEach> + </tbody> + </table> + + </div> +</div> + +<div style="clear:both;"/> \ No newline at end of file Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/billingPerAccountReport.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/billingPerAccountReport.jsp 2014-10-17 14:54:24 UTC (rev 437) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/billingPerAccountReport.jsp 2014-10-17 15:43:57 UTC (rev 438) @@ -91,7 +91,7 @@ <tbody> <c:forEach var="account" items="${data}"> <tr> - <td>${account.key}</td> + <td><a href="<c:url value="/financial/report/billingPerAccount/${account.key.wikittyId}"/>">${account.key}</a></td> <td>${account.value.sales}</td> <td>${account.value.quotations}</td> <td>${account.value.mean} €</td> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/billingPerProjectReport.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/billingPerProjectReport.jsp 2014-10-17 14:54:24 UTC (rev 437) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/billingPerProjectReport.jsp 2014-10-17 15:43:57 UTC (rev 438) @@ -91,7 +91,7 @@ <tbody> <c:forEach var="project" items="${data}"> <tr> - <td>${project.key.name}</td> + <td><a href="<c:url value="/financial/report/billingPerProject/${project.key.wikittyId}"/>">${project.key.name}</a></td> <td>${project.value.sales}</td> <td>${project.value.quotations}</td> <td>${project.value.mean} €</td> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/menu.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/menu.jsp 2014-10-17 14:54:24 UTC (rev 437) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/menu.jsp 2014-10-17 15:43:57 UTC (rev 438) @@ -20,8 +20,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #L% --%> + + +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + <ul class="list-group"> - <li class="list-group-item"><a href="billing"><i class="icon-chevron-right"></i> Facturation</a></li> - <li class="list-group-item"><a href="billingPerAccount"><i class="icon-chevron-right"></i> Facturation par client</a></li> - <li class="list-group-item"><a href="billingPerProject"><i class="icon-chevron-right"></i> Facturation par projet</a></li> + <li class="list-group-item"><a href="<c:url value="/financial/report/billing"/>"><i class="icon-chevron-right"></i> Facturation</a></li> + <li class="list-group-item"><a href="<c:url value="/financial/report/billingPerAccount"/>"><i class="icon-chevron-right"></i> Facturation par client</a></li> + <li class="list-group-item"><a href="<c:url value="/financial/report/billingPerProject"/>"><i class="icon-chevron-right"></i> Facturation par projet</a></li> </ul> \ No newline at end of file Copied: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/projectBillingReport.jsp (from rev 435, trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/salesReports/projectSalesReport.jsp) =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/projectBillingReport.jsp (rev 0) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial/reports/projectBillingReport.jsp 2014-10-17 15:43:57 UTC (rev 438) @@ -0,0 +1,122 @@ +<%-- + #%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-fluid"> + <div class="span2"> + <jsp:include page="/billingMenu"/> + </div> + + <div class="span10"> + <!-- Javascript to display graph --> + <script type="text/javascript"> + $(document).ready(function(){ + var sales = [ + <c:forEach var="entry" items="${data}" varStatus="counter"> + ['${entry.key}', ${entry.value.sales}] + <c:if test="${!counter.last}">, </c:if> + </c:forEach> + ]; + + var plot1 = $.jqplot ('sales', [sales], { + title:'Facturation par année', + seriesDefaults:{ + renderer:$.jqplot.BarRenderer, + rendererOptions: {fillToZero: true} + }, + axes:{ + xaxis:{ + pad: 0, + tickRenderer: $.jqplot.CanvasAxisTickRenderer , + tickOptions: { + angle: -30, + fontSize: '10pt' + }, + renderer: $.jqplot.CategoryAxisRenderer + }, + }, + highlighter: { + show: true, + tooltipAxes: 'y' + }, + cursor: { + show: false + }, + series:[ + <c:forEach var="entry" items="${data}" varStatus="counter"> + {label:${entry.key}}<c:if test="${!counter.last}">,</c:if> + </c:forEach>] + }); + + }); + </script> + + <h2>Facturation par année</h2> + + <form action="sales" method="get"> + <select name="from"> + <c:forEach var="entry" items="${allYears}" varStatus="counter"> + <option value="${entry}" <c:if test="${entry==fromYear}">selected</c:if>>${entry}</option> + </c:forEach> + </select> + <select name="to"> + <c:forEach var="entry" items="${allYears}" varStatus="counter"> + <option value="${entry}" ${entry == toYear ? 'selected' : ''} >${entry}</option> + </c:forEach> + </select> + <input type="submit" value="Rechercher"> + </form> + + <div id="sales" style="height:200px;"></div> + + + <table class="table table-striped table-bordered table-condensed"> + <thead> + <tr> + <th>Année</th> + <th>Facturation</th> + <th>Factures</th> + <th>€/factures</th> + <th>Progression</th> + </tr> + </thead> + <tbody> + <c:forEach var="year" items="${data}"> + <tr> + <td>${year.key}</td> + <td class="currency">${year.value.sales}</td> + <td>${year.value.quotations}</td> + <td class="currency">${year.value.mean}</td> + <td class="percent">${year.value.progression} %</td> + </tr> + </c:forEach> + </tbody> + </table> + + </div> +</div> + +<div style="clear:both;"/> \ No newline at end of file