Author: bpoussin Date: 2012-08-15 23:37:19 +0200 (Wed, 15 Aug 2012) New Revision: 240 Url: http://chorem.org/repositories/revision/chorem/240 Log: modification pour faire fonctionner le rapport budget. Il reste une erreur sur l'affichage des categories :( Modified: trunk/chorem-entities/src/main/xmi/chorem-model.properties trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/AdminAction.java trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/DashboardAction.java trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/injector/InjectorListener.java trunk/chorem-webmotion/src/main/java/org/wikitty/web/jsptag/WikittyDisplay.java trunk/chorem-webmotion/src/main/java/org/wikitty/web/jsptag/WikittyInput.java trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardBudget.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardInvoice.jsp trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial.jsp trunk/chorem-webmotion/src/main/webapp/css/chorem.less Modified: trunk/chorem-entities/src/main/xmi/chorem-model.properties =================================================================== --- trunk/chorem-entities/src/main/xmi/chorem-model.properties 2012-08-13 10:51:21 UTC (rev 239) +++ trunk/chorem-entities/src/main/xmi/chorem-model.properties 2012-08-15 21:37:19 UTC (rev 240) @@ -89,7 +89,7 @@ # # Invoice # -org.chorem.entities.Invoice.class.tagvalue.version=12.0 +org.chorem.entities.Invoice.class.tagvalue.version=14.0 org.chorem.entities.Invoice.class.tagvalue.preload=Invoice.customer;Invoice.supplier org.chorem.entities.Invoice.class.tagvalue.toString=%Invoice.reference|noref$s %Invoice.amount|noamount$s %Invoice.postedDate$tF %Invoice.expectedDate$tF %Invoice.paymentDate$tF org.chorem.entities.Invoice.class.tagvalue.sortOrder=Invoice.postedDate desc,Invoice.expectedDate,Invoice.paymentDate,Invoice.reference,Invoice.amount @@ -103,7 +103,6 @@ org.chorem.entities.Invoice.attribute.expectedDate.tagvalue.help=La date souhait\u00e9e de paiement org.chorem.entities.Invoice.attribute.paymentDate.tagvalue.help=La date de paiement r\u00e9elle org.chorem.entities.Invoice.attribute.supplier.tagvalue.help=La personne chez Code Lutin qui g\u00e8re la facturation -org.chorem.entities.Invoice.attribute.supplier.tagvalue.allowedQuery=SELECT id WHERE Employee.company="1628bcf9-82ea-440d-ab8d-ea93498af2d9" org.chorem.entities.Invoice.attribute.customer.tagvalue.help=La personne chez le client \u00e0 qui ont a envoyer la facture # # Invoiceable @@ -161,7 +160,7 @@ # # Quotation # -org.chorem.entities.Quotation.class.tagvalue.version=16.0 +org.chorem.entities.Quotation.class.tagvalue.version=17.0 org.chorem.entities.Quotation.class.tagvalue.preload=Quotation.project;Quotation.customer;Quotation.supplier;Quotation.category org.chorem.entities.Quotation.class.tagvalue.toString=%Interval.beginDate$tF-%Interval.endDate$tF %Quotation.reference|noref$s(%Quotation.category|noCategory$s) %Quotation.description|nodescription$s org.chorem.entities.Quotation.class.tagvalue.sortOrder=Interval.beginDate desc,Interval.endDate,Quotation.reference,Quotation.type,Quotation.description @@ -187,7 +186,7 @@ org.chorem.entities.Quotation.attribute.vrsStart.tagvalue.help=Date de d\u00e9but de la VSR (Validation en Service R\u00e9gulier) org.chorem.entities.Quotation.attribute.warrantyStart.tagvalue.help=Date de d\u00e9but de la garantie org.chorem.entities.Quotation.attribute.supplier.tagvalue.help=La personne en charge du dossier chez Code Lutin -org.chorem.entities.Quotation.attribute.supplier.tagvalue.allowedQuery=SELECT id WHERE Employee.company="1628bcf9-82ea-440d-ab8d-ea93498af2d9" +org.chorem.entities.Quotation.attribute.supplier.tagvalue.allowedQuery=Employee.company="1628bcf9-82ea-440d-ab8d-ea93498af2d9" org.chorem.entities.Quotation.attribute.customer.tagvalue.help=La personne en charge du dossier chez le client org.chorem.entities.Quotation.attribute.project.tagvalue.help=Le projet auquel se rapport ce devis org.chorem.entities.Quotation.attribute.category.tagvalue.help=La cat\u00e9gorie de ce devis Modified: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/AdminAction.java =================================================================== --- trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/AdminAction.java 2012-08-13 10:51:21 UTC (rev 239) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/AdminAction.java 2012-08-15 21:37:19 UTC (rev 240) @@ -46,15 +46,18 @@ /** to use log facility, just put in your code: log.info(\"...\"); */ static private Log log = LogFactory.getLog(AdminAction.class); - /** - * Bilan du nombre de jour travaille sur des projets client depuis le 01/01 par employer de la - * societe par defaut (Configuration.defaultCompany) + /** + * affiche les valeurs de configuration d'administration */ public Render variables(ChoremClient client) { Configuration conf = client.getConfiguration(); GenericAction g = new GenericAction(); + g.setContextable(contextable); return g.view(client, conf.getWikittyId(), null); + // la ligne suivante ne fonctionne pas (probleme de nombre d'argument) +// return renderAction("GenericAction.view", +// "client", client, "id", conf.getWikittyId(), "extension", null ); } } 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-13 10:51:21 UTC (rev 239) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/actions/DashboardAction.java 2012-08-15 21:37:19 UTC (rev 240) @@ -58,12 +58,15 @@ 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 javax.servlet.ServletContext; import org.apache.commons.lang3.StringUtils; +import org.nuiton.util.DateUtil; +import org.nuiton.wikitty.entities.Element; /** * @@ -320,9 +323,20 @@ * (task info not needed for not stated project) * @return */ - protected Render quotationFilter(ChoremClient client, String query, + protected Render quotationFilter(ChoremClient client, + Date start, Date end, String query, EnumSet<QuotationStatus> status, String jspRender, String title, boolean computeTask) { + + if (start == null) { + start = new Date(); + start = DateUtils.setMonths(start, Calendar.JANUARY); + } + + if (end == null) { + end = DateUtils.setMonths(start, Calendar.DECEMBER); + } + // recherche de la configuration pour les calcules Configuration config = client.getConfiguration(); @@ -330,6 +344,9 @@ WikittyQuery quotationQuery = new WikittyQueryMaker().and() .parse(query) .containsOne(Quotation.FQ_FIELD_QUOTATION_STATUS, status) + .or() + .bw(Quotation.FQ_FIELD_QUOTATION_POSTEDDATE, start, end) + .isNull(Quotation.FQ_FIELD_QUOTATION_POSTEDDATE) .end(); WikittyQueryResult<Quotation> result = @@ -419,25 +436,28 @@ "taskInfos", taskInfos); } - public Render quotation(ChoremClient client, String query) { + public Render quotation(ChoremClient client, + Date start, Date end, String query) { EnumSet<QuotationStatus> status = EnumSet.range(QuotationStatus.LEAD, QuotationStatus.SENT); String jsp = "dashboardQuotation.jsp"; String title = "Les propositions en attente de réponse"; - return quotationFilter(client, query, status, jsp, title, false); + return quotationFilter(client, start, end, query, status, jsp, title, false); } - public Render projectOpen(ChoremClient client, String query) { + public Render projectOpen(ChoremClient client, + Date start, Date end, String query) { EnumSet<QuotationStatus> status = EnumSet.range(QuotationStatus.ACCEPTED, QuotationStatus.RSV); String jsp = "dashboardProject.jsp"; String title = "Les projets en cours"; - return quotationFilter(client, query, status, jsp, title, true); + return quotationFilter(client, start, end, query, status, jsp, title, true); } - public Render projectClosed(ChoremClient client, String query) { + public Render projectClosed(ChoremClient client, + Date start, Date end, String query) { EnumSet<QuotationStatus> status = EnumSet.range(QuotationStatus.WARRANTY, QuotationStatus.CLOSED); String jsp = "dashboardProject.jsp"; String title = "Les projets clos"; - return quotationFilter(client, query, status, jsp, title, true); + return quotationFilter(client, start, end, query, status, jsp, title, true); } static public class TaskInfo implements Cloneable { @@ -535,11 +555,27 @@ // //////////////////////////////////////////////////////////////////////////// - public Render invoice(ChoremClient client, String query) { + protected Render invoiceFilter(ChoremClient client, String title, + String filter, Date start, Date end, String query) { + if (start == null) { + start = new Date(); + start = DateUtils.setMonths(start, Calendar.JANUARY); + } + + if (end == null) { + end = DateUtils.setMonths(start, Calendar.DECEMBER); + } + // recuperation des factures WikittyQuery invoiceQuery = new WikittyQueryMaker().and() + .parse(filter) .parse(query) .exteq(Invoice.EXT_INVOICE) + .or() + .bw(Invoice.FQ_FIELD_INVOICE_POSTEDDATE, start, end) + .isNull(Invoice.FQ_FIELD_INVOICE_POSTEDDATE) + .bw(Invoice.FQ_FIELD_INVOICE_EXPECTEDDATE, start, end) + .bw(Invoice.FQ_FIELD_INVOICE_PAYMENTDATE, start, end) .end(); WikittyQueryResult<Invoice> invoices = @@ -564,6 +600,7 @@ prepareAttachment(client, invoices.getAll()); return renderView("dashboardInvoice.jsp", + "title", title, "invoices", invoices.getAll(), "amount", amount, "amountPaid", amountPaid, @@ -572,112 +609,33 @@ ); } - 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); + public Render invoiceDebt(ChoremClient client, + Date start, Date end, String query) { + String title = "Factures à payer par la société"; + String companyId = client.getConfiguration().getDefaultCompany(); + String filter = Invoice.FQ_FIELD_INVOICE_CUSTOMER + "={SELECT id WHERE (" + + Employee.FQ_FIELD_EMPLOYEE_COMPANY + "=" + companyId+")}"; + return invoiceFilter(client, title, filter, start, end, query); } - //////////////////////////////////////////////////////////////////////////// - // - // H R - // - //////////////////////////////////////////////////////////////////////////// - - public Render vacationFilter(ChoremClient client, String query, String jspRender, EnumSet<VacationStatus> status) { - // recuperation des vacances en fonction de leur status - 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(), - "days", days - ); - + public Render invoiceIncome(ChoremClient client, + Date start, Date end, String query) { + String title = "Factures émises par la société"; + String companyId = client.getConfiguration().getDefaultCompany(); + String filter = Invoice.FQ_FIELD_INVOICE_SUPPLIER + "={SELECT id WHERE (" + + Employee.FQ_FIELD_EMPLOYEE_COMPANY + "=" + companyId+")}"; + return invoiceFilter(client, title, filter, start, end, query); } - /** - * 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)); + public Render profitability(ChoremClient client, + Date start, Date end, String query) { + EnumSet<QuotationStatus> status = EnumSet.range(QuotationStatus.STARTED, QuotationStatus.CLOSED); + String jsp = "dashboardProfitability.jsp"; + String title = "Profitability"; + return quotationFilter(client, start, end, query, status, jsp, title, true); } /** - * 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 - ); - } - - /** * Prévisionnel entre deux dates en fonction des factures */ public Render budget(ChoremClient client, Date start, Date end, String filter) { @@ -687,8 +645,12 @@ start, end, filter)); } String companyId = client.getConfiguration().getDefaultCompany(); - //TODO ymartel 2012/06/07 : manage when companyId is not defined. + if (StringUtils.isBlank(companyId)) { + getContext().addInfoMessage("message", "Vous devez définir une société par défaut"); + return renderURL("/admin/variables"); + } + if (start == null) { start = new Date(); start = DateUtils.addMonths(start, -1); @@ -698,11 +660,16 @@ end = DateUtils.addMonths(start, 6); } + start = DateUtil.setFirstDayOfMonth(start); + end = DateUtil.setLastDayOfMonth(end); + // La somme des factures que la company doit payer jusqu'a la date demandee WikittyQuery debt = new WikittyQueryMaker() .select(Invoice.FQ_FIELD_INVOICE_AMOUNT, Aggregate.SUM) .and() - .eq(Invoice.FQ_FIELD_INVOICE_CUSTOMER, companyId) + .containsOne(Invoice.FQ_FIELD_INVOICE_CUSTOMER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .close() .lt(Invoice.FQ_FIELD_INVOICE_EXPECTEDDATE, start) .end() .setLimit(WikittyQuery.MAX); @@ -711,21 +678,65 @@ WikittyQuery income = new WikittyQueryMaker() .select(Invoice.FQ_FIELD_INVOICE_AMOUNT, Aggregate.SUM) .and() - .eq(Invoice.FQ_FIELD_INVOICE_SUPPLIER, companyId) + .containsOne(Invoice.FQ_FIELD_INVOICE_SUPPLIER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .close() .lt(Invoice.FQ_FIELD_INVOICE_EXPECTEDDATE, start) .end() .setLimit(WikittyQuery.MAX); - // La liste des factures entre les deux dates - WikittyQuery q = new WikittyQueryMaker().and() + // La liste des factures entre les deux dates que l'on doit payer + WikittyQuery invoiceDebt = new WikittyQueryMaker().and() .parse(filter) + .containsOne(Invoice.FQ_FIELD_INVOICE_CUSTOMER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .close() .bw(Invoice.FQ_FIELD_INVOICE_EXPECTEDDATE, start, end) .end() .setLimit(WikittyQuery.MAX); + // La liste des factures entre les deux dates que l'on doit payer + WikittyQuery invoiceIncome = new WikittyQueryMaker().and() + .parse(filter) + .containsOne(Invoice.FQ_FIELD_INVOICE_SUPPLIER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .close() + .bw(Invoice.FQ_FIELD_INVOICE_EXPECTEDDATE, start, end) + .end() + .setLimit(WikittyQuery.MAX); + Double[] amounts = client.findByQuery(Double.class, debt, income); - WikittyQueryResult<Invoice> invoices = client.findAllByQuery(Invoice.class, q); + if (log.isDebugEnabled()) { + WikittyQuery debugDebt = new WikittyQueryMaker() + .select(Invoice.FQ_FIELD_INVOICE_AMOUNT) + .and() + .containsOne(Invoice.FQ_FIELD_INVOICE_CUSTOMER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .close() + .lt(Invoice.FQ_FIELD_INVOICE_EXPECTEDDATE, start) + .end() + .setLimit(WikittyQuery.MAX); + // La somme des factures que la company doit percevoir jusqu'a la date demandee + WikittyQuery debugIncome = new WikittyQueryMaker() + .select(Invoice.FQ_FIELD_INVOICE_AMOUNT) + .and() + .containsOne(Invoice.FQ_FIELD_INVOICE_SUPPLIER) + .select(Element.ID).eq(Employee.FQ_FIELD_EMPLOYEE_COMPANY, companyId) + .close() + .lt(Invoice.FQ_FIELD_INVOICE_EXPECTEDDATE, start) + .end() + .setLimit(WikittyQuery.MAX); + + WikittyQueryResult[] debugResult = client.findAllByQuery(debugDebt, debugIncome); + log.debug(String.format("\n\tDebt: %s [%s]\n\t\t(%s)\n\tIncome: %s [%s]\n\t\t(%s)", + amounts[0], debugResult[0].getAll(), debugResult[0].getQueryString(), + amounts[1], debugResult[1].getAll(), debugResult[1].getQueryString())); + } + + WikittyQueryResult<Invoice>[] invoices = + client.findAllByQuery(Invoice.class, invoiceDebt, invoiceIncome); + WikittyQuery categoriesQuery = new WikittyQueryMaker() .exteq(Category.EXT_CATEGORY) .end(); @@ -749,29 +760,73 @@ // key: date as MM/yyyy - Map<String, Map<Category, Double>> values = new HashMap<String, Map<Category, Double>>(); + Map<String, Map<Object, Double>> values = new HashMap<String, Map<Object, Double>>(); + String DEBT_KEY = "debt"; // cle pour les depenses sur le mois + String INCOME_KEY = "income"; // cle pour les revenus sur le mois + String TOTAL_KEY = "total"; // cle pour la diffence entre revenus et depenses sur le mois + String FINANCES_KEY = "finances"; // cle pour la tréso disponible + for (String d : dates) { - Map<Category, Double> catMap = new HashMap<Category, Double>(); + Map<Object, Double> catMap = new HashMap<Object, Double>(); values.put(d, catMap); for (Category c: categories[0]) { catMap.put(c, 0.0); } + catMap.put(DEBT_KEY, 0.0); + catMap.put(INCOME_KEY, 0.0); + catMap.put(TOTAL_KEY, 0.0); + catMap.put(FINANCES_KEY, 0.0); } - for (Invoice i : invoices) { + // Debt + for (Invoice i : invoices[0]) { String date = DateFormatUtils.format(i.getExpectedDate(), dateFormat); - Map<Category, Double> catMap = values.get(date); - System.out.println(String.format("*** date '%s' %s map %s", date, dates, values)); + Map<Object, Double> catMap = values.get(date); Category c = i.getCategory(true); - System.out.println("c: " + c + " catMap: " + catMap); if (catMap.containsKey(c)) { double v = catMap.get(c); v += i.getAmount(); catMap.put(c, v); + + v = catMap.get(DEBT_KEY); + v += i.getAmount(); + catMap.put(DEBT_KEY, v); + + v = catMap.get(TOTAL_KEY); + v -= i.getAmount(); + catMap.put(TOTAL_KEY, v); } } + // Income + for (Invoice i : invoices[1]) { + String date = DateFormatUtils.format(i.getExpectedDate(), dateFormat); + Map<Object, Double> catMap = values.get(date); + Category c = i.getCategory(true); + if (catMap.containsKey(c)) { + double v = catMap.get(c); + v += i.getAmount(); + catMap.put(c, v); + + v = catMap.get(INCOME_KEY); + v += i.getAmount(); + catMap.put(INCOME_KEY, v); + + v = catMap.get(TOTAL_KEY); + v += i.getAmount(); + catMap.put(TOTAL_KEY, v); + } + } + + // finances contient l'etat du compte, au depart finances vaut "recette passee" - "depense passee" + double finances = amounts[1] - amounts[0]; + for (String date : dates) { + double v = values.get(date).get(TOTAL_KEY); + finances += v; + values.get(date).put(FINANCES_KEY, finances); + } + List<WikittyQueryResultTreeNode<Category>> categoriesTree = new LinkedList<WikittyQueryResultTreeNode<Category>>(); for (Category c : categories[1]) { @@ -782,11 +837,111 @@ } } - System.out.println("DDDD dates: " + dates + " categoriesTree: " + categoriesTree + " values: " + values); + if (log.isDebugEnabled()) { + log.debug("budget data\n\t dates: " + dates + "\n\t rootTree: " + categories[1] + "\n\t categoriesTree: " + categoriesTree + "\n\t values: " + values); + } return renderView("dashboardBudget.jsp", "dates", dates, "categoriesTree", categoriesTree, "values", values); } + //////////////////////////////////////////////////////////////////////////// + // + // H R + // + //////////////////////////////////////////////////////////////////////////// + + public Render vacationFilter(ChoremClient client, String query, String jspRender, EnumSet<VacationStatus> status) { + // recuperation des vacances en fonction de leur status + 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(), + "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 + ); + } + } Modified: trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/injector/InjectorListener.java =================================================================== --- trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/injector/InjectorListener.java 2012-08-13 10:51:21 UTC (rev 239) +++ trunk/chorem-webmotion/src/main/java/org/chorem/webmotion/injector/InjectorListener.java 2012-08-15 21:37:19 UTC (rev 240) @@ -22,6 +22,7 @@ */ package org.chorem.webmotion.injector; +import java.lang.reflect.Array; import org.chorem.ChoremClient; import org.debux.webmotion.server.WebMotionServerListener; import org.debux.webmotion.server.call.Call; @@ -30,6 +31,12 @@ import org.debux.webmotion.server.mapping.Mapping; import java.lang.reflect.Type; +import java.util.Collection; +import java.util.Date; +import org.apache.commons.beanutils.ConversionException; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.lang3.StringUtils; +import org.nuiton.wikitty.WikittyUtil; /** * @author ymartel <martel@codelutin.com> @@ -38,6 +45,11 @@ @Override public void onStart(ServerContext context) { + + // FIXME poussin 20120815 il y a un probleme avec l'injection du ChoremClient. + // a terme, il doit y avoir un ChoremClient instancier pour chaque requete, + // car chaque requete est faite par un utilisateur different (token different) + // Get Client String token = ""; final ChoremClient client = ChoremClient.getClient(null); @@ -52,6 +64,45 @@ return null; } }); + + + // ajout d'un converter pour support tous les formats de date (comme wikitty) + context.addConverter(new Converter() { + @Override + public Object convert(Class type, Object value) { + if (value.getClass().isArray()) { + if (Array.getLength(value) > 0) { + value = Array.get(value, 0); + } else { + value = null; + } + } + if (value instanceof Collection) { + Collection collection = (Collection)value; + if (collection.size() > 0) { + value = collection.iterator().next(); + } else { + value = null; + } + } + + Object result = null; + if (value != null) { + if (String.class.isAssignableFrom(type)) { + if (StringUtils.isNotBlank((String)value)) { + result = WikittyUtil.toString(value); + } + } else if (Date.class.isAssignableFrom(type)) { + result = WikittyUtil.toDate(value); + } else { + throw new ConversionException(String.format( + "Chorem date converter can't convert '%s' to '%s'", + value, type)); + } + } + return result; + } + }, Date.class); } @Override Modified: trunk/chorem-webmotion/src/main/java/org/wikitty/web/jsptag/WikittyDisplay.java =================================================================== --- trunk/chorem-webmotion/src/main/java/org/wikitty/web/jsptag/WikittyDisplay.java 2012-08-13 10:51:21 UTC (rev 239) +++ trunk/chorem-webmotion/src/main/java/org/wikitty/web/jsptag/WikittyDisplay.java 2012-08-15 21:37:19 UTC (rev 240) @@ -320,17 +320,19 @@ protected void renderWikitty(JspWriter output, String contextPath, String id, Wikitty wikittyValue, String toString) throws JspException, IOException { - String url = contextPath + "/wikitty/view/" + id; - String value = id; // par defaut, si on a pas mieux on met l'id de l'objet + if (StringUtils.isNotBlank(id)) { + String url = contextPath + "/wikitty/view/" + id; + String value = id; // par defaut, si on a pas mieux on met l'id de l'objet - if (wikittyValue != null) { - if (StringUtils.isNotBlank(toString)) { - value = WikittyUtil.format(toString, wikittyValue); - } else { - value = wikittyValue.toString(); + if (wikittyValue != null) { + if (StringUtils.isNotBlank(toString)) { + value = WikittyUtil.format(toString, wikittyValue); + } else { + value = wikittyValue.toString(); + } } + /*{<a href="<%=url%>"><%=value%></a>}*/ } - /*{<a href="<%=url%>"><%=value%></a>}*/ } /** Modified: trunk/chorem-webmotion/src/main/java/org/wikitty/web/jsptag/WikittyInput.java =================================================================== --- trunk/chorem-webmotion/src/main/java/org/wikitty/web/jsptag/WikittyInput.java 2012-08-13 10:51:21 UTC (rev 239) +++ trunk/chorem-webmotion/src/main/java/org/wikitty/web/jsptag/WikittyInput.java 2012-08-15 21:37:19 UTC (rev 240) @@ -185,7 +185,7 @@ if (date != null) { value = DateFormatUtils.format(date, "MM/yyyy"); } - /*{<input class="monthpicker" type="date" name="<%=name%>" value="<%=value%>" <%=getDynamicAttribute()%>/>}*/ + /*{<input class="monthpicker" type="text" name="<%=name%>" value="<%=value%>" <%=getDynamicAttribute()%>/>}*/ } else if ("time".equals(field.getTagValue("subtype"))) { if (date != null) { value = DateFormatUtils.format(date, "HH:mm"); @@ -306,6 +306,8 @@ String url = ""; if (field.hasAllowed()) { url = contextPath + "/wikitty-json/search?extension=" + field.getAllowed(); + } else if (field.hasAllowedQuery()) { + url = contextPath + "/wikitty-json/search?query=" + field.getAllowedQuery(); } else { url = contextPath + "/wikitty-json/search?query="; } @@ -336,7 +338,15 @@ String id = wikitty.getWikittyId() + "-" + extName + "-" + fieldName; List<Wikitty> values = wikitty.getFieldAsWikittyList(extName, fieldName, false); - String url = contextPath + "/wikitty-json/search?extension=" + field.getAllowed(); +// String url = contextPath + "/wikitty-json/search?extension=" + field.getAllowed(); + String url = ""; + if (field.hasAllowed()) { + url = contextPath + "/wikitty-json/search?extension=" + field.getAllowed(); + } else if (field.hasAllowedQuery()) { + url = contextPath + "/wikitty-json/search?query=" + field.getAllowedQuery(); + } else { + url = contextPath + "/wikitty-json/search?query="; + } String sep = ""; String prePopulate = "["; Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardBudget.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardBudget.jsp 2012-08-13 10:51:21 UTC (rev 239) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardBudget.jsp 2012-08-15 21:37:19 UTC (rev 240) @@ -27,12 +27,6 @@ <h1>Budget</h1> -<form> - date start: <input type="date" name="start"/> - end: <input type="date" name="end"/> - <input type="submit"/> -</form> - <table class="table table-striped table-bordered table-condensed"> <thead> <tr> @@ -51,5 +45,29 @@ </c:forEach> </tr> </c:forEach> + <tr> + <th><span>Sorties</span></th> + <c:forEach var="d" items="${dates}"> + <td class="currency"><span><f:formatNumber type="currency" value='${values.get(d).get("debt")}'/></span></td> + </c:forEach> + </tr> + <tr> + <th><span>Entrées</span></th> + <c:forEach var="d" items="${dates}"> + <td class="currency"><span><f:formatNumber type="currency" value='${values.get(d).get("income")}'/></span></td> + </c:forEach> + </tr> + <tr> + <th><span>Total</span></th> + <c:forEach var="d" items="${dates}"> + <td class="currency"><span><f:formatNumber type="currency" value='${values.get(d).get("total")}'/></span></td> + </c:forEach> + </tr> + <tr> + <th><span>Total cumulé</span></th> + <c:forEach var="d" items="${dates}"> + <td class="currency"><span><f:formatNumber type="currency" value='${values.get(d).get("finances")}'/></span></td> + </c:forEach> + </tr> </tbody> </table> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardInvoice.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardInvoice.jsp 2012-08-13 10:51:21 UTC (rev 239) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/dashboardInvoice.jsp 2012-08-15 21:37:19 UTC (rev 240) @@ -25,7 +25,7 @@ <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="f" %> <%@ taglib uri="/WEB-INF/wikitty.tld" prefix="w"%> -<h1>Invoices</h1> +<h1>${title}</h1> <table class="table table-striped table-bordered table-condensed"> <thead> Modified: trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial.jsp =================================================================== --- trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial.jsp 2012-08-13 10:51:21 UTC (rev 239) +++ trunk/chorem-webmotion/src/main/webapp/WEB-INF/jsp/financial.jsp 2012-08-15 21:37:19 UTC (rev 240) @@ -25,10 +25,13 @@ <h1>Financial</h1> <form> - <input type="text" name="query"/> + date start: <input class="datepicker" type="text" name="start" value="${start}"/> + end: <input class="datepicker" type="text" name="end" value="${end}"/> + filtre: <input type="text" name="query"/> <input type="submit"/> </form> -<jsp:include page="/fragment/dashboard/invoice?query=${query}"/> -<jsp:include page="/fragment/dashboard/profitability?query=${query}"/> -<jsp:include page="/fragment/dashboard/budget?query=${query}"/> +<jsp:include page="/fragment/dashboard/invoiceDebt"/> +<jsp:include page="/fragment/dashboard/invoiceIncome"/> +<jsp:include page="/fragment/dashboard/profitability"/> +<jsp:include page="/fragment/dashboard/budget"/> Modified: trunk/chorem-webmotion/src/main/webapp/css/chorem.less =================================================================== --- trunk/chorem-webmotion/src/main/webapp/css/chorem.less 2012-08-13 10:51:21 UTC (rev 239) +++ trunk/chorem-webmotion/src/main/webapp/css/chorem.less 2012-08-15 21:37:19 UTC (rev 240) @@ -28,9 +28,16 @@ font-weight: bolder; } +/* les colonnes de tableau pour certain type ne doivent pas revenir a la ligne*/ td.number, td.currency, td.percent, td.date, td.nowrap { white-space: nowrap; } + +/* les colonnes de tableau pour certain type doivent etre aligne sur le separateur */ +td.number, td.currency, td.percent { + text-align: right; +} + .categorylevel (@level) { margin-left: @level * 10px; }