Package org.pau.assetmanager.viewmodel

Source Code of org.pau.assetmanager.viewmodel.AnnotationViewModel

/**
* 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.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang.time.DateUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.pau.assetmanager.business.AnnotationsBusiness;
import org.pau.assetmanager.business.ConceptsBusiness;
import org.pau.assetmanager.business.DaoFunction;
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.ExpensesAnnotation;
import org.pau.assetmanager.entities.GeneralExpensesAnnotation;
import org.pau.assetmanager.entities.GeneralIncomeAnnotation;
import org.pau.assetmanager.entities.IncomeAnnotation;
import org.pau.assetmanager.entities.MovementExpensesAnnotation;
import org.pau.assetmanager.entities.PropertyExpensesAnnotation;
import org.pau.assetmanager.entities.PropertyIncomeAnnotation;
import org.pau.assetmanager.entities.StockExpensesAnnotation;
import org.pau.assetmanager.entities.StockIncomeAnnotation;
import org.pau.assetmanager.viewmodel.stocks.ConceptValidation;
import org.pau.assetmanager.viewmodel.stocks.HistoricalStocksValuesDownloader;
import org.pau.assetmanager.viewmodel.stocks.StocksHistory;
import org.pau.assetmanager.viewmodel.stocks.StocksIncomeError;
import org.pau.assetmanager.viewmodel.stocks.StocksUtils;
import org.pau.assetmanager.viewmodel.type.BookSelectionType;
import org.pau.assetmanager.viewmodel.utils.AnnotationsFilter;
import org.pau.assetmanager.viewmodel.utils.BookSelection;
import org.pau.assetmanager.viewmodel.utils.SortingCriteria;
import org.zkoss.bind.BindUtils;
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.Event;
import org.zkoss.zk.ui.event.InputEvent;
import org.zkoss.zk.ui.util.Clients;

import com.google.common.base.Optional;

/**
* This class is the ViewModel class that deals with all the UI interactions
* related to the editable grid of annotations. This grid has sorting and
* filtering enabled for all the fields and also controls the enabling and the
* visibility of the editable cells depending on its applicability.
*
* The UI ZUL files involved directly or indirectly (using subclasses of the
* this class) are the following: - general_expenses_annotations.zul -
* general_income_annotations.zul - movement_annotations.zul -
* property_expenses_annotations.zul - property_income_annotations.zul -
* stocks_expenses_annotations.zul - stocks_income_annotations.zul
*
*
* @author Pau Carré Cardona
*
*/

public class AnnotationViewModel {

  // book selection in the main view
  protected BookSelection bookSelection = null;
  // current year selected
  protected Integer currentYear = null;
  // filtering applied
  protected AnnotationsFilter annotationsFilter = new AnnotationsFilter();
  // reference to the annotation that is just created
  protected Annotation justCreatedAnnotation = null;
  // reference to the last created annotation
  // TODO: this is not clear at all and makes confusion with the field
  // 'justCreatedAnnotation' --> refactor!!
  protected Annotation lastestCreatedAnnotation = null;
  // the type of annotation selected (income or expenses)
  protected AnnotationType annotationType;

  protected static Logger logger = LogManager
      .getLogger(MonthlyReportViewModel.class);

  @Init
  public void init(@BindingParam("annotationType") String annotationType) {
    Calendar calendar = GregorianCalendar.getInstance();
    calendar.setTime(new Date());
    this.currentYear = calendar.get(Calendar.YEAR);
    this.annotationType = AnnotationType.valueOf(annotationType);
  }

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

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

  public Integer getCurrentYear() {
    return currentYear;
  }

  // Annotations are notified by updateCurrentYear
  public void setCurrentYear(Integer currentYear) {
    this.currentYear = currentYear;
  }

  @Command
  @NotifyChange({ "annotations", "currentYear" })
  public void updateCurrentYear(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    String value = (String) event.getData();
    Integer newValue = new Integer(value);
    if (!newValue.equals(currentYear)) {
      this.currentYear = newValue;
    }
  }

