Package org.projectforge.web.fibu

Source Code of org.projectforge.web.fibu.MonthlyEmployeeReportPage

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition 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 General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.web.fibu;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.SubmitLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.projectforge.common.NumberHelper;
import org.projectforge.core.Configuration;
import org.projectforge.fibu.KostFormatter;
import org.projectforge.fibu.KundeDO;
import org.projectforge.fibu.MonthlyEmployeeReport;
import org.projectforge.fibu.MonthlyEmployeeReport.Kost2Row;
import org.projectforge.fibu.MonthlyEmployeeReportDao;
import org.projectforge.fibu.MonthlyEmployeeReportEntry;
import org.projectforge.fibu.MonthlyEmployeeReportWeek;
import org.projectforge.fibu.ProjektDO;
import org.projectforge.fibu.kost.Kost1DO;
import org.projectforge.fibu.kost.Kost1Dao;
import org.projectforge.fibu.kost.Kost2ArtDO;
import org.projectforge.fibu.kost.Kost2DO;
import org.projectforge.renderer.PdfRenderer;
import org.projectforge.task.TaskDO;
import org.projectforge.user.PFUserDO;
import org.projectforge.user.UserDao;
import org.projectforge.user.UserGroupCache;
import org.projectforge.web.calendar.DateTimeFormatter;
import org.projectforge.web.common.OutputType;
import org.projectforge.web.task.TaskFormatter;
import org.projectforge.web.timesheet.TimesheetListPage;
import org.projectforge.web.wicket.AbstractStandardFormPage;
import org.projectforge.web.wicket.DownloadUtils;
import org.projectforge.web.wicket.WicketUtils;
import org.projectforge.web.wicket.bootstrap.GridBuilder;
import org.projectforge.web.wicket.bootstrap.GridSize;
import org.projectforge.web.wicket.components.ContentMenuEntryPanel;
import org.projectforge.web.wicket.flowlayout.DivTextPanel;
import org.projectforge.web.wicket.flowlayout.FieldsetPanel;
import org.projectforge.web.wicket.flowlayout.TextStyle;

public class MonthlyEmployeeReportPage extends AbstractStandardFormPage implements ISelectCallerPage
{
  private static final long serialVersionUID = -136398850032685654L;

  private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(MonthlyEmployeeReportPage.class);

  private static final String USER_PREF_KEY_FILTER = "monthlyEmployeeReportFilter";

  @SpringBean(name = "userDao")
  private UserDao userDao;

  private final MonthlyEmployeeReportForm form;

  private MonthlyEmployeeReport report;

  private WebMarkupContainer table;

  @SpringBean(name = "monthlyEmployeeReportDao")
  private MonthlyEmployeeReportDao monthlyEmployeeReportDao;

  @SpringBean(name = "pdfRenderer")
  private PdfRenderer pdfRenderer;

  @SpringBean(name = "kost1Dao")
  private Kost1Dao kost1Dao;

  @SpringBean(name = "dateTimeFormatter")
  private DateTimeFormatter dateTimeFormatter;

  @SpringBean(name = "taskFormatter")
  private TaskFormatter taskFormatter;

  @SpringBean(name = "userGroupCache")
  private UserGroupCache userGroupCache;

  private final GridBuilder gridBuilder;

