Skip to content

Commit

Permalink
Merge branch 'jamis/master'
Browse files Browse the repository at this point in the history
Conflicts:
	app/views/accounts/_form.html.haml
	db/schema.rb
  • Loading branch information
JonathanTron committed May 27, 2009
2 parents 5ea7e1e + 3797771 commit 4c0fb39
Show file tree
Hide file tree
Showing 14 changed files with 128 additions and 16 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rdoc
@@ -1,5 +1,9 @@
=== (unreleased)

* Fix rounding error on ending balance for new statements [Cody Maggard]

* Track limit on credit card accounts [Kieran Pilkington]

* Change text on "save" button in event form to reflect edit vs. new [Kieran Pilkington]

* Make "BucketWise" in header a link to the root path [Kieran Pilkington]
Expand Down
1 change: 1 addition & 0 deletions TODO
Expand Up @@ -31,3 +31,4 @@ FEATURES that would be nice to have someday (in no particular order)
* graphical icons to replace the textual icons for various actions
* add/edit transactions from the reconciliation view
* statement API
* show percentage of credit limit consumed, rather than simply using text color
10 changes: 10 additions & 0 deletions app/helpers/subscriptions_helper.rb
Expand Up @@ -12,6 +12,16 @@ def balance_cell(container, options={})
classes = %w(number)
classes += Array(options[:classes]) if options[:classes]
classes << "negative" if balance < 0
classes << "current_balance"

if container.is_a?(Account) && container.credit_card? && !container.limit.blank?
percentage_used = container.limit.abs.to_i == 0 ? 100 :
((container.balance.abs.to_f / container.limit.abs.to_f) * 100).to_i
classes << if percentage_used >= Account::DEFAULT_LIMIT_VALUES[:critical]: "critical"
elsif percentage_used >= Account::DEFAULT_LIMIT_VALUES[:high]: "high"
elsif percentage_used >= Account::DEFAULT_LIMIT_VALUES[:medium]: "medium"
else "low" end
end

content = format_amount(balance)
if real_balance != balance
Expand Down
11 changes: 10 additions & 1 deletion app/models/account.rb
@@ -1,13 +1,22 @@
class Account < ActiveRecord::Base
DEFAULT_BUCKET_NAME = "General"

# When should the levels of credit cards be reached (in %)
DEFAULT_LIMIT_VALUES = {
:critical => 100,
:high => 80,
:medium => 30,
:low => 0
}

belongs_to :subscription
belongs_to :author, :class_name => "User", :foreign_key => "user_id"

attr_accessor :starting_balance
attr_accessible :name, :role, :starting_balance
attr_accessible :name, :role, :limit, :starting_balance

validates_presence_of :name
validates_presence_of :limit, :if => :credit_card?
validates_uniqueness_of :name, :scope => :subscription_id, :case_sensitive => false

has_many :buckets do
Expand Down
2 changes: 1 addition & 1 deletion app/models/statement.rb
Expand Up @@ -14,7 +14,7 @@ class Statement < ActiveRecord::Base

def ending_balance=(amount)
if amount.is_a?(Float) || amount =~ /[.,]/
amount = (amount.to_s.tr(",", "").to_f * 100).to_i
amount = (amount.to_s.tr(",", "").to_f * 100).round
end

super(amount)
Expand Down
7 changes: 6 additions & 1 deletion app/views/accounts/_form.html.haml
Expand Up @@ -21,7 +21,12 @@
%label
%strong=t :".what_kind"
=t :".of_account_is_this"
= form.select :role, [[t(:".Checking"), "checking"], [t(:".Credit_card"), "credit-card"], [t(:".Other"), "other"]]
= form.select :role, [[t(:".Checking"), "checking"], [t(:".Credit_card"), "credit-card"], [t(:".Other"), "other"]], {}, :onchange => "Accounts.showOrHideCreditLimit(this.value);"

%p{:style => 'display: none;', :id => 'credit_limit_div'}
%label
What is the <strong>credit limit</strong>:
== $#{form.text_field :limit, :class => "number", :size => 8}