  @Command
  public void saveAnnotation(@BindingParam("annotation") Annotation annotation) {
    if (annotation.getId() != null) { 
      if(annotation instanceof MovementExpensesAnnotation){
        MovementExpensesAnnotation movementExpensesAnnotation = (MovementExpensesAnnotation) annotation;
        DaoFunction.mergeFunction().apply(movementExpensesAnnotation.getMovementIncomeAnnotation());
      }
      DaoFunction.mergeFunction().apply(annotation);
      HistoricalStocksValuesDownloader.updateStocksHistoricalValuesAsync();
      BindUtils.postGlobalCommand(null, null, "updateReportAnnotations",
          null);
    }
  }

  @NotifyChange({ "annotations", "getConceptsForFiltering", "getConcepts" })
  @Command
  public void saveAnnotationWithConcept(
      @BindingParam("annotation") Annotation annotation,
      @ContextParam(ContextType.TRIGGER_EVENT) InputEvent event) {
    if (annotation.getId() != null) {
      String concept = event.getValue();
      annotation.setConcept(concept);
      if(annotation instanceof MovementExpensesAnnotation){
        MovementExpensesAnnotation movementExpensesAnnotation = (MovementExpensesAnnotation) annotation;
        DaoFunction.mergeFunction().apply(movementExpensesAnnotation.getMovementIncomeAnnotation());
      }
      DaoFunction.mergeFunction().apply(annotation);
      HistoricalStocksValuesDownloader.updateStocksHistoricalValuesAsync();
      BindUtils.postGlobalCommand(null, null, "updateReportAnnotations",
          null);
    }
  }

  @DependsOn({ "selectedBook", "bookSelectionType", "selectedClient",
      "currentYear", "annotationsFilter" })
  public List<Annotation> getAnnotations() {
    List<Annotation> annotations = new LinkedList<Annotation>();
    if (bookSelection.getSelectedBook() != null
        && bookSelection.getBookSelectionType().equals(
            BookSelectionType.SINGLE_BOOK)) {
      annotations = AnnotationsBusiness.getNonMovementAnnotations(
          Optional.<AnnotationType> of(annotationType),
          bookSelection, Optional.<Integer> of(currentYear),
          SortingCriteria.DESCENDING, annotationsFilter);
      if (justCreatedAnnotation != null
          && annotations.contains(justCreatedAnnotation)) {
        annotations.remove(justCreatedAnnotation);
        annotations.add(0, justCreatedAnnotation);
        justCreatedAnnotation = null;
      }
    }
    Clients.clearBusy();
    return annotations;
  }

  @NotifyChange({ "selectedBook", "bookSelectionType", "selectedClient" })
  @GlobalCommand
  public void updateBookSelection(
      @BindingParam("bookSelection") BookSelection bookSelection) {
    this.bookSelection = bookSelection;
  }

  @NotifyChange({ "annotations" })
  @Command
  public void addPropertyAnnotation() {
    Annotation annotation = null;
    if (annotationType.equals(AnnotationType.INCOME)) {
      PropertyIncomeAnnotation incomeAnnotation = new PropertyIncomeAnnotation();
      incomeAnnotation.setUpDefaults();
      annotation = incomeAnnotation;
      addDefaultValuesToAnnotation(annotation,
          bookSelection.getSelectedBook(), currentYear,
          annotationsFilter);
    } else {
      PropertyExpensesAnnotation expensesAnnotation = new PropertyExpensesAnnotation();
      expensesAnnotation.setUpDefaults();
      annotation = expensesAnnotation;
      addDefaultValuesToAnnotation(annotation,
          bookSelection.getSelectedBook(), currentYear,
          annotationsFilter);
    }
    addAnnotation(annotation);
    Clients.clearBusy();
  }

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

  public Annotation getJustCreatedAnnotation() {
    return justCreatedAnnotation;
  }

  public AnnotationsFilter getAnnotationsFilter() {
    return annotationsFilter;
  }

  public void setAnnotationsFilter(AnnotationsFilter annotationsFilter) {
    this.annotationsFilter = annotationsFilter;
  }

  public Annotation getLastestCreatedAnnotation() {
    return lastestCreatedAnnotation;
  }

