shoppe 0.0.15 → 0.0.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. data/README.rdoc +1 -0
  2. data/Rakefile +21 -1
  3. data/app/assets/javascripts/shoppe/application.coffee +5 -0
  4. data/app/assets/stylesheets/shoppe/application.scss +16 -3
  5. data/app/assets/stylesheets/shoppe/elements.scss +8 -0
  6. data/app/assets/stylesheets/shoppe/printable.scss +67 -0
  7. data/app/controllers/shoppe/application_controller.rb +1 -10
  8. data/app/controllers/shoppe/orders_controller.rb +4 -0
  9. data/app/controllers/shoppe/sessions_controller.rb +1 -0
  10. data/app/controllers/shoppe/settings_controller.rb +12 -0
  11. data/app/controllers/shoppe/users_controller.rb +2 -2
  12. data/app/controllers/shoppe/variants_controller.rb +1 -1
  13. data/app/helpers/shoppe/application_helper.rb +63 -8
  14. data/app/mailers/shoppe/order_mailer.rb +5 -7
  15. data/app/mailers/shoppe/user_mailer.rb +2 -2
  16. data/app/models/shoppe/country.rb +17 -1
  17. data/app/models/shoppe/delivery_service.rb +15 -0
  18. data/app/models/shoppe/delivery_service_price.rb +17 -0
  19. data/app/models/shoppe/order.rb +82 -9
  20. data/app/models/shoppe/order_item.rb +18 -0
  21. data/app/models/shoppe/product.rb +26 -1
  22. data/app/models/shoppe/product/product_attributes.rb +1 -1
  23. data/app/models/shoppe/product/variants.rb +3 -3
  24. data/app/models/shoppe/product_attribute.rb +15 -0
  25. data/app/models/shoppe/product_category.rb +12 -0
  26. data/app/models/shoppe/setting.rb +59 -0
  27. data/app/models/shoppe/stock_level_adjustment.rb +15 -0
  28. data/app/models/shoppe/tax_rate.rb +13 -1
  29. data/app/models/shoppe/user.rb +13 -0
  30. data/app/views/layouts/shoppe/application.html.haml +2 -1
  31. data/app/views/layouts/shoppe/printable.html.haml +11 -0
  32. data/app/views/shoppe/delivery_service_prices/index.html.haml +1 -1
  33. data/app/views/shoppe/order_mailer/accepted.text.erb +2 -2
  34. data/app/views/shoppe/order_mailer/received.text.erb +2 -2
  35. data/app/views/shoppe/order_mailer/rejected.text.erb +2 -2
  36. data/app/views/shoppe/order_mailer/shipped.text.erb +2 -2
  37. data/app/views/shoppe/orders/despatch_note.html.haml +45 -0
  38. data/app/views/shoppe/orders/index.html.haml +2 -2
  39. data/app/views/shoppe/orders/show.html.haml +21 -11
  40. data/app/views/shoppe/settings/edit.html.haml +19 -0
  41. data/app/views/shoppe/user_mailer/new_password.text.erb +1 -1
  42. data/app/views/shoppe/variants/form.html.haml +4 -0
  43. data/config/locales/en.yml +34 -0
  44. data/config/routes.rb +5 -0
  45. data/db/migrate/20130926094549_create_shoppe_initial_schema.rb +92 -33
  46. data/db/seeds.rb +1 -1
  47. data/lib/shoppe.rb +13 -35
  48. data/lib/shoppe/engine.rb +6 -6
  49. data/lib/shoppe/settings.rb +28 -0
  50. data/lib/shoppe/settings_loader.rb +16 -0
  51. data/lib/shoppe/setup_generator.rb +0 -4
  52. data/lib/shoppe/version.rb +1 -1
  53. data/test/{dummy → app}/README.rdoc +0 -0
  54. data/test/{dummy → app}/Rakefile +0 -0
  55. data/test/{dummy → app}/app/assets/javascripts/application.js +0 -0
  56. data/test/{dummy → app}/app/assets/stylesheets/application.css +0 -0
  57. data/test/{dummy → app}/app/controllers/application_controller.rb +0 -0
  58. data/test/{dummy → app}/app/helpers/application_helper.rb +0 -0
  59. data/test/{dummy → app}/app/views/layouts/application.html.erb +0 -0
  60. data/test/{dummy → app}/bin/bundle +0 -0
  61. data/test/{dummy → app}/bin/rails +0 -0
  62. data/test/{dummy → app}/bin/rake +0 -0
  63. data/test/{dummy → app}/config.ru +0 -0
  64. data/test/{dummy → app}/config/application.rb +0 -0
  65. data/test/{dummy → app}/config/boot.rb +0 -0
  66. data/test/app/config/database.example.yml +30 -0
  67. data/test/{dummy → app}/config/database.yml +9 -5
  68. data/test/{dummy → app}/config/environment.rb +0 -0
  69. data/test/{dummy → app}/config/environments/development.rb +0 -0
  70. data/test/{dummy → app}/config/environments/production.rb +0 -0
  71. data/test/{dummy → app}/config/environments/test.rb +0 -0
  72. data/test/{dummy → app}/config/initializers/backtrace_silencers.rb +0 -0
  73. data/test/{dummy → app}/config/initializers/filter_parameter_logging.rb +0 -0
  74. data/test/{dummy → app}/config/initializers/inflections.rb +0 -0
  75. data/test/{dummy → app}/config/initializers/mime_types.rb +0 -0
  76. data/test/{dummy → app}/config/initializers/secret_token.rb +0 -0
  77. data/test/app/config/initializers/session_store.rb +3 -0
  78. data/test/{dummy → app}/config/initializers/wrap_parameters.rb +0 -0
  79. data/test/{dummy → app}/config/locales/en.yml +0 -0
  80. data/test/{dummy → app}/config/routes.rb +0 -0
  81. data/{config/shoppe.example.yml → test/app/config/shoppe.yml} +0 -0
  82. data/test/{dummy → app}/db/development.sqlite3 +0 -0
  83. data/test/{dummy → app}/db/migrate/20131017165217_create_nifty_attachments_table.rb +0 -0
  84. data/test/{dummy → app}/db/migrate/20131017165222_create_nifty_key_value_store_table.rb +0 -0
  85. data/test/{dummy → app}/db/schema.rb +31 -16
  86. data/test/{dummy → app}/db/test.sqlite3 +0 -0
  87. data/test/app/log/development.log +8093 -0
  88. data/test/{dummy → app}/log/test.log +0 -0
  89. data/test/{dummy → app}/public/404.html +0 -0
  90. data/test/{dummy → app}/public/422.html +0 -0
  91. data/test/{dummy → app}/public/500.html +0 -0
  92. data/test/{dummy → app}/public/favicon.ico +0 -0
  93. data/test/app/tmp/cache/assets/development/sass/7c98994848dbb534749f971b176724aa382339bb/dialog.scssc +0 -0
  94. data/test/app/tmp/cache/assets/development/sass/edac894564dae62b78e653a08d1c41f10ade93f9/application.scssc +0 -0
  95. data/test/app/tmp/cache/assets/development/sass/edac894564dae62b78e653a08d1c41f10ade93f9/dialog.scssc +0 -0
  96. data/test/app/tmp/cache/assets/development/sass/edac894564dae62b78e653a08d1c41f10ade93f9/elements.scssc +0 -0
  97. data/test/app/tmp/cache/assets/development/sass/edac894564dae62b78e653a08d1c41f10ade93f9/reset.scssc +0 -0
  98. data/test/app/tmp/cache/assets/development/sass/edac894564dae62b78e653a08d1c41f10ade93f9/sub.scssc +0 -0
  99. data/test/app/tmp/cache/assets/development/sass/edac894564dae62b78e653a08d1c41f10ade93f9/variables.scssc +0 -0
  100. data/test/app/tmp/cache/assets/development/sprockets/06d540cec125e08e63a898c35e8235d6 +0 -0
  101. data/test/app/tmp/cache/assets/development/sprockets/0a6bca3e510625f255083bd154cc470b +0 -0
  102. data/test/app/tmp/cache/assets/development/sprockets/0d8942b2279b6bc7c68b3db3e2e4c342 +0 -0
  103. data/test/app/tmp/cache/assets/development/sprockets/122a65fdcbb923c3c1cd95549ef52f43 +0 -0
  104. data/test/app/tmp/cache/assets/development/sprockets/140840b7aefa4bf5beda2c32e20374a6 +0 -0
  105. data/test/app/tmp/cache/assets/development/sprockets/160ddfa6141944c4a03757fe91643137 +0 -0
  106. data/test/app/tmp/cache/assets/development/sprockets/1bb0d399b6b81fc3b47ff794b066873f +0 -0
  107. data/test/app/tmp/cache/assets/development/sprockets/1e1679158bd397a720be46fa3a5876a3 +0 -0
  108. data/test/app/tmp/cache/assets/development/sprockets/2a75ba35f8e751887ba89a914363fefd +0 -0
  109. data/test/app/tmp/cache/assets/development/sprockets/2cc6ef740b5691af5ee246c0dbc68f14 +0 -0
  110. data/test/app/tmp/cache/assets/development/sprockets/2f80004fb2e2ce07283a83ac15cf920a +0 -0
  111. data/test/app/tmp/cache/assets/development/sprockets/322295abdd8625fcce4da08f9565cc63 +0 -0
  112. data/test/app/tmp/cache/assets/development/sprockets/421b79f445cd87f3532a5c445877cbec +0 -0
  113. data/test/app/tmp/cache/assets/development/sprockets/4528fe4a109cad1ff031659cd9eeae17 +0 -0
  114. data/test/app/tmp/cache/assets/development/sprockets/45a9c7dfe9986570daa4c972277375ec +0 -0
  115. data/test/app/tmp/cache/assets/development/sprockets/48b2cd7153bbc442eaa84c3e24e963e0 +0 -0
  116. data/test/app/tmp/cache/assets/development/sprockets/4c3fef5a3e293ed6b6df3d869f54e1d1 +0 -0
  117. data/test/app/tmp/cache/assets/development/sprockets/4c8cb5cfd87990ebddbaa5b5fd594be5 +0 -0
  118. data/test/app/tmp/cache/assets/development/sprockets/4cefa37a52d669d3ca7e6aa1e1aaf435 +0 -0
  119. data/test/app/tmp/cache/assets/development/sprockets/4ea4f5c13aaeda9a7d39684ab72fa710 +0 -0
  120. data/test/app/tmp/cache/assets/development/sprockets/4ecd1cb66cb36718daadcfba0aa42c1e +0 -0
  121. data/test/app/tmp/cache/assets/development/sprockets/4ed3cbd180c275b98627eaeea4c9c838 +0 -0
  122. data/test/app/tmp/cache/assets/development/sprockets/519aa2b3c3ab8fd8f065c56507111878 +0 -0
  123. data/test/app/tmp/cache/assets/development/sprockets/51d409a48872319ac6a731aa880e6368 +0 -0
  124. data/test/app/tmp/cache/assets/development/sprockets/55bae604bcb5ccf7d9e0ed0fd61953b6 +0 -0
  125. data/test/app/tmp/cache/assets/development/sprockets/5805d2c402f412642d86ec03a7ec4a3d +0 -0
  126. data/test/app/tmp/cache/assets/development/sprockets/5cd772b44cdeae4d3b37b62193e946eb +0 -0
  127. data/test/app/tmp/cache/assets/development/sprockets/5f32b259cbcc52156d2fe21c185d9390 +0 -0
  128. data/test/app/tmp/cache/assets/development/sprockets/656ea3403f27a33b86d5bf9e8a0c0e46 +0 -0
  129. data/test/app/tmp/cache/assets/development/sprockets/679705affe2ad274da1ad48cb5137c21 +0 -0
  130. data/test/app/tmp/cache/assets/development/sprockets/69a687de4cbb95365bf8aa2037d63726 +0 -0
  131. data/test/app/tmp/cache/assets/development/sprockets/69d5224a79e874431294e8adf04e7d65 +0 -0
  132. data/test/app/tmp/cache/assets/development/sprockets/6bc5a76ff13bc4daebb7e164a4b64196 +0 -0
  133. data/test/app/tmp/cache/assets/development/sprockets/6c1a5456c2e5d87285dd1910762fe01e +0 -0
  134. data/test/app/tmp/cache/assets/development/sprockets/6d52ff2c9298014f2d648eb9e04a61a6 +0 -0
  135. data/test/app/tmp/cache/assets/development/sprockets/7938636d16e11b754d4dd046b89863c4 +0 -0
  136. data/test/app/tmp/cache/assets/development/sprockets/7ce7981501e05438faa017eb2e197379 +0 -0
  137. data/test/app/tmp/cache/assets/development/sprockets/7e232a7b4ac10fe1350e2b9b05ab0b02 +0 -0
  138. data/test/app/tmp/cache/assets/development/sprockets/81d7800826e89041f377af8570b8324f +0 -0
  139. data/test/app/tmp/cache/assets/development/sprockets/81f524fed55fe63e95c1aeccb5d83571 +0 -0
  140. data/test/app/tmp/cache/assets/development/sprockets/85984636ee801f63af86b35d7697d4c5 +0 -0
  141. data/test/app/tmp/cache/assets/development/sprockets/88de2cf8ce5990c5fa59f7c9f4599a65 +0 -0
  142. data/test/app/tmp/cache/assets/development/sprockets/8932a78ffe18ad2e3bb7ceb90ac4b933 +0 -0
  143. data/test/app/tmp/cache/assets/development/sprockets/8d6fd863923e78438318b02bf83be1c4 +0 -0
  144. data/test/app/tmp/cache/assets/development/sprockets/8f43db1e57a90ffbae3be00a895d5a09 +0 -0
  145. data/test/app/tmp/cache/assets/development/sprockets/91e11940ab63a407af03d21720ac2951 +0 -0
  146. data/test/app/tmp/cache/assets/development/sprockets/938abfdc262a8ab42e768545640bfb2a +0 -0
  147. data/test/app/tmp/cache/assets/development/sprockets/9e760b9565b110e433b7e42f827cb5f8 +0 -0
  148. data/test/app/tmp/cache/assets/development/sprockets/9e8fbfd56e8ef705ba94bb03b5b3696e +0 -0
  149. data/test/app/tmp/cache/assets/development/sprockets/9ebbf73fb48cdf8bc07a8bfdd6d14328 +0 -0
  150. data/test/app/tmp/cache/assets/development/sprockets/9f240d481b0818a6da0b1a1aaaac2b54 +0 -0
  151. data/test/app/tmp/cache/assets/development/sprockets/a2b956b30a80f996b5aeb1b2f226775c +0 -0
  152. data/test/app/tmp/cache/assets/development/sprockets/a5b5ed9849e8019160b73aa554132b37 +0 -0
  153. data/test/app/tmp/cache/assets/development/sprockets/a692ba7ed6cff183bb840c2622233c87 +0 -0
  154. data/test/app/tmp/cache/assets/development/sprockets/a951f4ceb83ae691f002b4f6183bc1ed +0 -0
  155. data/test/app/tmp/cache/assets/development/sprockets/accc4dc17ef18d0b510917a005340da5 +0 -0
  156. data/test/app/tmp/cache/assets/development/sprockets/b2db166e9974feb35358e7fcce87cb39 +0 -0
  157. data/test/app/tmp/cache/assets/development/sprockets/b519a4f6c5b5a0d9236bdca14e0eb00d +0 -0
  158. data/test/app/tmp/cache/assets/development/sprockets/b5cbeb3def40b118469fff2d80c1b596 +0 -0
  159. data/test/app/tmp/cache/assets/development/sprockets/b6f65271a0e77b349529ce9148dd2782 +0 -0
  160. data/test/app/tmp/cache/assets/development/sprockets/b9ad7ea18b7e55c3626a15d1dae142ed +0 -0
  161. data/test/app/tmp/cache/assets/development/sprockets/bc384ea2fdcc667aa4282209caba921f +0 -0
  162. data/test/app/tmp/cache/assets/development/sprockets/bcf06bf434bb3d3a5769036d6e24b301 +0 -0
  163. data/test/app/tmp/cache/assets/development/sprockets/bd83357635155d3457747e92e47da0ed +0 -0
  164. data/test/app/tmp/cache/assets/development/sprockets/c39634555e4eba3595350eeea648ddf4 +0 -0
  165. data/test/app/tmp/cache/assets/development/sprockets/c3ef336ca8f7e64969d8bfdcf837ad10 +0 -0
  166. data/test/app/tmp/cache/assets/development/sprockets/c55037904a95162828e5d0b087677878 +0 -0
  167. data/test/app/tmp/cache/assets/development/sprockets/c733f1a2fe9d05a3a634ff64a394f64b +0 -0
  168. data/test/app/tmp/cache/assets/development/sprockets/c83a337688a52890ba93372fea6ec932 +0 -0
  169. data/test/app/tmp/cache/assets/development/sprockets/ca92d0dbc43c066af9b31f2bc26d038d +0 -0
  170. data/test/app/tmp/cache/assets/development/sprockets/cae2fc80bfbc81ec7b6c11a72be18c98 +0 -0
  171. data/test/app/tmp/cache/assets/development/sprockets/cd665363677ffcef0dde972284e8d942 +0 -0
  172. data/test/app/tmp/cache/assets/development/sprockets/d5154a1eda9cfbfe54e091d6ead1ac5f +0 -0
  173. data/test/app/tmp/cache/assets/development/sprockets/daa7fa7a610bc5951cc3c4403f290eb6 +0 -0
  174. data/test/app/tmp/cache/assets/development/sprockets/dabc0e94bc1e37007351ac756dd2dd6a +0 -0
  175. data/test/app/tmp/cache/assets/development/sprockets/edf3c55a27678996371bffe56298925b +0 -0
  176. data/test/app/tmp/cache/assets/development/sprockets/f0f04c3b2b0091fa3ca4a1edacc23a1c +0 -0
  177. data/test/app/tmp/cache/assets/development/sprockets/f8610737fbfdcb85db95ae7c6a70514e +0 -0
  178. data/test/app/tmp/restart.txt +0 -0
  179. data/test/shoppe_test.rb +0 -5
  180. data/test/test_helper.rb +1 -1
  181. metadata +298 -98
  182. data/app/helpers/shoppe/shoppe_helper.rb +0 -30
  183. data/db/migrate/20131012123829_create_shoppe_product_attributes.rb +0 -11
  184. data/db/migrate/20131012163301_add_public_boolean_to_product_attributes.rb +0 -5
  185. data/db/migrate/20131013123937_add_cost_prices_to_various_objects.rb +0 -8
  186. data/db/migrate/20131013131658_add_stock_control_boolean_to_products.rb +0 -5
  187. data/db/migrate/20131017144430_create_shoppe_stock_level_adjustments.rb +0 -18
  188. data/db/migrate/20131017180920_create_shoppe_countries.rb +0 -16
  189. data/db/migrate/20131017183211_create_shoppe_tax_rates.rb +0 -26
  190. data/db/migrate/20131020204719_add_countries_to_tax_rates_and_delivery_prices.rb +0 -6
  191. data/db/migrate/20131021135208_add_notes_to_orders.rb +0 -5
  192. data/db/migrate/20131022090919_refactor_order_items_to_allow_any_product.rb +0 -6
  193. data/db/migrate/20131022092904_rename_product_title_to_name.rb +0 -5
  194. data/db/migrate/20131022093538_stock_level_adjustments_should_be_polymorphic.rb +0 -6
  195. data/db/migrate/20131022135331_add_parent_id_to_products.rb +0 -5
  196. data/db/migrate/20131022145653_cost_price_should_be_default_to_zero.rb +0 -9
  197. data/test/dummy/config/initializers/session_store.rb +0 -3
  198. data/test/dummy/config/shoppe.yml +0 -7
  199. data/test/dummy/log/development.log +0 -1162
