org.pau.assetmanager.viewmodel.MonthlyReportViewModel.java Source code

Java tutorial

Introduction

Here is the source code for org.pau.assetmanager.viewmodel.MonthlyReportViewModel.java

Source

/**
 * This file is part of Pau's Asset Manager Project.
 *
 * Pau's Asset Manager Project 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, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Pau's Asset Manager Project 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 Pau's Asset Manager Project.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.pau.assetmanager.viewmodel;

import java.awt.Color;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.PieDataset;
import org.pau.assetmanager.business.AnnotationsBusiness;
import org.pau.assetmanager.business.BooksBusiness;
import org.pau.assetmanager.entities.Annotation;
import org.pau.assetmanager.entities.Annotation.AnnotationType;
import org.pau.assetmanager.entities.Book;
import org.pau.assetmanager.entities.Client;
import org.pau.assetmanager.entities.GeneralBook;
import org.pau.assetmanager.entities.PropertyBook;
import org.pau.assetmanager.entities.StockExpensesAnnotation;
import org.pau.assetmanager.entities.StockIncomeAnnotation;
import org.pau.assetmanager.entities.StocksBook;
import org.pau.assetmanager.viewmodel.chart.ChartDataModel;
import org.pau.assetmanager.viewmodel.chart.PrepareChart;
import org.pau.assetmanager.viewmodel.chart.ResourceImageGenerator;
import org.pau.assetmanager.viewmodel.comparator.AnnotationDateMontlyComparator;
import org.pau.assetmanager.viewmodel.grouping.AnnotationDateMonthlyGroupingModel;
import org.pau.assetmanager.viewmodel.stocks.StockConceptPerformance;
import org.pau.assetmanager.viewmodel.stocks.StocksUtils;
import org.pau.assetmanager.viewmodel.type.BookSelectionType;
import org.pau.assetmanager.viewmodel.type.ClientDomainType;
import org.pau.assetmanager.viewmodel.utils.AnnotationsFilter;
import org.pau.assetmanager.viewmodel.utils.BookSelection;
import org.pau.assetmanager.viewmodel.utils.NumberFomatter;
import org.pau.assetmanager.viewmodel.utils.SortingCriteria;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.DependsOn;
import org.zkoss.bind.annotation.GlobalCommand;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.event.CheckEvent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Checkbox;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;

/**
 * This class is the ViewModel of the report that displays the performance
 * information given a book selection and a year in a *monthly basis*.
 * 
 * The ZUL related to this ViewModel is 'grouping_model_view_month.zul'
 * 
 * @author Pau Carr Cardona
 * 
 */

public class MonthlyReportViewModel {

    // book selection
    private BookSelection bookSelection = null;
    // year selected
    private Integer monthlyReportYear;
    // client domain type: the client of the book selection or all the clients
    private ClientDomainType clientType;

    @Init
    public void init() {
        Calendar calendar = GregorianCalendar.getInstance();
        calendar.setTime(new Date());
        monthlyReportYear = calendar.get(Calendar.YEAR);
        clientType = ClientDomainType.CURRENT_CLIENT;
    }

    public Collection<ClientDomainType> getClientDomainTypes() {
        return Arrays.asList(ClientDomainType.values());
    }

    @DependsOn("bookSelection")
    public Boolean getIsAllBooks() {
        return bookSelection.getBookSelectionType().equals(BookSelectionType.ALL_BOOKS);
    }

    public ClientDomainType getClientType() {
        return clientType;
    }

    public void setClientType(ClientDomainType clientType) {
        this.clientType = clientType;
    }

    public BookSelectionType getBookSelectionType() {
        return bookSelection.getBookSelectionType();
    }

    public Client getSelectedClient() {
        return bookSelection.getSelectedClient();
    }