  @SuppressWarnings("serial")
  public MonthlyEmployeeReportPage(final PageParameters parameters)
  {
    super(parameters);
    final boolean costConfigured = Configuration.getInstance().isCostConfigured();
    form = new MonthlyEmployeeReportForm(this);
    if (form.filter == null) {
      form.filter = (MonthlyEmployeeReportFilter) getUserPrefEntry(MonthlyEmployeeReportFilter.class, USER_PREF_KEY_FILTER);
    }
    if (form.filter == null) {
      form.filter = new MonthlyEmployeeReportFilter();
      putUserPrefEntry(USER_PREF_KEY_FILTER, form.filter, true);
    }
    if (form.filter.getUser() == null) {
      form.filter.setUser(getUser());
    }
    body.add(form);
    form.init();
    {
      final ContentMenuEntryPanel exportAsPdf = new ContentMenuEntryPanel(getNewContentMenuChildId(), new SubmitLink("link", form) {
        @Override
        public void onSubmit()
        {
          exportAsPdf();
        };
      }, getString("exportAsPdf"));
      addContentMenuEntry(exportAsPdf);
    }
    gridBuilder = form.newGridBuilder(body, "fields");
    final GridSize gridSize = costConfigured == true ? GridSize.COL33 : GridSize.COL50;
    gridBuilder.newSplitPanel(gridSize);
    {
      final FieldsetPanel fs = gridBuilder.newFieldset(getString("timesheet.user")).suppressLabelForWarning();
      fs.add(new DivTextPanel(fs.newChildId(), new Model<String>() {
        /**
         * @see org.apache.wicket.model.Model#getObject()
         */
        @Override
        public String getObject()
        {
          final PFUserDO user = form.filter.getUser();
          return user != null ? user.getFullname() : "";
        }
      }));
    }
    if (costConfigured == true) {
      gridBuilder.newSplitPanel(gridSize);
      final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.kost1")).suppressLabelForWarning();
      fs.add(new DivTextPanel(fs.newChildId(), new Model<String>() {
        /**
         * @see org.apache.wicket.model.Model#getObject()
         */
        @Override
        public String getObject()
        {
          if (report == null) {
            return "";
          }
          final Kost1DO kost1 = kost1Dao.internalGetById(report.getKost1Id());
          return kost1 != null ? KostFormatter.format(kost1) : "";
        }
      }));
    }
    gridBuilder.newSplitPanel(gridSize);
    {
      final FieldsetPanel fs = gridBuilder.newFieldset(getString("fibu.common.workingDays")).suppressLabelForWarning();
      fs.add(new DivTextPanel(fs.newChildId(), new Model<String>() {
        @Override
        public String getObject()
        {
          return report != null ? String.valueOf(report.getNumberOfWorkingDays()) : "";
        };
      }));
    }
    gridBuilder.newGridPanel();
    {
      final FieldsetPanel fs = new FieldsetPanel(gridBuilder.getPanel(), getString("fibu.common.workingDays"),
          getString("fibu.monthlyEmployeeReport.withoutTimesheets")) {
        /**
         * @see org.apache.wicket.Component#isVisible()
         */
        @Override
        public boolean isVisible()
        {
          return report != null && StringUtils.isNotBlank(report.getFormattedUnbookedDays());
        }
      }.suppressLabelForWarning();
      fs.add(new DivTextPanel(fs.newChildId(), new Model<String>() {
        /**
         * @see org.apache.wicket.model.Model#getObject()
         */
        @Override
        public String getObject()
        {
          return report.getFormattedUnbookedDays();
        }
      }, TextStyle.RED));
    }
  }

  @Override
  public void onBeforeRender()
  {
    if (table != null) {
      body.remove(table);
    }
    body.add(table = new WebMarkupContainer("table"));
    report = monthlyEmployeeReportDao.getReport(form.filter.getYear(), form.filter.getMonth(), form.filter.getUser());
    if (report == null) {
      table.setVisible(false);
    } else {
      addReport();
    }
    super.onBeforeRender();
  }