@@ -0,0 +1 @@
1
+ Hello.
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ rescue LoadError
4
4
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
5
  end
6
6
 
7
- APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
7
+ APP_RAKEFILE = File.expand_path("../test/app/Rakefile", __FILE__)
8
8
  load 'rails/tasks/engine.rake'
9
9
 
10
10
  Bundler::GemHelper.install_tasks
@@ -16,3 +16,23 @@ Rake::TestTask.new(:test) do |t|
16
16
  t.pattern = 'test/**/*_test.rb'
17
17
  t.verbose = false
18
18
  end
19
+
20
+ namespace :shoppe do
21
+
22
+ desc "Generate RDoc documentation into doc/"
23
+ task :generate_docs do
24
+ system("rm -Rf doc")
25
+ system("bundle exec sdoc app/models lib README.rdoc")
26
+ end
27
+
28
+ desc "Publish RDoc documentation from doc to api.tryshoppe.com"
29
+ task :publish_docs do
30
+ if File.exist?("doc")
31
+ system "ssh root@tryshoppe.com rm -Rf /var/www/shoppe-api"
32
+ system "scp -r doc root@tryshoppe.com:/var/www/shoppe-api"
33
+ else
34
+ puts "No doc/ folder found to publish."
35
+ end
36
+ end
37
+ end
38
+
@@ -43,6 +43,11 @@ $ ->
43
43
  $('select.chosen').chosen()
