package org.internna.ossmoney.mvc;
import java.util.Locale;
import java.util.Calendar;
import java.math.BigDecimal;
import org.springframework.ui.ModelMap;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.internna.ossmoney.model.Subcategory;
import org.internna.ossmoney.model.support.Interval;
import org.internna.ossmoney.services.AccountService;
import org.internna.ossmoney.model.budget.MonthlyBudget;
import org.internna.ossmoney.model.security.UserDetails;
import org.internna.ossmoney.model.support.NameValuePair;
import org.internna.ossmoney.model.budget.CategoryBudget;
@Controller
@RequestMapping("/financial/budget")
public class BudgetController {
private static final Log logger = LogFactory.getLog(BudgetController.class);
@Autowired private AccountService accountService;
@RequestMapping("/manage")
public String manage(ModelMap modelMap) {
UserDetails user = UserDetails.findCurrentUser();
modelMap.addAttribute("budgets", user.getBudget().getBudgets());
modelMap.addAttribute("categories", Subcategory.findExpenseCategories(user));
return "budget/manage";
}
@RequestMapping(value = "/manage", method = RequestMethod.POST)
public String manage(String currency, long subcategory, int month, double amount, ModelMap modelMap) {
UserDetails user = UserDetails.findCurrentUser();
Subcategory loaded = Subcategory.findSubcategory(subcategory);
if (month == -1) {
for (int i = 0; i < 12; i++) {
createBudget(user, currency, i, amount, loaded);
}
} else {
createBudget(user, currency, month, amount, loaded);
}
return manage(modelMap);
}
protected void createBudget(UserDetails user, String locale, int month, double amount, Subcategory category) {
CategoryBudget categoryBudget = new CategoryBudget();
categoryBudget.setCategory(category);
String[] locales = locale.split("_");
categoryBudget.setLocale(new Locale(locales[0], locales[1], ""));
categoryBudget.setExpectedAmount(new BigDecimal(amount));
MonthlyBudget monthlyBudget = obtainMonthlyBudget(user, month);
categoryBudget.setMonthlyBudget(monthlyBudget);
categoryBudget.persist();
monthlyBudget.getBudgets().add(categoryBudget);
monthlyBudget.merge();
}
protected MonthlyBudget obtainMonthlyBudget(UserDetails user, int month) {
return user.getBudget().getMonthlyBudget(month);
}
@RequestMapping(value = "/update", method = RequestMethod.POST)
public @ResponseBody Boolean update(long id, double value) {
CategoryBudget budget = getBudget(id);
if (budget != null) {
budget.setExpectedAmount(new BigDecimal(value));
budget.merge();
}
return budget != null && budget.getExpectedAmount().doubleValue() == value;
}
@RequestMapping(value = "/delete", method = RequestMethod.POST)
public @ResponseBody Boolean delete(Long id) {
boolean deleted = false;
try {
CategoryBudget budget = getBudget(id);
if (budget != null) {
budget.remove();
deleted = true;
}
} catch (Exception ex) {
logger.warn("Error deleting category [" + id + "]", ex);
}
return deleted;
}
private CategoryBudget getBudget(long id) {
UserDetails user = UserDetails.findCurrentUser();
CategoryBudget budget = CategoryBudget.findCategoryBudget(id);
return budget != null && user != null && budget.getMonthlyBudget().getBudget().getOwner().equals(user) ? budget : null;
}
@RequestMapping("/graph/{expanded}")
public String widget(@PathVariable String expanded, ModelMap modelMap) {
BigDecimal budgeted = BigDecimal.ZERO;
BigDecimal expended = BigDecimal.ZERO;
UserDetails user = UserDetails.findCurrentUser();
Interval monthToDate = new Interval(Interval.Intervals.MONTH_TO_DATE);
MonthlyBudget budget = user.getBudget().getMonthlyBudget(Calendar.getInstance().get(Calendar.MONTH));
for (CategoryBudget categoryBudget : budget.getBudgets()) {
budgeted = budgeted.add(categoryBudget.getExpectedAmount());
BigDecimal expendedInCategory = accountService.getExpenses(user, categoryBudget.getLocale(), categoryBudget.getCategory(), monthToDate);
expended = expended.add(expendedInCategory);
categoryBudget.setExpended(expendedInCategory);
}
modelMap.addAttribute("expanded", expanded);
modelMap.addAttribute("categories", budget.getBudgets());
modelMap.addAttribute("totals", new NameValuePair<Double, Double>(expended.doubleValue(), budgeted.doubleValue()));
return "budget/widget";
}
}