Package org.internna.ossmoney.mvc

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

package org.internna.ossmoney.mvc;

import java.util.Set;
import java.util.Map;
import java.util.Date;
import java.util.List;
import java.util.HashMap;
import java.util.Currency;
import java.util.ArrayList;
import java.math.BigDecimal;
import org.internna.ossmoney.model.Bill;
import org.internna.ossmoney.model.Account;
import org.internna.ossmoney.util.DateUtils;
import org.internna.ossmoney.cache.CacheStore;
import org.internna.ossmoney.model.Subcategory;
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.IncomeExpense;
import org.internna.ossmoney.model.support.NameValuePair;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;

import static org.springframework.util.StringUtils.hasText;

@Controller
@RequestMapping("/financial/widgets")
public final class WidgetController extends AbstractTransactionController {

  @Autowired private CacheStore cache;

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

  @RequestMapping("/income_vs_expenses/{intervals}")
    public String incomeVsExpenses(@PathVariable String intervals, ModelMap modelMap) {
      UserDetails user = getCurrentUser();
      String interval = hasText(intervals) ? intervals.toUpperCase() : Interval.Intervals.PREVIOUS_MONTH.toString();
      Map<Currency, NameValuePair<BigDecimal, BigDecimal>> data = cache.getIncomeAndExpenses(user, intervals);
      if (data == null) {
        List<AccountTransaction> transactions = getTransactions(user, intervals, null, modelMap);
        data = calculateIncomeAndExpenses(transactions);
        cache.storeIncomeAndExpenses(user, intervals, data);
      }
      modelMap.addAttribute("data", data);
      modelMap.addAttribute("interval", interval);
      modelMap.addAttribute("max", getMaxValue(data));
      modelMap.addAttribute("dataSet", data.entrySet());
      return "widgets/incomevsexpenses";
    }

    protected Map<Currency, NameValuePair<BigDecimal, BigDecimal>> calculateIncomeAndExpenses(List<AccountTransaction> transactions) {
      Map<Currency, NameValuePair<BigDecimal, BigDecimal>> data = new HashMap<Currency, NameValuePair<BigDecimal, BigDecimal>>();
      if (!CollectionUtils.isEmpty(transactions)) {
            for (AccountTransaction transaction : transactions) {
                BigDecimal amount = transaction.getAmount();
                Currency currency = Currency.getInstance(transaction.getAccount().getLocale());
                if (!data.containsKey(currency)) {
                    data.put(currency, new NameValuePair<BigDecimal, BigDecimal>(BigDecimal.ZERO, BigDecimal.ZERO));
                }
                NameValuePair<BigDecimal, BigDecimal> incomeExpense = data.get(currency);
                if (amount.doubleValue() >= 0) {
                    incomeExpense.setKey(amount.add(incomeExpense.getKey()));
                } else {
                    incomeExpense.setValue(amount.abs().add(incomeExpense.getValue()));
                }
                data.put(currency, incomeExpense);
            }
      }
      return data;
    }

    protected Long getMaxValue(Map<Currency, NameValuePair<BigDecimal, BigDecimal>> data) {
      Long max = 0L;
      for (Map.Entry<Currency, NameValuePair<BigDecimal, BigDecimal>> dataRow : data.entrySet()) {
            NameValuePair<BigDecimal, BigDecimal> incomeExpense = dataRow.getValue();
            max = Math.max(max, Math.max(incomeExpense.getKey().intValue(), incomeExpense.getValue().intValue()));
      }
      return Math.round(max * 1.1);
    }

    @RequestMapping("/expenses_by_category/{intervals}")
    public String expensesByCategory(@PathVariable String intervals, ModelMap modelMap) {
      UserDetails user = getCurrentUser();
      Interval interval = getInterval(intervals);
      Map<Currency, Map<Subcategory, BigDecimal>> data = cache.getExpensesByCategory(user, intervals);
      if (data == null) {
        List<AccountTransaction> transactions = getTransactions(interval, null, modelMap);
        data = organizeByCategory(transactions);
        cache.storeExpensesByCategory(user, intervals, data);
      }
      modelMap.addAttribute("data", data);
      Map<Currency, Set<Map.Entry<Subcategory, BigDecimal>>> dataAsSet = new HashMap<Currency, Set<Map.Entry<Subcategory, BigDecimal>>>();
      for (Currency currency : data.keySet()) {
            dataAsSet.put(currency, data.get(currency).entrySet());
      }
      modelMap.addAttribute("interval", interval);
      modelMap.addAttribute("dataSet", dataAsSet.entrySet());
      return "widgets/expenses_by_category";
    }