  // TODO: check it!!
  public List<String> getConceptsForFiltering(
      @BindingParam("type") String type) {
    List<String> conceptsForFiltering = new LinkedList<String>();
    conceptsForFiltering.addAll(getConcepts(type));
    // sort concept in a case-unsensitive way
    Collections.sort(conceptsForFiltering, new Comparator<String>() {
      @Override
      public int compare(String stringA, String stringB) {
        return stringA.compareToIgnoreCase(stringB);
      }
    });
    conceptsForFiltering.add(0, AnnotationsFilter.ALL_CONCEPTS);
    return conceptsForFiltering;
  }

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

  @NotifyChange({ "annotations" })
  @Command
  public void addGeneralAnnotation() {
    Annotation annotation = null;
    if (annotationType.equals(AnnotationType.EXPENSES)) {
      ExpensesAnnotation stockExpensesAnnotation = new GeneralExpensesAnnotation();
      annotation = stockExpensesAnnotation;
      addDefaultValuesToAnnotation(annotation,
          bookSelection.getSelectedBook(), currentYear,
          annotationsFilter);
    } else if (annotationType.equals(AnnotationType.INCOME)) {
      IncomeAnnotation stockIncomeAnnotation = new GeneralIncomeAnnotation();
      annotation = stockIncomeAnnotation;
      addDefaultValuesToAnnotation(annotation,
          bookSelection.getSelectedBook(), currentYear,
          annotationsFilter);
    }
    addAnnotation(annotation);
    Clients.clearBusy();
  }

  @NotifyChange({ "annotations" })
  @Command
  public void addStocksAnnotation() {
    Annotation annotation = null;
    if (annotationType.equals(AnnotationType.EXPENSES)) {
      StockExpensesAnnotation stockExpensesAnnotation = new StockExpensesAnnotation();
      annotation = stockExpensesAnnotation;
    } else if (annotationType.equals(AnnotationType.INCOME)) {
      StockIncomeAnnotation stockIncomeAnnotation = new StockIncomeAnnotation();
      annotation = stockIncomeAnnotation;
    }
    addDefaultValuesToAnnotation(annotation,
        bookSelection.getSelectedBook(), currentYear, annotationsFilter);
    addAnnotation(annotation);
    Clients.clearBusy();
  }

  protected Annotation addAnnotation(Annotation annotation) {
    annotation = AnnotationsBusiness.createAnnotation(annotation);
    justCreatedAnnotation = annotation;
    lastestCreatedAnnotation = justCreatedAnnotation;
    annotationsFilter.clearDateAndCostFilter();
    BindUtils
        .postGlobalCommand(null, null, "updateReportAnnotations", null);
    return annotation;
  }