  private void addReport()
  {
    final RepeatingView headcolRepeater = new RepeatingView("headcolRepeater");
    table.add(headcolRepeater);
    if (MapUtils.isEmpty(report.getKost2Rows()) == false) {
      headcolRepeater.add(new Label(headcolRepeater.newChildId(), getString("fibu.kost2")));
      headcolRepeater.add(new Label(headcolRepeater.newChildId(), getString("fibu.kunde")));
      headcolRepeater.add(new Label(headcolRepeater.newChildId(), getString("fibu.projekt")));
      headcolRepeater.add(new Label(headcolRepeater.newChildId(), getString("fibu.kost2.art")));
    } else {
      // No kost 2 entries, so only task as head is useful.
      headcolRepeater.add(new Label(headcolRepeater.newChildId(), getString("task")).add(AttributeModifier.replace("colspan", "4")));
    }
    final RepeatingView headcolWeekRepeater = new RepeatingView("headcolWeekRepeater");
    table.add(headcolWeekRepeater);
    for (final MonthlyEmployeeReportWeek week : report.getWeeks()) {
      headcolWeekRepeater.add(new Label(headcolWeekRepeater.newChildId(), week.getFormattedFromDayOfMonth()
          + ".-"
          + week.getFormattedToDayOfMonth()
          + "."));
    }
    final RepeatingView rowRepeater = new RepeatingView("rowRepeater");
    table.add(rowRepeater);
    int rowCounter = 0;
    for (final Map.Entry<String, Kost2Row> rowEntry : report.getKost2Rows().entrySet()) {
      final WebMarkupContainer row = new WebMarkupContainer(rowRepeater.newChildId());
      rowRepeater.add(row);
      if (rowCounter++ % 2 == 0) {
        row.add(AttributeModifier.replace("class", "even"));
      } else {
        row.add(AttributeModifier.replace("class", "odd"));
      }
      final Kost2Row kost2Row = rowEntry.getValue();
      final Kost2DO cost2 = kost2Row.getKost2();
      addLabelCols(row, cost2, null, "kost2.nummer:" + cost2.getFormattedNumber(), report.getUser(), report.getFromDate().getTime(), report
          .getToDate().getTime());
      final RepeatingView colWeekRepeater = new RepeatingView("colWeekRepeater");
      row.add(colWeekRepeater);
      for (final MonthlyEmployeeReportWeek week : report.getWeeks()) {
        final MonthlyEmployeeReportEntry entry = week.getKost2Entries().get(kost2Row.getKost2().getId());
        colWeekRepeater.add(new Label(colWeekRepeater.newChildId(), entry != null ? entry.getFormattedDuration() : ""));
      }
      row.add(new Label("sum", report.getKost2Durations().get(cost2.getId()).getFormattedDuration()));
    }

    for (final Map.Entry<String, TaskDO> rowEntry : report.getTaskEntries().entrySet()) {
      final WebMarkupContainer row = new WebMarkupContainer(rowRepeater.newChildId());
      rowRepeater.add(row);
      if (rowCounter++ % 2 == 0) {
        row.add(AttributeModifier.replace("class", "even"));
      } else {
        row.add(AttributeModifier.replace("class", "odd"));
      }
      final TaskDO task = rowEntry.getValue();
      addLabelCols(row, null, task, null, report.getUser(), report.getFromDate().getTime(), report.getToDate().getTime());
      final RepeatingView colWeekRepeater = new RepeatingView("colWeekRepeater");
      row.add(colWeekRepeater);
      for (final MonthlyEmployeeReportWeek week : report.getWeeks()) {
        final MonthlyEmployeeReportEntry entry = week.getTaskEntries().get(task.getId());
        colWeekRepeater.add(new Label(colWeekRepeater.newChildId(), entry != null ? entry.getFormattedDuration() : ""));
      }
      row.add(new Label("sum", report.getTaskDurations().get(task.getId()).getFormattedDuration()));
    }
    {
      // Sum row.
      final WebMarkupContainer row = new WebMarkupContainer(rowRepeater.newChildId());
      rowRepeater.add(row);
      if (rowCounter++ % 2 == 0) {
        row.add(AttributeModifier.replace("class", "even"));
      } else {
        row.add(AttributeModifier.replace("class", "odd"));
      }
      addLabelCols(row, null, null, null, report.getUser(), report.getFromDate().getTime(), report.getToDate().getTime()).add(
          AttributeModifier.replace("style", "text-align: right;"));
      final RepeatingView colWeekRepeater = new RepeatingView("colWeekRepeater");
      row.add(colWeekRepeater);
      for (final MonthlyEmployeeReportWeek week : report.getWeeks()) {
        colWeekRepeater.add(new Label(colWeekRepeater.newChildId(), week.getFormattedTotalDuration()));
      }
      row.add(new Label("sum", report.getFormattedTotalNetDuration()).add(AttributeModifier.replace("style",
          "font-weight: bold; color:red; text-align: right;")));
    }
    if (report.getTotalGrossDuration() != report.getTotalNetDuration()) {
      // Net sum row.
      final WebMarkupContainer row = new WebMarkupContainer(rowRepeater.newChildId());
      rowRepeater.add(row);
      if (rowCounter++ % 2 == 0) {
        row.add(AttributeModifier.replace("class", "even"));
      } else {
        row.add(AttributeModifier.replace("class", "odd"));
      }
      final Component comp = new WebMarkupContainer("cost2").setVisible(false);
      row.add(comp);
      row.add(new Label("customer", "").setVisible(false));
      row.add(new Label("project", "").setVisible(false));
      final Label title = addCostType(row, getString("fibu.monthlyEmployeeReport.totalSum"));
      WicketUtils.addTooltip(title, new ResourceModel("fibu.monthlyEmployeeReport.totalSum.tooltip"));
      final WebMarkupContainer tdContainer = title.findParent(WebMarkupContainer.class);
      tdContainer.add(AttributeModifier.replace("colspan", "4"));
      tdContainer.add(AttributeModifier.replace("style", "font-weight: bold; text-align: right;"));
      final RepeatingView colWeekRepeater = new RepeatingView("colWeekRepeater");
      row.add(colWeekRepeater);
      for (@SuppressWarnings("unused")
      final MonthlyEmployeeReportWeek week : report.getWeeks()) {
        colWeekRepeater.add(new Label(colWeekRepeater.newChildId(), ""));
      }
      row.add(new Label("sum", report.getFormattedTotalGrossDuration()).add(AttributeModifier.replace("style",
          "font-weight: bold; text-align: right;")));
    }
  }