    protected Map<Currency, Map<Subcategory, BigDecimal>> organizeByCategory(List<AccountTransaction> transactions) {
      Map<Currency, Map<Subcategory, BigDecimal>> data = new HashMap<Currency, Map<Subcategory, BigDecimal>>();
      if (!CollectionUtils.isEmpty(transactions)) {
            for (AccountTransaction transaction : transactions) {
                Subcategory category = transaction.getSubcategory();
                if (!category.getParentCategory().isIncome()) {
                    BigDecimal amount = transaction.getAmount();
                    Currency currency = Currency.getInstance(transaction.getAccount().getLocale());
                    if (!data.containsKey(currency)) {
                        data.put(currency, new HashMap<Subcategory, BigDecimal>());
                    }
                    if (!data.get(currency).containsKey(category)) {
                        data.get(currency).put(category, BigDecimal.ZERO);
                    }
                    BigDecimal expenses = data.get(currency).get(category);
                    data.get(currency).put(category, expenses.add(amount.abs()));
                }
            }
      }
      return data;
    }

    @RequestMapping("/expenses_over_time/{months}")
    public String expensesOverTime(@PathVariable int months, ModelMap modelMap) {
      UserDetails user = getCurrentUser();
        Date[] dates = DateUtils.dates(months);
        Map<Currency, Map<Date, IncomeExpense>> data = cache.getIncomeVsExpensesOverTime(user, months);
    if (data == null) {
      data = calculateIncomeVsExpensesOverTime(dates, getAccounts());
      cache.storeIncomeVsExpensesOverTime(user, months, data);
    }
        fillModel(dates, data, modelMap);
        return "widgets/expensesovertime";
    }

    @RequestMapping("/networth/{months}")
    public String netWorthOverTime(@PathVariable int months, ModelMap modelMap) {
      UserDetails user = getCurrentUser();
      Date[] dates = DateUtils.dates(months);
      Map<Currency, Map<Date, IncomeExpense>> data = cache.getNetWorthOverTime(user, months);
      if (data == null) {
        data = calculateWealth(dates, getAccounts());
        cache.storeNetWorthOverTime(user, months, data);
      }
      fillModel(dates, data, modelMap);
      return "widgets/networth";
    }

    @RequestMapping("/income_vs_expenses_over_time/{months}")
    public String incomeVsExpensesOverTime(@PathVariable int months, ModelMap modelMap) {
      UserDetails user = getCurrentUser();
        Date[] dates = DateUtils.dates(months);
        Map<Currency, Map<Date, IncomeExpense>> data = cache.getIncomeVsExpensesOverTime(user, months);
        if (data == null) {
          data = calculateIncomeVsExpensesOverTime(dates, getAccounts());
          cache.storeIncomeVsExpensesOverTime(user, months, data);
        }
        fillModel(dates, data, modelMap);
        return "widgets/incomevsexpensesovertime";
    }

