/* * This file is part of the aidGer project. * * Copyright (C) 2010-2013 The aidGer Team * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package de.aidger.model.models; import static de.aidger.utils.Translation._; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import siena.SienaException; import de.aidger.model.AbstractModel; import de.aidger.model.ObserverManager; import de.aidger.model.validators.ValidationException; /** * Represents a single entry in the financial category column of the database. * Contains functions to retrieve and change the data in the database. * * @author aidGer Team */ public class FinancialCategory extends AbstractModel<FinancialCategory> { /** * The name of the category. */ private String name; /** * The year the category is valid. */ private Short year; private ArrayList<InternalFinancialCategory> entries; /** * Initialize the FinancialCategory class. */ public FinancialCategory() { if (getValidators().isEmpty()) { validatePresenceOf(new String[] { "name", "year", "costUnits", "budgetCosts" }, new String[] { _("Name"), _("Year"), _("Cost unit"), _("Budget Costs") }); } entries = new ArrayList<InternalFinancialCategory>(); } /** * Initialize the FinancialCategory class with the given financial category * model. * * @param f * the financial category model */ public FinancialCategory(FinancialCategory f) { this(); setId(f.getId()); this.entries = f.entries; setName(f.getName()); setYear(f.getYear()); } /** * Clone the current category. */ @Override public FinancialCategory clone() { FinancialCategory f = new FinancialCategory(); f.setId(id); f.entries = this.entries; f.setName(name); f.setYear(year); return f; } @Override public void markAsNew() { for(InternalFinancialCategory entry : entries) { entry.markAsNew(); } } /** * Custom validation function. * * @return True if the validation is successful */ public boolean validate() { boolean ret = true; if (year != null) { if (year <= 1000 || year >= 10000) { addError("year", _("Year"), _("is an incorrect year")); ret = false; } } if (this.getBudgetCosts() != null && this.getBudgetCosts().length > 0) { for (Integer b : this.getBudgetCosts()) { if(b == null) { addError("budgetCosts", _("Budget Costs"), _("is empty")); ret = false; break; } if (b < 0) { addError("budgetCosts", _("Budget Costs"), _("can't be less than zero")); ret = false; break; } } } else { addError("budgetCosts", _("Budget Costs"), _("is empty")); ret = false; } if (this.getCostUnits() != null && this.getCostUnits().length > 0) { for (Integer c : this.getCostUnits()) { if(c == null) { addError("costUnits", _("Cost Units"), _("is empty")); ret = false; break; } if (Collections.frequency(Arrays.asList(this.getCostUnits()), c) > 1) { addError("costUnits", _("Cost Units"), _("can't be the same")); ret = false; break; } } } else { addError("costUnits", _("Cost Units"), _("is empty")); ret = false; } return ret; } /** * Custom validation function for remove(). * * @return True if everything is correct */ public boolean validateOnRemove() { boolean ret = true; List<Course> courses = (new Course()).getCourses(this); if (courses.size() > 0) { addError(_("Financial Category is still linked to a Course.")); ret = false; } return ret; } /** * Get a list of distinct funds. * * @return List of distinct cost units */ public List<Integer> getDistinctCostUnits() { // TODO: Make sure that distinct cost units mean // "SELECT DISTINCT Kostenstelle from finanzkategorie" List<Integer> costUnits = new ArrayList<Integer>(); List<InternalFinancialCategory> allEntries = new InternalFinancialCategory() .getAll(); for (InternalFinancialCategory fc : allEntries) { if (!costUnits.contains(fc.getCostUnit())) { costUnits.add(fc.getCostUnit()); } } return costUnits; } /** * Get the budget costs of the category. * * @return The budget costs of the category */ public Integer[] getBudgetCosts() { Integer[] costs = new Integer[entries.size()]; for (int i = 0; i < entries.size(); i++) { costs[i] = entries.get(i).getBudgetCost(); } return costs; } /** * Get the funds of the category. * * @return The funds of the category */ public Integer[] getCostUnits() { Integer[] costUnits = new Integer[entries.size()]; for (int i = 0; i < entries.size(); i++) { costUnits[i] = entries.get(i).getCostUnit(); } return costUnits; } /** * Get the name of the category. * * @return The name of the category */ public String getName() { return name; } /** * Get the year the category is valid. * * @return The year the category is valid */ public Short getYear() { return year; } /** * Set the budget costs of the category. * * @param costs * The budget costs of the category */ public void setBudgetCosts(Integer[] costs) { if(costs == null) return; for (int i = 0; i < costs.length; i++) { if (entries.size() >= i + 1) { InternalFinancialCategory entry = entries.get(i); entry.setBudgetCost(costs[i]); } else { InternalFinancialCategory entry = newEntry(); entry.setBudgetCost(costs[i]); entries.add(entry); } } } /** * Set the funds of the category. * * @param costUnits * The cost units of the category */ public void setCostUnits(Integer[] costUnits) { if(costUnits == null) return; for (int i = 0; i < costUnits.length; i++) { if (entries.size() >= i + 1) { InternalFinancialCategory entry = entries.get(i); entry.setCostUnit(costUnits[i]); } else { InternalFinancialCategory entry = newEntry(); entry.setCostUnit(costUnits[i]); entries.add(entry); } } for (int i = costUnits.length; i < entries.size(); i++) { entries.get(i).remove(); entries.remove(i); } } @Override public void setId(Long id) { this.id = id; for (InternalFinancialCategory entry : entries) { entry.setGroup(id); } } /** * Set the name of the category. * * @param name * The name of the category */ public void setName(String name) { this.name = name; for (InternalFinancialCategory entry : entries) { entry.setName(name); } } /** * Set the year the category is valid. * * @param year * The year the category is valid. */ public void setYear(Short year) { this.year = year; for (InternalFinancialCategory entry : entries) { entry.setYear(year); } } private InternalFinancialCategory newEntry() { InternalFinancialCategory entry = new InternalFinancialCategory(); entry.setGroup(this.id); entry.setName(this.name); entry.setYear(this.year); return entry; } public void save() { /* Validation of the model */ if (!doValidate()) { throw new ValidationException(_("Validation failed.")); } else if (!errors.isEmpty()) { throw new ValidationException( _("The model was not saved because the error list is not empty.")); } // TODO: implement als transaction to ensure no duplicate groups if (id == null) { List<InternalFinancialCategory> temp = new InternalFinancialCategory() .all().order("-group").fetch(); if (temp == null || temp.size() == 0) { this.setId((long) 0); } else { this.setId(temp.get(0).getGroup() + 1); } } for (InternalFinancialCategory entry : entries) { entry.save(); } /* Observable calls */ ObserverManager.getInstance().triggerSave(this); } public void remove() { /* Check if there is a custom validation function */ try { java.lang.reflect.Method m = getClass().getDeclaredMethod( "validateOnRemove"); if (!(Boolean) m.invoke(this, new Object[0])) { throw new ValidationException(); } } catch (NoSuchMethodException x) { } catch (IllegalAccessException x) { } catch (InvocationTargetException x) { } for (InternalFinancialCategory entry : entries) { entry.remove(); } /* Observable calls */ ObserverManager.getInstance().triggerRemove(this); } @Override public List<FinancialCategory> getAll() { List<InternalFinancialCategory> allEntries = new InternalFinancialCategory() .getAll(); HashMap<Long, FinancialCategory> fcMap = new HashMap<Long, FinancialCategory>(); for (InternalFinancialCategory entry : allEntries) { if (fcMap.containsKey(entry.getGroup())) { fcMap.get(entry.getGroup()).entries.add(entry); } else { FinancialCategory fc = new FinancialCategory(); fc.setId(entry.getGroup()); fc.setName(entry.getName()); fc.setYear(entry.getYear()); fc.entries.add(entry); fcMap.put(fc.getId(), fc); } } return new ArrayList<FinancialCategory>(fcMap.values()); } @Override public FinancialCategory getById(Long id) { for (FinancialCategory fc : this.getAll()) { if (fc.getId() == id) { return fc; } } return null; } @Override public FinancialCategory getByKey(Object id) { List<FinancialCategory> categories = this.getAll(); if (categories.isEmpty()) return null; for (FinancialCategory fc : categories) { if (id == null ? false : id.getClass() == Integer.class || id.getClass() == Long.class) { if (fc.getId() == id) return fc; } } return null; } @Override public int size() { return this.getAll().size(); } @Override public void clearTable() { try { InternalFinancialCategory entry = new InternalFinancialCategory(); entry.all().delete(); this.setId(null); } catch (SienaException x) { if (!x.getMessage().equals("No updated rows") && !x.getMessage().endsWith("rows deleted")) throw x; } } }