- if form.object.nil? || form.object.new_record?
%fieldset
Expand Down
3 changes: 3 additions & 0 deletions app/views/accounts/_name.html.haml
@@ -1,4 +1,7 @@
%span.actions
- if account.credit_card?
= link_to_function("Adjust Limit", "Accounts.adjustLimit(#{account_path(account).to_json}, #{account.limit.to_json}, #{form_authenticity_token.to_json})")
|
- if account.statements.pending.any?
= link_to(t(:".resume_reconciling"), edit_statement_path(account.statements.pending.first))
- else
Expand Down
9 changes: 9 additions & 0 deletions db/migrate/20090516072907_add_limit_to_accounts.rb
@@ -0,0 +1,9 @@
class AddLimitToAccounts < ActiveRecord::Migration
def self.up
add_column :accounts, :limit, :integer
end

def self.down
remove_column :accounts, :limit
end
end
23 changes: 12 additions & 11 deletions db/schema.rb
Expand Up @@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.

ActiveRecord::Schema.define(:version => 20090523111542) do
ActiveRecord::Schema.define(:version => 20090516072907) do

create_table "account_items", :force => true do |t|
t.integer "event_id", :null => false
Expand All @@ -21,7 +21,7 @@

add_index "account_items", ["account_id", "occurred_on"], :name => "index_account_items_on_account_id_and_occurred_on"
add_index "account_items", ["event_id"], :name => "index_account_items_on_event_id"
add_index "account_items", ["occurred_on", "statement_id"], :name => "index_account_items_on_statement_id_and_occurred_on"
add_index "account_items", ["statement_id", "occurred_on"], :name => "index_account_items_on_statement_id_and_occurred_on"

create_table "accounts", :force => true do |t|
t.integer "subscription_id", :null => false
Expand All @@ -31,9 +31,10 @@
t.datetime "created_at"
t.datetime "updated_at"
t.integer "balance", :default => 0, :null => false
t.integer "limit"
end

add_index "accounts", ["name", "subscription_id"], :name => "index_accounts_on_subscription_id_and_name", :unique => true
add_index "accounts", ["subscription_id", "name"], :name => "index_accounts_on_subscription_id_and_name", :unique => true

create_table "actors", :force => true do |t|
t.integer "subscription_id", :null => false
Expand All @@ -43,7 +44,7 @@
t.datetime "updated_at"
end

add_index "actors", ["sort_name", "subscription_id"], :name => "index_actors_on_subscription_id_and_sort_name", :unique => true
add_index "actors", ["subscription_id", "sort_name"], :name => "index_actors_on_subscription_id_and_sort_name", :unique => true
add_index "actors", ["subscription_id", "updated_at"], :name => "index_actors_on_subscription_id_and_updated_at"

create_table "buckets", :force => true do |t|
Expand Down Expand Up @@ -72,10 +73,10 @@
end

add_index "events", ["actor_id"], :name => "index_events_on_actor_id"
add_index "events", ["actor_name", "subscription_id"], :name => "index_events_on_subscription_id_and_actor"
add_index "events", ["check_number", "subscription_id"], :name => "index_events_on_subscription_id_and_check_number"
add_index "events", ["created_at", "subscription_id"], :name => "index_events_on_subscription_id_and_created_at"
add_index "events", ["occurred_on", "subscription_id"], :name => "index_events_on_subscription_id_and_occurred_on"
add_index "events", ["subscription_id", "actor_name"], :name => "index_events_on_subscription_id_and_actor"
add_index "events", ["subscription_id", "check_number"], :name => "index_events_on_subscription_id_and_check_number"
add_index "events", ["subscription_id", "created_at"], :name => "index_events_on_subscription_id_and_created_at"
add_index "events", ["subscription_id", "occurred_on"], :name => "index_events_on_subscription_id_and_occurred_on"

create_table "line_items", :force => true do |t|
t.integer "event_id", :null => false
Expand Down Expand Up @@ -117,7 +118,7 @@
end

add_index "tagged_items", ["event_id"], :name => "index_tagged_items_on_event_id"
add_index "tagged_items", ["occurred_on", "tag_id"], :name => "index_tagged_items_on_tag_id_and_occurred_on"
add_index "tagged_items", ["tag_id", "occurred_on"], :name => "index_tagged_items_on_tag_id_and_occurred_on"

