Package org.internna.ossmoney.mvc

Source Code of org.internna.ossmoney.mvc.ReportingController

package org.internna.ossmoney.mvc;

import java.util.Map;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.HashMap;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Calendar;
import java.util.Currency;
import java.util.Collection;
import java.math.BigDecimal;
import javax.servlet.http.HttpServletRequest;
import org.internna.ossmoney.model.Category;
import org.internna.ossmoney.util.DateUtils;
import org.internna.ossmoney.cache.CacheStore;
import org.internna.ossmoney.model.Subcategory;
import org.internna.ossmoney.model.budget.Budget;
import org.internna.ossmoney.model.support.Interval;
import org.internna.ossmoney.model.AccountTransaction;
import org.internna.ossmoney.model.security.UserDetails;
import org.internna.ossmoney.model.support.InflowOutflow;
import org.internna.ossmoney.model.support.NameValuePair;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/financial/reporting")
public final class ReportingController extends AbstractTransactionController {

  @Autowired private CacheStore cache;
  @Autowired private MessageSource messageSource;
  @Autowired private WidgetController widgetController;

    @RequestMapping
    public String index() {
        return "reporting/index";
    }

    protected void setCache(CacheStore cache) {
    this.cache = cache;
  }

  @RequestMapping("/inflows-outflows/{intervals}")
    public String monthlyInflowsOutflowsReport(@PathVariable final String intervals, final HttpServletRequest request, final ModelMap modelMap) {
      Interval interval = getInterval(intervals);
      modelMap.addAttribute("months", DateUtils.dates(interval.getNumberOfMonths() - 1));
      List<AccountTransaction> transactions = getTransactions(interval, null, modelMap);
      modelMap.addAttribute("data", calculateMonthlyInflowsOutflows(interval, transactions));
        return "reporting/monthly-inflows-outflows";
    }

    protected final Collection<InflowOutflow> calculateMonthlyInflowsOutflows(final Interval interval, final List<AccountTransaction> transactions) {
      Map<String, InflowOutflow> data = new HashMap<String, InflowOutflow>();
      if (!CollectionUtils.isEmpty(transactions)) {
        for (AccountTransaction transaction : transactions) {
          Locale locale = transaction.getAccount().getLocale();
          String currency = transaction.getAccount().getCurrency();
          InflowOutflow inflowOutflow = getOrCreateInflowOutflow(interval, currency, locale, data);
          process(transaction, inflowOutflow);
        }
      }
      return data.values();
    }

    protected final InflowOutflow getOrCreateInflowOutflow(final Interval interval, final String currency, final Locale locale, final Map<String, InflowOutflow> inflowsOutflows) {
      InflowOutflow inflowOutflow = inflowsOutflows.get(currency);
      if (inflowOutflow == null) {
        inflowOutflow = new InflowOutflow(interval, currency, locale, messageSource);
        inflowsOutflows.put(currency, inflowOutflow);
      }
      return inflowOutflow;
    }

    protected final void process(final AccountTransaction transaction, final InflowOutflow inflowOutflow) {
      boolean income = transaction.getSubcategory().isIncome();
      Map<Category, Map<Subcategory, BigDecimal>> data = income ? inflowOutflow.getInflow(transaction.getOperationDate()) : inflowOutflow.getOutflow(transaction.getOperationDate());
      Map<Subcategory, BigDecimal> categoryData = getOrCreateCategoryData(transaction, data);
      BigDecimal amount = getOrCreateSubcategoryAmount(transaction, categoryData);
      amount = amount.abs().add(transaction.getAmount().abs());
      categoryData.put(transaction.getSubcategory(), amount);
    }

    protected final Map<Subcategory, BigDecimal> getOrCreateCategoryData(final AccountTransaction transaction, final Map<Category, Map<Subcategory, BigDecimal>> data) {
      Subcategory subcategory = transaction.getSubcategory();
      Category category = subcategory.getParentCategory();
      Map<Subcategory, BigDecimal> categoryData = data.get(category);
      if (categoryData == null) {
        categoryData = new HashMap<Subcategory, BigDecimal>();
        data.put(category, categoryData);
      }
      return categoryData;
    }

    protected BigDecimal getOrCreateSubcategoryAmount(final AccountTransaction transaction, final Map<Subcategory, BigDecimal> categoryData) {
      Subcategory subcategory = transaction.getSubcategory();
      BigDecimal amount = categoryData.get(subcategory);
      if (amount == null) {
        amount = BigDecimal.ZERO;
        categoryData.put(subcategory, amount);
      }
      return amount;
    }

