From 31886789cc047347681e56d17e1139726bcb4065 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Fri, 8 Nov 2013 15:05:29 -0600 Subject: [PATCH 01/59] created budgets controller --- app/controllers/budgets_controller.rb | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 app/controllers/budgets_controller.rb diff --git a/app/controllers/budgets_controller.rb b/app/controllers/budgets_controller.rb new file mode 100644 index 0000000..5390114 --- /dev/null +++ b/app/controllers/budgets_controller.rb @@ -0,0 +1,2 @@ +class BudgetsController < ApplicationController +end From e89751bbaa736b08d4260d46eb0d1f511a8b8602 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Fri, 8 Nov 2013 15:06:05 -0600 Subject: [PATCH 02/59] created budgeted scope for categories --- app/models/category.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/category.rb b/app/models/category.rb index fc6134b..7f6b866 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1,8 +1,12 @@ class Category < ActiveRecord::Base + ## Budget period + # 1 Semanal + # 2 Mensual scope :active, -> { where(deleted:false) } scope :transaction_ids, ->(ids) { joins(:splits => :transaction).where(transactions: {id: ids}) } scope :transaction_totals, -> { joins(:splits => :transaction).merge(Transaction.total_amount) } scope :group_by_name, -> { select('categories.name', 'categories.id').group('categories.name', 'categories.id') } + scope :budgeted, -> { where("budget_limit is not null and budget_period is not null ") } has_many :splits end From 9e268eb7d1e8a8e05332dbc269f48177d4937ef8 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Fri, 8 Nov 2013 15:06:43 -0600 Subject: [PATCH 03/59] ignored database --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ac13607..ef2007a 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ config/database.yml config/config.yml +PocketMoneyDB.sql **/.DS_Store From 9cc502aa9f78062c87bdda3103189f6187b74803 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Fri, 8 Nov 2013 15:07:59 -0600 Subject: [PATCH 04/59] added link to budgets without correct url for now --- app/views/layouts/_navigation.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/layouts/_navigation.haml b/app/views/layouts/_navigation.haml index 2006527..83788d7 100644 --- a/app/views/layouts/_navigation.haml +++ b/app/views/layouts/_navigation.haml @@ -8,6 +8,7 @@ %ul.nav %li= link_to 'All transactions', transactions_path = render '/accounts/menu' + %li=link_to 'Budgets', root_path %li= link_to 'Import', import_index_path From df02d6d94f3343c07bd8699c30e9f241d656c6a3 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Fri, 8 Nov 2013 18:47:31 -0600 Subject: [PATCH 05/59] created view with real data but without filters --- app/assets/stylesheets/budgets.sass | 4 ++++ app/controllers/budgets_controller.rb | 3 +++ app/controllers/categories_controller.rb | 3 +++ app/helpers/budgets_helper.rb | 28 ++++++++++++++++++++++++ app/models/split.rb | 1 + app/models/transaction.rb | 1 - app/views/budgets/_actual_budgets.haml | 23 +++++++++++++++++++ app/views/budgets/budgets.haml | 5 +++++ app/views/layouts/_navigation.haml | 2 +- app/views/layouts/application.haml | 10 +++++---- app/views/transactions/_header.haml | 1 - config/routes.rb | 1 + db/schema.rb | 3 --- 13 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 app/assets/stylesheets/budgets.sass create mode 100644 app/controllers/categories_controller.rb create mode 100644 app/helpers/budgets_helper.rb create mode 100644 app/views/budgets/_actual_budgets.haml create mode 100644 app/views/budgets/budgets.haml diff --git a/app/assets/stylesheets/budgets.sass b/app/assets/stylesheets/budgets.sass new file mode 100644 index 0000000..c90b379 --- /dev/null +++ b/app/assets/stylesheets/budgets.sass @@ -0,0 +1,4 @@ +.budget + width: 700px + + diff --git a/app/controllers/budgets_controller.rb b/app/controllers/budgets_controller.rb index 5390114..bb9c714 100644 --- a/app/controllers/budgets_controller.rb +++ b/app/controllers/budgets_controller.rb @@ -1,2 +1,5 @@ class BudgetsController < ApplicationController + def budgets + @budgets = Category.budgeted + end end diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb new file mode 100644 index 0000000..d8161f9 --- /dev/null +++ b/app/controllers/categories_controller.rb @@ -0,0 +1,3 @@ +class CategoriesController < ApplicationController + +end diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb new file mode 100644 index 0000000..6cabb14 --- /dev/null +++ b/app/helpers/budgets_helper.rb @@ -0,0 +1,28 @@ +module BudgetsHelper + def status(budget) + total = total_category(budget) *-1 + if total > budget.budget_limit + "danger" + elsif total < budget.budget_limit + "success" + else + "warning" + end + end + + def total_category(budget) + total = Split.per_category(budget.id).sum(:amount) + total + end + + def budget_available(budget) + available = budget.budget_limit - total_category(budget)*-1 + available = 0 if available < 0 + available + end + + def budget_balance(budget) + available = budget.budget_limit - total_category(budget)*-1 + available + end +end diff --git a/app/models/split.rb b/app/models/split.rb index 0ff1ee7..e423c6d 100644 --- a/app/models/split.rb +++ b/app/models/split.rb @@ -4,4 +4,5 @@ class Split < ActiveRecord::Base belongs_to :category validates_associated :transaction, :category + scope :per_category, ->(id) {where(category_id: id)} end diff --git a/app/models/transaction.rb b/app/models/transaction.rb index ee2cc2b..2548981 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -17,7 +17,6 @@ class Transaction < ActiveRecord::Base scope :balance, -> { select('*').select('SUM(amount) OVER (PARTITION BY account_id ORDER BY date ASC) as balance') } scope :transaction_includes, -> { includes(:account,:splits => :category) } scope :full, -> { order_date.transaction_includes.active.balance } - scope :interval, ->(from, to) { where("transactions.date >= ? AND transactions.date <= ?", from, to) } scope :total_amount, -> { select('count(transactions.amount) as total_count', 'sum(transactions.amount) as total_amount') } diff --git a/app/views/budgets/_actual_budgets.haml b/app/views/budgets/_actual_budgets.haml new file mode 100644 index 0000000..b521f5f --- /dev/null +++ b/app/views/budgets/_actual_budgets.haml @@ -0,0 +1,23 @@ +%table.table-bordered + %thead + %tr + %th + %th Category + %th Budgeted + %th Available + %th Balance + %tbody.summary-header.progress + -@budgets.each do |budget| + %tr + %td + =total_category(budget) + %td.budget + =progress_bar status(budget), 100 do + %p + =budget.name + %td + =budget.budget_limit + %td + =budget_available(budget) + %td + =budget_balance(budget) diff --git a/app/views/budgets/budgets.haml b/app/views/budgets/budgets.haml new file mode 100644 index 0000000..e4289c5 --- /dev/null +++ b/app/views/budgets/budgets.haml @@ -0,0 +1,5 @@ +.content + %h1 Budgets + + = render partial: 'actual_budgets' + diff --git a/app/views/layouts/_navigation.haml b/app/views/layouts/_navigation.haml index 83788d7..2d17d5c 100644 --- a/app/views/layouts/_navigation.haml +++ b/app/views/layouts/_navigation.haml @@ -8,7 +8,7 @@ %ul.nav %li= link_to 'All transactions', transactions_path = render '/accounts/menu' - %li=link_to 'Budgets', root_path + %li=link_to 'Budgets', budgets_path %li= link_to 'Import', import_index_path diff --git a/app/views/layouts/application.haml b/app/views/layouts/application.haml index 3731878..4cf81e4 100644 --- a/app/views/layouts/application.haml +++ b/app/views/layouts/application.haml @@ -1,13 +1,15 @@ !!! %html %head - %meta{:charset => "utf-8"} - %meta{:name => "viewport", :content => "width=device-width, initial-scale=1, maximum-scale=1"} + %meta{charset: "utf-8"} + %meta{name: "viewport", :content => "width=device-width, initial-scale=1, maximum-scale=1"} %title= content_for?(:title) ? yield(:title) : "Bernard" - %meta{:content => "", :name => "description"} - %meta{:content => "", :name => "author"} + %meta{content: "", name: "description"} + %meta{content: "", name: "author"} = stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true = javascript_include_tag "application", "data-turbolinks-track" => true + %link{href: "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/themes/ui-lightness/jquery-ui.css", :rel => "stylesheet", :type => "text/css"} + %script{src: "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/jquery-ui.min.js"} = csrf_meta_tags = yield(:head) %body diff --git a/app/views/transactions/_header.haml b/app/views/transactions/_header.haml index 29d2c7d..6c7f05c 100644 --- a/app/views/transactions/_header.haml +++ b/app/views/transactions/_header.haml @@ -6,7 +6,6 @@ %p =link_to "Widthdrawals", params.merge(pm_type: 0) = money @filter.widthdrawals_amount - = progress_bar 'success', @filter.deposits_percentage do %p =link_to "Deposit", params.merge(pm_type: 1) diff --git a/config/routes.rb b/config/routes.rb index 51066a7..00c98fa 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,6 +8,7 @@ resources :import do post 'import_csv', on: :collection end + get 'budgets/' => 'budgets#budgets' # The priority is based upon order of creation: first created -> highest priority. # See how all your routes lay out with "rake routes". diff --git a/db/schema.rb b/db/schema.rb index af83078..43ddc34 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -13,9 +13,6 @@ ActiveRecord::Schema.define(version: 20130718222102) do - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" - create_table "accounts", force: true do |t| t.boolean "deleted" t.datetime "updated_at" From 1a286793e08707335ccf193b83d112d7fca7a6e7 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 10:26:18 -0600 Subject: [PATCH 06/59] added filter to splits active --- app/models/category.rb | 2 +- app/models/split.rb | 7 ++++++- app/views/budgets/budgets.haml | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/models/category.rb b/app/models/category.rb index 7f6b866..688ae4e 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -6,7 +6,7 @@ class Category < ActiveRecord::Base scope :transaction_ids, ->(ids) { joins(:splits => :transaction).where(transactions: {id: ids}) } scope :transaction_totals, -> { joins(:splits => :transaction).merge(Transaction.total_amount) } scope :group_by_name, -> { select('categories.name', 'categories.id').group('categories.name', 'categories.id') } - scope :budgeted, -> { where("budget_limit is not null and budget_period is not null ") } + scope :budgeted, -> { active.where("budget_limit is not null and budget_period is not null ") } has_many :splits end diff --git a/app/models/split.rb b/app/models/split.rb index e423c6d..0d4c15d 100644 --- a/app/models/split.rb +++ b/app/models/split.rb @@ -4,5 +4,10 @@ class Split < ActiveRecord::Base belongs_to :category validates_associated :transaction, :category - scope :per_category, ->(id) {where(category_id: id)} + scope :active, -> {Split.where({id: transaction_active_ids})} + scope :per_category, ->(id) {active.where(category_id: id)} + + def self.transaction_active_ids + ids = Transaction.active.map(&:id) + end end diff --git a/app/views/budgets/budgets.haml b/app/views/budgets/budgets.haml index e4289c5..ceb8cd0 100644 --- a/app/views/budgets/budgets.haml +++ b/app/views/budgets/budgets.haml @@ -1,5 +1,5 @@ .content %h1 Budgets - + = render partial: 'actual_budgets' From 51f05829b7684eeafe15b554822a8e1304d0cbba Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 10:28:04 -0600 Subject: [PATCH 07/59] deleted unnecesary variable --- app/models/split.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/split.rb b/app/models/split.rb index 0d4c15d..534f876 100644 --- a/app/models/split.rb +++ b/app/models/split.rb @@ -8,6 +8,6 @@ class Split < ActiveRecord::Base scope :per_category, ->(id) {active.where(category_id: id)} def self.transaction_active_ids - ids = Transaction.active.map(&:id) + Transaction.active.map(&:id) end end From 7cee04add959f25f1622121e72f5e61229ff4f22 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 11:43:23 -0600 Subject: [PATCH 08/59] moved class interval to a file into lib directory --- app/models/transaction.rb | 47 +-------------------------------------- lib/interval.rb | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 46 deletions(-) create mode 100644 lib/interval.rb diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 2548981..7a833a7 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -43,6 +43,7 @@ def self.filter(conditions) end class Filter + require 'interval' def initialize(conditions) @conditions = conditions @@ -173,52 +174,6 @@ def group_by @conditions[:group_by] || 'date' end - class Interval - attr_accessor :from, :to, :kind - - def initialize(kind, date = nil) - @kind = kind - @date = date - end - - def from - date.send("beginning_of_#{kind}") - end - - def to - date.send("end_of_#{kind}") - end - - def date - @date || Date.today - end - - def to_hash - { kind: kind, from: from_string, to: to_string } - end - - def from_string - from.strftime('%Y%m%d') - end - - def to_string - to.strftime('%Y%m%d') - end - - def name - kind.to_s.humanize - end - - def previous - Interval.new(kind, from - 1.send(kind)) - end - - def next - Interval.new(kind, from + 1.send(kind)) - end - - end - end end diff --git a/lib/interval.rb b/lib/interval.rb new file mode 100644 index 0000000..50a684f --- /dev/null +++ b/lib/interval.rb @@ -0,0 +1,46 @@ +class Interval + attr_accessor :from, :to, :kind + + def initialize(kind, date = nil) + @kind = kind + @date = date + end + + def from + date.send("beginning_of_#{kind}") + end + + def to + date.send("end_of_#{kind}") + end + + def date + @date || Date.today + end + + def to_hash + { kind: kind, from: from_string, to: to_string } + end + + def from_string + from.strftime('%Y%m%d') + end + + def to_string + to.strftime('%Y%m%d') + end + + def name + kind.to_s.humanize + end + + def previous + Interval.new(kind, from - 1.send(kind)) + end + + def next + Interval.new(kind, from + 1.send(kind)) + end + +end + From 99ba96e11fecf34db5b12a27ab5643bf6755cdb3 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 12:05:34 -0600 Subject: [PATCH 09/59] moved filter class to lib folder --- app/models/transaction.rb | 235 +++++++++++++++++++------------------- lib/filter.rb | 134 ++++++++++++++++++++++ 2 files changed, 252 insertions(+), 117 deletions(-) create mode 100644 lib/filter.rb diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 7a833a7..665c08e 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -1,4 +1,5 @@ class Transaction < ActiveRecord::Base + require 'filter' # pm_types # 0 Withdrawal # 1 Deposit @@ -42,138 +43,138 @@ def self.filter(conditions) Filter.new(conditions) end - class Filter - require 'interval' - - def initialize(conditions) - @conditions = conditions - @category_ids = [] - end - - def accounts - @accounts ||= Account.all - end - - def transactions - @transactions ||= transaction_query.full - end - - def grouped_transactions - case group_by - when 'date' - transactions.group_by {|t| t.date.to_s(:short_date) } - when 'type' - transactions.group_by {|t| t.type_name } - when 'account' - transactions.group_by {|t| t.account.name } - when 'category' - transactions.group_by {|t| t.category_name.to_s } - end - end - - def categories - @categories ||= Category.transaction_totals.group_by_name.transaction_ids(transaction_ids) - end - - def intervals - [ Interval.new(:week), Interval.new(:month), Interval.new(:year) ] - end - - def current_interval - @conditions[:from] ? Interval.new(kind,from) : intervals.select {|i| i.kind.to_s == kind }.first - end - - def from - @conditions[:from] ? Date.parse(@conditions[:from]) : current_interval.from - end - - def to - @conditions[:to] ? Date.parse(@conditions[:to]) : current_interval.to - end - - def kind - @conditions[:kind] || 'month' - end - - def previous - @previous ||= current_interval.previous - end - - def next - @next ||= current_interval.next - end - - def categories_total - categories.to_a.sum(&:total_amount) - end - - def types_total - @types_total = widthdrawals_amount + deposits_amount + transfers_amount - end - - def widthdrawals_amount - types_query[0].to_f.abs - end + #class Filter + #require 'interval' + + #def initialize(conditions) + #@conditions = conditions + #@category_ids = [] + #end + + #def accounts + #@accounts ||= Account.all + #end + + #def transactions + #@transactions ||= transaction_query.full + #end + + #def grouped_transactions + #case group_by + #when 'date' + #transactions.group_by {|t| t.date.to_s(:short_date) } + #when 'type' + #transactions.group_by {|t| t.type_name } + #when 'account' + #transactions.group_by {|t| t.account.name } + #when 'category' + #transactions.group_by {|t| t.category_name.to_s } + #end + #end + + #def categories + #@categories ||= Category.transaction_totals.group_by_name.transaction_ids(transaction_ids) + #end + + #def intervals + #[ Interval.new(:week), Interval.new(:month), Interval.new(:year) ] + #end + + #def current_interval + #@conditions[:from] ? Interval.new(kind,from) : intervals.select {|i| i.kind.to_s == kind }.first + #end + + #def from + #@conditions[:from] ? Date.parse(@conditions[:from]) : current_interval.from + #end + + #def to + #@conditions[:to] ? Date.parse(@conditions[:to]) : current_interval.to + #end + + #def kind + #@conditions[:kind] || 'month' + #end + + #def previous + #@previous ||= current_interval.previous + #end + + #def next + #@next ||= current_interval.next + #end + + #def categories_total + #categories.to_a.sum(&:total_amount) + #end + + #def types_total + #@types_total = widthdrawals_amount + deposits_amount + transfers_amount + #end + + #def widthdrawals_amount + #types_query[0].to_f.abs + #end - def deposits_amount - types_query[1].to_f.abs - end + #def deposits_amount + #types_query[1].to_f.abs + #end - def transfers_amount - types_query[2].to_f.abs - end + #def transfers_amount + #types_query[2].to_f.abs + #end - def widthdrawals_percentage - (widthdrawals_amount/types_total * 100) - end + #def widthdrawals_percentage + #(widthdrawals_amount/types_total * 100) + #end - def deposits_percentage - (deposits_amount / types_total * 100) - end + #def deposits_percentage + #(deposits_amount / types_total * 100) + #end - def transfers_percentage - (transfers_amount / types_total * 100) - end + #def transfers_percentage + #(transfers_amount / types_total * 100) + #end - def transaction_ids - @transaction_ids ||= transactions.map &:id - end + #def transaction_ids + #@transaction_ids ||= transactions.map &:id + #end - private + #private - def types_query - @types_query ||= Transaction.where(id: transaction_ids ).group('transactions.pm_type').sum(:amount) - end + #def types_query + #@types_query ||= Transaction.where(id: transaction_ids ).group('transactions.pm_type').sum(:amount) + #end - def transaction_interval - Transaction.interval(from, to) - end + #def transaction_interval + #Transaction.interval(from, to) + #end - def transaction_query - t = transaction_interval - t = t.where(pm_type: pm_type) if pm_type - t = t.where(account_id: account_id) if account_id - t = t.where('categories.id = ?', category_id) if category_id - t - end + #def transaction_query + #t = transaction_interval + #t = t.where(pm_type: pm_type) if pm_type + #t = t.where(account_id: account_id) if account_id + #t = t.where('categories.id = ?', category_id) if category_id + #t + #end - def account_id - @conditions[:account_id] - end + #def account_id + #@conditions[:account_id] + #end - def category_id - @conditions[:category_id] - end + #def category_id + #@conditions[:category_id] + #end - def pm_type - @conditions[:pm_type] - end + #def pm_type + #@conditions[:pm_type] + #end - def group_by - @conditions[:group_by] || 'date' - end + #def group_by + #@conditions[:group_by] || 'date' + #end - end + #end end diff --git a/lib/filter.rb b/lib/filter.rb new file mode 100644 index 0000000..3097ca1 --- /dev/null +++ b/lib/filter.rb @@ -0,0 +1,134 @@ +class Filter + require 'interval' + + def initialize(conditions) + @conditions = conditions + @category_ids = [] + end + + def accounts + @accounts ||= Account.all + end + + def transactions + @transactions ||= transaction_query.full + end + + def grouped_transactions + case group_by + when 'date' + transactions.group_by {|t| t.date.to_s(:short_date) } + when 'type' + transactions.group_by {|t| t.type_name } + when 'account' + transactions.group_by {|t| t.account.name } + when 'category' + transactions.group_by {|t| t.category_name.to_s } + end + end + + def categories + @categories ||= Category.transaction_totals.group_by_name.transaction_ids(transaction_ids) + end + + def intervals + [ Interval.new(:week), Interval.new(:month), Interval.new(:year) ] + end + + def current_interval + @conditions[:from] ? Interval.new(kind,from) : intervals.select {|i| i.kind.to_s == kind }.first + end + + def from + @conditions[:from] ? Date.parse(@conditions[:from]) : current_interval.from + end + + def to + @conditions[:to] ? Date.parse(@conditions[:to]) : current_interval.to + end + + def kind + @conditions[:kind] || 'month' + end + + def previous + @previous ||= current_interval.previous + end + + def next + @next ||= current_interval.next + end + + def categories_total + categories.to_a.sum(&:total_amount) + end + + def types_total + @types_total = widthdrawals_amount + deposits_amount + transfers_amount + end + + def widthdrawals_amount + types_query[0].to_f.abs + end + + def deposits_amount + types_query[1].to_f.abs + end + + def transfers_amount + types_query[2].to_f.abs + end + + def widthdrawals_percentage + (widthdrawals_amount/types_total * 100) + end + + def deposits_percentage + (deposits_amount / types_total * 100) + end + + def transfers_percentage + (transfers_amount / types_total * 100) + end + + def transaction_ids + @transaction_ids ||= transactions.map &:id + end + + + private + + def types_query + @types_query ||= Transaction.where(id: transaction_ids ).group('transactions.pm_type').sum(:amount) + end + + def transaction_interval + Transaction.interval(from, to) + end + + def transaction_query + t = transaction_interval + t = t.where(pm_type: pm_type) if pm_type + t = t.where(account_id: account_id) if account_id + t = t.where('categories.id = ?', category_id) if category_id + t + end + + def account_id + @conditions[:account_id] + end + + def category_id + @conditions[:category_id] + end + + def pm_type + @conditions[:pm_type] + end + + def group_by + @conditions[:group_by] || 'date' + end + +end + From 20128c2037e8a826d21a4549a1733061dab300d6 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 12:06:16 -0600 Subject: [PATCH 10/59] required filter class in split model --- app/models/split.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/split.rb b/app/models/split.rb index 534f876..f91fb7d 100644 --- a/app/models/split.rb +++ b/app/models/split.rb @@ -1,4 +1,5 @@ class Split < ActiveRecord::Base + require 'filter' belongs_to :transaction belongs_to :category @@ -10,4 +11,6 @@ class Split < ActiveRecord::Base def self.transaction_active_ids Transaction.active.map(&:id) end + + Interval.new(:month) end From 1f1a4ae78e788810ceba87d17e29938adbd84055 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 12:07:19 -0600 Subject: [PATCH 11/59] deleted code comented --- app/models/transaction.rb | 134 -------------------------------------- 1 file changed, 134 deletions(-) diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 665c08e..30b8125 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -43,138 +43,4 @@ def self.filter(conditions) Filter.new(conditions) end - #class Filter - #require 'interval' - - #def initialize(conditions) - #@conditions = conditions - #@category_ids = [] - #end - - #def accounts - #@accounts ||= Account.all - #end - - #def transactions - #@transactions ||= transaction_query.full - #end - - #def grouped_transactions - #case group_by - #when 'date' - #transactions.group_by {|t| t.date.to_s(:short_date) } - #when 'type' - #transactions.group_by {|t| t.type_name } - #when 'account' - #transactions.group_by {|t| t.account.name } - #when 'category' - #transactions.group_by {|t| t.category_name.to_s } - #end - #end - - #def categories - #@categories ||= Category.transaction_totals.group_by_name.transaction_ids(transaction_ids) - #end - - #def intervals - #[ Interval.new(:week), Interval.new(:month), Interval.new(:year) ] - #end - - #def current_interval - #@conditions[:from] ? Interval.new(kind,from) : intervals.select {|i| i.kind.to_s == kind }.first - #end - - #def from - #@conditions[:from] ? Date.parse(@conditions[:from]) : current_interval.from - #end - - #def to - #@conditions[:to] ? Date.parse(@conditions[:to]) : current_interval.to - #end - - #def kind - #@conditions[:kind] || 'month' - #end - - #def previous - #@previous ||= current_interval.previous - #end - - #def next - #@next ||= current_interval.next - #end - - #def categories_total - #categories.to_a.sum(&:total_amount) - #end - - #def types_total - #@types_total = widthdrawals_amount + deposits_amount + transfers_amount - #end - - #def widthdrawals_amount - #types_query[0].to_f.abs - #end - - #def deposits_amount - #types_query[1].to_f.abs - #end - - #def transfers_amount - #types_query[2].to_f.abs - #end - - #def widthdrawals_percentage - #(widthdrawals_amount/types_total * 100) - #end - - #def deposits_percentage - #(deposits_amount / types_total * 100) - #end - - #def transfers_percentage - #(transfers_amount / types_total * 100) - #end - - #def transaction_ids - #@transaction_ids ||= transactions.map &:id - #end - - - #private - - #def types_query - #@types_query ||= Transaction.where(id: transaction_ids ).group('transactions.pm_type').sum(:amount) - #end - - #def transaction_interval - #Transaction.interval(from, to) - #end - - #def transaction_query - #t = transaction_interval - #t = t.where(pm_type: pm_type) if pm_type - #t = t.where(account_id: account_id) if account_id - #t = t.where('categories.id = ?', category_id) if category_id - #t - #end - - #def account_id - #@conditions[:account_id] - #end - - #def category_id - #@conditions[:category_id] - #end - - #def pm_type - #@conditions[:pm_type] - #end - - #def group_by - #@conditions[:group_by] || 'date' - #end - - #end - end From 396876417f9ea507c7a95138401b081ddd6607f3 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 12:37:37 -0600 Subject: [PATCH 12/59] added filters to budgets view --- app/views/budgets/_filters.haml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 app/views/budgets/_filters.haml diff --git a/app/views/budgets/_filters.haml b/app/views/budgets/_filters.haml new file mode 100644 index 0000000..57a887a --- /dev/null +++ b/app/views/budgets/_filters.haml @@ -0,0 +1,22 @@ +%ul.nav.nav-list.left.filters + %li + %li.icon-backward + = link_to url_for params.merge(@filter.previous.to_hash) do + Previous + = @filter.previous.name + %li + %li.icon-forward + = link_to url_for params.merge(@filter.next.to_hash) do + Next + = @filter.next.name + + %li.divider + + - @filter.interval_budget.each do |interval| + = content_tag :li, :class=> params[:kind] == interval.kind.to_s ? 'active' : '' do + = link_to url_for params.merge(interval.to_hash) do + This + = interval.name + + %li.divider + From 3535b0bc0167a92bb4ac422ac442e609c8128f6a Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 12:38:12 -0600 Subject: [PATCH 13/59] added intervals to budgets, only per month --- lib/filter.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/filter.rb b/lib/filter.rb index 3097ca1..c4c4eeb 100644 --- a/lib/filter.rb +++ b/lib/filter.rb @@ -14,6 +14,10 @@ def transactions @transactions ||= transaction_query.full end + def budgets + @budgets = Category.budgeted + end + def grouped_transactions case group_by when 'date' @@ -35,6 +39,10 @@ def intervals [ Interval.new(:week), Interval.new(:month), Interval.new(:year) ] end + def interval_budget + [ Interval.new(:month) ] + end + def current_interval @conditions[:from] ? Interval.new(kind,from) : intervals.select {|i| i.kind.to_s == kind }.first end From 7711d67669e14ed638f755bc865a6380a6bd45a5 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 12:40:28 -0600 Subject: [PATCH 14/59] change view of budgets --- app/controllers/budgets_controller.rb | 2 +- app/models/split.rb | 7 +++++-- app/views/budgets/_actual_budgets.haml | 2 +- app/views/budgets/budgets.haml | 6 ++++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/controllers/budgets_controller.rb b/app/controllers/budgets_controller.rb index bb9c714..0e9ab97 100644 --- a/app/controllers/budgets_controller.rb +++ b/app/controllers/budgets_controller.rb @@ -1,5 +1,5 @@ class BudgetsController < ApplicationController def budgets - @budgets = Category.budgeted + @filter = Split.filter(params) end end diff --git a/app/models/split.rb b/app/models/split.rb index f91fb7d..c61acd7 100644 --- a/app/models/split.rb +++ b/app/models/split.rb @@ -11,6 +11,9 @@ class Split < ActiveRecord::Base def self.transaction_active_ids Transaction.active.map(&:id) end - - Interval.new(:month) + + def self.filter(conditions) + Filter.new(conditions) + end + end diff --git a/app/views/budgets/_actual_budgets.haml b/app/views/budgets/_actual_budgets.haml index b521f5f..327b8d5 100644 --- a/app/views/budgets/_actual_budgets.haml +++ b/app/views/budgets/_actual_budgets.haml @@ -7,7 +7,7 @@ %th Available %th Balance %tbody.summary-header.progress - -@budgets.each do |budget| + -@filter.budgets.each do |budget| %tr %td =total_category(budget) diff --git a/app/views/budgets/budgets.haml b/app/views/budgets/budgets.haml index ceb8cd0..8a5e392 100644 --- a/app/views/budgets/budgets.haml +++ b/app/views/budgets/budgets.haml @@ -1,5 +1,7 @@ .content %h1 Budgets - - = render partial: 'actual_budgets' + .row + .span3 + =render partial: 'filters' + = render partial: 'actual_budgets' From fe184c64349743ea1ddd943a5f3e23c87efaa4e1 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 13:12:20 -0600 Subject: [PATCH 15/59] added name of the month in the view --- app/views/budgets/_actual_budgets.haml | 2 ++ app/views/budgets/budgets.haml | 1 + 2 files changed, 3 insertions(+) diff --git a/app/views/budgets/_actual_budgets.haml b/app/views/budgets/_actual_budgets.haml index 327b8d5..f8be410 100644 --- a/app/views/budgets/_actual_budgets.haml +++ b/app/views/budgets/_actual_budgets.haml @@ -1,5 +1,7 @@ %table.table-bordered %thead + %h3 + =@filter.from.strftime("%B") %tr %th %th Category diff --git a/app/views/budgets/budgets.haml b/app/views/budgets/budgets.haml index 8a5e392..afeb6bc 100644 --- a/app/views/budgets/budgets.haml +++ b/app/views/budgets/budgets.haml @@ -1,5 +1,6 @@ .content %h1 Budgets + .row .span3 =render partial: 'filters' From e8f004be0adf53b0e9dfa6ea53d78029d4253101 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 15:09:01 -0600 Subject: [PATCH 16/59] added task to get category_id in transactions --- lib/categories.rb | 9 +++++++++ lib/filter.rb | 6 ++++++ lib/pocket_money.rb | 1 + lib/tasks/pm.rake | 6 ++++++ 4 files changed, 22 insertions(+) create mode 100644 lib/categories.rb diff --git a/lib/categories.rb b/lib/categories.rb new file mode 100644 index 0000000..8017e83 --- /dev/null +++ b/lib/categories.rb @@ -0,0 +1,9 @@ +class AddCategories + def self.categories + transactions = Transaction.all + transactions.each do |t| + t.category_id = t.splits.first.category_id + t.save + end + end +end diff --git a/lib/filter.rb b/lib/filter.rb index c4c4eeb..bfa9d46 100644 --- a/lib/filter.rb +++ b/lib/filter.rb @@ -14,6 +14,12 @@ def transactions @transactions ||= transaction_query.full end + def budgets_sum(id) + b = Transaction.interval(from, to) + b = b.per_category(id) + b + end + def budgets @budgets = Category.budgeted end diff --git a/lib/pocket_money.rb b/lib/pocket_money.rb index cb8bbf9..523347b 100644 --- a/lib/pocket_money.rb +++ b/lib/pocket_money.rb @@ -1,3 +1,4 @@ require 'pocket_money/base.rb' require 'pocket_money/tables' require 'pocket_money/import' +require 'categories' diff --git a/lib/tasks/pm.rake b/lib/tasks/pm.rake index a0c6a19..cfa891f 100644 --- a/lib/tasks/pm.rake +++ b/lib/tasks/pm.rake @@ -2,5 +2,11 @@ namespace :pm do desc 'import pocket money database' task :import => :environment do PocketMoney.import + AddCategories.categories end + + #desc 'add category_id to transactions' + #task :categories => :environment do + #AddCategories.categories + #end end From ec80a03c8564a72a062cfb291d72f4726b92425c Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 15:09:35 -0600 Subject: [PATCH 17/59] refactored code in order to the change in transactions table --- app/helpers/budgets_helper.rb | 2 +- app/models/split.rb | 2 ++ app/models/transaction.rb | 9 +++++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index 6cabb14..0d06112 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -11,7 +11,7 @@ def status(budget) end def total_category(budget) - total = Split.per_category(budget.id).sum(:amount) + total = @filter.budgets_sum(budget.id) total end diff --git a/app/models/split.rb b/app/models/split.rb index c61acd7..6c5e7fe 100644 --- a/app/models/split.rb +++ b/app/models/split.rb @@ -5,8 +5,10 @@ class Split < ActiveRecord::Base belongs_to :category validates_associated :transaction, :category + scope :active, -> {Split.where({id: transaction_active_ids})} scope :per_category, ->(id) {active.where(category_id: id)} + scope :interval, ->(from, to) { where("splits.date >= ? AND splits.date <= ?", from, to) } def self.transaction_active_ids Transaction.active.map(&:id) diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 30b8125..1aa99ee 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -20,10 +20,11 @@ class Transaction < ActiveRecord::Base scope :full, -> { order_date.transaction_includes.active.balance } scope :interval, ->(from, to) { where("transactions.date >= ? AND transactions.date <= ?", from, to) } scope :total_amount, -> { select('count(transactions.amount) as total_count', 'sum(transactions.amount) as total_amount') } - - belongs_to :account - has_many :splits - + scope :per_category, ->(id) {active.where(category_id: id).sum(:amount)} + + belongs_to :account + has_many :splits + def split? @split ||= splits.size > 1 From 65a853c11525db32975efb33256f9ed72c868219 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 15:23:29 -0600 Subject: [PATCH 18/59] removed unnecesary code --- app/models/split.rb | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/app/models/split.rb b/app/models/split.rb index 6c5e7fe..cc4993e 100644 --- a/app/models/split.rb +++ b/app/models/split.rb @@ -1,21 +1,9 @@ class Split < ActiveRecord::Base - require 'filter' belongs_to :transaction belongs_to :category validates_associated :transaction, :category - scope :active, -> {Split.where({id: transaction_active_ids})} - scope :per_category, ->(id) {active.where(category_id: id)} - scope :interval, ->(from, to) { where("splits.date >= ? AND splits.date <= ?", from, to) } - - def self.transaction_active_ids - Transaction.active.map(&:id) - end - - def self.filter(conditions) - Filter.new(conditions) - end end From 5883c8778e908ca90ddfc8bfba14aa0112f736ec Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 15:24:14 -0600 Subject: [PATCH 19/59] added spent at table --- app/views/budgets/_actual_budgets.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/budgets/_actual_budgets.haml b/app/views/budgets/_actual_budgets.haml index f8be410..151da8b 100644 --- a/app/views/budgets/_actual_budgets.haml +++ b/app/views/budgets/_actual_budgets.haml @@ -3,7 +3,7 @@ %h3 =@filter.from.strftime("%B") %tr - %th + %th Spent %th Category %th Budgeted %th Available From 2d79a6195a122e6019a1e72d218795b5003b7b50 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 15:26:07 -0600 Subject: [PATCH 20/59] changed instance of filter --- app/controllers/budgets_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/budgets_controller.rb b/app/controllers/budgets_controller.rb index 0e9ab97..102e062 100644 --- a/app/controllers/budgets_controller.rb +++ b/app/controllers/budgets_controller.rb @@ -1,5 +1,5 @@ class BudgetsController < ApplicationController def budgets - @filter = Split.filter(params) + @filter = Transaction.filter(params) end end From 2aefad4a55db50af155564b8b9d14045e9c70f6b Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Mon, 11 Nov 2013 15:34:04 -0600 Subject: [PATCH 21/59] removed commented code --- lib/tasks/pm.rake | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/tasks/pm.rake b/lib/tasks/pm.rake index cfa891f..2600712 100644 --- a/lib/tasks/pm.rake +++ b/lib/tasks/pm.rake @@ -5,8 +5,4 @@ namespace :pm do AddCategories.categories end - #desc 'add category_id to transactions' - #task :categories => :environment do - #AddCategories.categories - #end end From 280227d69e8c77eea04ded06420371b73541d37a Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 12 Nov 2013 13:36:35 -0600 Subject: [PATCH 22/59] added period to budgets --- app/helpers/budgets_helper.rb | 81 +++++++++++++++++++++++--- app/models/category.rb | 3 + app/views/budgets/_actual_budgets.haml | 4 +- app/views/budgets/_filters.haml | 2 +- 4 files changed, 79 insertions(+), 11 deletions(-) diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index 0d06112..6d64fce 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -1,28 +1,93 @@ module BudgetsHelper def status(budget) total = total_category(budget) *-1 - if total > budget.budget_limit + if total > budget_budgeted(budget) "danger" - elsif total < budget.budget_limit + elsif total < budget_budgeted(budget) "success" else "warning" end end - + def total_category(budget) total = @filter.budgets_sum(budget.id) - total + total.round(2) end def budget_available(budget) - available = budget.budget_limit - total_category(budget)*-1 + available = budget_budgeted(budget) - total_category(budget)*-1 available = 0 if available < 0 - available + available.round(2) end def budget_balance(budget) - available = budget.budget_limit - total_category(budget)*-1 - available + balance = budget_budgeted(budget) - total_category(budget)*-1 + balance.round(2) + end + + def budget_budgeted(budget) + case @filter.kind + when "week" + budget.budget_period == 1 ? budget.budget_limit : solve_budgeted_per_week(budget) + when "month" + budget.budget_period == 2 ? budget.budget_limit : solve_budgeted_per_month(budget) + when "year" + budget.budget_period == 4 ? budget.budget_limit : solve_budgeted_per_year(budget) + end + end + + def solve_budgeted_per_week(budget) + case budget.budget_period + when 0 + (budget.budget_limit * 7).round(2) + when 2 + weeks = Time::days_in_month(Time.now.month, Time.now.year).to_f / 7 + (budget.budget_limit / weeks).round(2) + when 3 + # to do + when 4 + (budget.budgeted_limit / 52).round(2) + end + end + + def solve_budgeted_per_month(budget) + case budget.budget_period + when 0 + days = Time::days_in_month(Time.now.month, Time.now.year) + (budget.budget_limit * days).round(2) + when 1 + weeks = Time::days_in_month(Time.now.month, Time.now.year).to_f / 7 + (budget.budget_limit * weeks).round(2) + when 3 + # to do + when 4 + (budget.budget_limit / 12).round(2) + end + end + + def solve_budgeted_per_year(budget) + case budget.budget_period + when 0 + (budget.budget_limit * 365).round(2) + when 1 + (budget.budget_limit * 52).round(2) + when 2 + (budget.budget_limit * 12).round(2) + when 3 + # to do + end + end + + def set_period + case @filter.kind + when "month" + @filter.from.strftime("%B") + when "week" + "#{@filter.from.strftime('%d %B %Y')} - #{@filter.to.strftime('%d %B %Y')}" + when "year" + @filter.from.year + end end + end diff --git a/app/models/category.rb b/app/models/category.rb index 688ae4e..f899115 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1,7 +1,10 @@ class Category < ActiveRecord::Base ## Budget period + # 0 diario # 1 Semanal # 2 Mensual + # 3 Cuatrimestral + # 4 Anual scope :active, -> { where(deleted:false) } scope :transaction_ids, ->(ids) { joins(:splits => :transaction).where(transactions: {id: ids}) } scope :transaction_totals, -> { joins(:splits => :transaction).merge(Transaction.total_amount) } diff --git a/app/views/budgets/_actual_budgets.haml b/app/views/budgets/_actual_budgets.haml index 151da8b..156d92e 100644 --- a/app/views/budgets/_actual_budgets.haml +++ b/app/views/budgets/_actual_budgets.haml @@ -1,7 +1,7 @@ %table.table-bordered %thead %h3 - =@filter.from.strftime("%B") + =set_period %tr %th Spent %th Category @@ -18,7 +18,7 @@ %p =budget.name %td - =budget.budget_limit + =budget_budgeted(budget) %td =budget_available(budget) %td diff --git a/app/views/budgets/_filters.haml b/app/views/budgets/_filters.haml index 57a887a..b1f5233 100644 --- a/app/views/budgets/_filters.haml +++ b/app/views/budgets/_filters.haml @@ -12,7 +12,7 @@ %li.divider - - @filter.interval_budget.each do |interval| + - @filter.intervals.each do |interval| = content_tag :li, :class=> params[:kind] == interval.kind.to_s ? 'active' : '' do = link_to url_for params.merge(interval.to_hash) do This From f05188c1c9fd0f8294665fc6510968c37800ad11 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 12 Nov 2013 15:59:51 -0600 Subject: [PATCH 23/59] removed unnecesary code --- lib/filter.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/filter.rb b/lib/filter.rb index bfa9d46..7ad1361 100644 --- a/lib/filter.rb +++ b/lib/filter.rb @@ -45,10 +45,6 @@ def intervals [ Interval.new(:week), Interval.new(:month), Interval.new(:year) ] end - def interval_budget - [ Interval.new(:month) ] - end - def current_interval @conditions[:from] ? Interval.new(kind,from) : intervals.select {|i| i.kind.to_s == kind }.first end From d09b29d9e48ce07caef180fb307a562c700e818b Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Wed, 13 Nov 2013 16:46:02 -0600 Subject: [PATCH 24/59] fixed problem with dates --- app/helpers/budgets_helper.rb | 51 ++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index 6d64fce..33ef25a 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -1,4 +1,5 @@ module BudgetsHelper + def status(budget) total = total_category(budget) *-1 if total > budget_budgeted(budget) @@ -12,18 +13,36 @@ def status(budget) def total_category(budget) total = @filter.budgets_sum(budget.id) - total.round(2) + total.round(0) end def budget_available(budget) available = budget_budgeted(budget) - total_category(budget)*-1 available = 0 if available < 0 - available.round(2) + available.round(0) end def budget_balance(budget) balance = budget_budgeted(budget) - total_category(budget)*-1 - balance.round(2) + balance.round(0) + end + + def available_percentage(budget) + unless status(budget) == "danger" or status(budget) == "warning" + percentage = (budget_available(budget) * 100 / budget_budgeted(budget)) + percentage = 100 if percentage > 100 + percentage + else + 100 + end + end + + def spent_percentage(budget) + unless status(budget) == "danger" or status(budget) == "warning" + ((total_category(budget)*-1) * 100 / budget_budgeted(budget)) + else + 0 + end end def budget_budgeted(budget) @@ -40,40 +59,40 @@ def budget_budgeted(budget) def solve_budgeted_per_week(budget) case budget.budget_period when 0 - (budget.budget_limit * 7).round(2) + (budget.budget_limit * 7).round(0) when 2 - weeks = Time::days_in_month(Time.now.month, Time.now.year).to_f / 7 - (budget.budget_limit / weeks).round(2) + weeks = Time::days_in_month(@filter.from.month, @filter.from.year).to_f / 7 + (budget.budget_limit / weeks).round(0) when 3 # to do when 4 - (budget.budgeted_limit / 52).round(2) + (budget.budgeted_limit / 52.142857143).round(0) end end def solve_budgeted_per_month(budget) case budget.budget_period when 0 - days = Time::days_in_month(Time.now.month, Time.now.year) - (budget.budget_limit * days).round(2) + days = Time::days_in_month(@filter.from.month, @filter.from.year) + (budget.budget_limit * days).round(0) when 1 - weeks = Time::days_in_month(Time.now.month, Time.now.year).to_f / 7 - (budget.budget_limit * weeks).round(2) + weeks = Time::days_in_month(@filter.from.month, @filter.from.year).to_f / 7 + (budget.budget_limit * weeks).round(0) when 3 # to do when 4 - (budget.budget_limit / 12).round(2) + (budget.budget_limit / 12).round(0) end end def solve_budgeted_per_year(budget) case budget.budget_period when 0 - (budget.budget_limit * 365).round(2) + (budget.budget_limit * 365).round(0) when 1 - (budget.budget_limit * 52).round(2) + (budget.budget_limit * 52.142857143).round(0) when 2 - (budget.budget_limit * 12).round(2) + (budget.budget_limit * 12).round(0) when 3 # to do end @@ -82,7 +101,7 @@ def solve_budgeted_per_year(budget) def set_period case @filter.kind when "month" - @filter.from.strftime("%B") + @filter.from.strftime("%B %Y") when "week" "#{@filter.from.strftime('%d %B %Y')} - #{@filter.to.strftime('%d %B %Y')}" when "year" From f583f87d23a932075d5c60cc5e3a8fb027c8660b Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Wed, 13 Nov 2013 16:47:06 -0600 Subject: [PATCH 25/59] refacored code --- app/models/budget.rb | 2 ++ app/models/transaction.rb | 5 +++++ app/views/budgets/_actual_budgets.haml | 9 ++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 app/models/budget.rb diff --git a/app/models/budget.rb b/app/models/budget.rb new file mode 100644 index 0000000..3ecaf97 --- /dev/null +++ b/app/models/budget.rb @@ -0,0 +1,2 @@ +class Budget < ActiveRecord::Base +end diff --git a/app/models/transaction.rb b/app/models/transaction.rb index 1aa99ee..f75454e 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -1,5 +1,6 @@ class Transaction < ActiveRecord::Base require 'filter' + require 'budget' # pm_types # 0 Withdrawal # 1 Deposit @@ -43,5 +44,9 @@ def type_name def self.filter(conditions) Filter.new(conditions) end + + def self.budget(budget) + CategoryBudget.new(budget) + end end diff --git a/app/views/budgets/_actual_budgets.haml b/app/views/budgets/_actual_budgets.haml index 156d92e..be23d11 100644 --- a/app/views/budgets/_actual_budgets.haml +++ b/app/views/budgets/_actual_budgets.haml @@ -1,7 +1,11 @@ %table.table-bordered %thead %h3 + = link_to url_for params.merge(@filter.previous.to_hash) do + .icon-backward =set_period + = link_to url_for params.merge(@filter.next.to_hash) do + .icon-forward %tr %th Spent %th Category @@ -14,7 +18,10 @@ %td =total_category(budget) %td.budget - =progress_bar status(budget), 100 do + =progress_bar "warning", spent_percentage(budget) do + %p + Spent + =progress_bar status(budget), available_percentage(budget) do %p =budget.name %td From 431c977fe7d91d942f375199b8354ae0570f2ce7 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Wed, 13 Nov 2013 16:47:43 -0600 Subject: [PATCH 26/59] changed interval to las day of month --- lib/filter.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/filter.rb b/lib/filter.rb index 7ad1361..cd24682 100644 --- a/lib/filter.rb +++ b/lib/filter.rb @@ -15,7 +15,7 @@ def transactions end def budgets_sum(id) - b = Transaction.interval(from, to) + b = Transaction.interval(from, to + 1.day) b = b.per_category(id) b end @@ -23,7 +23,7 @@ def budgets_sum(id) def budgets @budgets = Category.budgeted end - + def grouped_transactions case group_by when 'date' From 40e67783f20e85f5947df171db8fd8f198e91203 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 14 Nov 2013 16:04:51 -0600 Subject: [PATCH 27/59] added income and expenses budgets, also total values of budget --- app/helpers/budgets_helper.rb | 58 +++++++++++++++++++++-- app/models/category.rb | 3 ++ app/models/transaction.rb | 1 + app/views/budgets/_actual_budgets.haml | 64 ++++++++++++++++---------- app/views/budgets/_table_expenses.haml | 18 ++++++++ app/views/budgets/_table_incomes.haml | 19 ++++++++ lib/filter.rb | 8 +++- 7 files changed, 139 insertions(+), 32 deletions(-) create mode 100644 app/views/budgets/_table_expenses.haml create mode 100644 app/views/budgets/_table_incomes.haml diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index 33ef25a..a44d0d6 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -1,7 +1,7 @@ module BudgetsHelper def status(budget) - total = total_category(budget) *-1 + total = total_category(budget) if total > budget_budgeted(budget) "danger" elsif total < budget_budgeted(budget) @@ -12,18 +12,18 @@ def status(budget) end def total_category(budget) - total = @filter.budgets_sum(budget.id) + total = @filter.budgets_sum(budget.id) *-1 total.round(0) end def budget_available(budget) - available = budget_budgeted(budget) - total_category(budget)*-1 + available = budget_budgeted(budget) - total_category(budget) available = 0 if available < 0 available.round(0) end def budget_balance(budget) - balance = budget_budgeted(budget) - total_category(budget)*-1 + balance = budget_budgeted(budget) - total_category(budget) balance.round(0) end @@ -39,7 +39,7 @@ def available_percentage(budget) def spent_percentage(budget) unless status(budget) == "danger" or status(budget) == "warning" - ((total_category(budget)*-1) * 100 / budget_budgeted(budget)) + ((total_category(budget)) * 100 / budget_budgeted(budget)) else 0 end @@ -109,4 +109,52 @@ def set_period end end + def income_sum + interval = Transaction.interval(@filter.from, @filter.to + 1.day) + ids = Category.income.map(&:id) + interval.budget_category_sum(ids).to_f + end + + def expense_sum + interval = Transaction.interval(@filter.from, @filter.to + 1.day) + ids = Category.expense.map(&:id) + (interval.budget_category_sum(ids).to_f)*-1 + end + + def budgeted_income_sum + sum = 0 + @filter.budgets_income.each do |budget| + sum += budget_budgeted(budget) + end + sum + end + + def budgeted_expense_sum + sum = 0 + @filter.budgets_expense.each do |budget| + sum += budget_budgeted(budget) + end + sum + end + + def budget_saved + income_sum > expense_sum ? income_sum - expense_sum : 0 + end + + def beat_budget + income = income_sum - budgeted_income_sum + expense = budgeted_expense_sum - expense_sum + income + expense > 0 ? income + expense : 0 + end + + def missing_budget + income = income_sum - budgeted_income_sum + expense = budgeted_expense_sum - expense_sum + income + expense < 0 ? income + expense : 0 + end + + def deficit_budgets + income_sum - expense_sum > 0 ? 0 : income_sum - expense_sum + end + end diff --git a/app/models/category.rb b/app/models/category.rb index f899115..13e67b1 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -10,6 +10,9 @@ class Category < ActiveRecord::Base scope :transaction_totals, -> { joins(:splits => :transaction).merge(Transaction.total_amount) } scope :group_by_name, -> { select('categories.name', 'categories.id').group('categories.name', 'categories.id') } scope :budgeted, -> { active.where("budget_limit is not null and budget_period is not null ") } + scope :expense, -> { budgeted.where("pm_type = 0") } + scope :income, -> { budgeted.where("pm_type = 1") } + scope :income_sum, -> { income.sum(:budget_limit) } has_many :splits end diff --git a/app/models/transaction.rb b/app/models/transaction.rb index f75454e..f547a20 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -22,6 +22,7 @@ class Transaction < ActiveRecord::Base scope :interval, ->(from, to) { where("transactions.date >= ? AND transactions.date <= ?", from, to) } scope :total_amount, -> { select('count(transactions.amount) as total_count', 'sum(transactions.amount) as total_amount') } scope :per_category, ->(id) {active.where(category_id: id).sum(:amount)} + scope :budget_category_sum, ->(ids) {active.where(category_id: ids).sum(:amount)} belongs_to :account has_many :splits diff --git a/app/views/budgets/_actual_budgets.haml b/app/views/budgets/_actual_budgets.haml index be23d11..36d2570 100644 --- a/app/views/budgets/_actual_budgets.haml +++ b/app/views/budgets/_actual_budgets.haml @@ -1,32 +1,46 @@ +%h3 + = link_to url_for params.merge(@filter.previous.to_hash) do + .icon-backward + =set_period + = link_to url_for params.merge(@filter.next.to_hash) do + .icon-forward + %table.table-bordered %thead - %h3 - = link_to url_for params.merge(@filter.previous.to_hash) do - .icon-backward - =set_period - = link_to url_for params.merge(@filter.next.to_hash) do - .icon-forward %tr - %th Spent + %th %th Category %th Budgeted %th Available %th Balance - %tbody.summary-header.progress - -@filter.budgets.each do |budget| - %tr - %td - =total_category(budget) - %td.budget - =progress_bar "warning", spent_percentage(budget) do - %p - Spent - =progress_bar status(budget), available_percentage(budget) do - %p - =budget.name - %td - =budget_budgeted(budget) - %td - =budget_available(budget) - %td - =budget_balance(budget) + %tr + %th Entries + %th Incomes + %th + + =render "table_incomes" + %thead + %tr + %th Spent + %th Expenses + %th + =render "table_expenses" + +%table.table-bordered + %thead + %tr + %th Saved + %th Beat Budget + %th Missed Budget + %th Deficit + %tbody.summary-header + %tr + %th + =budget_saved + %th + =beat_budget + %th + =missing_budget + %th + =deficit_budgets + diff --git a/app/views/budgets/_table_expenses.haml b/app/views/budgets/_table_expenses.haml new file mode 100644 index 0000000..0d10ddd --- /dev/null +++ b/app/views/budgets/_table_expenses.haml @@ -0,0 +1,18 @@ +%tbody.summary-header.progress + -@filter.budgets_expense.each do |budget| + %tr + %td + =total_category(budget) + %td.budget + =progress_bar "warning", spent_percentage(budget) do + %p + Spent + =progress_bar status(budget), available_percentage(budget) do + %p + =budget.name + %td + =budget_budgeted(budget) + %td + =budget_available(budget) + %td + =budget_balance(budget) diff --git a/app/views/budgets/_table_incomes.haml b/app/views/budgets/_table_incomes.haml new file mode 100644 index 0000000..c6ea885 --- /dev/null +++ b/app/views/budgets/_table_incomes.haml @@ -0,0 +1,19 @@ +%tbody.summary-header.progress + -@filter.budgets_income.each do |budget| + %tr + %td + =total_category(budget) + %td.budget + =progress_bar "warning", spent_percentage(budget) do + %p + Spent + =progress_bar status(budget), available_percentage(budget) do + %p + =budget.name + %td + =budget_budgeted(budget) + %td + =budget_available(budget) + %td + =budget_balance(budget) + diff --git a/lib/filter.rb b/lib/filter.rb index cd24682..1cd58a2 100644 --- a/lib/filter.rb +++ b/lib/filter.rb @@ -20,8 +20,12 @@ def budgets_sum(id) b end - def budgets - @budgets = Category.budgeted + def budgets_income + @budgets_income = Category.income + end + + def budgets_expense + @budget_expense = Category.expense end def grouped_transactions From 311f561be29d3ab43e09bc01d1ae4069c8eed8f0 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 14 Nov 2013 16:59:42 -0600 Subject: [PATCH 28/59] refactored code --- app/helpers/budgets_helper.rb | 7 +++++++ app/views/budgets/_table_incomes.haml | 4 ++-- app/views/budgets/budgets.haml | 6 +++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index a44d0d6..c7a0534 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -13,6 +13,7 @@ def status(budget) def total_category(budget) total = @filter.budgets_sum(budget.id) *-1 + total = total*-1 if total < 0 total.round(0) end @@ -45,6 +46,12 @@ def spent_percentage(budget) end end + def income_percentage(budget) + percentage = ((total_category(budget)) * 100 / budget_budgeted(budget)) + percentage = 100 if percentage > 100 + percentage + end + def budget_budgeted(budget) case @filter.kind when "week" diff --git a/app/views/budgets/_table_incomes.haml b/app/views/budgets/_table_incomes.haml index c6ea885..8ce70c4 100644 --- a/app/views/budgets/_table_incomes.haml +++ b/app/views/budgets/_table_incomes.haml @@ -4,10 +4,10 @@ %td =total_category(budget) %td.budget - =progress_bar "warning", spent_percentage(budget) do + =progress_bar "success", income_percentage(budget) do %p Spent - =progress_bar status(budget), available_percentage(budget) do + =progress_bar "danger", 100 - income_percentage(budget) do %p =budget.name %td diff --git a/app/views/budgets/budgets.haml b/app/views/budgets/budgets.haml index afeb6bc..fa44ac9 100644 --- a/app/views/budgets/budgets.haml +++ b/app/views/budgets/budgets.haml @@ -1,8 +1,8 @@ .content %h1 Budgets - .row - .span3 - =render partial: 'filters' + .span3 + =render partial: 'filters' + .span8 = render partial: 'actual_budgets' From 222b9f4860b77835d3a52768f05d5053e052af36 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 14 Nov 2013 17:02:49 -0600 Subject: [PATCH 29/59] fix error in the view --- app/views/budgets/_table_incomes.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/budgets/_table_incomes.haml b/app/views/budgets/_table_incomes.haml index 8ce70c4..a14ad90 100644 --- a/app/views/budgets/_table_incomes.haml +++ b/app/views/budgets/_table_incomes.haml @@ -6,10 +6,10 @@ %td.budget =progress_bar "success", income_percentage(budget) do %p - Spent + =budget.name =progress_bar "danger", 100 - income_percentage(budget) do %p - =budget.name + Missing %td =budget_budgeted(budget) %td From 729ab437e138519c8a9b907cc1f2cee3991c54bb Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 14 Nov 2013 17:25:16 -0600 Subject: [PATCH 30/59] refactored code --- app/helpers/budgets_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb index c7a0534..82a31f9 100644 --- a/app/helpers/budgets_helper.rb +++ b/app/helpers/budgets_helper.rb @@ -118,13 +118,13 @@ def set_period def income_sum interval = Transaction.interval(@filter.from, @filter.to + 1.day) - ids = Category.income.map(&:id) + ids = @filter.budgets_income.map(&:id) interval.budget_category_sum(ids).to_f end def expense_sum interval = Transaction.interval(@filter.from, @filter.to + 1.day) - ids = Category.expense.map(&:id) + ids = @filter.budgets_expense.map(&:id) (interval.budget_category_sum(ids).to_f)*-1 end From 1c02e6d2a81c8bb76b8d95cb0abf5acf9fc81cf7 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 11:38:55 -0600 Subject: [PATCH 31/59] added sql view budget_categories --- ...20131115215846_create_budget_categories.rb | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 db/migrate/20131115215846_create_budget_categories.rb diff --git a/db/migrate/20131115215846_create_budget_categories.rb b/db/migrate/20131115215846_create_budget_categories.rb new file mode 100644 index 0000000..16598c3 --- /dev/null +++ b/db/migrate/20131115215846_create_budget_categories.rb @@ -0,0 +1,20 @@ +class CreateBudgetCategories < ActiveRecord::Migration + def change + execute <<-SQL + CREATE VIEW budget_categories AS + select name,c.id as id, t.id as transaction_id, + c.budget_limit as limit, c.budget_period as period, t.date, + c.pm_type as budget_type, t.amount, case + when budget_period = 1 then budget_limit/7 + when budget_period = 2 then budget_limit/30 + when budget_period = 4 then budget_limit/365 + end as amount_day, + (select sum(amount) from transactions t where t.category_id = c.id + and t.deleted = 'false' and t.pm_type <> 5) as category_amount + from categories c + inner join transactions t on t.category_id = c.id and t.deleted = false and t.pm_type <> 5 + WHERE c.budget_limit is not null and c.deleted = 'false' + order by c.name + SQL + end +end From e6eabbdb6677cbd3a6d16478c5193094a7bf35f7 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 11:41:47 -0600 Subject: [PATCH 32/59] deleted budgets_helper --- app/helpers/budgets_helper.rb | 167 ---------------------------------- 1 file changed, 167 deletions(-) delete mode 100644 app/helpers/budgets_helper.rb diff --git a/app/helpers/budgets_helper.rb b/app/helpers/budgets_helper.rb deleted file mode 100644 index 82a31f9..0000000 --- a/app/helpers/budgets_helper.rb +++ /dev/null @@ -1,167 +0,0 @@ -module BudgetsHelper - - def status(budget) - total = total_category(budget) - if total > budget_budgeted(budget) - "danger" - elsif total < budget_budgeted(budget) - "success" - else - "warning" - end - end - - def total_category(budget) - total = @filter.budgets_sum(budget.id) *-1 - total = total*-1 if total < 0 - total.round(0) - end - - def budget_available(budget) - available = budget_budgeted(budget) - total_category(budget) - available = 0 if available < 0 - available.round(0) - end - - def budget_balance(budget) - balance = budget_budgeted(budget) - total_category(budget) - balance.round(0) - end - - def available_percentage(budget) - unless status(budget) == "danger" or status(budget) == "warning" - percentage = (budget_available(budget) * 100 / budget_budgeted(budget)) - percentage = 100 if percentage > 100 - percentage - else - 100 - end - end - - def spent_percentage(budget) - unless status(budget) == "danger" or status(budget) == "warning" - ((total_category(budget)) * 100 / budget_budgeted(budget)) - else - 0 - end - end - - def income_percentage(budget) - percentage = ((total_category(budget)) * 100 / budget_budgeted(budget)) - percentage = 100 if percentage > 100 - percentage - end - - def budget_budgeted(budget) - case @filter.kind - when "week" - budget.budget_period == 1 ? budget.budget_limit : solve_budgeted_per_week(budget) - when "month" - budget.budget_period == 2 ? budget.budget_limit : solve_budgeted_per_month(budget) - when "year" - budget.budget_period == 4 ? budget.budget_limit : solve_budgeted_per_year(budget) - end - end - - def solve_budgeted_per_week(budget) - case budget.budget_period - when 0 - (budget.budget_limit * 7).round(0) - when 2 - weeks = Time::days_in_month(@filter.from.month, @filter.from.year).to_f / 7 - (budget.budget_limit / weeks).round(0) - when 3 - # to do - when 4 - (budget.budgeted_limit / 52.142857143).round(0) - end - end - - def solve_budgeted_per_month(budget) - case budget.budget_period - when 0 - days = Time::days_in_month(@filter.from.month, @filter.from.year) - (budget.budget_limit * days).round(0) - when 1 - weeks = Time::days_in_month(@filter.from.month, @filter.from.year).to_f / 7 - (budget.budget_limit * weeks).round(0) - when 3 - # to do - when 4 - (budget.budget_limit / 12).round(0) - end - end - - def solve_budgeted_per_year(budget) - case budget.budget_period - when 0 - (budget.budget_limit * 365).round(0) - when 1 - (budget.budget_limit * 52.142857143).round(0) - when 2 - (budget.budget_limit * 12).round(0) - when 3 - # to do - end - end - - def set_period - case @filter.kind - when "month" - @filter.from.strftime("%B %Y") - when "week" - "#{@filter.from.strftime('%d %B %Y')} - #{@filter.to.strftime('%d %B %Y')}" - when "year" - @filter.from.year - end - end - - def income_sum - interval = Transaction.interval(@filter.from, @filter.to + 1.day) - ids = @filter.budgets_income.map(&:id) - interval.budget_category_sum(ids).to_f - end - - def expense_sum - interval = Transaction.interval(@filter.from, @filter.to + 1.day) - ids = @filter.budgets_expense.map(&:id) - (interval.budget_category_sum(ids).to_f)*-1 - end - - def budgeted_income_sum - sum = 0 - @filter.budgets_income.each do |budget| - sum += budget_budgeted(budget) - end - sum - end - - def budgeted_expense_sum - sum = 0 - @filter.budgets_expense.each do |budget| - sum += budget_budgeted(budget) - end - sum - end - - def budget_saved - income_sum > expense_sum ? income_sum - expense_sum : 0 - end - - def beat_budget - income = income_sum - budgeted_income_sum - expense = budgeted_expense_sum - expense_sum - income + expense > 0 ? income + expense : 0 - end - - def missing_budget - income = income_sum - budgeted_income_sum - expense = budgeted_expense_sum - expense_sum - income + expense < 0 ? income + expense : 0 - end - - def deficit_budgets - income_sum - expense_sum > 0 ? 0 : income_sum - expense_sum - end - -end From d967650a399c4165ca409b0d2a90888eaf087a5a Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 11:44:52 -0600 Subject: [PATCH 33/59] changed routes for budgets --- config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 00c98fa..5806e37 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,7 +8,7 @@ resources :import do post 'import_csv', on: :collection end - get 'budgets/' => 'budgets#budgets' + get 'budgets/' => 'categories#budgets' # The priority is based upon order of creation: first created -> highest priority. # See how all your routes lay out with "rake routes". From e3dba8c9dd578b58dd84c79f19bd94800ec1f5fa Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 11:45:50 -0600 Subject: [PATCH 34/59] add BudgetCategory model into Category model --- app/models/category.rb | 73 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/app/models/category.rb b/app/models/category.rb index 13e67b1..75adede 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1,4 +1,67 @@ +require 'filter' class Category < ActiveRecord::Base + class BudgetCategory < ActiveRecord::Base + self.table_name = "budget_categories" + self.primary_key = "id" + belongs_to :category, foreign_key: "id" + scope :incomes, -> { budgets.where(budget_type: 1)} + scope :expenses, -> { budgets.where(budget_type: 0)} + scope :sum_incomes, -> { where(budget_type: 1).sum(:amount) } + scope :sum_expenses, -> { where(budget_type: 0).sum(:amount) } + scope :interval, ->(from, to) { where("budget_categories.date >= ? AND budget_categories.date <= ?", from, to) } + scope :budgets, -> {select("id, amount_day, budget_type, name").order("name").uniq} + scope :sum_category, ->(id) { where(id: id).sum(:amount) } + + def self.total_values(from, to) + @@days = (to - from).to_i + @@interval = interval(from, to) + @@spent = total_spent * -1 + @@entries = total_entries + Hash['saved', saved, 'beat', beat_budget, 'missing', missing_budget, 'deficit', deficit ] + end + + private + def self.total_spent + @@interval.sum_expenses + end + + def self.total_entries + @@interval.sum_incomes + end + + def self.saved + @@entries > @@spent ? @@entries - @@spent : 0 + end + + def self.beat_budget + value = income_vs_expense + value > 0 ? value : 0 + end + + def self.missing_budget + value = income_vs_expense + value < 0 ? value : 0 + end + + def self.deficit + @@entries - @@spent > 0 ? 0 : @@entries - @@spent + end + + def self.income_vs_expense + incomes = @@entries - budget_entries + expenses = budget_expenses - @@spent + incomes + expenses + end + + def self.budget_entries + ((incomes.map(&:amount_day).sum) * @@days).round(0) + end + + def self.budget_expenses + ((expenses.map(&:amount_day).sum) * @@days).round(0) + end + end + ## Budget period # 0 diario # 1 Semanal @@ -10,9 +73,13 @@ class Category < ActiveRecord::Base scope :transaction_totals, -> { joins(:splits => :transaction).merge(Transaction.total_amount) } scope :group_by_name, -> { select('categories.name', 'categories.id').group('categories.name', 'categories.id') } scope :budgeted, -> { active.where("budget_limit is not null and budget_period is not null ") } - scope :expense, -> { budgeted.where("pm_type = 0") } - scope :income, -> { budgeted.where("pm_type = 1") } scope :income_sum, -> { income.sum(:budget_limit) } - has_many :splits + has_one :budget_category, foreign_key: "id" + + def self.filter(params) + Filter.new(params) + end + + end From 495935bfb9baa59b5e6ebcc687f4c60e6d2ff244 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 11:47:33 -0600 Subject: [PATCH 35/59] removed views to budgets --- app/views/budgets/_actual_budgets.haml | 46 -------------------------- app/views/budgets/_filters.haml | 22 ------------ app/views/budgets/_table_expenses.haml | 18 ---------- app/views/budgets/_table_incomes.haml | 19 ----------- app/views/budgets/budgets.haml | 8 ----- 5 files changed, 113 deletions(-) delete mode 100644 app/views/budgets/_actual_budgets.haml delete mode 100644 app/views/budgets/_filters.haml delete mode 100644 app/views/budgets/_table_expenses.haml delete mode 100644 app/views/budgets/_table_incomes.haml delete mode 100644 app/views/budgets/budgets.haml diff --git a/app/views/budgets/_actual_budgets.haml b/app/views/budgets/_actual_budgets.haml deleted file mode 100644 index 36d2570..0000000 --- a/app/views/budgets/_actual_budgets.haml +++ /dev/null @@ -1,46 +0,0 @@ -%h3 - = link_to url_for params.merge(@filter.previous.to_hash) do - .icon-backward - =set_period - = link_to url_for params.merge(@filter.next.to_hash) do - .icon-forward - -%table.table-bordered - %thead - %tr - %th - %th Category - %th Budgeted - %th Available - %th Balance - %tr - %th Entries - %th Incomes - %th - - =render "table_incomes" - %thead - %tr - %th Spent - %th Expenses - %th - =render "table_expenses" - -%table.table-bordered - %thead - %tr - %th Saved - %th Beat Budget - %th Missed Budget - %th Deficit - %tbody.summary-header - %tr - %th - =budget_saved - %th - =beat_budget - %th - =missing_budget - %th - =deficit_budgets - diff --git a/app/views/budgets/_filters.haml b/app/views/budgets/_filters.haml deleted file mode 100644 index b1f5233..0000000 --- a/app/views/budgets/_filters.haml +++ /dev/null @@ -1,22 +0,0 @@ -%ul.nav.nav-list.left.filters - %li - %li.icon-backward - = link_to url_for params.merge(@filter.previous.to_hash) do - Previous - = @filter.previous.name - %li - %li.icon-forward - = link_to url_for params.merge(@filter.next.to_hash) do - Next - = @filter.next.name - - %li.divider - - - @filter.intervals.each do |interval| - = content_tag :li, :class=> params[:kind] == interval.kind.to_s ? 'active' : '' do - = link_to url_for params.merge(interval.to_hash) do - This - = interval.name - - %li.divider - diff --git a/app/views/budgets/_table_expenses.haml b/app/views/budgets/_table_expenses.haml deleted file mode 100644 index 0d10ddd..0000000 --- a/app/views/budgets/_table_expenses.haml +++ /dev/null @@ -1,18 +0,0 @@ -%tbody.summary-header.progress - -@filter.budgets_expense.each do |budget| - %tr - %td - =total_category(budget) - %td.budget - =progress_bar "warning", spent_percentage(budget) do - %p - Spent - =progress_bar status(budget), available_percentage(budget) do - %p - =budget.name - %td - =budget_budgeted(budget) - %td - =budget_available(budget) - %td - =budget_balance(budget) diff --git a/app/views/budgets/_table_incomes.haml b/app/views/budgets/_table_incomes.haml deleted file mode 100644 index a14ad90..0000000 --- a/app/views/budgets/_table_incomes.haml +++ /dev/null @@ -1,19 +0,0 @@ -%tbody.summary-header.progress - -@filter.budgets_income.each do |budget| - %tr - %td - =total_category(budget) - %td.budget - =progress_bar "success", income_percentage(budget) do - %p - =budget.name - =progress_bar "danger", 100 - income_percentage(budget) do - %p - Missing - %td - =budget_budgeted(budget) - %td - =budget_available(budget) - %td - =budget_balance(budget) - diff --git a/app/views/budgets/budgets.haml b/app/views/budgets/budgets.haml deleted file mode 100644 index fa44ac9..0000000 --- a/app/views/budgets/budgets.haml +++ /dev/null @@ -1,8 +0,0 @@ -.content - %h1 Budgets - - .span3 - =render partial: 'filters' - .span8 - = render partial: 'actual_budgets' - From 4f15800eb535647ee852eb03dd8eddf3c6fb8354 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 11:48:01 -0600 Subject: [PATCH 36/59] added views to categories --- app/views/categories/_actual_budgets.haml | 40 +++++++++++++++++++++++ app/views/categories/_expenses_table.haml | 19 +++++++++++ app/views/categories/_filters.haml | 22 +++++++++++++ app/views/categories/_incomes_table.haml | 18 ++++++++++ app/views/categories/budgets.haml | 7 ++++ 5 files changed, 106 insertions(+) create mode 100644 app/views/categories/_actual_budgets.haml create mode 100644 app/views/categories/_expenses_table.haml create mode 100644 app/views/categories/_filters.haml create mode 100644 app/views/categories/_incomes_table.haml create mode 100644 app/views/categories/budgets.haml diff --git a/app/views/categories/_actual_budgets.haml b/app/views/categories/_actual_budgets.haml new file mode 100644 index 0000000..3a7fc95 --- /dev/null +++ b/app/views/categories/_actual_budgets.haml @@ -0,0 +1,40 @@ +%table.table-bordered + %thead + %tr + %th Categories + %th + =set_period + %th + %tr + %th + %th Entries + %th Budgeted + %th Remaining + =render 'incomes_table' + %thead + %tr + %th + %th Expenses + %th Budgeted + %th Available + %th Balance + =render 'expenses_table' +%table.table-bordered + %thead + %tr + %th Saved + %th Beat Budget + %th Missed Budget + %th Deficit + %tbody.summary-header + -result = total_budget + %tr + %th + =result['saved'] + %th + =result['beat'] + %th + =result['missing'] + %th + =result['deficit'] + diff --git a/app/views/categories/_expenses_table.haml b/app/views/categories/_expenses_table.haml new file mode 100644 index 0000000..b80d53f --- /dev/null +++ b/app/views/categories/_expenses_table.haml @@ -0,0 +1,19 @@ +%tbody.summary-header.progress + -@budgets.expenses.each do |budget| + -value = values(budget) + %tr + %td + =budget.name + %td.budget + =progress_bar value['color'], value['spent_percentage'] do + %p + =value['amount'] + =progress_bar "success", value['available_percentage'] do + %p + =value['available'] + %td + =value['limit'] + %td + =value['available'] + %td + =value['balance'] diff --git a/app/views/categories/_filters.haml b/app/views/categories/_filters.haml new file mode 100644 index 0000000..b1f5233 --- /dev/null +++ b/app/views/categories/_filters.haml @@ -0,0 +1,22 @@ +%ul.nav.nav-list.left.filters + %li + %li.icon-backward + = link_to url_for params.merge(@filter.previous.to_hash) do + Previous + = @filter.previous.name + %li + %li.icon-forward + = link_to url_for params.merge(@filter.next.to_hash) do + Next + = @filter.next.name + + %li.divider + + - @filter.intervals.each do |interval| + = content_tag :li, :class=> params[:kind] == interval.kind.to_s ? 'active' : '' do + = link_to url_for params.merge(interval.to_hash) do + This + = interval.name + + %li.divider + diff --git a/app/views/categories/_incomes_table.haml b/app/views/categories/_incomes_table.haml new file mode 100644 index 0000000..11a4845 --- /dev/null +++ b/app/views/categories/_incomes_table.haml @@ -0,0 +1,18 @@ +%tbody.summary-header.progress + -@budgets.incomes.each do |budget| + -value = values(budget) + %tr + %td + =budget.name + %td.budget + =progress_bar "success", value['spent_percentage'] do + %p + =value['amount'] + =progress_bar "danger", value['available_percentage'] do + %p + =value['available'] + %td + =value['limit'] + %td + =value['available'] + %td diff --git a/app/views/categories/budgets.haml b/app/views/categories/budgets.haml new file mode 100644 index 0000000..76c146c --- /dev/null +++ b/app/views/categories/budgets.haml @@ -0,0 +1,7 @@ +.content + %h1 Budgets + + .span3 + =render partial: 'filters' + .span8 + = render partial: 'actual_budgets' From 5a72a5ad2078f32939f28dfac0df97c69e7c6626 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 11:48:58 -0600 Subject: [PATCH 37/59] deleted unnnecesary budgets controller --- app/controllers/budgets_controller.rb | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 app/controllers/budgets_controller.rb diff --git a/app/controllers/budgets_controller.rb b/app/controllers/budgets_controller.rb deleted file mode 100644 index 102e062..0000000 --- a/app/controllers/budgets_controller.rb +++ /dev/null @@ -1,5 +0,0 @@ -class BudgetsController < ApplicationController - def budgets - @filter = Transaction.filter(params) - end -end From d6e85f37cdfca2da4247f67ac79f9951d0e8ed71 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 11:54:03 -0600 Subject: [PATCH 38/59] added categories helper --- app/helpers/categories_helper.rb | 64 ++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 app/helpers/categories_helper.rb diff --git a/app/helpers/categories_helper.rb b/app/helpers/categories_helper.rb new file mode 100644 index 0000000..9d036ac --- /dev/null +++ b/app/helpers/categories_helper.rb @@ -0,0 +1,64 @@ +module CategoriesHelper + def values(budget) + amount = amount(budget.id) + limit = limit(budget.amount_day) + balance = balance(limit, amount) + available = available(balance) + color = color(balance) + spent_percentage = spent_percentage(amount, limit) + available_percentage = available_percentage(spent_percentage) + Hash['amount', amount, 'limit', + limit, 'balance', balance, + 'available', available, + 'spent_percentage', spent_percentage, + 'color', color, + 'available_percentage', available_percentage] + end + + def amount(id) + amount = Category::BudgetCategory.interval(@filter.from, @filter.to+1) + amount = amount.sum_category(id) + amount < 0 ? amount*-1 : amount + end + + def limit(limit) + (limit * ((@filter.to - @filter.from).to_i+1)).round(0) + end + + def available(balance) + balance < 0 ? 0 : balance + end + + def balance(limit, amount) + (limit - amount).round(0) + end + + def color(balance) + balance < 0 ? "danger" : "warning" + end + + def spent_percentage(amount, limit) + percentage = (amount * 100) / limit + percentage < 100 ? percentage : 100 + end + + def available_percentage(spent) + 100 - spent + end + + def set_period + case @filter.kind + when "month" + @filter.from.strftime("%B %Y") + when "week" + "#{@filter.from.strftime('%d %B %Y')} - #{@filter.to.strftime('%d %B %Y')}" + when "year" + @filter.from.year + end + end + + def total_budget + Category::BudgetCategory.total_values(@filter.from, @filter.to+1.day) + end + +end From ba6e4076a124a4422c32ab68800dfab43d18c55d Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 11:54:34 -0600 Subject: [PATCH 39/59] added categories controller --- app/controllers/categories_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index d8161f9..23370bf 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -1,3 +1,6 @@ class CategoriesController < ApplicationController - + def budgets + @budgets = Category::BudgetCategory.all + @filter = Category.filter(params) + end end From 4036602ba0d96925eca643d81855481492f7e0db Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 13:25:16 -0600 Subject: [PATCH 40/59] deleted duplicated code --- lib/filter.rb | 148 ------------------------------------------------ lib/interval.rb | 46 --------------- 2 files changed, 194 deletions(-) delete mode 100644 lib/filter.rb delete mode 100644 lib/interval.rb diff --git a/lib/filter.rb b/lib/filter.rb deleted file mode 100644 index 1cd58a2..0000000 --- a/lib/filter.rb +++ /dev/null @@ -1,148 +0,0 @@ -class Filter - require 'interval' - - def initialize(conditions) - @conditions = conditions - @category_ids = [] - end - - def accounts - @accounts ||= Account.all - end - - def transactions - @transactions ||= transaction_query.full - end - - def budgets_sum(id) - b = Transaction.interval(from, to + 1.day) - b = b.per_category(id) - b - end - - def budgets_income - @budgets_income = Category.income - end - - def budgets_expense - @budget_expense = Category.expense - end - - def grouped_transactions - case group_by - when 'date' - transactions.group_by {|t| t.date.to_s(:short_date) } - when 'type' - transactions.group_by {|t| t.type_name } - when 'account' - transactions.group_by {|t| t.account.name } - when 'category' - transactions.group_by {|t| t.category_name.to_s } - end - end - - def categories - @categories ||= Category.transaction_totals.group_by_name.transaction_ids(transaction_ids) - end - - def intervals - [ Interval.new(:week), Interval.new(:month), Interval.new(:year) ] - end - - def current_interval - @conditions[:from] ? Interval.new(kind,from) : intervals.select {|i| i.kind.to_s == kind }.first - end - - def from - @conditions[:from] ? Date.parse(@conditions[:from]) : current_interval.from - end - - def to - @conditions[:to] ? Date.parse(@conditions[:to]) : current_interval.to - end - - def kind - @conditions[:kind] || 'month' - end - - def previous - @previous ||= current_interval.previous - end - - def next - @next ||= current_interval.next - end - - def categories_total - categories.to_a.sum(&:total_amount) - end - - def types_total - @types_total = widthdrawals_amount + deposits_amount + transfers_amount - end - - def widthdrawals_amount - types_query[0].to_f.abs - end - - def deposits_amount - types_query[1].to_f.abs - end - - def transfers_amount - types_query[2].to_f.abs - end - - def widthdrawals_percentage - (widthdrawals_amount/types_total * 100) - end - - def deposits_percentage - (deposits_amount / types_total * 100) - end - - def transfers_percentage - (transfers_amount / types_total * 100) - end - - def transaction_ids - @transaction_ids ||= transactions.map &:id - end - - - private - - def types_query - @types_query ||= Transaction.where(id: transaction_ids ).group('transactions.pm_type').sum(:amount) - end - - def transaction_interval - Transaction.interval(from, to) - end - - def transaction_query - t = transaction_interval - t = t.where(pm_type: pm_type) if pm_type - t = t.where(account_id: account_id) if account_id - t = t.where('categories.id = ?', category_id) if category_id - t - end - - def account_id - @conditions[:account_id] - end - - def category_id - @conditions[:category_id] - end - - def pm_type - @conditions[:pm_type] - end - - def group_by - @conditions[:group_by] || 'date' - end - -end - diff --git a/lib/interval.rb b/lib/interval.rb deleted file mode 100644 index 50a684f..0000000 --- a/lib/interval.rb +++ /dev/null @@ -1,46 +0,0 @@ -class Interval - attr_accessor :from, :to, :kind - - def initialize(kind, date = nil) - @kind = kind - @date = date - end - - def from - date.send("beginning_of_#{kind}") - end - - def to - date.send("end_of_#{kind}") - end - - def date - @date || Date.today - end - - def to_hash - { kind: kind, from: from_string, to: to_string } - end - - def from_string - from.strftime('%Y%m%d') - end - - def to_string - to.strftime('%Y%m%d') - end - - def name - kind.to_s.humanize - end - - def previous - Interval.new(kind, from - 1.send(kind)) - end - - def next - Interval.new(kind, from + 1.send(kind)) - end - -end - From 97fc795a4aec0ca72356ae88adf69a75bf3aafa3 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 13:41:35 -0600 Subject: [PATCH 41/59] fecator code --- app/models/category.rb | 2 +- app/models/transaction.rb | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/app/models/category.rb b/app/models/category.rb index 75adede..aa91495 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1,5 +1,5 @@ -require 'filter' class Category < ActiveRecord::Base + include FilterInterval class BudgetCategory < ActiveRecord::Base self.table_name = "budget_categories" self.primary_key = "id" diff --git a/app/models/transaction.rb b/app/models/transaction.rb index f547a20..fed26c6 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -1,6 +1,5 @@ class Transaction < ActiveRecord::Base - require 'filter' - require 'budget' + include FilterInterval # pm_types # 0 Withdrawal # 1 Deposit @@ -21,8 +20,6 @@ class Transaction < ActiveRecord::Base scope :full, -> { order_date.transaction_includes.active.balance } scope :interval, ->(from, to) { where("transactions.date >= ? AND transactions.date <= ?", from, to) } scope :total_amount, -> { select('count(transactions.amount) as total_count', 'sum(transactions.amount) as total_amount') } - scope :per_category, ->(id) {active.where(category_id: id).sum(:amount)} - scope :budget_category_sum, ->(ids) {active.where(category_id: ids).sum(:amount)} belongs_to :account has_many :splits @@ -45,9 +42,5 @@ def type_name def self.filter(conditions) Filter.new(conditions) end - - def self.budget(budget) - CategoryBudget.new(budget) - end end From 67010b0a653058929777b68e84d07e462a212b41 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 13:44:11 -0600 Subject: [PATCH 42/59] moved categories to pocketmoney namespce --- lib/{ => pocket_money}/categories.rb | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/{ => pocket_money}/categories.rb (100%) diff --git a/lib/categories.rb b/lib/pocket_money/categories.rb similarity index 100% rename from lib/categories.rb rename to lib/pocket_money/categories.rb From 087af2dc8d4c13f72723c159e0966f08f61caae3 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 13:45:01 -0600 Subject: [PATCH 43/59] deleted budgets table --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 43ddc34..a7e297c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20130718222102) do +ActiveRecord::Schema.define(version: 20131115215846) do create_table "accounts", force: true do |t| t.boolean "deleted" From b42f566ae1c0c711293f5cea8ae26bb50200135f Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 13:46:16 -0600 Subject: [PATCH 44/59] change route to categories.rb --- lib/pocket_money.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pocket_money.rb b/lib/pocket_money.rb index 523347b..026a7c3 100644 --- a/lib/pocket_money.rb +++ b/lib/pocket_money.rb @@ -1,4 +1,4 @@ require 'pocket_money/base.rb' require 'pocket_money/tables' require 'pocket_money/import' -require 'categories' +require 'pocket_money/categories' From 1be1df8182971cfe73201283a67ee52110859b46 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 13:47:03 -0600 Subject: [PATCH 45/59] moved filter class --- config/initializers/filter.rb | 1 + lib/modules/module_filter.rb | 180 ++++++++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) create mode 100644 config/initializers/filter.rb create mode 100644 lib/modules/module_filter.rb diff --git a/config/initializers/filter.rb b/config/initializers/filter.rb new file mode 100644 index 0000000..4ceeaa0 --- /dev/null +++ b/config/initializers/filter.rb @@ -0,0 +1 @@ +require 'modules/module_filter' diff --git a/lib/modules/module_filter.rb b/lib/modules/module_filter.rb new file mode 100644 index 0000000..eb24c5e --- /dev/null +++ b/lib/modules/module_filter.rb @@ -0,0 +1,180 @@ +module FilterInterval + class Filter + + def initialize(conditions) + @conditions = conditions + @category_ids = [] + end + + def accounts + @accounts ||= Account.all + end + + def transactions + @transactions ||= transaction_query.full + end + + def grouped_transactions + case group_by + when 'date' + transactions.group_by {|t| t.date.to_s(:short_date) } + when 'type' + transactions.group_by {|t| t.type_name } + when 'account' + transactions.group_by {|t| t.account.name } + when 'category' + transactions.group_by {|t| t.category_name.to_s } + end + end + + def categories + @categories ||= Category.transaction_totals.group_by_name.transaction_ids(transaction_ids) + end + + def intervals + [ Interval.new(:week), Interval.new(:month), Interval.new(:year) ] + end + + def current_interval + @conditions[:from] ? Interval.new(kind,from) : intervals.select {|i| i.kind.to_s == kind }.first + end + + def from + @conditions[:from] ? Date.parse(@conditions[:from]) : current_interval.from + end + + def to + @conditions[:to] ? Date.parse(@conditions[:to]) : current_interval.to + end + + def kind + @conditions[:kind] || 'month' + end + + def previous + @previous ||= current_interval.previous + end + + def next + @next ||= current_interval.next + end + + def categories_total + categories.to_a.sum(&:total_amount) + end + + def types_total + @types_total = widthdrawals_amount + deposits_amount + transfers_amount + end + + def widthdrawals_amount + types_query[0].to_f.abs + end + + def deposits_amount + types_query[1].to_f.abs + end + + def transfers_amount + types_query[2].to_f.abs + end + + def widthdrawals_percentage + (widthdrawals_amount/types_total * 100) + end + + def deposits_percentage + (deposits_amount / types_total * 100) + end + + def transfers_percentage + (transfers_amount / types_total * 100) + end + + def transaction_ids + @transaction_ids ||= transactions.map &:id + end + + + private + + def types_query + @types_query ||= Transaction.where(id: transaction_ids ).group('transactions.pm_type').sum(:amount) + end + + def transaction_interval + Transaction.interval(from, to) + end + + def transaction_query + t = transaction_interval + t = t.where(pm_type: pm_type) if pm_type + t = t.where(account_id: account_id) if account_id + t = t.where('categories.id = ?', category_id) if category_id + t + end + + def account_id + @conditions[:account_id] + end + + def category_id + @conditions[:category_id] + end + + def pm_type + @conditions[:pm_type] + end + + def group_by + @conditions[:group_by] || 'date' + end + + class Interval + attr_accessor :from, :to, :kind + + def initialize(kind, date = nil) + @kind = kind + @date = date + end + + def from + date.send("beginning_of_#{kind}") + end + + def to + date.send("end_of_#{kind}") + end + + def date + @date || Date.today + end + + def to_hash + { kind: kind, from: from_string, to: to_string } + end + + def from_string + from.strftime('%Y%m%d') + end + + def to_string + to.strftime('%Y%m%d') + end + + def name + kind.to_s.humanize + end + + def previous + Interval.new(kind, from - 1.send(kind)) + end + + def next + Interval.new(kind, from + 1.send(kind)) + end + + end + end +end + From f7d44bc7f224cd869920c1521c69b1e42729585c Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 13:49:42 -0600 Subject: [PATCH 46/59] renamed style file to budgets --- app/assets/stylesheets/{budgets.sass => categories.sass} | 2 -- 1 file changed, 2 deletions(-) rename app/assets/stylesheets/{budgets.sass => categories.sass} (92%) diff --git a/app/assets/stylesheets/budgets.sass b/app/assets/stylesheets/categories.sass similarity index 92% rename from app/assets/stylesheets/budgets.sass rename to app/assets/stylesheets/categories.sass index c90b379..c215c0c 100644 --- a/app/assets/stylesheets/budgets.sass +++ b/app/assets/stylesheets/categories.sass @@ -1,4 +1,2 @@ .budget width: 700px - - From e1c23cae2e9b967ff95900ee8be29e123eadf053 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 13:55:36 -0600 Subject: [PATCH 47/59] moved set_period method at application helper --- app/helpers/application_helper.rb | 11 +++++++++++ app/helpers/categories_helper.rb | 10 ---------- app/views/categories/_actual_budgets.haml | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a65b4e1..717067d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -27,4 +27,15 @@ def progress_bar(type, percentage, &block) content_tag :div, :class=> "bar bar-#{type}", :style=>"width:#{percentage}%;", &block if percentage > 0 end + def set_period(filter) + case filter.kind + when "month" + filter.from.strftime("%B %Y") + when "week" + "#{filter.from.strftime('%d %B %Y')} - #{filter.to.strftime('%d %B %Y')}" + when "year" + filter.from.year + end + end + end diff --git a/app/helpers/categories_helper.rb b/app/helpers/categories_helper.rb index 9d036ac..71ee3a3 100644 --- a/app/helpers/categories_helper.rb +++ b/app/helpers/categories_helper.rb @@ -46,16 +46,6 @@ def available_percentage(spent) 100 - spent end - def set_period - case @filter.kind - when "month" - @filter.from.strftime("%B %Y") - when "week" - "#{@filter.from.strftime('%d %B %Y')} - #{@filter.to.strftime('%d %B %Y')}" - when "year" - @filter.from.year - end - end def total_budget Category::BudgetCategory.total_values(@filter.from, @filter.to+1.day) diff --git a/app/views/categories/_actual_budgets.haml b/app/views/categories/_actual_budgets.haml index 3a7fc95..d01a8d8 100644 --- a/app/views/categories/_actual_budgets.haml +++ b/app/views/categories/_actual_budgets.haml @@ -3,7 +3,7 @@ %tr %th Categories %th - =set_period + =set_period(@filter) %th %tr %th From 9ac4a789b8eeaf08431ca5b606c6062bda3e9c53 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 14:03:13 -0600 Subject: [PATCH 48/59] deleted unnecesary code --- app/helpers/categories_helper.rb | 1 - app/models/budget.rb | 2 -- app/models/category.rb | 1 - app/models/transaction.rb | 1 - app/views/categories/_filters.haml | 1 - 5 files changed, 6 deletions(-) delete mode 100644 app/models/budget.rb diff --git a/app/helpers/categories_helper.rb b/app/helpers/categories_helper.rb index 71ee3a3..bb34da9 100644 --- a/app/helpers/categories_helper.rb +++ b/app/helpers/categories_helper.rb @@ -46,7 +46,6 @@ def available_percentage(spent) 100 - spent end - def total_budget Category::BudgetCategory.total_values(@filter.from, @filter.to+1.day) end diff --git a/app/models/budget.rb b/app/models/budget.rb deleted file mode 100644 index 3ecaf97..0000000 --- a/app/models/budget.rb +++ /dev/null @@ -1,2 +0,0 @@ -class Budget < ActiveRecord::Base -end diff --git a/app/models/category.rb b/app/models/category.rb index aa91495..81624d5 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -80,6 +80,5 @@ def self.budget_expenses def self.filter(params) Filter.new(params) end - end diff --git a/app/models/transaction.rb b/app/models/transaction.rb index fed26c6..e0ed4fe 100644 --- a/app/models/transaction.rb +++ b/app/models/transaction.rb @@ -24,7 +24,6 @@ class Transaction < ActiveRecord::Base belongs_to :account has_many :splits - def split? @split ||= splits.size > 1 end diff --git a/app/views/categories/_filters.haml b/app/views/categories/_filters.haml index b1f5233..54d0a44 100644 --- a/app/views/categories/_filters.haml +++ b/app/views/categories/_filters.haml @@ -19,4 +19,3 @@ = interval.name %li.divider - From 81a4ff04d4bbf22778547d3a962da4717d1e4a06 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Tue, 19 Nov 2013 14:14:05 -0600 Subject: [PATCH 49/59] deleted unnecesary code --- app/models/category.rb | 3 +-- app/models/split.rb | 2 -- app/views/layouts/application.haml | 2 -- app/views/transactions/_header.haml | 1 + 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/models/category.rb b/app/models/category.rb index 81624d5..8c13b40 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -72,8 +72,7 @@ def self.budget_expenses scope :transaction_ids, ->(ids) { joins(:splits => :transaction).where(transactions: {id: ids}) } scope :transaction_totals, -> { joins(:splits => :transaction).merge(Transaction.total_amount) } scope :group_by_name, -> { select('categories.name', 'categories.id').group('categories.name', 'categories.id') } - scope :budgeted, -> { active.where("budget_limit is not null and budget_period is not null ") } - scope :income_sum, -> { income.sum(:budget_limit) } + has_many :splits has_one :budget_category, foreign_key: "id" diff --git a/app/models/split.rb b/app/models/split.rb index cc4993e..0ff1ee7 100644 --- a/app/models/split.rb +++ b/app/models/split.rb @@ -4,6 +4,4 @@ class Split < ActiveRecord::Base belongs_to :category validates_associated :transaction, :category - - end diff --git a/app/views/layouts/application.haml b/app/views/layouts/application.haml index 4cf81e4..1725ec4 100644 --- a/app/views/layouts/application.haml +++ b/app/views/layouts/application.haml @@ -8,8 +8,6 @@ %meta{content: "", name: "author"} = stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true = javascript_include_tag "application", "data-turbolinks-track" => true - %link{href: "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/themes/ui-lightness/jquery-ui.css", :rel => "stylesheet", :type => "text/css"} - %script{src: "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/jquery-ui.min.js"} = csrf_meta_tags = yield(:head) %body diff --git a/app/views/transactions/_header.haml b/app/views/transactions/_header.haml index 6c7f05c..29d2c7d 100644 --- a/app/views/transactions/_header.haml +++ b/app/views/transactions/_header.haml @@ -6,6 +6,7 @@ %p =link_to "Widthdrawals", params.merge(pm_type: 0) = money @filter.widthdrawals_amount + = progress_bar 'success', @filter.deposits_percentage do %p =link_to "Deposit", params.merge(pm_type: 1) From eacb6fd259a1c92305e0f3698dd844aa35ab328d Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Wed, 4 Dec 2013 15:23:36 -0600 Subject: [PATCH 50/59] added draper gem --- Gemfile | 2 +- Gemfile.lock | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index f58c20f..bd0c390 100644 --- a/Gemfile +++ b/Gemfile @@ -28,7 +28,7 @@ gem 'turbolinks' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 1.0.1' - +gem 'draper' gem 'haml' gem 'twitter-bootstrap-rails', :git => 'git://github.com/seyhunak/twitter-bootstrap-rails.git' gem 'less-rails' diff --git a/Gemfile.lock b/Gemfile.lock index cb0d74c..51974e5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -47,6 +47,11 @@ GEM execjs coffee-script-source (1.6.2) commonjs (0.2.6) + draper (1.3.0) + actionpack (>= 3.0) + activemodel (>= 3.0) + activesupport (>= 3.0) + request_store (~> 1.0.3) erubis (2.7.0) execjs (1.4.0) multi_json (~> 1.0) @@ -104,6 +109,7 @@ GEM rdoc (3.12.2) json (~> 1.4) ref (1.0.5) + request_store (1.0.5) ruby-progressbar (1.1.1) sass (3.2.9) sass-rails (4.0.0.rc1) @@ -148,6 +154,7 @@ PLATFORMS DEPENDENCIES coffee-rails (~> 4.0.0) + draper haml jbuilder (~> 1.0.1) jquery-rails From 91665835f17f1b0c14d93421a6bbaaad6faddf02 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Wed, 4 Dec 2013 15:25:57 -0600 Subject: [PATCH 51/59] generated decorator for categories --- app/decorators/budget_category_decorator.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 app/decorators/budget_category_decorator.rb diff --git a/app/decorators/budget_category_decorator.rb b/app/decorators/budget_category_decorator.rb new file mode 100644 index 0000000..a1646d6 --- /dev/null +++ b/app/decorators/budget_category_decorator.rb @@ -0,0 +1,13 @@ +class BudgetCategoryDecorator < Draper::Decorator + delegate_all + + # Define presentation-specific methods here. Helpers are accessed through + # `helpers` (aka `h`). You can override attributes, for example: + # + # def created_at + # helpers.content_tag :span, class: 'time' do + # object.created_at.strftime("%a %m/%d/%y") + # end + # end + +end From 856cf64140e1494792ce962319a4ced5ea0ab09b Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Wed, 4 Dec 2013 16:32:15 -0600 Subject: [PATCH 52/59] added collection decorated --- app/controllers/categories_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index 23370bf..2d173f3 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -1,6 +1,6 @@ class CategoriesController < ApplicationController def budgets - @budgets = Category::BudgetCategory.all + @budgets = BudgetCategoryDecorator.new(Category::BudgetCategory.all) @filter = Category.filter(params) end end From fa98af41603e2ad28968fe0903e6daeea8102a69 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 5 Dec 2013 10:42:17 -0600 Subject: [PATCH 53/59] created new partial to intervals --- app/views/categories/_filters.haml | 6 +----- app/views/categories/_intervals.html.haml | 5 +++++ 2 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 app/views/categories/_intervals.html.haml diff --git a/app/views/categories/_filters.haml b/app/views/categories/_filters.haml index 54d0a44..259446b 100644 --- a/app/views/categories/_filters.haml +++ b/app/views/categories/_filters.haml @@ -12,10 +12,6 @@ %li.divider - - @filter.intervals.each do |interval| - = content_tag :li, :class=> params[:kind] == interval.kind.to_s ? 'active' : '' do - = link_to url_for params.merge(interval.to_hash) do - This - = interval.name + =render "intervals" %li.divider diff --git a/app/views/categories/_intervals.html.haml b/app/views/categories/_intervals.html.haml new file mode 100644 index 0000000..e12d789 --- /dev/null +++ b/app/views/categories/_intervals.html.haml @@ -0,0 +1,5 @@ +- @filter.intervals.each do |interval| + = content_tag :li, :class=> params[:kind] == interval.kind.to_s ? 'active' : '' do + = link_to url_for params.merge(interval.to_hash) do + This + = interval.name From 0bcf160f35f0b6e82a88a0b63e8876d0671eed62 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 5 Dec 2013 16:09:40 -0600 Subject: [PATCH 54/59] added identation to sql view --- ...20131115215846_create_budget_categories.rb | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/db/migrate/20131115215846_create_budget_categories.rb b/db/migrate/20131115215846_create_budget_categories.rb index 16598c3..e52bfba 100644 --- a/db/migrate/20131115215846_create_budget_categories.rb +++ b/db/migrate/20131115215846_create_budget_categories.rb @@ -2,19 +2,24 @@ class CreateBudgetCategories < ActiveRecord::Migration def change execute <<-SQL CREATE VIEW budget_categories AS - select name,c.id as id, t.id as transaction_id, - c.budget_limit as limit, c.budget_period as period, t.date, - c.pm_type as budget_type, t.amount, case - when budget_period = 1 then budget_limit/7 - when budget_period = 2 then budget_limit/30 - when budget_period = 4 then budget_limit/365 - end as amount_day, - (select sum(amount) from transactions t where t.category_id = c.id - and t.deleted = 'false' and t.pm_type <> 5) as category_amount - from categories c - inner join transactions t on t.category_id = c.id and t.deleted = false and t.pm_type <> 5 + SELECT name,c.id as id, + t.id as transaction_id, + c.budget_limit as limit, + c.budget_period as period, + t.date, + c.pm_type as budget_type, + t.amount, + CASE + when budget_period = 1 then budget_limit/7 + when budget_period = 2 then budget_limit/30 + when budget_period = 4 then budget_limit/365 + end as amount_day, + (SELECT sum(amount) from transactions t where t.category_id = c.id + and t.deleted = 'false' and t.pm_type <> 5) as category_amount + FROM categories c + inner join transactions t on t.category_id = c.id and t.deleted = false and t.pm_type <> 5 WHERE c.budget_limit is not null and c.deleted = 'false' - order by c.name + ORDER BY c.name SQL end end From a5b6475fbc1d430a083903ce409f2ef04c1515b6 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 5 Dec 2013 17:24:58 -0600 Subject: [PATCH 55/59] decorated collection to budgets categories --- app/controllers/categories_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb index 2d173f3..eaa431c 100644 --- a/app/controllers/categories_controller.rb +++ b/app/controllers/categories_controller.rb @@ -1,6 +1,6 @@ class CategoriesController < ApplicationController def budgets - @budgets = BudgetCategoryDecorator.new(Category::BudgetCategory.all) + @budgets = BudgetCategoriesDecorator.new(Category::BudgetCategory.all) @filter = Category.filter(params) end end From da4550ea88b0158703e8a7b6ca64d3024682ef84 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 5 Dec 2013 17:26:00 -0600 Subject: [PATCH 56/59] decorator to budgets category --- app/decorators/budget_categories_decorator.rb | 3 ++ app/decorators/budget_category_decorator.rb | 43 +++++++++++++++---- 2 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 app/decorators/budget_categories_decorator.rb diff --git a/app/decorators/budget_categories_decorator.rb b/app/decorators/budget_categories_decorator.rb new file mode 100644 index 0000000..11d84d9 --- /dev/null +++ b/app/decorators/budget_categories_decorator.rb @@ -0,0 +1,3 @@ +class BudgetCategoriesDecorator < Draper::Decorator + delegate_all +end diff --git a/app/decorators/budget_category_decorator.rb b/app/decorators/budget_category_decorator.rb index a1646d6..061b5b2 100644 --- a/app/decorators/budget_category_decorator.rb +++ b/app/decorators/budget_category_decorator.rb @@ -1,13 +1,40 @@ class BudgetCategoryDecorator < Draper::Decorator delegate_all - # Define presentation-specific methods here. Helpers are accessed through - # `helpers` (aka `h`). You can override attributes, for example: - # - # def created_at - # helpers.content_tag :span, class: 'time' do - # object.created_at.strftime("%a %m/%d/%y") - # end - # end + def dates_intervals(from, to) + @@from = from + @@to = to+1 + end + + def amount + amount = Category::BudgetCategory.interval(@@from, @@to) + amount = amount.sum_category(model.id) + amount < 0 ? amount*-1 : amount + end + + def limit + (model.amount_day * ((@@to - @@from).to_i+1)).round(0) + end + + def balance + (limit - amount).round(0) + end + + def available + balance < 0 ? 0 : balance + end + + def color + balance < 0 ? "danger" : "warning" + end + + def spent_percentage + percentage = (amount * 100) / limit + percentage < 100 ? percentage : 100 + end + + def available_percentage + 100 - spent_percentage + end end From 6aaa93bc97634c2cef1eda5a89c496e3188ab89e Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 5 Dec 2013 17:26:38 -0600 Subject: [PATCH 57/59] removed code from categories_helper --- app/helpers/categories_helper.rb | 46 -------------------------------- 1 file changed, 46 deletions(-) diff --git a/app/helpers/categories_helper.rb b/app/helpers/categories_helper.rb index bb34da9..5e35611 100644 --- a/app/helpers/categories_helper.rb +++ b/app/helpers/categories_helper.rb @@ -1,50 +1,4 @@ module CategoriesHelper - def values(budget) - amount = amount(budget.id) - limit = limit(budget.amount_day) - balance = balance(limit, amount) - available = available(balance) - color = color(balance) - spent_percentage = spent_percentage(amount, limit) - available_percentage = available_percentage(spent_percentage) - Hash['amount', amount, 'limit', - limit, 'balance', balance, - 'available', available, - 'spent_percentage', spent_percentage, - 'color', color, - 'available_percentage', available_percentage] - end - - def amount(id) - amount = Category::BudgetCategory.interval(@filter.from, @filter.to+1) - amount = amount.sum_category(id) - amount < 0 ? amount*-1 : amount - end - - def limit(limit) - (limit * ((@filter.to - @filter.from).to_i+1)).round(0) - end - - def available(balance) - balance < 0 ? 0 : balance - end - - def balance(limit, amount) - (limit - amount).round(0) - end - - def color(balance) - balance < 0 ? "danger" : "warning" - end - - def spent_percentage(amount, limit) - percentage = (amount * 100) / limit - percentage < 100 ? percentage : 100 - end - - def available_percentage(spent) - 100 - spent - end def total_budget Category::BudgetCategory.total_values(@filter.from, @filter.to+1.day) From e174d65fe62304d8d3288599b02dccb79de9eb59 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 5 Dec 2013 17:27:13 -0600 Subject: [PATCH 58/59] change code in views in order to use new decorator --- app/views/categories/_expenses_table.haml | 19 ++++++++++--------- app/views/categories/_incomes_table.haml | 17 +++++++++-------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/app/views/categories/_expenses_table.haml b/app/views/categories/_expenses_table.haml index b80d53f..965aadc 100644 --- a/app/views/categories/_expenses_table.haml +++ b/app/views/categories/_expenses_table.haml @@ -1,19 +1,20 @@ %tbody.summary-header.progress - -@budgets.expenses.each do |budget| - -value = values(budget) + -@budgets.expenses.each do |bud| + -budget = BudgetCategoryDecorator.decorate(bud) + -budget.dates_intervals(@filter.from, @filter.to+1) %tr %td =budget.name %td.budget - =progress_bar value['color'], value['spent_percentage'] do + =progress_bar budget.color, budget.spent_percentage do %p - =value['amount'] - =progress_bar "success", value['available_percentage'] do + =budget.amount + =progress_bar "success", budget.available_percentage do %p - =value['available'] + =budget.available %td - =value['limit'] + =budget.limit %td - =value['available'] + =budget.available %td - =value['balance'] + =budget.balance diff --git a/app/views/categories/_incomes_table.haml b/app/views/categories/_incomes_table.haml index 11a4845..e046db4 100644 --- a/app/views/categories/_incomes_table.haml +++ b/app/views/categories/_incomes_table.haml @@ -1,18 +1,19 @@ %tbody.summary-header.progress - -@budgets.incomes.each do |budget| - -value = values(budget) + -@budgets.incomes.each do |bud| + -budget = BudgetCategoryDecorator.decorate(bud) + -budget.dates_intervals(@filter.from, @filter.to+1) %tr %td =budget.name %td.budget - =progress_bar "success", value['spent_percentage'] do + =progress_bar "success", budget.spent_percentage do %p - =value['amount'] - =progress_bar "danger", value['available_percentage'] do + =budget.amount + =progress_bar "danger", budget.available_percentage do %p - =value['available'] + =budget.available %td - =value['limit'] + =budget.limit %td - =value['available'] + =budget.available %td From 01f2e68b13ddebf5602b360ec4628adb572ac549 Mon Sep 17 00:00:00 2001 From: Jesus Romero Date: Thu, 5 Dec 2013 17:35:51 -0600 Subject: [PATCH 59/59] fix double substraction --- app/views/categories/_expenses_table.haml | 2 +- app/views/categories/_incomes_table.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/categories/_expenses_table.haml b/app/views/categories/_expenses_table.haml index 965aadc..9df675d 100644 --- a/app/views/categories/_expenses_table.haml +++ b/app/views/categories/_expenses_table.haml @@ -1,7 +1,7 @@ %tbody.summary-header.progress -@budgets.expenses.each do |bud| -budget = BudgetCategoryDecorator.decorate(bud) - -budget.dates_intervals(@filter.from, @filter.to+1) + -budget.dates_intervals(@filter.from, @filter.to) %tr %td =budget.name diff --git a/app/views/categories/_incomes_table.haml b/app/views/categories/_incomes_table.haml index e046db4..4848dc1 100644 --- a/app/views/categories/_incomes_table.haml +++ b/app/views/categories/_incomes_table.haml @@ -1,7 +1,7 @@ %tbody.summary-header.progress -@budgets.incomes.each do |bud| -budget = BudgetCategoryDecorator.decorate(bud) - -budget.dates_intervals(@filter.from, @filter.to+1) + -budget.dates_intervals(@filter.from, @filter.to) %tr %td =budget.name