    /**
     * @param annotations
     * @return the multimap 'Year of Annotaion' --> 'Annotations Involved'
     */
    private static Multimap<Integer, Annotation> getYearToAnnotationMultimapFromAnnotations(
            Collection<Annotation> annotations) {
        ImmutableMap<Annotation, Integer> annotationToYear = Maps.toMap(annotations,
                new Function<Annotation, Integer>() {
                    @Override
                    public Integer apply(Annotation input) {
                        Calendar calendar = GregorianCalendar.getInstance();
                        calendar.setTime(input.getDate());
                        return calendar.get(Calendar.YEAR);
                    }
                });
        ListMultimap<Integer, Annotation> yearToAnnotationMultimap = Multimaps
                .invertFrom(Multimaps.forMap(annotationToYear), ArrayListMultimap.<Integer, Annotation>create());
        return yearToAnnotationMultimap;
    }

    /**
     * This method generates an image of a chart of the evolution of the total
     * amount of money a book selection for a year in a monthly bases
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getBalanceChartURL() {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }
        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.<Integer>absent());
        Multimap<Integer, Annotation> yearToAnnotationMultimap = getYearToAnnotationMultimapFromAnnotations(
                anotations);
        CategoryDataset categoryModel = ChartDataModel.getBalance(monthlyReportYear, yearToAnnotationMultimap,
                bookSelection, true, Optional.<String>absent());
        JFreeChart jfchart = ChartFactory.createLineChart("Saldo Total", "Fecha", "Euros", categoryModel,
                PlotOrientation.VERTICAL, true, true, false);
        PrepareChart.prepareBalanceChart(jfchart);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getBalanceChartURLForStock(final String stockLabel) {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }
        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.<Integer>absent());
        List<Annotation> anotationsForStockLabel = Lists
                .newLinkedList(Collections2.filter(anotations, new Predicate<Annotation>() {
                    @Override
                    public boolean apply(Annotation annotation) {
                        if (annotation instanceof StockIncomeAnnotation
                                || annotation instanceof StockExpensesAnnotation) {
                            return annotation.getConcept().equals(stockLabel);
                        } else {
                            return false;
                        }
                    }
                }));
        Multimap<Integer, Annotation> yearToAnnotationMultimap = getYearToAnnotationMultimapFromAnnotations(
                anotationsForStockLabel);
        CategoryDataset categoryModel = ChartDataModel.getBalance(monthlyReportYear, yearToAnnotationMultimap,
                bookSelection, true, Optional.<String>of(stockLabel));
        JFreeChart jfchart = ChartFactory.createLineChart("Saldo Total para el valor " + stockLabel, "Fecha",
                "Euros", categoryModel, PlotOrientation.VERTICAL, true, true, false);
        PrepareChart.prepareBalanceChart(jfchart);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public List<String> getStocks() {
        List<Annotation> allStocksAnnotationsFromDatabase = AnnotationsBusiness.getAllStocksAnnotationsFromDatabase(
                bookSelection, Optional.<Integer>absent(), clientType, SortingCriteria.DESCENDING);
        Set<String> allStocksConcepts = Sets.newHashSet(
                Collections2.transform(allStocksAnnotationsFromDatabase, new Function<Annotation, String>() {
                    @Override
                    public String apply(Annotation input) {
                        return input.getConcept();
                    }
                }));
        List<String> allStocksConceptsList = Lists.newLinkedList(allStocksConcepts);
        Collections.sort(allStocksConceptsList);
        return allStocksConceptsList;
    }

    /**
     * This method generates an image of a chart of the evolution of the total
     * amount of money a properties book selection for a year in a monthly bases
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getBalancePropertiesChartURL() {
        if (bookSelection.getSelectedBook() == null || !getIsAllBooks()) {
            return "";
        }
        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.<Integer>absent());
        Collection<Annotation> annotationsFromPropertiesBooks = Collections2.filter(anotations,
                new Predicate<Annotation>() {
                    @Override
                    public boolean apply(Annotation annotation) {
                        return annotation.getBook() instanceof PropertyBook;
                    }
                });
        Multimap<Integer, Annotation> yearToBookAnnotationsMultimap = getYearToAnnotationMultimapFromAnnotations(
                annotationsFromPropertiesBooks);
        CategoryDataset categoryModel = ChartDataModel.getBalance(monthlyReportYear, yearToBookAnnotationsMultimap,
                bookSelection, false, Optional.<String>absent());
        JFreeChart jfchart = ChartFactory.createLineChart("Saldo de propiedades (viviendas y locales)", "Fecha",
                "Euros", categoryModel, PlotOrientation.VERTICAL, true, true, false);
        PrepareChart.prepareBalanceChart(jfchart);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    /**
     * This method generates an image of a chart of the evolution of the total
     * amount of money for the stocks book selection for a year in a monthly basis
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getBalanceStocksChartURL() {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }
        if (!getIsAllBooks()) {
            return "";
        }
        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.<Integer>absent());
        Collection<Annotation> annotationsFromStocksBooks = Collections2.filter(anotations,
                new Predicate<Annotation>() {
                    @Override
                    public boolean apply(Annotation annotation) {
                        return annotation.getBook() instanceof StocksBook;
                    }
                });
        Multimap<Integer, Annotation> yearToStocksBooksMultimap = getYearToAnnotationMultimapFromAnnotations(
                annotationsFromStocksBooks);
        CategoryDataset categoryModel = ChartDataModel.getBalance(monthlyReportYear, yearToStocksBooksMultimap,
                bookSelection, false, Optional.<String>absent());
        JFreeChart jfchart = ChartFactory.createLineChart("Saldo de inversin en bolsa", "Fecha", "Euros",
                categoryModel, PlotOrientation.VERTICAL, true, true, false);
        PrepareChart.prepareBalanceChart(jfchart);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    /**
     * This method generates an image of a chart of the evolution of the total
     * amount of money a general book selection for a year in a monthly bases
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getBalanceOwnChartURL() {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }
        if (!getIsAllBooks()) {
            return "";
        }
        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.<Integer>absent());
        Collection<Annotation> annotationsFromGeneralBooks = Collections2.filter(anotations,
                new Predicate<Annotation>() {
                    @Override
                    public boolean apply(Annotation annotation) {
                        return annotation.getBook() instanceof GeneralBook;
                    }
                });
        Multimap<Integer, Annotation> yearToGeneralBooksMultimap = getYearToAnnotationMultimapFromAnnotations(
                annotationsFromGeneralBooks);

        CategoryDataset categoryModel = ChartDataModel.getBalance(monthlyReportYear, yearToGeneralBooksMultimap,
                bookSelection, false, Optional.<String>absent());
        JFreeChart jfchart = ChartFactory.createLineChart("Saldo de gastos e ingresos generales", "Fecha", "Euros",
                categoryModel, PlotOrientation.VERTICAL, true, true, false);
        PrepareChart.prepareBalanceChart(jfchart);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    /**
     * Generates the image of a pie chart that displays the percentage of
     * expenses of the different books which for a given year are loosing money
     * (not profitable)
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getDeficitPieChartURL() {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }
        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.of(monthlyReportYear));
        PieDataset categoryModel = ChartDataModel.deficitsPieChartDataset(anotations);
        JFreeChart jfchart = ChartFactory.createPieChart(
                "Dficit ( ingresos menos gastos, siendo los gastos mayores a los ingresos )", categoryModel, true,
                true, false);
        PiePlot piePlot = ((PiePlot) jfchart.getPlot());
        piePlot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0} (-{1} , {2} )",
                NumberFomatter.PERCENTAGE_FORMATTER, NumberFormat.getPercentInstance()));
        piePlot.setBackgroundPaint(Color.white);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    /**
     * Generates the image of a pie chart that displays the percentage of income
     * of the different books which for a given year are profitable
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getIncomePieChartURL() {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }
        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.of(monthlyReportYear));
        PieDataset categoryModel = ChartDataModel.incomesPieChartDataset(anotations);
        JFreeChart jfchart = ChartFactory.createPieChart(
                "Beneficios ( ingresos menos gastos, siendo los ingresos mayores a los gastos )", categoryModel,
                true, true, false);
        PiePlot piePlot = ((PiePlot) jfchart.getPlot());
        piePlot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0} ({1} , {2} )",
                NumberFomatter.PERCENTAGE_FORMATTER, NumberFormat.getPercentInstance()));
        piePlot.setBackgroundPaint(Color.white);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    /**
     * Generates the image of a pie chart that displays the percentage of
     * expenses of the different concept which for a given year are loosing
     * money (not profitable)
     * 
     * NOTE: usually, a given concept is only related to either income or
     * expenses but this *not* always the case (for example, in stocks the
     * concept is the company involved and there can be incomes and expenses)
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getExpensesPieChartURL() {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }

        Map<String, Double> expensesDataForBook = AnnotationsBusiness.getExpensesDataForBook(bookSelection,
                monthlyReportYear, clientType);
        PieDataset categoryModel = ChartDataModel.expensesPieChartDataset(expensesDataForBook);
        JFreeChart jfchart = ChartFactory.createPieChart("Gastos (nicamente gastos)", categoryModel, true, true,
                false);
        PiePlot piePlot = ((PiePlot) jfchart.getPlot());
        piePlot.setLabelGenerator(new StandardPieSectionLabelGenerator("{0} ({1} , {2} )",
                NumberFomatter.PERCENTAGE_FORMATTER, NumberFormat.getPercentInstance()));

        piePlot.setBackgroundPaint(Color.white);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    /**
     * Generates the image of a time series in which there are four series --
     * Income: the sum of amount of income annotations for a given month in a
     * year -- Expenses: the sum of amount of expenses annotations for a given
     * month in a year -- Monthly Total: the *difference* between Income and
     * Expenses (Monthly Total := Income - Expenses) -- Cumulative: the
     * cumulative sum over time of 'Monthly Total'
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getMonthlyReportSimpleChartURL() {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }
        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.of(monthlyReportYear));
        CategoryDataset categoryModel = ChartDataModel.getIncomeExpensesSimpleOverTime(anotations,
                monthlyReportYear, bookSelection.getSelectedBook());
        JFreeChart jfchart = ChartFactory.createLineChart("Ingresos vs. Gastos", "Fecha", "Euros", categoryModel,
                PlotOrientation.VERTICAL, true, true, false);
        PrepareChart.prepareSimpleJFreeChart(jfchart);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    /**
     * Generates the image of a bar chart with the performance of the sold
     * stocks. It computes the amount of money earned or lost given the price
     * per stock of the sold stocks.
     * 
     * Note: The chart has into account that the stocks could have been bought
     * at different points in time and that the sold stocks can span different
     * different 'stock purchases' with different price per stock
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getStocksPerformanceURL() {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }
        List<Annotation> annotations = AnnotationsBusiness.getAllStocksAnnotationsFromDatabase(bookSelection,
                Optional.<Integer>of(monthlyReportYear), clientType, SortingCriteria.ASCENDING);
        Map<String, StockConceptPerformance> stocksConceptToProfitLimitedToNumberOfSoldSlocks = StocksUtils
                .getStocksConceptToProfitLimitedToNumberOfSoldSlocks(annotations);
        CategoryDataset categoryModel = ChartDataModel
                .getStockConceptsPerformance(stocksConceptToProfitLimitedToNumberOfSoldSlocks);
        JFreeChart jfchart = ChartFactory.createBarChart(
                "Rendimiento de valores vendidos en Bolsa (slo valores vendidos)", "Valor", "Euros",
                categoryModel, PlotOrientation.VERTICAL, true, true, false);
        PrepareChart.prepareJFreeBarChartForStocks(jfchart, categoryModel);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    /**
     * Generates the image of a grouping bar for each month along a year. Each
     * monthly group contains two bars (Income and Expenses) for each of the
     * three types of books type (General, Stocks and Properties)
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getPropertiesVsOwnAllPropertiesURL() {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }
        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.of(monthlyReportYear));
        CategoryDataset categoryModel = ChartDataModel.getIncomeExpensesOverTime(anotations, monthlyReportYear,
                bookSelection.getSelectedBook(), bookSelection.getBookSelectionType());
        JFreeChart jfchart = ChartFactory.createBarChart("Propiedades vs. Generales vs. Bolsa", "Fecha", "Euros",
                categoryModel, PlotOrientation.VERTICAL, true, true, false);
        PrepareChart.preparePropertiesVsOwnAllPropertiesJFreeChart(jfchart, categoryModel);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    /**
     * Generates the image of a grouping bar for each month along a year. Each
     * monthly group contains a bar that represent the totals for each of the
     * selected properties (Incomes - Expenses) The selected property will be
     * the one from the properties book or all the properties for a client in
     * case the selection is for all the books
     * 
     * @return the relative random URL generated
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public String getMonthlyReportPerBookChartURL() {
        if (bookSelection.getSelectedBook() == null) {
            return "";
        }

        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.of(monthlyReportYear));
        List<PropertyBook> listOfPropertties = getPropertyBooksFromClient();
        CategoryDataset categoryModel = ChartDataModel.getTotalsOverTimePerBook(anotations, monthlyReportYear,
                bookSelection.getSelectedBook(), listOfPropertties);
        JFreeChart jfchart = ChartFactory.createBarChart("Propiedades", "Fecha", "Euros", categoryModel,
                PlotOrientation.VERTICAL, true, true, false);
        PrepareChart.prepareJFreeBarChart(jfchart, listOfPropertties, categoryModel);
        return ResourceImageGenerator.getFunction().apply(jfchart);
    }

    /**
     * The method generated a grouping model to be displayed in a grid which
     * contains the all the annotations involved in the selected book for a
     * given year and a grouping for each month
     * 
     * @return The grouping model for the monthly report
     */
    @DependsOn({ "selectedBook", "clientType", "monthlyReportYear" })
    public AnnotationDateMonthlyGroupingModel getAnnotationsDateMonthlyGroupingModel() {
        List<Annotation> anotations = getAnnotationsInAscendingDateOrder(Optional.of(monthlyReportYear));
        return new AnnotationDateMonthlyGroupingModel(anotations, new AnnotationDateMontlyComparator(), true);
    }

