/******************************************************************************* * Copyright (c) 2010 Denis Solonenko. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v2.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * Denis Solonenko - initial API and implementation ******************************************************************************/ package ru.orangesoftware.financisto2.model; import android.support.v4.util.LongSparseArray; import ru.orangesoftware.financisto2.blotter.BlotterFilter; import ru.orangesoftware.financisto2.utils.RecurUtils; import ru.orangesoftware.financisto2.utils.RecurUtils.Recur; import javax.persistence.*; import java.util.Map; import static ru.orangesoftware.financisto2.utils.Utils.isNotEmpty; @Entity @Table(name = "budget") public class Budget { @Id @Column(name = "_id") public long id = -1; @Column(name = "title") public String title; @Column(name = "category_id") public String categories; @Column(name = "project_id") public String projects; @Column(name = "currency_id") public long currencyId = -1; @JoinColumn(name = "budget_currency_id", required = false) public Currency currency; @JoinColumn(name = "budget_account_id", required = false) public Account account; @Column(name = "amount") public long amount; @Column(name = "include_subcategories") public boolean includeSubcategories; @Column(name = "expanded") public boolean expanded; @Column(name = "include_credit") public boolean includeCredit = true; @Column(name = "start_date") public long startDate; @Column(name = "end_date") public long endDate; @Column(name = "recur") public String recur; @Column(name = "recur_num") public long recurNum; @Column(name = "is_current") public boolean isCurrent; @Column(name = "parent_budget_id") public long parentBudgetId; @Column(name = "updated_on") public long updatedOn = System.currentTimeMillis(); @Column(name = "remote_key") public String remoteKey ; @Transient public String categoriesText = ""; @Transient public String projectsText = ""; @Transient public long spent = 0; @Transient public volatile boolean updated = false; public Recur getRecur() { return RecurUtils.createFromExtraString(recur); } public static String createWhere(Budget b, LongSparseArray<Category> categories, LongSparseArray<Project> projects) { StringBuilder sb = new StringBuilder(); // currency if (b.currency != null) { sb.append(BlotterFilter.FROM_ACCOUNT_CURRENCY_ID).append("=").append(b.currency.id); } else if (b.account != null) { sb.append(BlotterFilter.FROM_ACCOUNT_ID).append("=").append(b.account.id); } else { sb.append(" 1=1 "); } // categories & projects String categoriesWhere = createCategoriesWhere(b, categories); boolean hasCategories = isNotEmpty(categoriesWhere); String projectWhere = createProjectsWhere(b, projects); boolean hasProjects = isNotEmpty(projectWhere); if (hasCategories && hasProjects) { sb.append(" AND ((").append(categoriesWhere).append(") "); sb.append(b.expanded ? "OR" : "AND"); sb.append(" (").append(projectWhere).append("))"); } else if (hasCategories) { sb.append(" AND (").append(categoriesWhere).append(")"); } else if (hasProjects) { sb.append(" AND (").append(projectWhere).append(")"); } // start date if (b.startDate > 0) { sb.append(" AND ").append(BlotterFilter.DATETIME).append(">=").append(b.startDate); } // end date if (b.endDate > 0) { sb.append(" AND ").append(BlotterFilter.DATETIME).append("<=").append(b.endDate); } if (!b.includeCredit) { sb.append(" AND from_amount<0"); } return sb.toString(); } private static String createCategoriesWhere(Budget b, LongSparseArray<Category> categories) { long[] ids = MyEntity.splitIds(b.categories); if (ids != null) { StringBuilder sb = new StringBuilder(); boolean f = false; for (long id : ids) { Category c = categories.get(id); if (c != null) { if (f) { sb.append(" OR "); } if (b.includeSubcategories) { sb.append("(").append(BlotterFilter.CATEGORY_LEFT).append(" BETWEEN ").append(c.left).append(" AND ").append(c.right).append(")"); } else { sb.append(BlotterFilter.CATEGORY_ID).append("=").append(c.id); } f = true; } } if (f) { return sb.toString(); } } return null; } private static String createProjectsWhere(Budget b, LongSparseArray<Project> projects) { long[] ids = MyEntity.splitIds(b.projects); if (ids != null) { StringBuilder sb = new StringBuilder(); boolean f = false; for (long id : ids) { Project p = projects.get(id); if (p != null) { if (f) { sb.append(" OR "); } sb.append(BlotterFilter.PROJECT_ID).append("=").append(p.id); f = true; } } if (f) { return sb.toString(); } } return null; } public Currency getBudgetCurrency() { return currency != null ? currency : (account != null ? account.currency : null); } }