create_table "tags", :force => true do |t|
t.integer "subscription_id", :null => false
Expand All @@ -127,8 +128,8 @@
t.datetime "updated_at"
end

add_index "tags", ["balance", "subscription_id"], :name => "index_tags_on_subscription_id_and_balance"
add_index "tags", ["name", "subscription_id"], :name => "index_tags_on_subscription_id_and_name", :unique => true
add_index "tags", ["subscription_id", "balance"], :name => "index_tags_on_subscription_id_and_balance"
add_index "tags", ["subscription_id", "name"], :name => "index_tags_on_subscription_id_and_name", :unique => true

create_table "user_subscriptions", :force => true do |t|
t.integer "subscription_id", :null => false
Expand Down
47 changes: 47 additions & 0 deletions public/javascripts/accounts.js
Expand Up @@ -34,9 +34,18 @@ var Accounts = {
return false;
}

if($F('account_role') == 'credit-card' && $F('account_limit').blank()) {
$('account_name').activate();
alert('Please provide a limit for the account.');
return false;
}

var balance = Money.parse('current_balance', true);
$('account_starting_balance_amount').value = balance;

var limit = Money.parse('account_limit', true);
$('account_limit').value = limit;

return true;
},

Expand All @@ -57,5 +66,43 @@ var Accounts = {
parameters:params
});
}
},

adjustLimit: function(url, limit, token) {
new_limit = prompt("Enter the new limit for this account:", Money.formatValue(limit));
new_limit = Money.parseValue(new_limit);
while(new_limit == '') {
new_limit = prompt("Cannot have have a blank limit. Please re-enter it:", Money.formatValue(limit));
}
if(new_limit && new_limit != limit) {
params = encodeURIComponent("account[limit]") + "=" + encodeURIComponent(new_limit) +
"&authenticity_token=" + encodeURIComponent(token);

new Ajax.Request(url, {
asynchronous:true,
evalScripts:true,
method:'put',
parameters:params,
onSuccess: function(request) {
window.location.reload();
}
});
}
},

showOrHideCreditLimit: function(value) {
if (value == 'credit-card') {
Accounts.showCreditLimit();
} else {
Accounts.hideCreditLimit();
}
},

showCreditLimit: function() {
$('credit_limit_div').show();
},

hideCreditLimit: function() {
$('credit_limit_div').hide();
}
}
18 changes: 17 additions & 1 deletion public/stylesheets/money.css
Expand Up @@ -277,7 +277,23 @@ span.check {
}

.negative {
color: red;
color: red !important;
}

.critical {
color: red !important;
}

.high {
color: brown !important;
}

.medium {
color: sandybrown !important;
}

.low {
color: green !important;
}

td.date, th.date {
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/accounts.yml
Expand Up @@ -17,6 +17,7 @@ john_mastercard:
name: Mastercard
role: credit-card
balance: -2525
limit: 5000
created_at: <%= (60.days.ago + 2.hours).utc.to_s(:db) %>
updated_at: <%= (60.days.ago + 2.hours).utc.to_s(:db) %>

Expand Down
3 changes: 2 additions & 1 deletion test/unit/account_test.rb
Expand Up @@ -141,7 +141,8 @@ def new_account(options={})
subscription = options.delete(:subscription) || subscriptions(:john)

options = {:name => "Visa",
:role => "credit-card"}.merge(options)
:role => "credit-card",
:limit => 5000}.merge(options)

subscription.accounts.create(options, :author => users(:john))
end
Expand Down
5 changes: 5 additions & 0 deletions test/unit/statement_test.rb
Expand Up @@ -77,4 +77,9 @@ class StatementTest < ActiveSupport::TestCase
:cleared => statements(:john).account_items.map(&:id)
assert !statements(:john).balanced?(true)
end

test "ending_balance should not have truncation errors" do
statements(:john).update_attribute :ending_balance, 2557.68
assert statements(:john).ending_balance == 255768
end
end

0 comments on commit 4c0fb39

Please sign in to comment.