    private void fillModel(Date[] dates, Map<Currency, Map<Date, IncomeExpense>> data, ModelMap modelMap) {
      Map<Currency, BigDecimal> totalMax = new HashMap<Currency, BigDecimal>();
      Map<Currency, IncomeExpense> maxValues = new HashMap<Currency, IncomeExpense>();
      Map<Currency, List<NameValuePair<Date, IncomeExpense>>> dataAsSet = new HashMap<Currency, List<NameValuePair<Date, IncomeExpense>>>();
      for (Currency currency : data.keySet()) {
        IncomeExpense max = maxValues.containsKey(currency) ? maxValues.get(currency) : new IncomeExpense();
            List<NameValuePair<Date, IncomeExpense>> orderedData = new ArrayList<NameValuePair<Date, IncomeExpense>>();
            for (Date date : dates) {
              IncomeExpense value = data.get(currency).get(date);
                max.setKey(max.getKey().doubleValue() > value.getKey().doubleValue() ? max.getKey() : value.getKey());
                max.setValue(max.getValue().doubleValue() > value.getValue().doubleValue() ? max.getValue() : value.getValue());
                orderedData.add(new NameValuePair<Date, IncomeExpense>(date, value));
            }
            maxValues.put(currency, max);
            dataAsSet.put(currency, orderedData);
      }
      for (Map.Entry<Currency, IncomeExpense>  entry : maxValues.entrySet()) {
        totalMax.put(entry.getKey(), entry.getValue().getKey().max(entry.getValue().getValue()));
      }
      modelMap.addAttribute("maxValues", maxValues);
      modelMap.addAttribute("totalMaxValue", totalMax);
      modelMap.addAttribute("dataSet", dataAsSet.entrySet());
    }

    protected Map<Currency, Map<Date, IncomeExpense>> calculateWealth(Date[] dates, Set<Account> accounts) {
      Map<Currency, Map<Date, IncomeExpense>> wealthOverTimeAndCurrency = new HashMap<Currency, Map<Date, IncomeExpense>>();
        if (!CollectionUtils.isEmpty(accounts)) {
            for (Account account : accounts) {
                Currency currency = Currency.getInstance(account.getLocale());
                if (!wealthOverTimeAndCurrency.containsKey(currency)) {
                    wealthOverTimeAndCurrency.put(currency, new HashMap<Date, IncomeExpense>());
                }
                Map<Date, IncomeExpense> wealthOverTime = wealthOverTimeAndCurrency.get(currency);
                for (Date month : dates) {
                    if (!wealthOverTime.containsKey(month)) {
                        wealthOverTime.put(month, new IncomeExpense());
                    }
                    IncomeExpense data = wealthOverTime.get(month);
                    data.setKey(data.getKey().add(account.calculateBalance(month)));
                    wealthOverTime.put(month, data);
                }
            }
        }
      return wealthOverTimeAndCurrency;
    }

    protected Map<Currency, Map<Date, IncomeExpense>> calculateIncomeVsExpensesOverTime(Date[] dates, Set<Account> accounts) {
      Map<Currency, Map<Date, IncomeExpense>> expensesOverTimeAndCurrency = new HashMap<Currency, Map<Date, IncomeExpense>>();
        if (!CollectionUtils.isEmpty(accounts)) {
            for (Account account : accounts) {
                Currency currency = Currency.getInstance(account.getLocale());
                if (!expensesOverTimeAndCurrency.containsKey(currency)) {
                    expensesOverTimeAndCurrency.put(currency, new HashMap<Date, IncomeExpense>());
                }
                Map<Date, IncomeExpense> incomeExpensesOverTime = expensesOverTimeAndCurrency.get(currency);
                for (Date month : dates) {
                    if (!incomeExpensesOverTime.containsKey(month)) {
                      incomeExpensesOverTime.put(month, new IncomeExpense());
                    }
                    IncomeExpense monthIncomeExpenses = incomeExpensesOverTime.get(month);
                    List<AccountTransaction> transactions = account.getTransactionsInPeriod(new Interval(DateUtils.getMonthStartDate(month), month), null, true);
                    if (!CollectionUtils.isEmpty(transactions)) {
                        for (AccountTransaction transaction : transactions) {
                            BigDecimal amount = transaction.getAmount();
                            if (amount.doubleValue() >= 0) {
                              monthIncomeExpenses.setKey(monthIncomeExpenses.getKey().add(amount.abs()));
                            } else {
                              monthIncomeExpenses.setValue(monthIncomeExpenses.getValue().add(amount.abs()));
                            }
                        }
                    }
                    incomeExpensesOverTime.put(month, monthIncomeExpenses);
                }
            }
        }
        return expensesOverTimeAndCurrency;
    }

    @RequestMapping("/remainder/{days}")
    public String remainders(@PathVariable int days, ModelMap modelMap) {
      UserDetails user = UserDetails.findCurrentUser();
      modelMap.addAttribute("bills", Bill.findPending(user, days));
      return "widgets/remainders";
    }

}
TOP

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

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.