  protected void addDefaultValuesToAnnotation(Annotation annotation,
      Book selectedBook, Integer currentYear,
      AnnotationsFilter annotationsFilter) {
    annotation.setBook(selectedBook);
    annotation.setAmount(0.0);
    Calendar calendar = GregorianCalendar.getInstance();
    Integer systemDateYear = calendar.get(Calendar.YEAR);
    if (!systemDateYear.equals(currentYear)) {
      String dateAsString = "01/01/" + currentYear;
      SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
          "dd/MM/yyyy");
      try {
        Date dateForNewAnnotation = simpleDateFormat
            .parse(dateAsString);
        annotation.setDate(dateForNewAnnotation);
      } catch (ParseException e) {
        logger.error("Error parsing date", e);
      }
    } else {
      Calendar currentCalendar = GregorianCalendar.getInstance();
      currentCalendar = DateUtils
          .truncate(currentCalendar, Calendar.DATE);
      annotation.setDate(currentCalendar.getTime());
    }
    if (annotationsFilter.getConcept() != null
        && !annotationsFilter.getConcept().equals(
            AnnotationsFilter.ALL_CONCEPTS)) {
      annotation.setConcept(annotationsFilter.getConcept());
    } else {
      annotation.setConcept(getDefaultConcept(annotation));
    }
  }

  private String getDefaultConcept(Annotation annotation) {
    String concept = ConceptsBusiness.getDefaultConcept(annotation
        .getClass().getSimpleName());
    return concept;
  }

  @NotifyChange({ "annotations" })
  @Command
  public void deleteAnnotation(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    Annotation annotation = (Annotation) event.getData();
    AnnotationsBusiness.deleteAnnotation(annotation);
    BindUtils
        .postGlobalCommand(null, null, "updateReportAnnotations", null);
    Clients.clearBusy();
  }

  @NotifyChange({ "annotations" })
  @Command
  public void duplicateAnnotation(
      @BindingParam("annotation") Annotation annotation,
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotation.setId(null);
    annotation.setDate(new Date());
    addAnnotation(annotation);
  }

  // TODO: check this for type
  public List<String> getConcepts(@BindingParam("type") String type) {
    List<String> concepts = new LinkedList<String>();
    concepts.add(ConceptsBusiness.getDefaultConcept(type));
    concepts.addAll(ConceptsBusiness.getConceptsUsedInBook(bookSelection));
    Collections.sort(concepts);
    return concepts;
  }

  /**
   * @return the list of wrong/inconsistent stock concepts. The method returns
   *         all the sold stock that were done at a time in which the number
   *         of bought stocks is below the amount of bought stocks (i.e. it is
   *         not possible to sell stocks one does not previously have)
   */
  @DependsOn("annotations")
  public List<ConceptValidation> getWrongStockConcepts() {
    List<ConceptValidation> conceptValidations = new LinkedList<ConceptValidation>();
    List<Annotation> annotations = StocksYearlyReportViewModel
        .getStocksAnnotationsUntilYear(bookSelection, currentYear);
    StocksHistory stocksHistory = StocksUtils.getStocksHistory(annotations);
    for (String currentConcept : stocksHistory.getStocksErrorsHistoryMap()
        .keySet()) {
      StocksIncomeError currentError = stocksHistory
          .getStocksErrorsHistoryMap().get(currentConcept);
      ConceptValidation conceptValidation = new ConceptValidation(
          currentConcept, currentError.toString());
      conceptValidations.add(conceptValidation);
    }
    return conceptValidations;
  }

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

  }

  @Command
  @NotifyChange({ "annotations", "annotationsFilter" })
  public void disableDateFilter(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotationsFilter.setDateFrom(null);
    annotationsFilter.setDateTo(null);
  }

  @Command
  @NotifyChange({ "annotations", "annotationsFilter" })
  public void disableForCompanyFilter(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotationsFilter.setForCompany(null);
  }

  @Command
  @NotifyChange({ "annotations", "annotationsFilter" })
  public void disableUseQuarterly(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotationsFilter.setUseQuarterly(null);
  }

  @Command
  @NotifyChange({ "annotations", "annotationsFilter" })
  public void disableCostFilter(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotationsFilter.setCostFrom(null);
    annotationsFilter.setCostTo(null);
  }

  @Command
  @NotifyChange({ "annotations", "annotationsFilter" })
  public void disableRetentionFilter(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotationsFilter.setRetentionFrom(null);
    annotationsFilter.setRetentionTo(null);
  }

  @Command
  @NotifyChange({ "annotations", "annotationsFilter" })
  public void disableVatFilter(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotationsFilter.setVatFrom(null);
    annotationsFilter.setVatTo(null);
  }

  @Command
  @NotifyChange({ "annotations", "annotationsFilter" })
  public void disableUseYearlyFilter(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotationsFilter.setUseYearly(null);
  }

  @Command
  @NotifyChange({ "annotations", "annotationsFilter" })
  public void disableDoneFilter(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotationsFilter.setDone(null);
  }

  @Command
  @NotifyChange({ "annotations", "annotationsFilter" })
  public void disableDeductiblePercentageFilter(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotationsFilter.setDeductiblePercentageFrom(null);
    annotationsFilter.setDeductiblePercentageTo(null);
  }

  @Command
  @NotifyChange({ "annotations", "annotationsFilter" })
  public void disableCommunityFilter(
      @ContextParam(ContextType.TRIGGER_EVENT) Event event) {
    annotationsFilter.setCommunity(null);
  }

}
TOP

Related Classes of org.pau.assetmanager.viewmodel.AnnotationViewModel

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.