kylekthompson-shoppe 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (239) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +55 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/images/shoppe/chosen-sprite.png +0 -0
  6. data/app/assets/images/shoppe/chosen-sprite@2x.png +0 -0
  7. data/app/assets/images/shoppe/document.svg +1 -0
  8. data/app/assets/images/shoppe/icons/bag.svg +1 -0
  9. data/app/assets/images/shoppe/icons/balance.svg +1 -0
  10. data/app/assets/images/shoppe/icons/box.svg +1 -0
  11. data/app/assets/images/shoppe/icons/building.svg +1 -0
  12. data/app/assets/images/shoppe/icons/chart.svg +1 -0
  13. data/app/assets/images/shoppe/icons/chat.svg +1 -0
  14. data/app/assets/images/shoppe/icons/checkbox.svg +1 -0
  15. data/app/assets/images/shoppe/icons/checkbox2.svg +1 -0
  16. data/app/assets/images/shoppe/icons/cloud.svg +1 -0
  17. data/app/assets/images/shoppe/icons/cone.svg +1 -0
  18. data/app/assets/images/shoppe/icons/credit_card.svg +1 -0
  19. data/app/assets/images/shoppe/icons/currency.svg +1 -0
  20. data/app/assets/images/shoppe/icons/edit.svg +14 -0
  21. data/app/assets/images/shoppe/icons/flowchart.svg +1 -0
  22. data/app/assets/images/shoppe/icons/gift.svg +1 -0
  23. data/app/assets/images/shoppe/icons/globe.svg +1 -0
  24. data/app/assets/images/shoppe/icons/id.svg +1 -0
  25. data/app/assets/images/shoppe/icons/id2.svg +1 -0
  26. data/app/assets/images/shoppe/icons/locked.svg +1 -0
  27. data/app/assets/images/shoppe/icons/report.svg +1 -0
  28. data/app/assets/images/shoppe/icons/search.svg +1 -0
  29. data/app/assets/images/shoppe/icons/support.svg +1 -0
  30. data/app/assets/images/shoppe/icons/tags.svg +1 -0
  31. data/app/assets/images/shoppe/icons/toolbox.svg +1 -0
  32. data/app/assets/images/shoppe/icons/unlocked.svg +1 -0
  33. data/app/assets/images/shoppe/icons/wallet.svg +1 -0
  34. data/app/assets/images/shoppe/logo.svg +47 -0
  35. data/app/assets/images/shoppe/move.svg +1 -0
  36. data/app/assets/images/shoppe/shoppe.svg +25 -0
  37. data/app/assets/images/shoppe/square.svg +9 -0
  38. data/app/assets/images/shoppe/statuses/accepted.svg +14 -0
  39. data/app/assets/images/shoppe/statuses/paid.svg +16 -0
  40. data/app/assets/images/shoppe/statuses/received.svg +15 -0
  41. data/app/assets/images/shoppe/statuses/rejected.svg +14 -0
  42. data/app/assets/images/shoppe/statuses/shipped.svg +14 -0
  43. data/app/assets/images/shoppe/table-tear-off.png +0 -0
  44. data/app/assets/javascripts/shoppe/application.coffee +123 -0
  45. data/app/assets/javascripts/shoppe/chosen.jquery.js +1166 -0
  46. data/app/assets/javascripts/shoppe/jquery_ui.js +6 -0
  47. data/app/assets/javascripts/shoppe/mousetrap.js +9 -0
  48. data/app/assets/javascripts/shoppe/order_form.coffee +47 -0
  49. data/app/assets/stylesheets/shoppe/application.scss +601 -0
  50. data/app/assets/stylesheets/shoppe/chosen.scss +424 -0
  51. data/app/assets/stylesheets/shoppe/dialog.scss +25 -0
  52. data/app/assets/stylesheets/shoppe/elements.scss +79 -0
  53. data/app/assets/stylesheets/shoppe/printable.scss +67 -0
  54. data/app/assets/stylesheets/shoppe/reset.scss +93 -0
  55. data/app/assets/stylesheets/shoppe/sub.scss +106 -0
  56. data/app/assets/stylesheets/shoppe/variables.scss +1 -0
  57. data/app/controllers/shoppe/addresses_controller.rb +47 -0
  58. data/app/controllers/shoppe/application_controller.rb +46 -0
  59. data/app/controllers/shoppe/attachments_controller.rb +14 -0
  60. data/app/controllers/shoppe/countries_controller.rb +47 -0
  61. data/app/controllers/shoppe/customers_controller.rb +55 -0
  62. data/app/controllers/shoppe/dashboard_controller.rb +9 -0
  63. data/app/controllers/shoppe/delivery_service_prices_controller.rb +45 -0
  64. data/app/controllers/shoppe/delivery_services_controller.rb +47 -0
  65. data/app/controllers/shoppe/orders_controller.rb +119 -0
  66. data/app/controllers/shoppe/payments_controller.rb +33 -0
  67. data/app/controllers/shoppe/product_categories_controller.rb +47 -0
  68. data/app/controllers/shoppe/product_category_localisations_controller.rb +58 -0
  69. data/app/controllers/shoppe/product_localisations_controller.rb +58 -0
  70. data/app/controllers/shoppe/products_controller.rb +58 -0
  71. data/app/controllers/shoppe/sessions_controller.rb +34 -0
  72. data/app/controllers/shoppe/settings_controller.rb +16 -0
  73. data/app/controllers/shoppe/stock_level_adjustments_controller.rb +40 -0
  74. data/app/controllers/shoppe/tax_rates_controller.rb +49 -0
  75. data/app/controllers/shoppe/users_controller.rb +53 -0
  76. data/app/controllers/shoppe/variants_controller.rb +50 -0
  77. data/app/helpers/shoppe/application_helper.rb +60 -0
  78. data/app/helpers/shoppe/product_category_helper.rb +36 -0
  79. data/app/mailers/shoppe/order_mailer.rb +25 -0
  80. data/app/mailers/shoppe/user_mailer.rb +10 -0
  81. data/app/models/shoppe/address.rb +44 -0
  82. data/app/models/shoppe/country.rb +27 -0
  83. data/app/models/shoppe/customer.rb +41 -0
  84. data/app/models/shoppe/delivery_service.rb +33 -0
  85. data/app/models/shoppe/delivery_service_price.rb +31 -0
  86. data/app/models/shoppe/order.rb +100 -0
  87. data/app/models/shoppe/order/actions.rb +94 -0
  88. data/app/models/shoppe/order/billing.rb +105 -0
  89. data/app/models/shoppe/order/delivery.rb +229 -0
  90. data/app/models/shoppe/order/states.rb +69 -0
  91. data/app/models/shoppe/order_item.rb +239 -0
  92. data/app/models/shoppe/payment.rb +86 -0
  93. data/app/models/shoppe/product.rb +189 -0
  94. data/app/models/shoppe/product/product_attributes.rb +20 -0
  95. data/app/models/shoppe/product/variants.rb +51 -0
  96. data/app/models/shoppe/product_attribute.rb +66 -0
  97. data/app/models/shoppe/product_categorization.rb +14 -0
  98. data/app/models/shoppe/product_category.rb +75 -0
  99. data/app/models/shoppe/setting.rb +68 -0
  100. data/app/models/shoppe/stock_level_adjustment.rb +19 -0
  101. data/app/models/shoppe/tax_rate.rb +46 -0
  102. data/app/models/shoppe/user.rb +49 -0
  103. data/app/validators/permalink_validator.rb +7 -0
  104. data/app/views/layouts/shoppe/application.html.haml +34 -0
  105. data/app/views/layouts/shoppe/printable.html.haml +11 -0
  106. data/app/views/layouts/shoppe/sub.html.haml +10 -0
  107. data/app/views/shoppe/addresses/_form.html.haml +33 -0
  108. data/app/views/shoppe/addresses/edit.html.haml +5 -0
  109. data/app/views/shoppe/addresses/new.html.haml +5 -0
  110. data/app/views/shoppe/countries/_form.html.haml +35 -0
  111. data/app/views/shoppe/countries/edit.html.haml +6 -0
  112. data/app/views/shoppe/countries/index.html.haml +25 -0
  113. data/app/views/shoppe/countries/new.html.haml +7 -0
  114. data/app/views/shoppe/customers/_addresses.html.haml +20 -0
  115. data/app/views/shoppe/customers/_form.html.haml +30 -0
  116. data/app/views/shoppe/customers/_search_form.html.haml +13 -0
  117. data/app/views/shoppe/customers/edit.html.haml +5 -0
  118. data/app/views/shoppe/customers/index.html.haml +32 -0
  119. data/app/views/shoppe/customers/new.html.haml +5 -0
  120. data/app/views/shoppe/customers/show.html.haml +53 -0
  121. data/app/views/shoppe/delivery_service_prices/_form.html.haml +44 -0
  122. data/app/views/shoppe/delivery_service_prices/edit.html.haml +6 -0
  123. data/app/views/shoppe/delivery_service_prices/index.html.haml +23 -0
  124. data/app/views/shoppe/delivery_service_prices/new.html.haml +6 -0
  125. data/app/views/shoppe/delivery_services/_form.html.haml +38 -0
  126. data/app/views/shoppe/delivery_services/edit.html.haml +9 -0
  127. data/app/views/shoppe/delivery_services/index.html.haml +27 -0
  128. data/app/views/shoppe/delivery_services/new.html.haml +6 -0
  129. data/app/views/shoppe/order_mailer/accepted.text.erb +12 -0
  130. data/app/views/shoppe/order_mailer/received.text.erb +9 -0
  131. data/app/views/shoppe/order_mailer/rejected.text.erb +10 -0
  132. data/app/views/shoppe/order_mailer/shipped.text.erb +16 -0
  133. data/app/views/shoppe/orders/_form.html.haml +58 -0
  134. data/app/views/shoppe/orders/_order_details.html.haml +57 -0
  135. data/app/views/shoppe/orders/_order_items.html.haml +38 -0
  136. data/app/views/shoppe/orders/_order_items_form.html.haml +61 -0
  137. data/app/views/shoppe/orders/_payments_form.html.haml +15 -0
  138. data/app/views/shoppe/orders/_payments_table.html.haml +37 -0
  139. data/app/views/shoppe/orders/_search_form.html.haml +24 -0
  140. data/app/views/shoppe/orders/_status_bar.html.haml +35 -0
  141. data/app/views/shoppe/orders/despatch_note.html.haml +45 -0
  142. data/app/views/shoppe/orders/edit.html.haml +21 -0
  143. data/app/views/shoppe/orders/index.html.haml +39 -0
  144. data/app/views/shoppe/orders/new.html.haml +14 -0
  145. data/app/views/shoppe/orders/show.html.haml +25 -0
  146. data/app/views/shoppe/payments/refund.html.haml +13 -0
  147. data/app/views/shoppe/product_categories/_form.html.haml +50 -0
  148. data/app/views/shoppe/product_categories/edit.html.haml +8 -0
  149. data/app/views/shoppe/product_categories/index.html.haml +27 -0
  150. data/app/views/shoppe/product_categories/new.html.haml +6 -0
  151. data/app/views/shoppe/product_category_localisations/form.html.haml +29 -0
  152. data/app/views/shoppe/product_category_localisations/index.html.haml +26 -0
  153. data/app/views/shoppe/product_localisations/form.html.haml +32 -0
  154. data/app/views/shoppe/product_localisations/index.html.haml +26 -0
  155. data/app/views/shoppe/products/_form.html.haml +118 -0
  156. data/app/views/shoppe/products/_table.html.haml +42 -0
  157. data/app/views/shoppe/products/edit.html.haml +9 -0
  158. data/app/views/shoppe/products/import.html.haml +67 -0
  159. data/app/views/shoppe/products/index.html.haml +9 -0
  160. data/app/views/shoppe/products/new.html.haml +7 -0
  161. data/app/views/shoppe/sessions/new.html.haml +12 -0
  162. data/app/views/shoppe/sessions/reset.html.haml +12 -0
  163. data/app/views/shoppe/settings/edit.html.haml +19 -0
  164. data/app/views/shoppe/shared/error.html.haml +6 -0
  165. data/app/views/shoppe/stock_level_adjustments/index.html.haml +40 -0
  166. data/app/views/shoppe/tax_rates/form.html.haml +28 -0
  167. data/app/views/shoppe/tax_rates/index.html.haml +17 -0
  168. data/app/views/shoppe/user_mailer/new_password.text.erb +9 -0
  169. data/app/views/shoppe/users/_form.html.haml +27 -0
  170. data/app/views/shoppe/users/edit.html.haml +5 -0
  171. data/app/views/shoppe/users/index.html.haml +17 -0
  172. data/app/views/shoppe/users/new.html.haml +7 -0
  173. data/app/views/shoppe/variants/form.html.haml +68 -0
  174. data/app/views/shoppe/variants/index.html.haml +33 -0
  175. data/config/locales/de.yml +653 -0
  176. data/config/locales/en.yml +744 -0
  177. data/config/locales/es.yml +653 -0
  178. data/config/locales/pl.yml +662 -0
  179. data/config/locales/pt-BR.yml +655 -0
  180. data/config/routes.rb +53 -0
  181. data/db/countries.txt +252 -0
  182. data/db/migrate/20130926094549_create_shoppe_initial_schema.rb +175 -0
  183. data/db/migrate/20131024201501_add_address_type_to_shoppe_tax_rates.rb +5 -0
  184. data/db/migrate/20131024204815_create_shoppe_payments.rb +32 -0
  185. data/db/migrate/20131102143930_remove_default_on_order_item_weight.rb +9 -0
  186. data/db/migrate/20141013192427_create_shoppe_customers.rb +14 -0
  187. data/db/migrate/20141026175622_add_indexes_to_shoppe_order_items.rb +6 -0
  188. data/db/migrate/20141026175943_add_indexes_to_shoppe_orders.rb +7 -0
  189. data/db/migrate/20141026180333_add_indexes_to_shoppe_payments.rb +6 -0
  190. data/db/migrate/20141026180835_add_indexes_to_shoppe_product_attributes.rb +7 -0
  191. data/db/migrate/20141026180952_add_indexes_to_shoppe_product_categories.rb +5 -0
  192. data/db/migrate/20141026181040_add_indexes_to_shoppe_products.rb +8 -0
  193. data/db/migrate/20141026181312_add_indexes_to_shoppe_settings.rb +5 -0
  194. data/db/migrate/20141026181354_add_indexes_to_shoppe_stock_level_adjustments.rb +6 -0
  195. data/db/migrate/20141026181559_add_indexes_to_shoppe_users.rb +5 -0
  196. data/db/migrate/20141026181716_add_indexes_to_shoppe_delivery_services.rb +9 -0
  197. data/db/migrate/20141026181717_allow_multiple_shoppe_products_per_shoppe_product_category.rb +46 -0
  198. data/db/migrate/20141026181718_add_nested_to_product_categories.rb +30 -0
  199. data/db/migrate/20141027215005_create_shoppe_addresses.rb +17 -0
  200. data/db/migrate/20150315215633_add_customer_to_shoppe_orders.rb +5 -0
  201. data/db/migrate/20150513171350_create_shoppe_product_category_translation_table.rb +17 -0
  202. data/db/migrate/20150519173350_create_shoppe_product_translation_table.rb +18 -0
  203. data/db/schema.rb +308 -0
  204. data/db/seeds.rb +137 -0
  205. data/db/seeds_data/poe400.jpg +0 -0
  206. data/db/seeds_data/snom-870-blk.jpg +0 -0
  207. data/db/seeds_data/snom-870-grey.jpg +0 -0
  208. data/db/seeds_data/snom-mm2.jpg +0 -0
  209. data/db/seeds_data/spa303.jpg +0 -0
  210. data/db/seeds_data/t18p.jpg +0 -0
  211. data/db/seeds_data/t20p.jpg +0 -0
  212. data/db/seeds_data/t22p.jpg +0 -0
  213. data/db/seeds_data/t26p.jpg +0 -0
  214. data/db/seeds_data/t41pn.jpg +0 -0
  215. data/db/seeds_data/t46gn.jpg +0 -0
  216. data/db/seeds_data/w52p.jpg +0 -0
  217. data/db/seeds_data/yhs32.jpg +0 -0
  218. data/lib/shoppe.rb +60 -0
  219. data/lib/shoppe/associated_countries.rb +20 -0
  220. data/lib/shoppe/country_importer.rb +15 -0
  221. data/lib/shoppe/default_navigation.rb +21 -0
  222. data/lib/shoppe/engine.rb +55 -0
  223. data/lib/shoppe/error.rb +21 -0
  224. data/lib/shoppe/errors/inappropriate_delivery_service.rb +6 -0
  225. data/lib/shoppe/errors/insufficient_stock_to_fulfil.rb +15 -0
  226. data/lib/shoppe/errors/invalid_configuration.rb +6 -0
  227. data/lib/shoppe/errors/not_enough_stock.rb +15 -0
  228. data/lib/shoppe/errors/payment_declined.rb +6 -0
  229. data/lib/shoppe/errors/refund_failed.rb +6 -0
  230. data/lib/shoppe/errors/unorderable_item.rb +6 -0
  231. data/lib/shoppe/navigation_manager.rb +81 -0
  232. data/lib/shoppe/orderable_item.rb +39 -0
  233. data/lib/shoppe/settings.rb +26 -0
  234. data/lib/shoppe/settings_loader.rb +16 -0
  235. data/lib/shoppe/setup_generator.rb +10 -0
  236. data/lib/shoppe/version.rb +3 -0
  237. data/lib/shoppe/view_helpers.rb +16 -0
  238. data/lib/tasks/shoppe.rake +29 -0
  239. metadata +662 -0
