yhara-moneyrail 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/.gitmodules +6 -0
- data/Changelog +21 -0
- data/README +1 -0
- data/Rakefile +32 -0
- data/VERSION +1 -0
- data/app/controllers/accounts_controller.rb +99 -0
- data/app/controllers/application_controller.rb +10 -0
- data/app/controllers/categories_controller.rb +99 -0
- data/app/controllers/home_controller.rb +31 -0
- data/app/controllers/items_controller.rb +105 -0
- data/app/controllers/logs_controller.rb +20 -0
- data/app/helpers/accounts_helper.rb +2 -0
- data/app/helpers/application_helper.rb +3 -0
- data/app/helpers/categories_helper.rb +2 -0
- data/app/helpers/home_helper.rb +2 -0
- data/app/helpers/items_helper.rb +2 -0
- data/app/helpers/logs_helper.rb +42 -0
- data/app/models/account.rb +12 -0
- data/app/models/category.rb +26 -0
- data/app/models/expense.rb +2 -0
- data/app/models/income.rb +2 -0
- data/app/models/item.rb +31 -0
- data/app/models/move.rb +37 -0
- data/app/models/simple_item.rb +27 -0
- data/app/views/accounts/edit.html.erb +16 -0
- data/app/views/accounts/index.html.erb +24 -0
- data/app/views/accounts/new.html.erb +15 -0
- data/app/views/accounts/show.html.erb +8 -0
- data/app/views/categories/edit.html.erb +20 -0
- data/app/views/categories/index.html.erb +26 -0
- data/app/views/categories/new.html.erb +19 -0
- data/app/views/categories/show.html.erb +13 -0
- data/app/views/home/index.html.erb +15 -0
- data/app/views/items/edit.html.erb +45 -0
- data/app/views/items/index.html.erb +38 -0
- data/app/views/items/new.html.erb +40 -0
- data/app/views/items/show.html.erb +3 -0
- data/app/views/layouts/application.html.erb +37 -0
- data/app/views/logs/view.html.erb +120 -0
- data/config/boot.rb +110 -0
- data/config/database.yml +25 -0
- data/config/environment.rb +41 -0
- data/config/environments/cucumber.rb +21 -0
- data/config/environments/development.rb +17 -0
- data/config/environments/production.rb +28 -0
- data/config/environments/test.rb +28 -0
- data/config/initializers/backtrace_silencers.rb +7 -0
- data/config/initializers/inflections.rb +10 -0
- data/config/initializers/mime_types.rb +5 -0
- data/config/initializers/new_rails_defaults.rb +19 -0
- data/config/initializers/session_store.rb +15 -0
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +80 -0
- data/db/migrate/20090802070406_create_accounts.rb +14 -0
- data/db/migrate/20090802073601_create_categories.rb +15 -0
- data/db/migrate/20090804065900_create_items.rb +26 -0
- data/doc/README_FOR_APP +2 -0
- data/features/step_definitions/webrat_steps.rb +129 -0
- data/features/support/env.rb +37 -0
- data/features/support/paths.rb +27 -0
- data/lib/tasks/cucumber.rake +20 -0
- data/lib/tasks/rspec.rake +182 -0
- data/main.rb +5 -0
- data/moneyrail.gemspec +170 -0
- data/public/404.html +30 -0
- data/public/422.html +30 -0
- data/public/500.html +30 -0
- data/public/favicon.ico +0 -0
- data/public/images/rails.png +0 -0
- data/public/javascripts/application.js +2 -0
- data/public/javascripts/controls.js +963 -0
- data/public/javascripts/dragdrop.js +973 -0
- data/public/javascripts/editor.js +188 -0
- data/public/javascripts/effects.js +1128 -0
- data/public/javascripts/jquery-ui.js +160 -0
- data/public/javascripts/jquery.js +32 -0
- data/public/javascripts/prototype.js +4320 -0
- data/public/robots.txt +5 -0
- data/public/stylesheets/editor.less +67 -0
- data/script/about +4 -0
- data/script/autospec +6 -0
- data/script/console +3 -0
- data/script/cucumber +8 -0
- data/script/dbconsole +3 -0
- data/script/destroy +3 -0
- data/script/generate +3 -0
- data/script/performance/benchmarker +3 -0
- data/script/performance/profiler +3 -0
- data/script/plugin +3 -0
- data/script/runner +3 -0
- data/script/server +3 -0
- data/script/spec +10 -0
- data/script/spec_server +9 -0
- data/spec/_fixtures/accounts.yml +5 -0
- data/spec/_fixtures/categories.yml +19 -0
- data/spec/_fixtures/incomes.yml +7 -0
- data/spec/_fixtures/items.yml +7 -0
- data/spec/fixtures/accounts.yml +11 -0
- data/spec/fixtures/categories.yml +24 -0
- data/spec/fixtures/items.yml +82 -0
- data/spec/helpers/accounts_helper_spec.rb +11 -0
- data/spec/helpers/categories_helper_spec.rb +11 -0
- data/spec/helpers/items_helper_spec.rb +11 -0
- data/spec/models/account_spec.rb +13 -0
- data/spec/models/category_spec.rb +9 -0
- data/spec/models/income_spec.rb +9 -0
- data/spec/models/item_spec.rb +13 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +51 -0
- data/vendor/plugins/acts_as_list/README +23 -0
- data/vendor/plugins/acts_as_list/init.rb +3 -0
- data/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb +256 -0
- data/vendor/plugins/acts_as_list/test/list_test.rb +332 -0
- data/vendor/plugins/less/LICENCE +20 -0
- data/vendor/plugins/less/README +52 -0
- data/vendor/plugins/less/init.rb +19 -0
- data/vendor/plugins/less/lib/less_for_rails.rb +37 -0
- data/vendor/plugins/less/test/less_for_rails_test.rb +15 -0
- metadata +201 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
module LogsHelper
|
2
|
+
|
3
|
+
def cell(value)
|
4
|
+
if @mode == :edit
|
5
|
+
"<input type='text' value='#{h value}' />"
|
6
|
+
else
|
7
|
+
"<div>#{h value}</div>"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# returns [Date(2009/8/1), nil, nil, Income, ..]
|
12
|
+
def make_table_data(account)
|
13
|
+
condition = {
|
14
|
+
:conditions => {:date => @month_range},
|
15
|
+
}
|
16
|
+
items = [
|
17
|
+
account.expenses.all(condition),
|
18
|
+
account.incomes.all(condition),
|
19
|
+
account.moves_from.all(condition),
|
20
|
+
account.moves_to.all(condition),
|
21
|
+
].flatten(1)
|
22
|
+
|
23
|
+
@month_range.map{|today|
|
24
|
+
todays, items = items.partition{|m| m.date == today}
|
25
|
+
positions = todays.map(&:position)
|
26
|
+
max_position = (positions.empty?) ? 0 : positions.max
|
27
|
+
|
28
|
+
(0..max_position).map{|i|
|
29
|
+
day = (i==0) ? today : :no_date
|
30
|
+
[
|
31
|
+
today,
|
32
|
+
i,
|
33
|
+
i == max_position,
|
34
|
+
@cat_all.map{|cat|
|
35
|
+
todays.find{|m| m.category == cat && m.position == i}
|
36
|
+
}.unshift(day)
|
37
|
+
]
|
38
|
+
}
|
39
|
+
}.flatten(1)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Account < ActiveRecord::Base
|
2
|
+
has_many :incomes
|
3
|
+
has_many :expenses
|
4
|
+
has_many :moves_from, :class_name => "Move", :foreign_key => :account_id_from
|
5
|
+
has_many :moves_to, :class_name => "Move", :foreign_key => :account_id_to
|
6
|
+
|
7
|
+
validates_presence_of :name
|
8
|
+
validates_uniqueness_of :name
|
9
|
+
|
10
|
+
# provides move_higher, move_lower, etc.
|
11
|
+
acts_as_list
|
12
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Category < ActiveRecord::Base
|
2
|
+
validates_presence_of :name
|
3
|
+
validates_uniqueness_of :name
|
4
|
+
|
5
|
+
def validate
|
6
|
+
unless %w(Income Expense Move).include?(self.kind)
|
7
|
+
errors.add("kind", "#{self.kind.inspect} must be either of Income, Expense, Move")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# provides move_higher, move_lower, etc.
|
12
|
+
# categories are indexed in those of the same kind
|
13
|
+
acts_as_list :scope => 'kind == \'#{kind}\''
|
14
|
+
|
15
|
+
def self.hashed
|
16
|
+
{
|
17
|
+
:income =>
|
18
|
+
self.all(:conditions => {:kind => "Income"}, :order => "position"),
|
19
|
+
:expense =>
|
20
|
+
self.all(:conditions => {:kind => "Expense"}, :order => "position"),
|
21
|
+
:move =>
|
22
|
+
self.all(:conditions => {:kind => "Move"}, :order => "position")
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/app/models/item.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
class Item < ActiveRecord::Base
|
2
|
+
belongs_to :category
|
3
|
+
|
4
|
+
# validations
|
5
|
+
|
6
|
+
def before_validation
|
7
|
+
self.title = "" if self.title.nil?
|
8
|
+
self.amount = 0 if self.amount.blank?
|
9
|
+
end
|
10
|
+
|
11
|
+
validates_presence_of :date
|
12
|
+
|
13
|
+
validates_presence_of :amount, :position
|
14
|
+
validates_numericality_of :amount, :position
|
15
|
+
|
16
|
+
def self.find_conflict(item)
|
17
|
+
item.type.constantize.find_conflict(item)
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate
|
21
|
+
# validate category
|
22
|
+
unless self.category && self.category.kind == self.type
|
23
|
+
errors.add("category", "the category is not for #{self.type}")
|
24
|
+
end
|
25
|
+
|
26
|
+
# validate index of day
|
27
|
+
if same = self.class.find_conflict(self)
|
28
|
+
errors.add("position", "position #{position} conflicts with #{same.title} (#{same.amount}, #{same.date})")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/app/models/move.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class Move < Item
|
2
|
+
# associations
|
3
|
+
|
4
|
+
belongs_to :account_from, :class_name => "Account", :foreign_key => :account_id_from
|
5
|
+
belongs_to :account_to, :class_name => "Account", :foreign_key => :account_id_to
|
6
|
+
|
7
|
+
# validations
|
8
|
+
|
9
|
+
validates_presence_of :account_from
|
10
|
+
validates_presence_of :account_to
|
11
|
+
|
12
|
+
def self.find_conflict(item)
|
13
|
+
Move.all(:conditions => {
|
14
|
+
:date => item.date,
|
15
|
+
:account_id_from => item.account_id_from,
|
16
|
+
:account_id_to => item.account_id_to,
|
17
|
+
:category_id => item.category_id,
|
18
|
+
:position => item.position,
|
19
|
+
}).reject{|x| x.id == item.id}.first
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate
|
23
|
+
if account_id_from == account_id_to
|
24
|
+
errors.add("account_id_from", "from and to must not be same")
|
25
|
+
end
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
# featues
|
30
|
+
|
31
|
+
acts_as_list :scope => [
|
32
|
+
'date = #{date}',
|
33
|
+
'account_id_from = #{account_id_from}',
|
34
|
+
'account_id_to = #{account_id_to}',
|
35
|
+
'category_id = #{category_id}',
|
36
|
+
].join(" AND ")
|
37
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class SimpleItem < Item
|
2
|
+
# associations
|
3
|
+
|
4
|
+
belongs_to :account
|
5
|
+
|
6
|
+
# validations
|
7
|
+
|
8
|
+
validates_presence_of :account
|
9
|
+
|
10
|
+
def self.find_conflict(item)
|
11
|
+
Item.all(:conditions => {
|
12
|
+
:type => item.type,
|
13
|
+
:date => item.date,
|
14
|
+
:account_id => item.account_id,
|
15
|
+
:category_id => item.category_id,
|
16
|
+
:position => item.position,
|
17
|
+
}).reject{|x| x.id == item.id}.first
|
18
|
+
end
|
19
|
+
|
20
|
+
# featues
|
21
|
+
|
22
|
+
acts_as_list :scope => [
|
23
|
+
'date = #{date}',
|
24
|
+
'account_id = #{account_id}',
|
25
|
+
'category_id = #{category_id}',
|
26
|
+
].join(" AND ")
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<h2>Editing account</h2>
|
2
|
+
|
3
|
+
<% form_for(@account) do |f| %>
|
4
|
+
<%= f.error_messages %>
|
5
|
+
|
6
|
+
<p>
|
7
|
+
<%= f.label :name %><br />
|
8
|
+
<%= f.text_field :name %>
|
9
|
+
</p>
|
10
|
+
<p>
|
11
|
+
<%= f.submit 'Update' %>
|
12
|
+
</p>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<%= link_to 'Show', @account %> |
|
16
|
+
<%= link_to 'Back', accounts_path %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<h2>Listing accounts</h2>
|
2
|
+
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th>Name</th>
|
6
|
+
</tr>
|
7
|
+
|
8
|
+
<% @accounts.each do |account| %>
|
9
|
+
<tr>
|
10
|
+
<td><%=h account.name %></td>
|
11
|
+
<td><%= link_to 'Show', account %></td>
|
12
|
+
<td><%= link_to 'Edit', edit_account_path(account) %></td>
|
13
|
+
<td><%= link_to 'Destroy', account, :confirm => 'Are you sure?', :method => :delete %></td>
|
14
|
+
<td><%= link_to '↑', move_up_account_path(account) %></td>
|
15
|
+
<td><%= link_to '↓', move_down_account_path(account) %></td>
|
16
|
+
</tr>
|
17
|
+
<% end %>
|
18
|
+
</table>
|
19
|
+
|
20
|
+
<br />
|
21
|
+
|
22
|
+
<%= link_to 'New account', new_account_path %>
|
23
|
+
|
24
|
+
<%= link_to 'back', root_path %>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<h2>New account</h2>
|
2
|
+
|
3
|
+
<% form_for(@account) do |f| %>
|
4
|
+
<%= f.error_messages %>
|
5
|
+
|
6
|
+
<p>
|
7
|
+
<%= f.label :name %><br />
|
8
|
+
<%= f.text_field :name %>
|
9
|
+
</p>
|
10
|
+
<p>
|
11
|
+
<%= f.submit 'Create' %>
|
12
|
+
</p>
|
13
|
+
<% end %>
|
14
|
+
|
15
|
+
<%= link_to 'Back', accounts_path %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<h2>Editing category</h2>
|
2
|
+
|
3
|
+
<% form_for(@category) do |f| %>
|
4
|
+
<%= f.error_messages %>
|
5
|
+
|
6
|
+
<p>
|
7
|
+
<%= f.label :name %><br />
|
8
|
+
<%= f.text_field :name %>
|
9
|
+
</p>
|
10
|
+
<p>
|
11
|
+
<%= f.label :kind %><br />
|
12
|
+
<%= f.text_field :kind %>
|
13
|
+
</p>
|
14
|
+
<p>
|
15
|
+
<%= f.submit 'Update' %>
|
16
|
+
</p>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<%= link_to 'Show', @category %> |
|
20
|
+
<%= link_to 'Back', categories_path %>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<h2>Listing categories</h2>
|
2
|
+
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<th>Name</th>
|
6
|
+
<th>Kind</th>
|
7
|
+
</tr>
|
8
|
+
|
9
|
+
<% @categories.each do |category| %>
|
10
|
+
<tr>
|
11
|
+
<td><%=h category.name %></td>
|
12
|
+
<td><%=h category.kind %></td>
|
13
|
+
<td><%= link_to 'Show', category %></td>
|
14
|
+
<td><%= link_to 'Edit', edit_category_path(category) %></td>
|
15
|
+
<td><%= link_to 'Destroy', category, :confirm => 'Are you sure?', :method => :delete %></td>
|
16
|
+
<td><%= link_to '↑', move_up_category_path(category) %></td>
|
17
|
+
<td><%= link_to '↓', move_down_category_path(category) %></td>
|
18
|
+
</tr>
|
19
|
+
<% end %>
|
20
|
+
</table>
|
21
|
+
|
22
|
+
<br />
|
23
|
+
|
24
|
+
<%= link_to 'New category', new_category_path %>
|
25
|
+
|
26
|
+
<%= link_to 'back', root_path %>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<h2>New category</h2>
|
2
|
+
|
3
|
+
<% form_for(@category) do |f| %>
|
4
|
+
<%= f.error_messages %>
|
5
|
+
|
6
|
+
<p>
|
7
|
+
<%= f.label :name %><br />
|
8
|
+
<%= f.text_field :name %>
|
9
|
+
</p>
|
10
|
+
<p>
|
11
|
+
<%= f.label :kind %><br />
|
12
|
+
<%= f.select :kind, %w(Expense Income Move) %>
|
13
|
+
</p>
|
14
|
+
<p>
|
15
|
+
<%= f.submit 'Create' %>
|
16
|
+
</p>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<%= link_to 'Back', categories_path %>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<ul>
|
2
|
+
<li><%= link_to 'Accounts', accounts_path %></li>
|
3
|
+
<li><%= link_to 'Categories', categories_path %></li>
|
4
|
+
<li><%= link_to 'Items', items_path %></li>
|
5
|
+
</ul>
|
6
|
+
<ul>
|
7
|
+
<% @months.each do |m| %>
|
8
|
+
<li>
|
9
|
+
<%= link_to "Logs: #{m.year}-#{m.month}",
|
10
|
+
show_logs_path(:year => m.year, :month => m.month) %>
|
11
|
+
<%= link_to "(edit)",
|
12
|
+
edit_logs_path(:year => m.year, :month => m.month) %>
|
13
|
+
</li>
|
14
|
+
<% end %>
|
15
|
+
</ul>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
<h2>Editing item</h2>
|
2
|
+
|
3
|
+
<% form_for :item, @item, :url => item_path(@item), :html => {:method => :put} do |f| %>
|
4
|
+
<%= f.error_messages %>
|
5
|
+
|
6
|
+
<p>
|
7
|
+
<%= f.label :title %><br />
|
8
|
+
<%= f.text_field :title %>
|
9
|
+
</p>
|
10
|
+
<p>
|
11
|
+
<%= f.label :amount %><br />
|
12
|
+
<%= f.text_field :amount %>
|
13
|
+
</p>
|
14
|
+
<p>
|
15
|
+
<%= f.label :type %><br />
|
16
|
+
<%= f.select :type, %w(Expense Income Move).map{|x| [x, x]} %>
|
17
|
+
</p>
|
18
|
+
<p>
|
19
|
+
<%= f.label :category_id %><br />
|
20
|
+
<%= f.select :category_id, @categories.map{|c| [c.name, c.id]} %>
|
21
|
+
</p>
|
22
|
+
<p>
|
23
|
+
<%= f.label :date %><br />
|
24
|
+
<%= f.text_field :date %>
|
25
|
+
</p>
|
26
|
+
<p>
|
27
|
+
<%= f.label :position %><br />
|
28
|
+
<%= f.text_field :position %>
|
29
|
+
</p>
|
30
|
+
<p id="one_account">
|
31
|
+
<%= f.label :account_id %><br />
|
32
|
+
<%= f.select :account_id, @accounts.map{|a| [a.name, a.id]} %>
|
33
|
+
</p>
|
34
|
+
<p id="two_accounts">
|
35
|
+
<%= f.label :account_id_from %><br />
|
36
|
+
<%= f.select :account_id_from, @accounts.map{|a| [a.name, a.id]} %>
|
37
|
+
→ <%= f.select :account_id_to, @accounts.map{|a| [a.name, a.id]} %>
|
38
|
+
</p>
|
39
|
+
<p>
|
40
|
+
<%= f.submit 'Update' %>
|
41
|
+
</p>
|
42
|
+
<% end %>
|
43
|
+
|
44
|
+
<%= link_to 'Show', @item %> |
|
45
|
+
<%= link_to 'Back', items_path %>
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<h2>Listing items</h2>
|
2
|
+
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<td>date</td>
|
6
|
+
<td>category</td>
|
7
|
+
<td>title</td>
|
8
|
+
<td>amount</td>
|
9
|
+
<td>account</td>
|
10
|
+
</tr>
|
11
|
+
|
12
|
+
<% @items.each do |item| %>
|
13
|
+
<tr>
|
14
|
+
<td><%=h item.date %></td>
|
15
|
+
<td><%=h item.category.name %></td>
|
16
|
+
<td><%=h item.title %></td>
|
17
|
+
<td><%=h item.amount %></td>
|
18
|
+
<td>
|
19
|
+
<% if item.is_a?(Move) %>
|
20
|
+
<%=h item.account_from.name %>→<%=h item.account_to.name %>
|
21
|
+
<% elsif item.is_a?(Expense) %>
|
22
|
+
←<%=h item.account.name %>
|
23
|
+
<% else %>
|
24
|
+
→<%=h item.account.name %>
|
25
|
+
<% end %>
|
26
|
+
</td>
|
27
|
+
<!--<td><%= link_to 'Show', item %></td>-->
|
28
|
+
<td><%= link_to 'Edit', edit_item_path(item) %></td>
|
29
|
+
<td><%= link_to 'Destroy', item, :confirm => 'Are you sure?', :method => :delete %></td>
|
30
|
+
</tr>
|
31
|
+
<% end %>
|
32
|
+
</table>
|
33
|
+
|
34
|
+
<br />
|
35
|
+
|
36
|
+
<%= link_to 'New item', new_item_path %>
|
37
|
+
|
38
|
+
<%= link_to 'back', root_path %>
|