bookkeeper 0.0.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +22 -0
  3. data/Rakefile +44 -0
  4. data/app/assets/javascripts/bookkeeper.js +10 -0
  5. data/app/assets/javascripts/bookkeeper/bootstrap-datepicker.js +470 -0
  6. data/app/assets/stylesheets/bookkeeper.css +13 -0
  7. data/app/assets/stylesheets/bookkeeper/datepicker.css +182 -0
  8. data/app/assets/stylesheets/bookkeeper/scaffold.css +56 -0
  9. data/app/controllers/bookkeeper/application_controller.rb +5 -0
  10. data/app/controllers/bookkeeper/purchases_controller.rb +74 -0
  11. data/app/helpers/bookkeeper/application_helper.rb +4 -0
  12. data/app/inputs/datepicker_input.rb +9 -0
  13. data/app/models/bookkeeper/purchase.rb +11 -0
  14. data/app/uploaders/receipt_uploader.rb +57 -0
  15. data/app/views/bookkeeper/purchases/_form.html.erb +17 -0
  16. data/app/views/bookkeeper/purchases/edit.html.erb +6 -0
  17. data/app/views/bookkeeper/purchases/index.html.erb +34 -0
  18. data/app/views/bookkeeper/purchases/new.html.erb +5 -0
  19. data/app/views/bookkeeper/purchases/show.html.erb +34 -0
  20. data/app/views/layouts/bookkeeper/application.html.erb +14 -0
  21. data/config/initializers/carrierwave.rb +6 -0
  22. data/config/initializers/simple_form.rb +142 -0
  23. data/config/initializers/simple_form_bootstrap.rb +45 -0
  24. data/config/initializers/validates_timeliness.rb +40 -0
  25. data/config/locales/simple_form.en.yml +26 -0
  26. data/config/locales/validates_timeliness.en.yml +16 -0
  27. data/config/routes.rb +3 -0
  28. data/db/migrate/20130215165240_create_bookkeeper_purchases.rb +13 -0
  29. data/lib/bookkeeper.rb +4 -0
  30. data/lib/bookkeeper/engine.rb +17 -0
  31. data/lib/bookkeeper/version.rb +3 -0
  32. data/lib/tasks/bookkeeper_tasks.rake +4 -0
  33. data/lib/templates/erb/scaffold/_form.html.erb +13 -0
  34. data/spec/assets/images/receipt.jpg +0 -0
  35. data/spec/controllers/bookkeeper/purchases_controller_spec.rb +156 -0
  36. data/spec/dummy/README.rdoc +261 -0
  37. data/spec/dummy/Rakefile +7 -0
  38. data/spec/dummy/app/assets/images/glyphicons-halflings-white.png +0 -0
  39. data/spec/dummy/app/assets/images/glyphicons-halflings.png +0 -0
  40. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  41. data/spec/dummy/app/assets/javascripts/bootstrap.js +2268 -0
  42. data/spec/dummy/app/assets/stylesheets/application.css +14 -0
  43. data/spec/dummy/app/assets/stylesheets/bootstrap-responsive.css +1109 -0
  44. data/spec/dummy/app/assets/stylesheets/bootstrap.css +6158 -0
  45. data/spec/dummy/app/assets/stylesheets/font-awesome-ie7.min.css +22 -0
  46. data/spec/dummy/app/assets/stylesheets/font-awesome.min.css +33 -0
  47. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  48. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  49. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  50. data/spec/dummy/config.ru +4 -0
  51. data/spec/dummy/config/application.rb +65 -0
  52. data/spec/dummy/config/boot.rb +10 -0
  53. data/spec/dummy/config/database.yml +25 -0
  54. data/spec/dummy/config/environment.rb +5 -0
  55. data/spec/dummy/config/environments/development.rb +37 -0
  56. data/spec/dummy/config/environments/production.rb +67 -0
  57. data/spec/dummy/config/environments/test.rb +37 -0
  58. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  59. data/spec/dummy/config/initializers/inflections.rb +15 -0
  60. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  61. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  62. data/spec/dummy/config/initializers/session_store.rb +8 -0
  63. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  64. data/spec/dummy/config/locales/en.yml +5 -0
  65. data/spec/dummy/config/routes.rb +4 -0
  66. data/spec/dummy/db/development.sqlite3 +0 -0
  67. data/spec/dummy/db/schema.rb +26 -0
  68. data/spec/dummy/db/test.sqlite3 +0 -0
  69. data/spec/dummy/public/404.html +26 -0
  70. data/spec/dummy/public/422.html +26 -0
  71. data/spec/dummy/public/500.html +25 -0
  72. data/spec/dummy/public/favicon.ico +0 -0
  73. data/spec/dummy/public/font/FontAwesome.otf +0 -0
  74. data/spec/dummy/public/font/fontawesome-webfont.eot +0 -0
  75. data/spec/dummy/public/font/fontawesome-webfont.svg +284 -0
  76. data/spec/dummy/public/font/fontawesome-webfont.ttf +0 -0
  77. data/spec/dummy/public/font/fontawesome-webfont.woff +0 -0
  78. data/spec/dummy/script/rails +6 -0
  79. data/spec/factories/bookkeeper_purchases.rb +15 -0
  80. data/spec/models/bookkeeper/purchase_spec.rb +51 -0
  81. data/spec/routing/bookkeeper/purchases_routing_spec.rb +37 -0
  82. data/spec/spec_helper.rb +19 -0
  83. data/spec/uploaders/receipt_uploader_spec.rb +26 -0
  84. data/spec/views/bookkeeper/purchases/edit.html.erb_spec.rb +22 -0
  85. data/spec/views/bookkeeper/purchases/index.html.erb_spec.rb +26 -0
  86. data/spec/views/bookkeeper/purchases/new.html.erb_spec.rb +22 -0
  87. data/spec/views/bookkeeper/purchases/show.html.erb_spec.rb +19 -0
  88. metadata +396 -0
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree './bookkeeper'
13
+ */
@@ -0,0 +1,182 @@
1
+ /*!
2
+ * Datepicker for Bootstrap
3
+ *
4
+ * Copyright 2012 Stefan Petre
5
+ * Licensed under the Apache License v2.0
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ */
9
+ .datepicker {
10
+ top: 0;
11
+ left: 0;
12
+ padding: 4px;
13
+ /* margin-top: 1px; */
14
+ -webkit-border-radius: 4px;
15
+ -moz-border-radius: 4px;
16
+ border-radius: 4px;
17
+ /*.dow {
18
+ border-top: 1px solid #ddd !important;
19
+ }*/
20
+
21
+ }
22
+ .datepicker:before {
23
+ content: '';
24
+ display: inline-block;
25
+ border-left: 7px solid transparent;
26
+ border-right: 7px solid transparent;
27
+ border-bottom: 7px solid #ccc;
28
+ border-bottom-color: rgba(0, 0, 0, 0.2);
29
+ position: absolute;
30
+ top: -7px;
31
+ left: 6px;
32
+ }
33
+ .datepicker:after {
34
+ content: '';
35
+ display: inline-block;
36
+ border-left: 6px solid transparent;
37
+ border-right: 6px solid transparent;
38
+ border-bottom: 6px solid #ffffff;
39
+ position: absolute;
40
+ top: -6px;
41
+ left: 7px;
42
+ }
43
+ .datepicker > div {
44
+ display: none;
45
+ }
46
+ .datepicker table {
47
+ width: 100%;
48
+ margin: 0;
49
+ }
50
+ .datepicker td,
51
+ .datepicker th {
52
+ text-align: center;
53
+ width: 20px;
54
+ height: 20px;
55
+ -webkit-border-radius: 4px;
56
+ -moz-border-radius: 4px;
57
+ border-radius: 4px;
58
+ }
59
+ .datepicker td.day:hover {
60
+ background: #eeeeee;
61
+ cursor: pointer;
62
+ }
63
+ .datepicker td.day.disabled {
64
+ color: #eeeeee;
65
+ }
66
+ .datepicker td.old,
67
+ .datepicker td.new {
68
+ color: #999999;
69
+ }
70
+ .datepicker td.active,
71
+ .datepicker td.active:hover {
72
+ color: #ffffff;
73
+ background-color: #006dcc;
74
+ background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
75
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
76
+ background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
77
+ background-image: -o-linear-gradient(top, #0088cc, #0044cc);
78
+ background-image: linear-gradient(to bottom, #0088cc, #0044cc);
79
+ background-repeat: repeat-x;
80
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
81
+ border-color: #0044cc #0044cc #002a80;
82
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
83
+ *background-color: #0044cc;
84
+ /* Darken IE7 buttons by default so they stand out more given they won't have borders */
85
+
86
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
87
+ color: #fff;
88
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
89
+ }
90
+ .datepicker td.active:hover,
91
+ .datepicker td.active:hover:hover,
92
+ .datepicker td.active:focus,
93
+ .datepicker td.active:hover:focus,
94
+ .datepicker td.active:active,
95
+ .datepicker td.active:hover:active,
96
+ .datepicker td.active.active,
97
+ .datepicker td.active:hover.active,
98
+ .datepicker td.active.disabled,
99
+ .datepicker td.active:hover.disabled,
100
+ .datepicker td.active[disabled],
101
+ .datepicker td.active:hover[disabled] {
102
+ color: #ffffff;
103
+ background-color: #0044cc;
104
+ *background-color: #003bb3;
105
+ }
106
+ .datepicker td.active:active,
107
+ .datepicker td.active:hover:active,
108
+ .datepicker td.active.active,
109
+ .datepicker td.active:hover.active {
110
+ background-color: #003399 \9;
111
+ }
112
+ .datepicker td span {
113
+ display: block;
114
+ width: 47px;
115
+ height: 54px;
116
+ line-height: 54px;
117
+ float: left;
118
+ margin: 2px;
119
+ cursor: pointer;
120
+ -webkit-border-radius: 4px;
121
+ -moz-border-radius: 4px;
122
+ border-radius: 4px;
123
+ }
124
+ .datepicker td span:hover {
125
+ background: #eeeeee;
126
+ }
127
+ .datepicker td span.active {
128
+ color: #ffffff;
129
+ background-color: #006dcc;
130
+ background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
131
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
132
+ background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
133
+ background-image: -o-linear-gradient(top, #0088cc, #0044cc);
134
+ background-image: linear-gradient(to bottom, #0088cc, #0044cc);
135
+ background-repeat: repeat-x;
136
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
137
+ border-color: #0044cc #0044cc #002a80;
138
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
139
+ *background-color: #0044cc;
140
+ /* Darken IE7 buttons by default so they stand out more given they won't have borders */
141
+
142
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
143
+ color: #fff;
144
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
145
+ }
146
+ .datepicker td span.active:hover,
147
+ .datepicker td span.active:focus,
148
+ .datepicker td span.active:active,
149
+ .datepicker td span.active.active,
150
+ .datepicker td span.active.disabled,
151
+ .datepicker td span.active[disabled] {
152
+ color: #ffffff;
153
+ background-color: #0044cc;
154
+ *background-color: #003bb3;
155
+ }
156
+ .datepicker td span.active:active,
157
+ .datepicker td span.active.active {
158
+ background-color: #003399 \9;
159
+ }
160
+ .datepicker td span.old {
161
+ color: #999999;
162
+ }
163
+ .datepicker th.switch {
164
+ width: 145px;
165
+ }
166
+ .datepicker th.next,
167
+ .datepicker th.prev {
168
+ font-size: 21px;
169
+ }
170
+ .datepicker thead tr:first-child th {
171
+ cursor: pointer;
172
+ }
173
+ .datepicker thead tr:first-child th:hover {
174
+ background: #eeeeee;
175
+ }
176
+ .input-append.date .add-on i,
177
+ .input-prepend.date .add-on i {
178
+ display: block;
179
+ cursor: pointer;
180
+ width: 16px;
181
+ height: 16px;
182
+ }
@@ -0,0 +1,56 @@
1
+ body { background-color: #fff; color: #333; }
2
+
3
+ body, p, ol, ul, td {
4
+ font-family: verdana, arial, helvetica, sans-serif;
5
+ font-size: 13px;
6
+ line-height: 18px;
7
+ }
8
+
9
+ pre {
10
+ background-color: #eee;
11
+ padding: 10px;
12
+ font-size: 11px;
13
+ }
14
+
15
+ a { color: #000; }
16
+ a:visited { color: #666; }
17
+ a:hover { color: #fff; background-color:#000; }
18
+
19
+ div.field, div.actions {
20
+ margin-bottom: 10px;
21
+ }
22
+
23
+ #notice {
24
+ color: green;
25
+ }
26
+
27
+ .field_with_errors {
28
+ padding: 2px;
29
+ background-color: red;
30
+ display: table;
31
+ }
32
+
33
+ #error_explanation {
34
+ width: 450px;
35
+ border: 2px solid red;
36
+ padding: 7px;
37
+ padding-bottom: 0;
38
+ margin-bottom: 20px;
39
+ background-color: #f0f0f0;
40
+ }
41
+
42
+ #error_explanation h2 {
43
+ text-align: left;
44
+ font-weight: bold;
45
+ padding: 5px 5px 5px 15px;
46
+ font-size: 12px;
47
+ margin: -7px;
48
+ margin-bottom: 0px;
49
+ background-color: #c00;
50
+ color: #fff;
51
+ }
52
+
53
+ #error_explanation ul li {
54
+ font-size: 12px;
55
+ list-style: square;
56
+ }
@@ -0,0 +1,5 @@
1
+ module Bookkeeper
2
+ class ApplicationController < ActionController::Base
3
+ layout 'application'
4
+ end
5
+ end
@@ -0,0 +1,74 @@
1
+ require_dependency "bookkeeper/application_controller"
2
+
3
+ module Bookkeeper
4
+ class PurchasesController < ApplicationController
5
+ def index
6
+ @purchases = Purchase.all
7
+
8
+ respond_to do |format|
9
+ format.html
10
+ format.json { render json: @purchases }
11
+ end
12
+ end
13
+
14
+ def show
15
+ @purchase = Purchase.find(params[:id])
16
+
17
+ respond_to do |format|
18
+ format.html
19
+ format.json { render json: @purchase }
20
+ end
21
+ end
22
+
23
+ def new
24
+ @purchase = Purchase.new
25
+
26
+ respond_to do |format|
27
+ format.html
28
+ format.json { render json: @purchase }
29
+ end
30
+ end
31
+
32
+ def edit
33
+ @purchase = Purchase.find(params[:id])
34
+ end
35
+
36
+ def create
37
+ @purchase = Purchase.new(params[:purchase])
38
+
39
+ respond_to do |format|
40
+ if @purchase.save
41
+ format.html { redirect_to purchases_path, notice: 'Purchase was successfully created.' }
42
+ format.json { render json: @purchase, status: :created, location: @purchase }
43
+ else
44
+ format.html { render action: "new" }
45
+ format.json { render json: @purchase.errors, status: :unprocessable_entity }
46
+ end
47
+ end
48
+ end
49
+
50
+ def update
51
+ @purchase = Purchase.find(params[:id])
52
+
53
+ respond_to do |format|
54
+ if @purchase.update_attributes(params[:purchase])
55
+ format.html { redirect_to purchases_path, notice: 'Purchase was successfully updated.' }
56
+ format.json { head :no_content }
57
+ else
58
+ format.html { render action: "edit" }
59
+ format.json { render json: @purchase.errors, status: :unprocessable_entity }
60
+ end
61
+ end
62
+ end
63
+
64
+ def destroy
65
+ @purchase = Purchase.find(params[:id])
66
+ @purchase.destroy
67
+
68
+ respond_to do |format|
69
+ format.html { redirect_to purchases_url }
70
+ format.json { head :no_content }
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,4 @@
1
+ module Bookkeeper
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,9 @@
1
+ class DatepickerInput < SimpleForm::Inputs::Base
2
+ def input
3
+ "#{@builder.text_field(attribute_name, input_html_options.merge(datepicker_options(object.send(attribute_name))))}".html_safe
4
+ end
5
+
6
+ def datepicker_options(value = nil)
7
+ datepicker_options = {:class => 'input-small datepicker string', :value => value.nil?? nil : value.strftime("%d/%m/%Y")}
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Bookkeeper
2
+ class Purchase < ActiveRecord::Base
3
+ mount_uploader :receipt, ReceiptUploader
4
+
5
+ attr_accessible :description, :purchase_date, :title, :warranty_duration, :receipt
6
+
7
+ validates_presence_of :title
8
+ validates_numericality_of :warranty_duration, allow_nil: true
9
+ validates_date :purchase_date, allow_nil: true, allow_blank: true
10
+ end
11
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ class ReceiptUploader < CarrierWave::Uploader::Base
4
+
5
+ # Include RMagick or MiniMagick support:
6
+ include CarrierWave::RMagick
7
+ # include CarrierWave::MiniMagick
8
+
9
+ # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility:
10
+ # include Sprockets::Helpers::RailsHelper
11
+ # include Sprockets::Helpers::IsolatedHelper
12
+
13
+ permissions 0600
14
+
15
+ # Choose what kind of storage to use for this uploader:
16
+ storage :file
17
+ # storage :fog
18
+
19
+ # Override the directory where uploaded files will be stored.
20
+ # This is a sensible default for uploaders that are meant to be mounted:
21
+ # def store_dir
22
+ # "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
23
+ # end
24
+
25
+ # Provide a default URL as a default if there hasn't been a file uploaded:
26
+ def default_url
27
+ # For Rails 3.1+ asset pipeline compatibility:
28
+ asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
29
+
30
+ "/images/fallback/" + [version_name, "default.png"].compact.join('_')
31
+ end
32
+
33
+ # Process files as they are uploaded:
34
+ process :resize_to_fit => [1000, 1000]
35
+ #
36
+ # def scale(width, height)
37
+ # # do something
38
+ # end
39
+
40
+ # Create different versions of your uploaded files:
41
+ version :thumb do
42
+ process :resize_to_fill => [64, 64]
43
+ end
44
+
45
+ # Add a white list of extensions which are allowed to be uploaded.
46
+ # For images you might use something like this:
47
+ def extension_white_list
48
+ %w(jpg jpeg gif png pdf)
49
+ end
50
+
51
+ # Override the filename of the uploaded files:
52
+ # Avoid using model.id or version_name here, see uploader/store.rb for details.
53
+ # def filename
54
+ # "something.jpg" if original_filename
55
+ # end
56
+
57
+ end
@@ -0,0 +1,17 @@
1
+ <%= simple_form_for @purchase, html: { class: 'form-horizontal' } do |f| %>
2
+
3
+ <%= f.error_notification %>
4
+
5
+ <div class="form-inputs">
6
+ <%= f.input :title %>
7
+ <%= f.input :description, input_html: { class: 'input-xxlarge', rows: 4 } %>
8
+ <%= f.input :purchase_date, :wrapper => :prepend do %>
9
+ <%= content_tag :span, '<i class="icon-th"></i>'.html_safe, class: "add-on calendar" %><%= f.input_field :purchase_date, as: :datepicker, data: { 'date-format' => 'dd/mm/yyyy' } %>
10
+ <% end %>
11
+ <%= f.input :warranty_duration, collection: [["6 months", 6], ["1 year", 12], ["2 years", 24], ["3 years", 36]], input_html: { class: 'input-small' } %>
12
+ <%= f.input :receipt %>
13
+ </div>
14
+ <div class="form-actions">
15
+ <%= button_tag '<i class="icon-ok"></i> Save'.html_safe, class: 'btn' %>
16
+ </div>
17
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing purchase</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to '<i class="icon-search"></i> Show'.html_safe, @purchase, class: 'btn' %>
6
+ <%= link_to '<i class="icon-arrow-left"></i> Back'.html_safe, purchases_path, class: 'btn' %>