    @RequestMapping("/categories")
    public String expensesByCategoryOverTime(final ModelMap modelMap) {
      UserDetails user = getCurrentUser();
      modelMap.addAttribute("subcategories", new TreeSet<Subcategory>(Subcategory.findExpenseCategories(user)));
      return "reporting/categories";
    }

    @RequestMapping("/categories-chart/{id}/{intervals}")
    public String expensesByCategoryOverTimeChartData(@PathVariable final Long id, @PathVariable final String intervals, final ModelMap modelMap) {
      UserDetails user = getCurrentUser();
      Interval interval = getInterval(intervals);
      Subcategory subcat = Subcategory.findSubcategory(id);
      Map<String, BigDecimal> maxValues = cache.getMaxCategoryData(user, subcat, intervals);
      Map<String, Map<Date, NameValuePair<Date, BigDecimal>>> budgetData = cache.getAlloted(user, subcat, intervals);
      Map<String, Map<Date, NameValuePair<Date, BigDecimal>>> currencyData = cache.getCategoryData(user, subcat, intervals);
      if (maxValues == null) {
        maxValues = new HashMap<String, BigDecimal>();
        budgetData = new HashMap<String, Map<Date, NameValuePair<Date, BigDecimal>>>();
        currencyData = new HashMap<String, Map<Date, NameValuePair<Date, BigDecimal>>>();
        for (AccountTransaction transaction : getTransactions(interval, subcat, modelMap)) {
          Locale locale = transaction.getAccount().getLocale();
          String isoCode = Currency.getInstance(locale).getCurrencyCode();
          if (!currencyData.containsKey(isoCode)) {
            maxValues.put(isoCode, BigDecimal.ZERO);
            currencyData.put(isoCode, createDateValueMap(interval));
            budgetData.put(isoCode, budget(user, subcat, locale, interval));
          }
          Date date = DateUtils.getMonthEndDate(transaction.getOperationDate());
          if (!currencyData.get(isoCode).containsKey(date)) {
            date = DateUtils.end(Calendar.getInstance()).getTime();
          }
          NameValuePair<Date, BigDecimal> stored = currencyData.get(isoCode).get(date);
          stored.setValue(stored.getValue().add(transaction.getAmount().abs()));
          maxValues.put(isoCode, maxValues.get(isoCode).max(stored.getValue()));
        }
        cache.storeAlloted(user, subcat, intervals, budgetData);
        cache.storeCategoryData(user, subcat, intervals, currencyData);
        cache.storeMaxCategoryData(user, subcat, intervals, maxValues);
      }
      modelMap.addAttribute("max", maxValues);
      modelMap.addAttribute("category", subcat);
      modelMap.addAttribute("currencies", currencyData.keySet());
      for (String code : currencyData.keySet()) {
        modelMap.addAttribute("data" + code, new TreeSet<NameValuePair<Date, BigDecimal>>(currencyData.get(code).values()));
        modelMap.addAttribute("budget" + code, new TreeSet<NameValuePair<Date, BigDecimal>>(budgetData.get(code).values()));
      }
      if (widgetController != null) {
        widgetController.incomeVsExpensesOverTime(interval.getNumberOfMonths(), modelMap);
      }
      return "reporting/categories-chart";
    }

    private Map<Date, NameValuePair<Date, BigDecimal>> createDateValueMap(Interval interval) {
      Map<Date, NameValuePair<Date, BigDecimal>> data = new TreeMap<Date, NameValuePair<Date, BigDecimal>>();
      for (Date date : DateUtils.dates(interval.getNumberOfMonths())) {
        data.put(date, new NameValuePair<Date, BigDecimal>(date, BigDecimal.ZERO));
      }
      return data;
    }

    protected Map<Date, NameValuePair<Date, BigDecimal>> budget(UserDetails user, Subcategory category, Locale locale, Interval interval) {
      Map<Date, NameValuePair<Date, BigDecimal>> budgetData = new HashMap<Date, NameValuePair<Date, BigDecimal>>();
      Budget budget = user.getBudget();
      for (Date date : DateUtils.dates(interval.getNumberOfMonths())) {
        budgetData.put(date, new NameValuePair<Date, BigDecimal>(date, budget.getAlloted(date, locale, category)));
      }
      return budgetData;
    }
}
TOP

Related Classes of org.internna.ossmoney.mvc.ReportingController

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.