@@ -0,0 +1,137 @@
1
+ # encoding: UTF-8
2
+
3
+ # tax rates
4
+ tax_rate = Shoppe::TaxRate.create!(:name => "Standard VAT", :rate => 20.0)
5
+ exempt_tax = Shoppe::TaxRate.create!(:name => "Exempt VAT", :rate => 0.0)
6
+
7
+ # delivery services
8
+
9
+ ds = Shoppe::DeliveryService.create!(:name => "Next Day Delivery", :code => 'ND16', :courier => 'AnyCourier', :tracking_url => 'http://trackingurl.com/track/{{consignment_number}}')
10
+ ds.delivery_service_prices.create!(:code => 'Parcel', :min_weight => 0, :max_weight => 1, :price => 5.0, :cost_price => 4.50, :tax_rate => tax_rate)
11
+ ds.delivery_service_prices.create!(:code => 'Parcel', :min_weight => 1, :max_weight => 5, :price => 8.0, :cost_price => 7.5, :tax_rate => tax_rate)
12
+ ds.delivery_service_prices.create!(:code => 'Parcel', :min_weight => 5, :max_weight => 20, :price => 10.0, :cost_price => 9.50, :tax_rate => tax_rate)
13
+
14
+ ds = Shoppe::DeliveryService.create!(:name => "Saturday Delivery", :code => 'NDSA16', :courier => 'AnyCourier', :tracking_url => 'http://trackingurl.com/track/{{consignment_number}}')
15
+ ds.delivery_service_prices.create!(:code => 'Parcel', :min_weight => 0, :max_weight => 1, :price => 27.0, :cost_price => 24.00, :tax_rate => tax_rate)
16
+ ds.delivery_service_prices.create!(:code => 'Parcel', :min_weight => 1, :max_weight => 5, :price => 29.0, :cost_price => 20.00, :tax_rate => tax_rate)
17
+ ds.delivery_service_prices.create!(:code => 'Parcel', :min_weight => 5, :max_weight => 20, :price => 37.0, :cost_price => 32.00,:tax_rate => tax_rate)
18
+
19
+ # categories
20
+ cat1 = Shoppe::ProductCategory.create!(:name => 'VoIP Phones')
21
+ cat2 = Shoppe::ProductCategory.create!(:name => 'VoIP Accessories')
22
+ cat3 = Shoppe::ProductCategory.create!(:name => 'Network Eqipment')
23
+
24
+ def get_file(name, content_type = 'image/jpeg')
25
+ file = ActionDispatch::Http::UploadedFile.new(:tempfile => File.open(File.join(Shoppe.root, 'db', 'seeds_data', name), 'rb'))
26
+ file.original_filename = name
27
+ file.content_type = content_type
28
+ file
29
+ end
30
+
31
+ lorem = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
32
+
33
+ pro = Shoppe::Product.new(:name => 'Yealink T20P', :sku => 'YL-SIP-T20P', :description => lorem, :short_description => 'If cheap & cheerful is what you’re after, the Yealink T20P is what you’re looking for.', :weight => 1.119, :price => 54.99, :cost_price => 44.99, :tax_rate => tax_rate, :featured => true)
34
+ pro.product_category_ids = cat1.id
35
+ pro.default_image_file = get_file('t20p.jpg')
36
+ pro.save!
37
+ pro.stock_level_adjustments.create(:description => 'Initial Stock', :adjustment => 17)
38
+ pro.product_attributes.create!(:key => 'Manufacturer', :value => 'Yealink', :position => 1)
39
+ pro.product_attributes.create!(:key => 'Model', :value => 'T20P', :position => 1)
40
+ pro.product_attributes.create!(:key => 'Colour', :value => 'Black', :position => 1)
41
+ pro.product_attributes.create!(:key => 'Lines', :value => '3', :position => 1)
42
+ pro.product_attributes.create!(:key => 'Colour Screen?', :value => 'No', :position => 1)
43
+ pro.product_attributes.create!(:key => 'Power over ethernet?', :value => 'Yes', :position => 1)
44
+
45
+ pro = Shoppe::Product.new(:name => 'Yealink T22P', :sku => 'YL-SIP-T22P', :description => lorem, :short_description => lorem, :weight => 1.419, :price => 64.99, :cost_price => 56.99, :tax_rate => tax_rate)
46
+ pro.product_category_ids = cat1.id
47
+ pro.default_image_file = get_file('t22p.jpg')
48
+ pro.save!
49
+ pro.stock_level_adjustments.create(:description => 'Initial Stock', :adjustment => 200)
50
+ pro.product_attributes.create!(:key => 'Manufacturer', :value => 'Yealink', :position => 1)
51
+ pro.product_attributes.create!(:key => 'Model', :value => 'T22P', :position => 1)
52
+ pro.product_attributes.create!(:key => 'Colour', :value => 'Black', :position => 1)
53
+ pro.product_attributes.create!(:key => 'Lines', :value => '4', :position => 1)
54
+ pro.product_attributes.create!(:key => 'Colour Screen?', :value => 'No', :position => 1)
55
+ pro.product_attributes.create!(:key => 'Power over ethernet?', :value => 'Yes', :position => 1)
56
+
57
+
58
+ pro = Shoppe::Product.new(:name => 'Yealink T26P', :sku => 'YL-SIP-T26P', :description => lorem, :short_description => lorem, :weight => 2.23, :price => 88.99, :cost_price => 78.99, :tax_rate => tax_rate)
59
+ pro.product_category_ids = cat1.id
60
+ pro.default_image_file = get_file('t26p.jpg')
61
+ pro.save!
62
+ pro.stock_level_adjustments.create(:description => 'Initial Stock', :adjustment => 100)
63
+ pro.product_attributes.create!(:key => 'Manufacturer', :value => 'Yealink', :position => 1)
64
+ pro.product_attributes.create!(:key => 'Model', :value => 'T26P', :position => 1)
65
+ pro.product_attributes.create!(:key => 'Colour', :value => 'Black', :position => 1)
66
+ pro.product_attributes.create!(:key => 'Lines', :value => '6', :position => 1)
67
+ pro.product_attributes.create!(:key => 'Colour Screen?', :value => 'No', :position => 1)
68
+ pro.product_attributes.create!(:key => 'Power over ethernet?', :value => 'Yes', :position => 1)
69
+
70
+ pro = Shoppe::Product.new(:name => 'Yealink T46GN', :sku => 'YL-SIP-T46GN', :description => lorem, :short_description => 'Colourful, sharp, fast & down right sexy. The Yealink T46P will make your scream!', :weight => 2.23, :price => 149.99, :cost_price => 139.99, :tax_rate => tax_rate, :featured => true)
71
+ pro.product_category_ids = cat1.id
72
+ pro.default_image_file = get_file('t46gn.jpg')
73
+ pro.save!
74
+ pro.stock_level_adjustments.create(:description => 'Initial Stock', :adjustment => 10)
75
+ pro.product_attributes.create!(:key => 'Manufacturer', :value => 'Yealink', :position => 1)
76
+ pro.product_attributes.create!(:key => 'Model', :value => 'T46GN', :position => 1)
77
+ pro.product_attributes.create!(:key => 'Colour', :value => 'Black', :position => 1)
78
+ pro.product_attributes.create!(:key => 'Lines', :value => '4', :position => 1)
79
+ pro.product_attributes.create!(:key => 'Colour Screen?', :value => 'Yes', :position => 1)
80
+ pro.product_attributes.create!(:key => 'Power over ethernet?', :value => 'Yes', :position => 1)
81
+
82
+ pro = Shoppe::Product.new(:name => 'Snom 870', :sku => 'SM-870', :description => lorem, :short_description => 'The perfect & beautiful VoIP phone for the discerning professional desk.', :featured => true)
83
+ pro.product_category_ids = cat1.id
84
+ pro.default_image_file = get_file('snom-870-grey.jpg')
85
+ pro.save!
86
+ pro.product_attributes.create!(:key => 'Manufacturer', :value => 'Snom', :position => 1)
87
+ pro.product_attributes.create!(:key => 'Model', :value => '870', :position => 1)
88
+ pro.product_attributes.create!(:key => 'Colour', :value => 'Grey', :position => 1)
89
+ pro.product_attributes.create!(:key => 'Lines', :value => '10', :position => 1)
90
+ pro.product_attributes.create!(:key => 'Colour Screen?', :value => 'Yes', :position => 1)
91
+ pro.product_attributes.create!(:key => 'Power over ethernet?', :value => 'Yes', :position => 1)
92
+
93
+ v1 = pro.variants.create(:name => "White/Grey", :sku => "SM-870-GREY", :price => 230.00, :cost_price => 220, :tax_rate => tax_rate, :weight => 1.35, :default => true)
94
+ v1.default_image_file = get_file('snom-870-grey.jpg')
95
+ v1.save!
96
+ v1.stock_level_adjustments.create(:description => 'Initial Stock', :adjustment => 4)
97
+
98
+
99
+ v2 = pro.variants.create(:name => "Black", :sku => "SM-870-BLK", :price => 230.00, :cost_price => 220, :tax_rate => tax_rate, :weight => 1.35)
100
+ v2.default_image_file = get_file('snom-870-blk.jpg')
101
+ v2.save!
102
+ v2.stock_level_adjustments.create(:description => 'Initial Stock', :adjustment => 2)
103
+
104
+
105
+ pro = Shoppe::Product.new(:name => 'Yealink Mono Headset', :sku => 'YL-YHS32', :description => lorem, :short_description => 'If you\'re often on the phone, this headset will make your life 100x easier. Guaranteed*.', :weight => 0.890, :price => 34.99, :cost_price => 24.99, :tax_rate => tax_rate, :featured => true)
106
+ pro.product_category_ids = cat2.id
107
+ pro.default_image_file = get_file('yhs32.jpg')
108
+ pro.save!
109
+ pro.product_attributes.create!(:key => 'Manufacturer', :value => 'Yealink', :position => 1)
110
+ pro.product_attributes.create!(:key => 'Model', :value => 'YHS32', :position => 1)
111
+
112
+ pro = Shoppe::Product.new(:name => 'Snom Wired Headset (MM2)', :sku => 'SM-MM2', :description => lorem, :short_description => lorem, :weight => 0.780, :price => 38.00, :cost_price => 30, :tax_rate => tax_rate)
113
+ pro.product_category_ids = cat2.id
114
+ pro.default_image_file = get_file('snom-mm2.jpg')
115
+ pro.save!
116
+ pro.stock_level_adjustments.create(:description => 'Initial Stock', :adjustment => 7)
117
+ pro.product_attributes.create!(:key => 'Manufacturer', :value => 'Snom', :position => 1)
118
+ pro.product_attributes.create!(:key => 'Model', :value => 'MM2', :position => 1)
119
+
120
+ pro = Shoppe::Product.new(:name => 'Snom Wired Headset (MM3)', :sku => 'SM-MM3', :description => lorem, :short_description => lorem, :weight => 0.780, :price => 38.00, :cost_price => 30, :tax_rate => tax_rate)
121
+ pro.product_category_ids = cat2.id
122
+ pro.default_image_file = get_file('snom-mm2.jpg')
123
+ pro.save!
124
+ pro.stock_level_adjustments.create(:description => 'Initial Stock', :adjustment => 5)
125
+ pro.product_attributes.create!(:key => 'Manufacturer', :value => 'Snom', :position => 1)
126
+ pro.product_attributes.create!(:key => 'Model', :value => 'MM3', :position => 1)
127
+
128
+ pro = Shoppe::Product.new(:name => 'Yealink W52P', :sku => 'TL-SIP-W52P', :description => lorem, :short_description => 'Wireless SIP phones are hard to come by but this beauty from Yealink is fab.', :weight => 1.280, :price => 99.99, :cost_price => 89.99, :tax_rate => tax_rate, :featured => true)
129
+ pro.product_category_ids = cat1.id
130
+ pro.default_image_file = get_file('w52p.jpg')
131
+ pro.save!
132
+ pro.stock_level_adjustments.create(:description => 'Initial Stock', :adjustment => 10)
133
+ pro.product_attributes.create!(:key => 'Manufacturer', :value => 'Snom', :position => 1)
134
+ pro.product_attributes.create!(:key => 'Model', :value => 'W52P', :position => 1)
135
+ pro.product_attributes.create!(:key => 'Lines', :value => '3', :position => 1)
136
+ pro.product_attributes.create!(:key => 'Colour Screen?', :value => 'Yes', :position => 1)
137
+ pro.product_attributes.create!(:key => 'Power over ethernet?', :value => 'No', :position => 1)
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,60 @@
1
+ require "coffee-rails"
2
+ require "sass-rails"
3
+ require "jquery-rails"
4
+ require 'haml'
5
+ require 'bcrypt'
6
+ require 'dynamic_form'
7
+ require 'kaminari'
8
+ require 'ransack'
9
+ require "globalize"
10
+
11
+ require 'nifty/utils'
12
+ require 'nifty/key_value_store'
13
+ require 'nifty/attachments'
14
+ require 'nifty/dialog'
15
+
16
+ module Shoppe
17
+ class << self
18
+
19
+ # The path to the root of the Shoppe applicatinio
20
+ #
21
+ # @return [String]
22
+ def root
23
+ File.expand_path('../../', __FILE__)
24
+ end
25
+
26
+ # Shoppe settings as configured in the database
27
+ #
28
+ # @return [Shoppe::Settings]
29
+ def settings
30
+ Thread.current[:shoppe_settings] ||= Shoppe::Settings.new(Shoppe::Setting.to_hash)
31
+ end
32
+
33
+ # Clears the settings from the thread cache so they will be taken
34
+ # from the database on next access
35
+ #
36
+ # @return [NilClass]
37
+ def reset_settings
38
+ Thread.current[:shoppe_settings] = nil
39
+ end
40
+
41
+ # Defines a new set of settings which should be configrable from the settings page
42
+ # in the Shoppe UI.
43
+ def add_settings_group(group, fields = [])
44
+ settings_groups[group] ||= []
45
+ settings_groups[group] = settings_groups[group] | fields
46
+ end
47
+
48
+ # All settings groups which are available for configuration on the settings page.
49
+ #
50
+ # @return [Hash]
51
+ def settings_groups
52
+ @settings_groups ||= {}
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+
59
+ # Start your engines.
60
+ require "shoppe/engine"
@@ -0,0 +1,20 @@
1
+ module Shoppe
2
+ module AssociatedCountries
3
+
4
+ def self.included(base)
5
+ base.serialize :country_ids, Array
6
+ base.before_validation { self.country_ids = self.country_ids.map(&:to_i).select { |i| i > 0} if self.country_ids.is_a?(Array) }
7
+ end
8
+
9
+ def country?(id)
10
+ id = id.id if id.is_a?(Shoppe::Country)
11
+ self.country_ids.is_a?(Array) && self.country_ids.include?(id.to_i)
12
+ end
13
+
14
+ def countries
15
+ return [] unless self.country_ids.is_a?(Array) && !self.country_ids.empty?
16
+ Shoppe::Country.where(:id => self.country_ids)
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ module Shoppe
2
+ module CountryImporter
3
+ def self.import
4
+
5
+ eu_members = ['Austria', 'Belgium', 'Bulgaria', 'Croatia','Cyprus','Czech Republic','Denmark','Estonia','Finland','France','Germany','Greece','Hungary','Ireland','Italy','Latvia','Lithuania','Luxembourg','Malta','Netherlands','Poland','Portugal','Romania','Slovakia','Slovenia','Spain','Sweden','United Kingdom']
6
+ countries = File.read(File.join(Shoppe.root, 'db', 'countries.txt')).gsub(/\r/, "\n").split("\n").map { |c| c.split(/\t/) }
7
+ countries.each do |code2, code3, name, continent, tld, currency|
8
+ country = Country.new(:name => name, :code2 => code2, :code3 => code3, :continent => continent, :tld => tld.gsub('.', ''), :currency => currency)
9
+ country.eu_member = true if eu_members.map(&:upcase).include?(name.upcase)
10
+ country.save
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ require 'shoppe/navigation_manager'
2
+
3
+ # This file defines all the default navigation managers used in Shoppe. Of course,
4
+ # modules can make changes to these by removing them or adding their own. This
5
+ # file is loaded on application initialization so if you make changes, you'll need
6
+ # to restart the webserver.
7
+
8
+ #
9
+ # This is the default navigation manager for the admin interface.
10
+ #
11
+ Shoppe::NavigationManager.build(:admin_primary) do
12
+ add_item :customers
13
+ add_item :orders
14
+ add_item :products
15
+ add_item :product_categories
16
+ add_item :delivery_services
17
+ add_item :tax_rates
18
+ add_item :users
19
+ add_item :countries
20
+ add_item :settings
21
+ end
@@ -0,0 +1,55 @@
1
+ module Shoppe
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace Shoppe
4
+
5
+ if Shoppe.respond_to?(:root)
6
+ config.autoload_paths << File.join(Shoppe.root, 'lib')
7
+ config.assets.precompile += ['shoppe/sub.css', 'shoppe/printable.css']
8
+ end
9
+
10
+ # We don't want any automatic generators in the engine.
11
+ config.generators do |g|
12
+ g.orm :active_record
13
+ g.test_framework false
14
+ g.stylesheets false
15
+ g.javascripts false
16
+ g.helper false
17
+ end
18
+
19
+ config.to_prepare do
20
+ Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c|
21
+ require_dependency(c)
22
+ end
23
+ end
24
+
25
+ initializer 'shoppe.initialize' do |app|
26
+ # Add the default settings
27
+ Shoppe.add_settings_group :system_settings, [:store_name, :email_address, :currency_unit, :tax_name, :demo_mode]
28
+
29
+ # Add middleware
30
+ app.config.middleware.use Shoppe::SettingsLoader
31
+
32
+ # Load our migrations into the application's db/migrate path
33
+ unless app.root.to_s.match root.to_s
34
+ config.paths["db/migrate"].expanded.each do |expanded_path|
35
+ app.config.paths["db/migrate"] << expanded_path
36
+ end
37
+ end
38
+
39
+ # Load view helpers for the base application
40
+ ActiveSupport.on_load(:action_view) do
41
+ require 'shoppe/view_helpers'
42
+ ActionView::Base.send :include, Shoppe::ViewHelpers
43
+ end
44
+
45
+ # Load default navigation
46
+ require 'shoppe/default_navigation'
47
+ end
48
+
49
+ generators do
50
+ require 'shoppe/setup_generator'
51
+ end
52
+
53
+ end
54
+ end
55
+
@@ -0,0 +1,21 @@
1
+ module Shoppe
2
+ class Error < StandardError
3
+
4
+ def initialize(options = {})
5
+ if options.is_a?(String)
6
+ @options = {:message => options}
7
+ else
8
+ @options = options
9
+ end
10
+ end
11
+
12
+ def message
13
+ @options[:message]
14
+ end
15
+
16
+ def options
17
+ @options
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,6 @@
1
+ module Shoppe
2
+ module Errors
3
+ class InappropriateDeliveryService < Error
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,15 @@
1
+ module Shoppe
2
+ module Errors
3
+ class InsufficientStockToFulfil < Error
4
+
5
+ def order
6
+ @options[:order]
7
+ end
8
+
9
+ def out_of_stock_items
10
+ @options[:out_of_stock_items]
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ module Shoppe
2
+ module Errors
3
+ class InvalidConfiguration < Error
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,15 @@
1
+ module Shoppe
2
+ module Errors
3
+ class NotEnoughStock < Error
4
+
5
+ def available_stock
6
+ @options[:ordered_item].stock
7
+ end
8
+
9
+ def requested_stock
10
+ @options[:requested_stock]
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ module Shoppe
2
+ module Errors
3
+ class PaymentDeclined < Shoppe::Error
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Shoppe
2
+ module Errors
3
+ class RefundFailed < Error
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Shoppe
2
+ module Errors
3
+ class UnorderableItem < Error
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,81 @@
1
+ module Shoppe
2
+ class NavigationManager
3
+
4
+ def self.managers
5
+ @managers ||= []
6
+ end
7
+
8
+ def self.create(identifier)
9
+ managers << self.new(identifier.to_s)
10
+ end
11
+
12
+ def self.build(identifier, &block)
13
+ manager = self.new(identifier.to_s)
14
+ manager.instance_eval(&block) if block_given?
15
+ managers << manager
16
+ end
17
+
18
+ def self.find(identifier)
19
+ managers.select { |m| m.identifier == identifier.to_s }.first
20
+ end
21
+
22
+ def self.render(identifier)
23
+ find(identifier).try(:to_html)
24
+ end
25
+
26
+ attr_reader :identifier
27
+
28
+ def initialize(identifier)
29
+ @identifier = identifier
30
+ end
31
+
32
+ def items
33
+ @items ||= []
34
+ end
35
+
36
+ def add_item(identifier, options = {}, &block)
37
+ item = NavigationItem.new
38
+ item.manager = self
39
+ item.identifier = identifier.to_s
40
+ item.url = options[:url] if options[:url]
41
+ item.link_options = options[:link_options] if options[:link_options]
42
+ item.active_if = block if block_given?
43
+ items << item
44
+ end
45
+
46
+ def remove_item(identifier)
47
+ items.delete_if { |i| i.identifier.to_s == identifier.to_s }
48
+ end
49
+
50
+ class NavigationItem
51
+ attr_accessor :manager
52
+ attr_accessor :identifier
53
+ attr_accessor :url
54
+ attr_accessor :link_options
55
+ attr_accessor :active_if
56
+
57
+ def description
58
+ I18n.translate("shoppe.navigation.#{manager.identifier}.#{identifier}")
59
+ end
60
+
61
+ def url(request = nil)
62
+ (@url.is_a?(Proc) && request && request.instance_eval(&@url) ) ||
63
+ @url ||
64
+ Shoppe::Engine.routes.url_helpers.send("#{identifier}_path")
65
+ end
66
+
67
+ def active?(request)
68
+ if active_if.is_a?(Proc)
69
+ request.instance_eval(&active_if) == true
70
+ elsif active_nav_var = request.instance_variable_get('@active_nav')
71
+ active_nav_var.to_s == identifier
72
+ end
73
+ end
74
+
75
+ def link_options
76
+ @link_options ||= {}
77
+ end
78
+ end
79
+
80
+ end
81
+ end