  @SuppressWarnings("serial")
  private WebMarkupContainer addLabelCols(final WebMarkupContainer row, final Kost2DO cost2, final TaskDO task, final String searchString,
      final PFUserDO user, final long startTime, final long stopTime)
  {
    final WebMarkupContainer result = new WebMarkupContainer("cost2");
    row.add(result);
    final Link<String> link = new Link<String>("link") {
      @Override
      public void onClick()
      {
        final PageParameters params = new PageParameters();
        params.add("userId", user.getId());
        if (task != null) {
          params.add("taskId", task.getId());
        }
        params.add("startTime", startTime);
        params.add("stopTime", stopTime);
        params.add("storeFilter", false);
        if (searchString != null) {
          params.add("searchString", searchString);
        }
        setResponsePage(new TimesheetListPage(params));
      }
    };
    result.add(link);
    WicketUtils.addRowClick(row);
    if (cost2 != null) {
      final ProjektDO project = cost2.getProjekt();
      final KundeDO customer = project != null ? project.getKunde() : null;
      final Kost2ArtDO costType = cost2.getKost2Art();
      link.add(new Label("label", KostFormatter.format(cost2)));
      if (project != null) {
        row.add(new Label("customer", customer != null ? customer.getName() : ""));
        row.add(new Label("project", project.getName()));
      } else {
        row.add(new Label("customer", cost2.getDescription()).add(AttributeModifier.replace("colspan", "2")));
        row.add(new Label("project", "").setVisible(false));
      }
      addCostType(row, costType.getName());
    } else {
      if (task != null) {
        // Entries for one task (not cost2).
        link.add(new Label("label", taskFormatter.getTaskPath(task.getId(), true, OutputType.PLAIN)));
      } else {
        link.add(new Label("label", getString("sum")));
      }
      result.add(AttributeModifier.replace("colspan", "4"));
      row.add(new Label("customer", "").setVisible(false));
      row.add(new Label("project", "").setVisible(false));
      addCostType(row, null);
    }
    return result;
  }