    private List<PropertyBook> getPropertyBooksFromClient() {
        return BooksBusiness.getPropertyBooksFromClient(bookSelection.getSelectedBook().getClient());
    }

    public Book getSelectedBook() {
        return bookSelection.getSelectedBook();
    }

    @DependsOn({ "selectedBook" })
    public Boolean getSelectedBookIsStocksOrAllProperties() {
        return bookSelection.getSelectedBook() != null
                && (getIsAllBooks() || bookSelection.getSelectedBook() instanceof StocksBook);
    }

    @NotifyChange({ "selectedBook", "bookSelectionType", "selectedClient", "clientType" })
    @GlobalCommand
    public void updateBookSelection(@BindingParam("bookSelection") BookSelection bookSelection) {
        this.bookSelection = bookSelection;
        if (bookSelection.getBookSelectionType().equals(BookSelectionType.SINGLE_BOOK)) {
            clientType = ClientDomainType.CURRENT_CLIENT;
        }
    }

    @NotifyChange({ "selectedBook" })
    @GlobalCommand
    public void updateReportAnnotations() {

    }

    public Integer getMonthlyReportYear() {
        return monthlyReportYear;
    }

    public void setMonthlyReportYear(Integer monthlyReportYear) {
        this.monthlyReportYear = monthlyReportYear;
    }

    @Command
    @NotifyChange({ "monthlyReportYear" })
    public void refreshMonthlyReportYear(@ContextParam(ContextType.TRIGGER_EVENT) Event event) {

        String value = (String) event.getData();
        this.monthlyReportYear = new Integer(value);
    }

    @Command
    @NotifyChange({ "clientType" })
    public void refreshMonthlyReportClientType(@ContextParam(ContextType.TRIGGER_EVENT) Event event) {
        CheckEvent checkEvent = (CheckEvent) event.getData();
        Checkbox checkbox = (Checkbox) checkEvent.getTarget();
        clientType = checkbox.getValue();
        Clients.clearBusy();
    }

    private List<Annotation> getAnnotationsInAscendingDateOrder(Optional<Integer> optionalYear) {
        List<Annotation> listOfAnnotations = AnnotationsBusiness.getAnnotationsWithFilter(
                Optional.<AnnotationType>absent(), bookSelection, optionalYear, clientType,
                SortingCriteria.ASCENDING, AnnotationsFilter.emptyAnnotationsFilter());
        return listOfAnnotations;
    }

}