44
44
  $('select.chosen-with-deselect').chosen({allow_single_deselect: true})
45
45
 
46
+ # Printables
47
+ $('a[rel=print]').on 'click', ->
48
+ window.open($(this).attr('href'), 'despatchnote', 'width=700,height=800')
49
+ false
50
+
46
51
  # Open AJAX dialogs
47
52
  $('a[rel=dialog]').on 'click', ->
48
53
  element = $(this)
@@ -81,6 +81,7 @@ header.main {
81
81
  h2.delivery_services { background-image:image-url('shoppe/icons/box.svg'); background-position: 0 3px; background-size:20px;}
82
82
  h2.tax_rates { background-image:image-url('shoppe/icons/currency.svg'); background-position: 0 2px; background-size:22px;}
83
83
  h2.users { background-image:image-url('shoppe/icons/id.svg'); background-position: 0 2px; background-size:22px;}
84
+ h2.settings { background-image:image-url('shoppe/icons/toolbox.svg'); background-position: 0 2px; background-size:22px;}
84
85
 
85
86
  }
86
87
 
@@ -154,10 +155,13 @@ header.main {
154
155
  }
155
156
  dd select { width:100%;}
156
157
  dd textarea { height:80px; }
157
- dd p.help { margin-top:15px; color:#333; background:image-url('shoppe/icons/support.svg') no-repeat 0 1px; background-size:13px; padding-left:15px;}
158
+ dd p.help { margin-top:15px; color:#333; background:image-url('shoppe/icons/support.svg') no-repeat 0 3px; line-height:1.5; background-size:13px; padding-left:18px; opacity:0.7;}
158
159
  dd.checkbox { margin-top:14px; font-size:1.1em; color:#999;}
159
160
  dd.checkbox input { float:left; margin-right:10px; margin-top:2px; }
160
-
161
+ dd div.radios {
162
+ padding-top:4px;
163
+ input,label { margin-right:10px;}
164
+ }
161
165
  &.half {
162
166
  width:49%;
163
167
  margin:0;
@@ -172,9 +176,17 @@ header.main {
172
176
  &:nth-child(2) { margin-left:2%; width:32%;}
173
177
  &:last-child { float:right; width:33%;}
174
178
  }
175
-
176
179
  }
177
180
 
181
+ dl.sided {
182
+ clear:both;
183
+ dt { float:left; width:25%; text-align:right; padding-top:4px;}
184
+ dd { margin-left:30%; }
185
+ dd p.help { margin-top:10px;}
186
+ dd div.checkbox { padding-top:5px;}
187
+ }
188
+
189
+
178
190
  //
179
191
  // margined container
180
192
  //
@@ -204,6 +216,7 @@ header.main {
204
216
  p.submit .button { margin-right:5px;}
205
217
  p.submit .right .button {margin-left:5px; margin-right:0;}
206
218
  p.submit span.right { float:right;}
219
+ p.submit.sided { padding-left:30%;}
207
220
  .errorExplanation {
208
221
  margin-bottom:25px;
209
222
  border:1px solid #EB2732;
@@ -49,6 +49,14 @@
49
49
  &:active { background:#e75d19}
50
50
  }
51
51
 
52
+ &.grey {
53
+ background-color:#777;
54
+ border-color:#777;
55
+ border-bottom-color:#777;
56
+ &:active { background:#888}
57
+ }
58
+
59
+
52
60
  &.white {
53
61
  background-color:#fff;
54
62
  color:#333 !important;
@@ -0,0 +1,67 @@
1
+ /*
2
+ *= require shoppe/reset
3
+ */
4
+ html { font-family:'Helvetica Neue', Helvetica, Arial, sans-serif; color:#000; font-size:12px;background:#efefef;}
5
+ #content {
6
+ background:#fff;
7
+ margin:5%;
8
+ outline:1px solid #ccc;
9
+ padding:35px;
10
+ }
11
+
12
+ div.despatchNote {
13
+ header {
14
+ float:left;
15
+ h1 {
16
+ font-size:1.8em;
17
+ font-weight:300;
18
+ }
19
+ h2 { margin-top:5px; font-size:2.3em; font-weight:500; }
20
+ width:40%;
21
+ }
22
+
23
+ .address {
24
+ border:1px solid #000;
25
+ padding:25px;
26
+ margin-left:45%;
27
+ line-height:1.5;
28
+ font-size:1.3em;
29
+ p.name { font-size:1.2em; font-weight:500;}
30
+ }
31
+ table.details {
32
+ width:100%;
33
+ margin:25px 0;
34
+ td, th {
35
+ border:1px solid #000;
36
+ padding:10px;
37
+ text-align:center;
38
+ }
39
+ th { background:#efefef;}
40
+ }
41
+
42
+ table.items {
43
+ width:100%;
44
+ margin:25px 0;
45
+ td, th {
46
+ border:1px solid #000;
47
+ padding:10px;
48
+ text-align:center;
49
+ &.check { width:5%;}
50
+ }
51
+ th { background:#efefef;}
52
+ }
53
+
54
+ p.footer {
55
+ font-size:1.2em;
56
+ border:1px solid #000;
57
+ padding:15px;
58
+ text-align:center;
59
+ }
60
+ }
61
+
62
+
63
+ @media print {
64
+ html { background:none;}
65
+ body {margin:5%;}
66
+ #content { margin:0; padding:0; outline:0;}
67
+ }
@@ -1,8 +1,6 @@
1
1
  module Shoppe
2
2
  class ApplicationController < ActionController::Base
3
3
 
4
- # Require that a user is logged in for all parts of the Shoppe admin
5
- # interface.
6
4
  before_filter :login_required
7
5
 
8
6
  rescue_from ActiveRecord::DeleteRestrictionError do |e|
@@ -16,39 +14,32 @@ module Shoppe
16
14
 
17
15
  private
18
16
 
19
- # If not logged in, redirect users to the login page. This should be
20
- # used in a before filter.
21
17
  def login_required
22
18
  unless logged_in?
23
19
  redirect_to login_path
24
20
  end
25
21
  end
26
22
 
27
- # Is there a user currently logged in?
28
23
  def logged_in?
29
24
  current_user.is_a?(User)
30
25
  end
31
26
 
32
- # Returns the currently logged in user
33
27
  def current_user
34
28
  @current_user ||= login_from_session || login_with_demo_mdoe || :false
35
29
  end
36
30
 
37
- # Attempt to find a user based on the value stored in the local session
38
31
  def login_from_session
39
32
  if session[:shoppe_user_id]
40
33
  @user = User.find_by_id(session[:shoppe_user_id])
41
34
  end
42
35
  end
43
36
 
44
- # Attempt to login using the demo mode
45
37
  def login_with_demo_mdoe
46
- if Shoppe.config[:demo_mode]
38
+ if Shoppe.settings.demo_mode?
47
39
  @user = User.first
48
40
  end
49
41
  end
50
42
 
51
- # Expose a current_user and logged_in? as helpers to views
52
43
  helper_method :current_user, :logged_in?
53
44
 
54
45
  end
@@ -38,6 +38,10 @@ module Shoppe
38
38
  @order.pay!(params[:payment_reference], params[:payment_method].blank? ? 'Unknown' : params[:payment_method])
39
39
  redirect_to @order, :notice => "Order has been marked as paid successfully"
40
40
  end
41
+
42
+ def despatch_note
43
+ render :layout => 'shoppe/printable'
44
+ end
41
45
 
42
46
  end
43
47
  end
@@ -1,5 +1,6 @@
1
1
  module Shoppe
2
2
  class SessionsController < Shoppe::ApplicationController
3
+
3
4
  layout 'shoppe/sub'
4
5
  skip_before_filter :login_required, :only => [:new, :create, :reset]
5
6
 
@@ -0,0 +1,12 @@
1
+ module Shoppe
2
+ class SettingsController < ApplicationController
3
+
4
+ before_filter { @active_nav = :settings }
5
+
6
+ def update
7
+ Shoppe::Setting.update_from_hash(params[:settings].permit!)
8
+ redirect_to :settings, :notice => "Settings have been updated successfully."
9
+ end
10
+
11
+ end
12
+ end
@@ -3,8 +3,8 @@ module Shoppe
3
3
 
4
4
  before_filter { @active_nav = :users }
5
5
  before_filter { params[:id] && @user = Shoppe::User.find(params[:id]) }
6
- if Shoppe.config[:demo_mode]
7
- before_filter(:only => [:create, :update, :destroy]) do
6
+ before_filter(:only => [:create, :update, :destroy]) do
7
+ if Shoppe.settings.demo_mode?
8
8
  raise Shoppe::Error, "You cannot make changes to user in demo mode. Sorry about that."
9
9
  end
10
10
  end
@@ -43,7 +43,7 @@ module Shoppe
43
43
  private
44
44
 
45
45
  def safe_params
46
- params[:product].permit(:name, :permalink, :sku, :default_image_file, :price, :cost_price, :tax_rate_id, :weight, :stock_control, :active)
46
+ params[:product].permit(:name, :permalink, :sku, :default_image_file, :price, :cost_price, :tax_rate_id, :weight, :stock_control, :active, :default)
47
47
  end
48
48
 
49
49
  end
@@ -1,10 +1,65 @@
1
- module Shoppe::ApplicationHelper
1
+ module Shoppe
2
+ module ApplicationHelper
2
3
 
3
- # Return all currencies with the currency provided by the Shoppe
4
- # configuration file.
5
- def number_to_currency(number, options = {})
6
- options[:unit] ||= Shoppe.config[:currency_unit]
7
- super
8
- end
4
+ def number_to_currency(number, options = {})
5
+ options[:unit] ||= Shoppe.settings.currency_unit
6
+ super
7
+ end
8
+
9
+ def number_to_weight(kg)
10
+ "#{kg}#{t('shoppe.helpers.number_to_weight.kg', :default => 'kg')}"
11
+ end
12
+
13
+ def status_tag(status)
14
+ content_tag :span, status, :class => "status-tag #{status}"
15
+ end
9
16
 
10
- end
17
+ def attachment_preview(attachment, options = {})
18
+ if attachment
19
+ String.new.tap do |s|
20
+ if attachment.image?
21
+ style = "style='background-image:url(#{attachment.path})'"
22
+ else
23
+ style = ''
24
+ end
25
+ s << "<div class='attachmentPreview #{attachment.image? ? 'image' : 'doc'}'>"
26
+ s << "<div class='imgContainer'><div class='img' #{style}></div></div>"
27
+ s << "<div class='desc'>"
28
+ s << "<span class='filename'><a href='#{attachment_path(attachment)}'>#{attachment.file_name}</a></span>"
29
+ s << "<span class='delete'>"
30
+ s << link_to(t('shoppe.helpers.attachment_preview.delete', :default => 'Delete this file?'), attachment_path(attachment), :method => :delete, :data => {:confirm => t('shoppe.helpers.attachment_preview.delete_confirm', :default => "Are you sure you wish to remove this attachment?")})
31
+ s << "</span>"
32
+ s << "</div>"
33
+ s << "</div>"
34
+ end.html_safe
35
+ elsif !options[:hide_if_blank]
36
+ "<div class='attachmentPreview'><div class='imgContainer'><div class='img none'></div></div><div class='desc none'>No attachment</div></div>".html_safe
37
+ end
38
+ end
39
+
40
+ def settings_label(field)
41
+ "<label for='settings_#{field}'>#{t("shoppe.settings.labels.#{field}")}</label>".html_safe
42
+ end
43
+
44
+ def settings_field(field, options = {})
45
+ default = t("shoppe.settings.defaults")[field.to_sym]
46
+ value = (params[:settings] && params[:settings][field]) || Shoppe.settings[field.to_s]
47
+ type = t("shoppe.settings.types")[field.to_sym] || 'string'
48
+ case type
49
+ when 'boolean'
50
+ String.new.tap do |s|
51
+ value = default if value.blank?
52
+ s << "<div class='radios'>"
53
+ s << radio_button_tag("settings[#{field}]", 'true', value == true, :id => "settings_#{field}_true")
54
+ s << label_tag("settings_#{field}_true", t("shoppe.settings.options.#{field}.affirmative", :default => 'Yes'))
55
+ s << radio_button_tag("settings[#{field}]", 'false', value == false, :id => "settings_#{field}_false")
56
+ s << label_tag("settings_#{field}_false", t("shoppe.settings.options.#{field}.negative", :default => 'No'))
57
+ s << "</div>"
58
+ end.html_safe
59
+ else
60
+ text_field_tag "settings[#{field}]", value, options.merge(:placeholder => default, :class => 'text')
61
+ end
62
+ end
63
+
64
+ end
65
+ end
@@ -1,27 +1,25 @@
1
1
  module Shoppe
2
2
  class OrderMailer < ActionMailer::Base
3
3
 
4
- default :from => "#{Shoppe.config[:store_name]} <#{Shoppe.config[:email_address]}>"
5
-
6
4
  def received(order)
7
5
  @order = order
8
- mail :to => order.email_address, :subject => I18n.t('shoppe.order_mailer.received.subject', :default => "Order Confirmation")
6
+ mail :from => Shoppe.settings.outbound_email_address, :to => order.email_address, :subject => I18n.t('shoppe.order_mailer.received.subject', :default => "Order Confirmation")
9
7
  end
10
8
 
11
9
  def accepted(order)
12
10
  @order = order
13
- mail :to => order.email_address, :subject => I18n.t('shoppe.order_mailer.received.accepted', :default => "Order Accepted")
11
+ mail :from => Shoppe.settings.outbound_email_address, :to => order.email_address, :subject => I18n.t('shoppe.order_mailer.received.accepted', :default => "Order Accepted")
14
12
  end
15
13
 
16
14
  def rejected(order)
17
15
  @order = order
18
- mail :to => order.email_address, :subject => I18n.t('shoppe.order_mailer.received.rejected', :default => "Order Rejected")
16
+ mail :from => Shoppe.settings.outbound_email_address, :to => order.email_address, :subject => I18n.t('shoppe.order_mailer.received.rejected', :default => "Order Rejected")
19
17
  end
20
18
 
21
19
  def shipped(order)
22
20
  @order = order
23
- mail :to => order.email_address, :subject => I18n.t('shoppe.order_mailer.received.shipped', :default => "Order Shipped")
21
+ mail :from => Shoppe.settings.outbound_email_address, :to => order.email_address, :subject => I18n.t('shoppe.order_mailer.received.shipped', :default => "Order Shipped")
24
22
  end
25
-
23
+
26
24
  end
27
25
  end
@@ -1,10 +1,10 @@
1
1
  module Shoppe
2
2
  class UserMailer < ActionMailer::Base
3
- default :from => "#{Shoppe.config[:store_name]} <#{Shoppe.config[:email_address]}>"
4
3
 
5
4
  def new_password(user)
6
5
  @user = user
7
- mail :to => user.email_address, :subject => "Your new Shoppe password"
6
+ mail :from => Shoppe.settings.outbound_email_address, :to => user.email_address, :subject => "Your new Shoppe password"
8
7
  end
8
+
9
9
  end
10
10
  end
@@ -1,3 +1,17 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: shoppe_countries
4
+ #
5
+ # id :integer not null, primary key
6
+ # name :string(255)
7
+ # code2 :string(255)
8
+ # code3 :string(255)
9
+ # continent :string(255)
10
+ # tld :string(255)
11
+ # currency :string(255)
12
+ # eu_member :boolean default(FALSE)
13
+ #
14
+
1
15
  module Shoppe
2
16
  class Country < ActiveRecord::Base
3
17
 
@@ -5,7 +19,9 @@ module Shoppe
5
19
  self.table_name = 'shoppe_countries'
6
20
 
7
21
  # Relationships
8
- has_many :orders, :dependent => :restrict_with_exception, :class_name => 'Shoppe::Order'
22
+ has_many :billed_orders, :dependent => :restrict_with_exception, :class_name => 'Shoppe::Order', :foreign_key => 'billing_country_id'
23
+ has_many :delivered_orders, :dependent => :restrict_with_exception, :class_name => 'Shoppe::Order', :foreign_key => 'delivery_country_id'
24
+
9
25
 
10
26
  # Scopes
11
27
  scope :ordered, -> { order('shoppe_countries.name asc') }
@@ -1,3 +1,18 @@
1
+ # == Schema Information
2
+ #
3
+ # Table name: shoppe_delivery_services
4
+ #
5
+ # id :integer not null, primary key
6
+ # name :string(255)
7
+ # code :string(255)
8
+ # default :boolean default(FALSE)
9
+ # active :boolean default(TRUE)
10
+ # created_at :datetime
11
+ # updated_at :datetime
12
+ # courier :string(255)
13
+ # tracking_url :string(255)
14
+ #
15
+
1
16
  module Shoppe
2
17
  class DeliveryService < ActiveRecord::Base
3
18