  private Label addCostType(final WebMarkupContainer row, final String content)
  {
    final WebMarkupContainer costTypeContainer = new WebMarkupContainer("costType");
    row.add(costTypeContainer);
    if (content == null) {
      costTypeContainer.setVisible(false);
      return null;
    } else {
      final Label label = new Label("content", content);
      costTypeContainer.add(label);
      return label;
    }
  }

  protected void exportAsPdf()
  {
    log.info("Monthly employee report for " + form.filter.getUser().getFullname() + ": " + form.filter.getFormattedMonth());
    final StringBuffer buf = new StringBuffer();
    buf.append(getString("menu.monthlyEmployeeReport.fileprefix")).append("_");
    final PFUserDO employee = userDao.getById(form.filter.getUserId());
    buf.append(employee.getLastname()).append("_").append(form.filter.getYear()).append("-").append(form.filter.getFormattedMonth())
    .append(".pdf");
    final String filename = buf.toString();

    // get the sheets of the given format
    final String styleSheet = "fo-styles/monthlyEmployeeReport-template-fo.xsl";
    final String xmlData = "fo-styles/monthlyEmployeeReport2pdf.xml";

    report = monthlyEmployeeReportDao.getReport(form.filter.getYear(), form.filter.getMonth(), employee);
    final Map<String, Object> data = new HashMap<String, Object>();
    data.put("systemDate", dateTimeFormatter.getFormattedDateTime(new Date()));
    data.put("title", getString("menu.monthlyEmployeeReport"));
    data.put("employeeLabel", getString("timesheet.user"));
    data.put("employee", employee.getFullname());
    data.put("monthLabel", getString("calendar.month"));
    data.put("year", form.filter.getYear());
    data.put("month", form.filter.getFormattedMonth());
    data.put("workingDaysLabel", getString("fibu.common.workingDays"));
    data.put("workingDays", report.getNumberOfWorkingDays());
    data.put("kost1Label", getString("fibu.kost1"));
    final Kost1DO kost1 = kost1Dao.internalGetById(report.getKost1Id());
    data.put("kost1", kost1 != null ? kost1.getFormattedNumber() : "--");
    data.put("kost2Label", getString("fibu.kost2"));
    data.put("kundeLabel", getString("fibu.kunde"));
    data.put("projektLabel", getString("fibu.projekt"));
    data.put("kost2ArtLabel", getString("fibu.kost2.art"));
    data.put("sumLabel", getString("sum"));
    data.put("netSumLabel", getString("sum"));
    data.put("totalSumLabel", getString("fibu.monthlyEmployeeReport.totalSum"));
    data.put("report", report);
    data.put("signatureEmployeeLabel", getString("timesheet.signatureEmployee") + ": " + employee.getFullname());
    data.put("signatureProjectLeaderLabel", getString("timesheet.signatureProjectLeader"));
    data.put("unbookedWorkingDaysLabel", getString("fibu.monthlyEmployeeReport.withoutTimesheets"));
    // render the PDF with fop
    final byte[] ba = pdfRenderer.render(styleSheet, xmlData, data);
    DownloadUtils.setDownloadTarget(ba, filename);
  }

  @Override
  protected String getTitle()
  {
    return getString("menu.monthlyEmployeeReport");
  }

  @Override
  public void cancelSelection(final String property)
  {
    log.error("cancelSelection not supported. Property was '" + property + "'.");
  }

  @Override
  public void select(final String property, final Object selectedValue)
  {
    if ("user".equals(property) == true) {
      final Integer id;
      if (selectedValue instanceof String) {
        id = NumberHelper.parseInteger((String) selectedValue);
      } else {
        id = (Integer) selectedValue;
      }
      form.filter.setUser(userGroupCache.getUser(id));
    } else if ("quickSelect".equals(property) == true) {
      final Date date = (Date) selectedValue;
      form.setDate(date);
    } else {
      log.error("Property '" + property + "' not supported for selection.");
    }
  }

  @Override
  public void unselect(final String property)
  {
    log.error("unselect not supported. Property was '" + property + "'.");
  }
}
TOP

Related Classes of org.projectforge.web.fibu.MonthlyEmployeeReportPage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.