kylekthompson-shoppe 1.0.7
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +55 -0
- data/Rakefile +36 -0
- data/app/assets/images/shoppe/chosen-sprite.png +0 -0
- data/app/assets/images/shoppe/chosen-sprite@2x.png +0 -0
- data/app/assets/images/shoppe/document.svg +1 -0
- data/app/assets/images/shoppe/icons/bag.svg +1 -0
- data/app/assets/images/shoppe/icons/balance.svg +1 -0
- data/app/assets/images/shoppe/icons/box.svg +1 -0
- data/app/assets/images/shoppe/icons/building.svg +1 -0
- data/app/assets/images/shoppe/icons/chart.svg +1 -0
- data/app/assets/images/shoppe/icons/chat.svg +1 -0
- data/app/assets/images/shoppe/icons/checkbox.svg +1 -0
- data/app/assets/images/shoppe/icons/checkbox2.svg +1 -0
- data/app/assets/images/shoppe/icons/cloud.svg +1 -0
- data/app/assets/images/shoppe/icons/cone.svg +1 -0
- data/app/assets/images/shoppe/icons/credit_card.svg +1 -0
- data/app/assets/images/shoppe/icons/currency.svg +1 -0
- data/app/assets/images/shoppe/icons/edit.svg +14 -0
- data/app/assets/images/shoppe/icons/flowchart.svg +1 -0
- data/app/assets/images/shoppe/icons/gift.svg +1 -0
- data/app/assets/images/shoppe/icons/globe.svg +1 -0
- data/app/assets/images/shoppe/icons/id.svg +1 -0
- data/app/assets/images/shoppe/icons/id2.svg +1 -0
- data/app/assets/images/shoppe/icons/locked.svg +1 -0
- data/app/assets/images/shoppe/icons/report.svg +1 -0
- data/app/assets/images/shoppe/icons/search.svg +1 -0
- data/app/assets/images/shoppe/icons/support.svg +1 -0
- data/app/assets/images/shoppe/icons/tags.svg +1 -0
- data/app/assets/images/shoppe/icons/toolbox.svg +1 -0
- data/app/assets/images/shoppe/icons/unlocked.svg +1 -0
- data/app/assets/images/shoppe/icons/wallet.svg +1 -0
- data/app/assets/images/shoppe/logo.svg +47 -0
- data/app/assets/images/shoppe/move.svg +1 -0
- data/app/assets/images/shoppe/shoppe.svg +25 -0
- data/app/assets/images/shoppe/square.svg +9 -0
- data/app/assets/images/shoppe/statuses/accepted.svg +14 -0
- data/app/assets/images/shoppe/statuses/paid.svg +16 -0
- data/app/assets/images/shoppe/statuses/received.svg +15 -0
- data/app/assets/images/shoppe/statuses/rejected.svg +14 -0
- data/app/assets/images/shoppe/statuses/shipped.svg +14 -0
- data/app/assets/images/shoppe/table-tear-off.png +0 -0
- data/app/assets/javascripts/shoppe/application.coffee +123 -0
- data/app/assets/javascripts/shoppe/chosen.jquery.js +1166 -0
- data/app/assets/javascripts/shoppe/jquery_ui.js +6 -0
- data/app/assets/javascripts/shoppe/mousetrap.js +9 -0
- data/app/assets/javascripts/shoppe/order_form.coffee +47 -0
- data/app/assets/stylesheets/shoppe/application.scss +601 -0
- data/app/assets/stylesheets/shoppe/chosen.scss +424 -0
- data/app/assets/stylesheets/shoppe/dialog.scss +25 -0
- data/app/assets/stylesheets/shoppe/elements.scss +79 -0
- data/app/assets/stylesheets/shoppe/printable.scss +67 -0
- data/app/assets/stylesheets/shoppe/reset.scss +93 -0
- data/app/assets/stylesheets/shoppe/sub.scss +106 -0
- data/app/assets/stylesheets/shoppe/variables.scss +1 -0
- data/app/controllers/shoppe/addresses_controller.rb +47 -0
- data/app/controllers/shoppe/application_controller.rb +46 -0
- data/app/controllers/shoppe/attachments_controller.rb +14 -0
- data/app/controllers/shoppe/countries_controller.rb +47 -0
- data/app/controllers/shoppe/customers_controller.rb +55 -0
- data/app/controllers/shoppe/dashboard_controller.rb +9 -0
- data/app/controllers/shoppe/delivery_service_prices_controller.rb +45 -0
- data/app/controllers/shoppe/delivery_services_controller.rb +47 -0
- data/app/controllers/shoppe/orders_controller.rb +119 -0
- data/app/controllers/shoppe/payments_controller.rb +33 -0
- data/app/controllers/shoppe/product_categories_controller.rb +47 -0
- data/app/controllers/shoppe/product_category_localisations_controller.rb +58 -0
- data/app/controllers/shoppe/product_localisations_controller.rb +58 -0
- data/app/controllers/shoppe/products_controller.rb +58 -0
- data/app/controllers/shoppe/sessions_controller.rb +34 -0
- data/app/controllers/shoppe/settings_controller.rb +16 -0
- data/app/controllers/shoppe/stock_level_adjustments_controller.rb +40 -0
- data/app/controllers/shoppe/tax_rates_controller.rb +49 -0
- data/app/controllers/shoppe/users_controller.rb +53 -0
- data/app/controllers/shoppe/variants_controller.rb +50 -0
- data/app/helpers/shoppe/application_helper.rb +60 -0
- data/app/helpers/shoppe/product_category_helper.rb +36 -0
- data/app/mailers/shoppe/order_mailer.rb +25 -0
- data/app/mailers/shoppe/user_mailer.rb +10 -0
- data/app/models/shoppe/address.rb +44 -0
- data/app/models/shoppe/country.rb +27 -0
- data/app/models/shoppe/customer.rb +41 -0
- data/app/models/shoppe/delivery_service.rb +33 -0
- data/app/models/shoppe/delivery_service_price.rb +31 -0
- data/app/models/shoppe/order.rb +100 -0
- data/app/models/shoppe/order/actions.rb +94 -0
- data/app/models/shoppe/order/billing.rb +105 -0
- data/app/models/shoppe/order/delivery.rb +229 -0
- data/app/models/shoppe/order/states.rb +69 -0
- data/app/models/shoppe/order_item.rb +239 -0
- data/app/models/shoppe/payment.rb +86 -0
- data/app/models/shoppe/product.rb +189 -0
- data/app/models/shoppe/product/product_attributes.rb +20 -0
- data/app/models/shoppe/product/variants.rb +51 -0
- data/app/models/shoppe/product_attribute.rb +66 -0
- data/app/models/shoppe/product_categorization.rb +14 -0
- data/app/models/shoppe/product_category.rb +75 -0
- data/app/models/shoppe/setting.rb +68 -0
- data/app/models/shoppe/stock_level_adjustment.rb +19 -0
- data/app/models/shoppe/tax_rate.rb +46 -0
- data/app/models/shoppe/user.rb +49 -0
- data/app/validators/permalink_validator.rb +7 -0
- data/app/views/layouts/shoppe/application.html.haml +34 -0
- data/app/views/layouts/shoppe/printable.html.haml +11 -0
- data/app/views/layouts/shoppe/sub.html.haml +10 -0
- data/app/views/shoppe/addresses/_form.html.haml +33 -0
- data/app/views/shoppe/addresses/edit.html.haml +5 -0
- data/app/views/shoppe/addresses/new.html.haml +5 -0
- data/app/views/shoppe/countries/_form.html.haml +35 -0
- data/app/views/shoppe/countries/edit.html.haml +6 -0
- data/app/views/shoppe/countries/index.html.haml +25 -0
- data/app/views/shoppe/countries/new.html.haml +7 -0
- data/app/views/shoppe/customers/_addresses.html.haml +20 -0
- data/app/views/shoppe/customers/_form.html.haml +30 -0
- data/app/views/shoppe/customers/_search_form.html.haml +13 -0
- data/app/views/shoppe/customers/edit.html.haml +5 -0
- data/app/views/shoppe/customers/index.html.haml +32 -0
- data/app/views/shoppe/customers/new.html.haml +5 -0
- data/app/views/shoppe/customers/show.html.haml +53 -0
- data/app/views/shoppe/delivery_service_prices/_form.html.haml +44 -0
- data/app/views/shoppe/delivery_service_prices/edit.html.haml +6 -0
- data/app/views/shoppe/delivery_service_prices/index.html.haml +23 -0
- data/app/views/shoppe/delivery_service_prices/new.html.haml +6 -0
- data/app/views/shoppe/delivery_services/_form.html.haml +38 -0
- data/app/views/shoppe/delivery_services/edit.html.haml +9 -0
- data/app/views/shoppe/delivery_services/index.html.haml +27 -0
- data/app/views/shoppe/delivery_services/new.html.haml +6 -0
- data/app/views/shoppe/order_mailer/accepted.text.erb +12 -0
- data/app/views/shoppe/order_mailer/received.text.erb +9 -0
- data/app/views/shoppe/order_mailer/rejected.text.erb +10 -0
- data/app/views/shoppe/order_mailer/shipped.text.erb +16 -0
- data/app/views/shoppe/orders/_form.html.haml +58 -0
- data/app/views/shoppe/orders/_order_details.html.haml +57 -0
- data/app/views/shoppe/orders/_order_items.html.haml +38 -0
- data/app/views/shoppe/orders/_order_items_form.html.haml +61 -0
- data/app/views/shoppe/orders/_payments_form.html.haml +15 -0
- data/app/views/shoppe/orders/_payments_table.html.haml +37 -0
- data/app/views/shoppe/orders/_search_form.html.haml +24 -0
- data/app/views/shoppe/orders/_status_bar.html.haml +35 -0
- data/app/views/shoppe/orders/despatch_note.html.haml +45 -0
- data/app/views/shoppe/orders/edit.html.haml +21 -0
- data/app/views/shoppe/orders/index.html.haml +39 -0
- data/app/views/shoppe/orders/new.html.haml +14 -0
- data/app/views/shoppe/orders/show.html.haml +25 -0
- data/app/views/shoppe/payments/refund.html.haml +13 -0
- data/app/views/shoppe/product_categories/_form.html.haml +50 -0
- data/app/views/shoppe/product_categories/edit.html.haml +8 -0
- data/app/views/shoppe/product_categories/index.html.haml +27 -0
- data/app/views/shoppe/product_categories/new.html.haml +6 -0
- data/app/views/shoppe/product_category_localisations/form.html.haml +29 -0
- data/app/views/shoppe/product_category_localisations/index.html.haml +26 -0
- data/app/views/shoppe/product_localisations/form.html.haml +32 -0
- data/app/views/shoppe/product_localisations/index.html.haml +26 -0
- data/app/views/shoppe/products/_form.html.haml +118 -0
- data/app/views/shoppe/products/_table.html.haml +42 -0
- data/app/views/shoppe/products/edit.html.haml +9 -0
- data/app/views/shoppe/products/import.html.haml +67 -0
- data/app/views/shoppe/products/index.html.haml +9 -0
- data/app/views/shoppe/products/new.html.haml +7 -0
- data/app/views/shoppe/sessions/new.html.haml +12 -0
- data/app/views/shoppe/sessions/reset.html.haml +12 -0
- data/app/views/shoppe/settings/edit.html.haml +19 -0
- data/app/views/shoppe/shared/error.html.haml +6 -0
- data/app/views/shoppe/stock_level_adjustments/index.html.haml +40 -0
- data/app/views/shoppe/tax_rates/form.html.haml +28 -0
- data/app/views/shoppe/tax_rates/index.html.haml +17 -0
- data/app/views/shoppe/user_mailer/new_password.text.erb +9 -0
- data/app/views/shoppe/users/_form.html.haml +27 -0
- data/app/views/shoppe/users/edit.html.haml +5 -0
- data/app/views/shoppe/users/index.html.haml +17 -0
- data/app/views/shoppe/users/new.html.haml +7 -0
- data/app/views/shoppe/variants/form.html.haml +68 -0
- data/app/views/shoppe/variants/index.html.haml +33 -0
- data/config/locales/de.yml +653 -0
- data/config/locales/en.yml +744 -0
- data/config/locales/es.yml +653 -0
- data/config/locales/pl.yml +662 -0
- data/config/locales/pt-BR.yml +655 -0
- data/config/routes.rb +53 -0
- data/db/countries.txt +252 -0
- data/db/migrate/20130926094549_create_shoppe_initial_schema.rb +175 -0
- data/db/migrate/20131024201501_add_address_type_to_shoppe_tax_rates.rb +5 -0
- data/db/migrate/20131024204815_create_shoppe_payments.rb +32 -0
- data/db/migrate/20131102143930_remove_default_on_order_item_weight.rb +9 -0
- data/db/migrate/20141013192427_create_shoppe_customers.rb +14 -0
- data/db/migrate/20141026175622_add_indexes_to_shoppe_order_items.rb +6 -0
- data/db/migrate/20141026175943_add_indexes_to_shoppe_orders.rb +7 -0
- data/db/migrate/20141026180333_add_indexes_to_shoppe_payments.rb +6 -0
- data/db/migrate/20141026180835_add_indexes_to_shoppe_product_attributes.rb +7 -0
- data/db/migrate/20141026180952_add_indexes_to_shoppe_product_categories.rb +5 -0
- data/db/migrate/20141026181040_add_indexes_to_shoppe_products.rb +8 -0
- data/db/migrate/20141026181312_add_indexes_to_shoppe_settings.rb +5 -0
- data/db/migrate/20141026181354_add_indexes_to_shoppe_stock_level_adjustments.rb +6 -0
- data/db/migrate/20141026181559_add_indexes_to_shoppe_users.rb +5 -0
- data/db/migrate/20141026181716_add_indexes_to_shoppe_delivery_services.rb +9 -0
- data/db/migrate/20141026181717_allow_multiple_shoppe_products_per_shoppe_product_category.rb +46 -0
- data/db/migrate/20141026181718_add_nested_to_product_categories.rb +30 -0
- data/db/migrate/20141027215005_create_shoppe_addresses.rb +17 -0
- data/db/migrate/20150315215633_add_customer_to_shoppe_orders.rb +5 -0
- data/db/migrate/20150513171350_create_shoppe_product_category_translation_table.rb +17 -0
- data/db/migrate/20150519173350_create_shoppe_product_translation_table.rb +18 -0
- data/db/schema.rb +308 -0
- data/db/seeds.rb +137 -0
- data/db/seeds_data/poe400.jpg +0 -0
- data/db/seeds_data/snom-870-blk.jpg +0 -0
- data/db/seeds_data/snom-870-grey.jpg +0 -0
- data/db/seeds_data/snom-mm2.jpg +0 -0
- data/db/seeds_data/spa303.jpg +0 -0
- data/db/seeds_data/t18p.jpg +0 -0
- data/db/seeds_data/t20p.jpg +0 -0
- data/db/seeds_data/t22p.jpg +0 -0
- data/db/seeds_data/t26p.jpg +0 -0
- data/db/seeds_data/t41pn.jpg +0 -0
- data/db/seeds_data/t46gn.jpg +0 -0
- data/db/seeds_data/w52p.jpg +0 -0
- data/db/seeds_data/yhs32.jpg +0 -0
- data/lib/shoppe.rb +60 -0
- data/lib/shoppe/associated_countries.rb +20 -0
- data/lib/shoppe/country_importer.rb +15 -0
- data/lib/shoppe/default_navigation.rb +21 -0
- data/lib/shoppe/engine.rb +55 -0
- data/lib/shoppe/error.rb +21 -0
- data/lib/shoppe/errors/inappropriate_delivery_service.rb +6 -0
- data/lib/shoppe/errors/insufficient_stock_to_fulfil.rb +15 -0
- data/lib/shoppe/errors/invalid_configuration.rb +6 -0
- data/lib/shoppe/errors/not_enough_stock.rb +15 -0
- data/lib/shoppe/errors/payment_declined.rb +6 -0
- data/lib/shoppe/errors/refund_failed.rb +6 -0
- data/lib/shoppe/errors/unorderable_item.rb +6 -0
- data/lib/shoppe/navigation_manager.rb +81 -0
- data/lib/shoppe/orderable_item.rb +39 -0
- data/lib/shoppe/settings.rb +26 -0
- data/lib/shoppe/settings_loader.rb +16 -0
- data/lib/shoppe/setup_generator.rb +10 -0
- data/lib/shoppe/version.rb +3 -0
- data/lib/shoppe/view_helpers.rb +16 -0
- data/lib/tasks/shoppe.rake +29 -0
- metadata +662 -0
data/db/seeds.rb
ADDED
|
@@ -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
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/shoppe.rb
ADDED
|
@@ -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
|
+
|
data/lib/shoppe/error.rb
ADDED
|
@@ -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,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
|