glysellin 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +15 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +100 -0
  4. data/Rakefile +29 -0
  5. data/app/assets/javascripts/glysellin/address.coffee +38 -0
  6. data/app/assets/javascripts/glysellin/async-cart.coffee +139 -0
  7. data/app/assets/javascripts/glysellin/base.js +6 -0
  8. data/app/assets/javascripts/glysellin/cart.coffee +54 -0
  9. data/app/assets/javascripts/glysellin/main.coffee +0 -0
  10. data/app/assets/javascripts/glysellin/product.coffee +0 -0
  11. data/app/assets/stylesheets/glysellin/application.css +13 -0
  12. data/app/assets/stylesheets/glysellin/orders.css +4 -0
  13. data/app/assets/stylesheets/glysellin/products.css +4 -0
  14. data/app/controllers/glysellin/cart/addresses_controller.rb +17 -0
  15. data/app/controllers/glysellin/cart/discount_code_controller.rb +10 -0
  16. data/app/controllers/glysellin/cart/payment_method_controller.rb +17 -0
  17. data/app/controllers/glysellin/cart/products_controller.rb +37 -0
  18. data/app/controllers/glysellin/cart/shipping_method_controller.rb +18 -0
  19. data/app/controllers/glysellin/cart/state_controller.rb +15 -0
  20. data/app/controllers/glysellin/cart_controller.rb +53 -0
  21. data/app/controllers/glysellin/orders_controller.rb +53 -0
  22. data/app/controllers/glysellin/products_controller.rb +12 -0
  23. data/app/helpers/glysellin/application_helper.rb +4 -0
  24. data/app/helpers/glysellin/cart_helper.rb +21 -0
  25. data/app/helpers/glysellin/orders_helper.rb +35 -0
  26. data/app/helpers/glysellin/products_helper.rb +4 -0
  27. data/app/mailers/glysellin/order_admin_mailer.rb +17 -0
  28. data/app/mailers/glysellin/order_customer_mailer.rb +27 -0
  29. data/app/models/glysellin/address.rb +35 -0
  30. data/app/models/glysellin/brand.rb +14 -0
  31. data/app/models/glysellin/discount_code.rb +36 -0
  32. data/app/models/glysellin/discount_type.rb +9 -0
  33. data/app/models/glysellin/order.rb +243 -0
  34. data/app/models/glysellin/order_adjustment.rb +19 -0
  35. data/app/models/glysellin/order_item.rb +38 -0
  36. data/app/models/glysellin/orderer.rb +28 -0
  37. data/app/models/glysellin/payment.rb +46 -0
  38. data/app/models/glysellin/payment_method.rb +36 -0
  39. data/app/models/glysellin/product.rb +136 -0
  40. data/app/models/glysellin/product_image.rb +11 -0
  41. data/app/models/glysellin/product_property.rb +22 -0
  42. data/app/models/glysellin/product_property_type.rb +11 -0
  43. data/app/models/glysellin/product_type.rb +11 -0
  44. data/app/models/glysellin/shipping_method.rb +22 -0
  45. data/app/models/glysellin/taxonomy.rb +35 -0
  46. data/app/models/glysellin/variant.rb +100 -0
  47. data/app/views/glysellin/cart/_added_to_cart_warning.html.erb +21 -0
  48. data/app/views/glysellin/cart/_cart.html.erb +13 -0
  49. data/app/views/glysellin/cart/_navigation.html.erb +11 -0
  50. data/app/views/glysellin/cart/_products.html.erb +125 -0
  51. data/app/views/glysellin/cart/_recap.html.erb +16 -0
  52. data/app/views/glysellin/cart/recap/_addresses.html.erb +13 -0
  53. data/app/views/glysellin/cart/recap/_products.html.erb +63 -0
  54. data/app/views/glysellin/cart/show.html.erb +13 -0
  55. data/app/views/glysellin/cart/states/_addresses.html.erb +25 -0
  56. data/app/views/glysellin/cart/states/_choose_payment_method.html.erb +14 -0
  57. data/app/views/glysellin/cart/states/_choose_shipping_method.html.erb +14 -0
  58. data/app/views/glysellin/cart/states/_filled.html.erb +3 -0
  59. data/app/views/glysellin/cart/states/_init.html.erb +5 -0
  60. data/app/views/glysellin/cart/states/_ready.html.erb +1 -0
  61. data/app/views/glysellin/order_admin_mailer/_order_header.text.erb +5 -0
  62. data/app/views/glysellin/order_admin_mailer/send_check_order_created_email.text.erb +8 -0
  63. data/app/views/glysellin/order_admin_mailer/send_order_paid_email.text.erb +8 -0
  64. data/app/views/glysellin/order_customer_mailer/_order_footer.text.erb +3 -0
  65. data/app/views/glysellin/order_customer_mailer/_order_header.text.erb +5 -0
  66. data/app/views/glysellin/order_customer_mailer/send_order_created_email.text.erb +7 -0
  67. data/app/views/glysellin/order_customer_mailer/send_order_paid_email.text.erb +7 -0
  68. data/app/views/glysellin/order_customer_mailer/send_order_shipped_email.text.erb +8 -0
  69. data/app/views/glysellin/orders/_addresses_fields.html.erb +29 -0
  70. data/app/views/glysellin/orders/_order.html.erb +18 -0
  71. data/app/views/glysellin/orders/_payment_canceled.html.erb +13 -0
  72. data/app/views/glysellin/orders/_payment_successful.html.erb +6 -0
  73. data/app/views/glysellin/orders/payment_response.html.erb +5 -0
  74. data/app/views/glysellin/payment_methods/_paypal-integral.html.erb +22 -0
  75. data/app/views/glysellin/products/_add_to_cart.html.erb +16 -0
  76. data/app/views/glysellin/products/_item.html.erb +21 -0
  77. data/app/views/glysellin/products/filter.html.erb +0 -0
  78. data/app/views/glysellin/products/index.html.erb +3 -0
  79. data/app/views/glysellin/products/show.html.erb +3 -0
  80. data/app/views/glysellin/shared/_address.html.erb +11 -0
  81. data/app/views/glysellin/shared/_address.text.erb +7 -0
  82. data/app/views/glysellin/shared/_order.text.erb +56 -0
  83. data/app/views/glysellin/shared/mailer/_footer.text.erb +2 -0
  84. data/app/views/layouts/glysellin/application.html.erb +14 -0
  85. data/config/locales/glysellin.en.yml +113 -0
  86. data/config/locales/glysellin.fr.yml +119 -0
  87. data/db/migrate/20120206115004_create_glysellin_orders.rb +16 -0
  88. data/db/migrate/20120206115132_create_glysellin_customers.rb +8 -0
  89. data/db/migrate/20120206115657_create_glysellin_addresses.rb +22 -0
  90. data/db/migrate/20120206124505_create_glysellin_products.rb +20 -0
  91. data/db/migrate/20120206124545_create_glysellin_order_items.rb +15 -0
  92. data/db/migrate/20120206124630_create_glysellin_product_images.rb +10 -0
  93. data/db/migrate/20120206125210_add_attachment_image_to_product_image.rb +15 -0
  94. data/db/migrate/20120206130920_create_glysellin_payments.rb +13 -0
  95. data/db/migrate/20120206131042_create_glysellin_payment_methods.rb +10 -0
  96. data/db/migrate/20120207175050_create_glysellin_taxonomies.rb +11 -0
  97. data/db/migrate/20120207175158_create_products_taxonomies_table.rb +12 -0
  98. data/db/migrate/20120515143231_create_brands.rb +9 -0
  99. data/db/migrate/20120515143233_add_attachment_image_to_brands.rb +15 -0
  100. data/db/migrate/20120620151705_create_product_properties.rb +12 -0
  101. data/db/migrate/20130204121211_create_glysellin_discount_types.rb +10 -0
  102. data/db/migrate/20130204121228_create_glysellin_discount_codes.rb +15 -0
  103. data/db/migrate/20130204125310_create_glysellin_order_adjustments.rb +13 -0
  104. data/db/migrate/20130204202102_create_glysellin_shipping_methods.rb +12 -0
  105. data/db/migrate/20130204202109_add_shipping_method_id_to_glysellin_orders.rb +5 -0
  106. data/db/migrate/20130205110036_add_weight_to_glysellin_products.rb +5 -0
  107. data/db/migrate/20130205120541_add_weight_to_glysellin_order_items.rb +5 -0
  108. data/db/migrate/20130208162813_create_glysellin_variants.rb +17 -0
  109. data/db/migrate/20130208165020_create_glysellin_product_property_types.rb +7 -0
  110. data/db/migrate/20130211105557_add_type_id_to_glysellin_product_properties.rb +5 -0
  111. data/db/migrate/20130211112302_add_variant_id_to_glysellin_product_properties.rb +13 -0
  112. data/db/migrate/20130211152651_add_product_id_to_glysellin_variants.rb +5 -0
  113. data/db/migrate/20130212131658_add_weight_to_glysellin_variants.rb +5 -0
  114. data/db/migrate/20130212132253_remove_variant_columns_from_glysellin_products.rb +15 -0
  115. data/db/migrate/20130212154943_remove_eot_price_from_glysellin_products.rb +9 -0
  116. data/db/migrate/20130214184204_create_glysellin_product_types.rb +9 -0
  117. data/db/migrate/20130214184352_create_product_type_behavior.rb +15 -0
  118. data/db/migrate/20130221102200_add_unmarked_price_to_glysellin_variants.rb +5 -0
  119. data/db/migrate/20130311135842_add_addressable_to_glysellin_addresses.rb +6 -0
  120. data/db/migrate/20130314114048_change_addressable_associations_in_glysellin_addresses.rb +15 -0
  121. data/db/migrate/20130325113903_remove_address_ids_from_glysellin_orders.rb +11 -0
  122. data/db/seeds/shipping_carrier/rates/colissimo.csv +16 -0
  123. data/db/seeds/shipping_carrier/rates/lettre-max.csv +9 -0
  124. data/lib/active_model/model.rb +101 -0
  125. data/lib/generators/glysellin/install/USAGE +8 -0
  126. data/lib/generators/glysellin/install/install_generator.rb +50 -0
  127. data/lib/generators/glysellin/install/templates/initializer.rb +119 -0
  128. data/lib/generators/glysellin/install/templates/order_observer.rb +12 -0
  129. data/lib/generators/glysellin/install/utils.rb +11 -0
  130. data/lib/glysellin.rb +124 -0
  131. data/lib/glysellin/acts_as_sellable.rb +14 -0
  132. data/lib/glysellin/cart.rb +21 -0
  133. data/lib/glysellin/cart/address.rb +16 -0
  134. data/lib/glysellin/cart/adjustment.rb +17 -0
  135. data/lib/glysellin/cart/adjustment/base.rb +41 -0
  136. data/lib/glysellin/cart/adjustment/discount_code.rb +43 -0
  137. data/lib/glysellin/cart/adjustment/shipping_method.rb +31 -0
  138. data/lib/glysellin/cart/basket.rb +482 -0
  139. data/lib/glysellin/cart/customer.rb +36 -0
  140. data/lib/glysellin/cart/model_wrapper.rb +90 -0
  141. data/lib/glysellin/cart/nested_resource.rb +39 -0
  142. data/lib/glysellin/cart/payment_method.rb +8 -0
  143. data/lib/glysellin/cart/product.rb +16 -0
  144. data/lib/glysellin/cart/select.rb +31 -0
  145. data/lib/glysellin/cart/serializable.rb +30 -0
  146. data/lib/glysellin/cart/shipping_method.rb +8 -0
  147. data/lib/glysellin/discount_type_calculator.rb +7 -0
  148. data/lib/glysellin/discount_type_calculator/base.rb +30 -0
  149. data/lib/glysellin/discount_type_calculator/order_percentage.rb +16 -0
  150. data/lib/glysellin/engine.rb +14 -0
  151. data/lib/glysellin/engine/routes.rb +61 -0
  152. data/lib/glysellin/gateway.rb +16 -0
  153. data/lib/glysellin/gateway/atos.rb +111 -0
  154. data/lib/glysellin/gateway/base.rb +43 -0
  155. data/lib/glysellin/gateway/check.rb +34 -0
  156. data/lib/glysellin/gateway/paypal_integral.rb +71 -0
  157. data/lib/glysellin/helpers.rb +15 -0
  158. data/lib/glysellin/helpers/controller.rb +22 -0
  159. data/lib/glysellin/helpers/countries.rb +261 -0
  160. data/lib/glysellin/helpers/views.rb +28 -0
  161. data/lib/glysellin/product_methods.rb +66 -0
  162. data/lib/glysellin/products_list.rb +72 -0
  163. data/lib/glysellin/property_finder.rb +13 -0
  164. data/lib/glysellin/shipping_carrier.rb +14 -0
  165. data/lib/glysellin/shipping_carrier/base.rb +55 -0
  166. data/lib/glysellin/shipping_carrier/colissimo.rb +19 -0
  167. data/lib/glysellin/shipping_carrier/flat_rate.rb +19 -0
  168. data/lib/glysellin/shipping_carrier/free_shipping.rb +14 -0
  169. data/lib/glysellin/shipping_carrier/helpers/country_weight_table.rb +65 -0
  170. data/lib/glysellin/shipping_carrier/lettre_max.rb +19 -0
  171. data/lib/glysellin/version.rb +3 -0
  172. data/lib/tasks/glysellin_tasks.rake +37 -0
  173. metadata +341 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTc3ZmMwNGU1YTk5ODFhMDAxZTgwMjBiNDk1Njk5OGZlYzJmOGJmMQ==
5
+ data.tar.gz: !binary |-
6
+ YzY4Y2U4NmE1NDEzODQ2NmEwNjVlNWE3NmYzN2NjMDNlYWZlMmIyYw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ MmZjMzA5YTRiOWUzN2Y5ZjgxYWZiZmUzOWI3NDQ3ODI0ZDA1YzJmZDBkYzBk
10
+ MjYzMGE2NThkYWE5NDc4NTM2NDlkMmJmMzU4NmE4ZGI2ZGQxMmU1MTM5OGQ5
11
+ MTU3NTYyMjg5ZGQxMzEwNTEwM2ZjMmE2YjQxMDRmYjcxZDZmZjE=
12
+ data.tar.gz: !binary |-
13
+ MTU1ZjBiY2M0ZjlkNDBmYzdiYThhNzViMDY3N2M0YjY4ODI5Zjk2OTE5MGQ3
14
+ NzQ4ZjRmNzdmMGNkMDhiNzVhNWJkMzAxY2YyMGVjMjZlYTc3MDNkNmM3MWJm
15
+ MmM4NjAwYTA3YmE5NDc5N2ZhN2QxZGIwODAwYTE4MTg0MWY5OGM=
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 Valentin Ballestrino
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # Glysellin
2
+
3
+ Glysellin is a Rails lightweight e-commerce solution that helps you get simple products, orders and payment gateways without the whole set of functionalities a real e-commerce needs.
4
+
5
+ In order to stay simple, we choosed for now to keep with some strong dependencies that may not fit to your app.
6
+
7
+ Also, no admin interface is provided so you can integrate it, but we always use [RailsAdmin](https://github.com/sferik/rails_admin).
8
+
9
+
10
+ ## Dependencies
11
+
12
+ * [Devise](https://github.com/plataformatec/devise)
13
+ * [Paperclip](https://github.com/thoughtbot/paperclip)
14
+ * [Simple Form](https://github.com/plataformatec/simple_form)
15
+
16
+
17
+ ## Disclaimer
18
+
19
+ Glysellin is under development and can now be used, but documentation is poor, there are no tests and API can change quickly while we don't have tested it within enough projects.
20
+
21
+
22
+ ## Installing
23
+
24
+ To process to glysellin's installation, you shall use the install generator which will :
25
+
26
+ * Create an initializer file to configure the shop's behavior
27
+ * Copy all needed migrations
28
+ * Migrate and seed default data
29
+ * Mount the engine
30
+ * Copy the actions and mailers views to be overriden
31
+
32
+ The install generator command :
33
+
34
+ ```bash
35
+ rails generate glysellin:install
36
+ ```
37
+
38
+
39
+ ## Using the Cart
40
+
41
+ The shopping cart contents are stored in user's cookies, with the key `glysellin.cart`
42
+
43
+
44
+ ### Displaying the cart
45
+
46
+ To display the cart you must render it's partial in your layout :
47
+
48
+ ```erb
49
+ <%= render_cart(current_cart) %>
50
+ ```
51
+
52
+
53
+ ### Filling the cart
54
+
55
+ To fill the cart, you can use the pre-built helper to create a simple "Add to cart" form that asynchronously updates user's cart contents.
56
+ You must pass the helper a `Glysellin::Product` instance in order to make it work :
57
+
58
+ ```erb
59
+ <%= add_to_cart_form(@product) %>
60
+ ```
61
+
62
+
63
+ ## Managing orders
64
+
65
+ By default, being bound to Devise, Glysellin automatically generates anonymous users to bind orders to. You can choose to keep this behavior alone, or add real subscription in the ordering process or remove the default behavior to force users to create an account by switching off the default functionality in the initializer (default parameter is commented) :
66
+
67
+ ```ruby
68
+ # config/initializers/glysellin.rb
69
+ Glysellin.config do |config|
70
+ # Allows creating fake accounts for customers with automatic random
71
+ # password generation
72
+ # Defaults to true
73
+ #
74
+ config.allow_anonymous_orders = true
75
+ end
76
+ ```
77
+
78
+
79
+ ## Customizing Order behavior
80
+
81
+ Since the Order object is implemented with the [state_machine gem](), it emits state transition events.
82
+ On install, a sample observer is copied to `app/models/order_observer.rb` in your application.
83
+ To be able to use it, you must configure your app to allow the `OrderObserver` to listen to `Order` state transitions by uncommenting and editing the following `active_record.observers` config line in your `application.rb` file :
84
+
85
+ ```ruby
86
+ # config/application.rb
87
+
88
+ # Activate observers that should always be running.
89
+ config.active_record.observers = :order_observer
90
+ ```
91
+
92
+
93
+ ## Gateway integration
94
+
95
+ The routes to redirect the payments gateways to are :
96
+
97
+ * For the automatic Server to Server response : `http://yourapp.com/<glysellin_mount_point>/orders/gateway/:gateway` where :gateway is the gateway slug
98
+ * For the "Return to shop" redirections :
99
+ * Success response : `http://yourapp.com/<glysellin_mount_point>/orders/gateway/response/paid`
100
+ * Error response : `http://yourapp.com/<glysellin_mount_point>/orders/gateway/response/cancel`
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Glysellin'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
@@ -0,0 +1,38 @@
1
+ class GlysellinAddress
2
+ defaults =
3
+ onUpdated: null
4
+
5
+ constructor: (@container) ->
6
+ @shipping_address_container = @container.find('.shipping-address-container')
7
+ @billing_address_container = @container.find('.billing-address-container')
8
+ @toggle_shipping_address = @container.find('[data-toggle="address"]')
9
+ @shipping_address_fields = @shipping_address_container.clone()
10
+ @bindAll()
11
+
12
+ bindAll: () ->
13
+ @toggle_shipping_address.on "change", =>
14
+ @switchAddress()
15
+
16
+ switchAddress: () ->
17
+ if @toggle_shipping_address.is(':checked')
18
+ @shipping_address_container.html(@shipping_address_fields)
19
+
20
+ for attr in ['first_name', 'last_name', 'address', 'zip', 'city', 'tel']
21
+ if @shipping_address_container.find("[name*='[#{ attr }]']").val() == ""
22
+ @shipping_address_container.find("[name*='[#{ attr }]']").val(@billing_address_container.find("[name*='[#{ attr }]']").val())
23
+
24
+ # Country
25
+ val = @billing_address_container.find("[name*='country']").val()
26
+ if @shipping_address_container.find("[name*='country']").val() == ""
27
+ @shipping_address_container.find("[name*='country']").val(val)
28
+ @shipping_address_container.find("[name*='country']").change()
29
+
30
+ else
31
+ @shipping_address_fields = @shipping_address_container.clone()
32
+ @shipping_address_container.html('')
33
+
34
+
35
+ $.fn.glysellinAddress = () ->
36
+ @each ->
37
+ address = new GlysellinAddress($(this))
38
+ address.switchAddress()
@@ -0,0 +1,139 @@
1
+ class AsyncCart
2
+ constructor: (@container) ->
3
+ @defaultPostOptions = {
4
+ utf8: @container.find('input[name="utf8"]').val(),
5
+ authenticity_token: @container.find('input[name="authenticity_token"]').val()
6
+ }
7
+
8
+ $totalRow = @container.find('.products-total-row')
9
+ @totals = {
10
+ eot: $totalRow.find('.total-eot-price')
11
+ total: $totalRow.find('.total-price')
12
+ }
13
+
14
+ @subtotalsRow = @container.find('.products-subtotal-row')
15
+ @subtotals = {
16
+ eot: @subtotalsRow.find('.eot-subtotal'),
17
+ total: @subtotalsRow.find('.subtotal')
18
+ }
19
+
20
+ @adjustmentRow = @container.find('.adjustment-row[data-type=discount-code]')
21
+ @adjustment = {
22
+ name: @adjustmentRow.find('.adjustment-name'),
23
+ value: @adjustmentRow.find('.adjustment-value')
24
+ }
25
+
26
+ @discountCode = @container.find('#glysellin_cart_basket_discount_code')
27
+
28
+ @cart_path = @container.data("cart-url")
29
+
30
+ @bindAll()
31
+
32
+ bindAll: ->
33
+ @container.find('.quantity-input')
34
+ .on('change', (e) => @quantityChanged(e.currentTarget))
35
+ .on 'keyup', (e) =>
36
+ @handleEnterKey(e)
37
+
38
+ @discountCode.on 'keyup', (e) =>
39
+ @handleEnterKey(e)
40
+
41
+ @container.find('.update-discount-code-btn').on 'click', (e) =>
42
+ @discountCodeUpdated()
43
+
44
+ @discountCode.on 'change', (e) =>
45
+ @discountCodeUpdated()
46
+
47
+ @adjustmentRow.find('.remove-discount-btn').on 'click', (e) =>
48
+ @resetDiscountCode(); false
49
+
50
+ @container.on "submit", (e, force = false) -> force
51
+
52
+ @container.find("[name=submit_order]").on "click", (e) =>
53
+ if e.clientX != 0 && e.clientY != 0
54
+ @container.trigger("submit", [true])
55
+
56
+ handleEnterKey: (e) ->
57
+ $(e.currentTarget).trigger('change') if e.which == 13
58
+ false
59
+
60
+ quantityChanged: (el) ->
61
+ $el = $(el)
62
+ quantity = parseInt($el.val(), 10)
63
+
64
+ # Ensure we have an int > 0 or use 1
65
+ unless $.isNumeric(quantity) && quantity > 0
66
+ quantity = 1
67
+ $el.val(quantity)
68
+
69
+ @update(
70
+ "products/#{ $el.data('id') }",
71
+ { _method: "put", quantity: quantity}
72
+ (resp) => @remoteQuantityUpdated(resp, $el)
73
+ )
74
+
75
+ remoteQuantityUpdated: (resp, $el) ->
76
+ # Current product row update handling
77
+ $tr = $el.closest('tr')
78
+ $el.val(resp.quantity)
79
+ $tr.find('.product-eot-price').text(resp.eot_price)
80
+ $tr.find('.product-price').text(resp.price)
81
+
82
+ # Total row handling
83
+ @setTotals(resp)
84
+ @setDiscountValues(resp)
85
+
86
+ @container.trigger('quantity-updated.glysellin')
87
+
88
+ discountCodeUpdated: ->
89
+ @update(
90
+ "discount_code"
91
+ { _method: "put", code: @discountCode.val() }
92
+ (resp) => @remoteAdjustmentUpdated(resp)
93
+ )
94
+
95
+ resetDiscountCode: ->
96
+ @update(
97
+ 'update-discount-code'
98
+ { _method: "put", code: '' }
99
+ (resp) => @remoteAdjustmentUpdated(resp)
100
+ )
101
+
102
+ remoteAdjustmentUpdated: (resp) ->
103
+ discount = resp.discount_name
104
+ if discount
105
+ @setDiscountValues(resp)
106
+ @subtotalsRow.fadeIn(200)
107
+ @adjustmentRow.fadeIn(200)
108
+ else
109
+ @subtotalsRow.fadeOut(200) unless $('.adjustment-row').length > 1
110
+ @adjustmentRow.fadeOut(200, => @setDiscountValues(resp))
111
+
112
+ # Total row handling when
113
+ @setTotals(resp)
114
+
115
+ @container.trigger('discount-updated.glysellin', [discount])
116
+
117
+ update: (action, options, callback) ->
118
+ $.post(
119
+ "#{ @cart_path }/#{ action }",
120
+ $.extend({}, @defaultPostOptions, options),
121
+ callback,
122
+ 'json'
123
+ )
124
+
125
+ setDiscountValues: (totals) ->
126
+ @adjustment.name.text(totals.discount_name)
127
+ @adjustment.value.text(totals.discount_value)
128
+
129
+ setTotals: (totals) ->
130
+ @subtotals.eot.text(totals.eot_subtotal)
131
+ @subtotals.total.text(totals.subtotal)
132
+ @totals.eot.text(totals.total_eot_price)
133
+ @totals.total.text(totals.total_price)
134
+
135
+ $.fn.glysellinAsyncCart = (options = {})->
136
+ @each ->
137
+ $cart = $(this)
138
+ data = $cart.data('glysellin.async-cart')
139
+ $cart.data('glysellin.async-cart', new AsyncCart $cart, options) unless data
@@ -0,0 +1,6 @@
1
+ //= require ./cart
2
+ //= require ./async-cart
3
+ //= require ./address
4
+ //= require ./product
5
+ //= require ./main
6
+
@@ -0,0 +1,54 @@
1
+ class GlysellinCart
2
+ defaults =
3
+ onUpdated: null
4
+
5
+ constructor: (@container, options) ->
6
+ @options = $.extend({}, defaults, options)
7
+ @add_to_cart_forms = $('[data-add-to-cart-form]')
8
+ @bindAll()
9
+
10
+ bindAll: ->
11
+ @add_to_cart_forms.on 'ajax:success', (e, resp) =>
12
+ @update(resp)
13
+
14
+ update: (markup) ->
15
+ $markup = $(markup)
16
+ $cart = $markup.find('.cart-container')
17
+ $warning = $markup.find('.added-to-cart-warning').remove()
18
+
19
+ @container.html($cart.html())
20
+
21
+ if $warning.length > 0
22
+ $warning.prependTo('body')
23
+ if ($default_modal = $warning.filter("[data-warning]"))
24
+ @handleDefaultModal($default_modal)
25
+
26
+ @updated()
27
+
28
+ updated: ->
29
+ # Allow app to update cart handlers when content updated
30
+ @container.trigger('updated.glysellin')
31
+ # Trigger update callback if passed
32
+ @options.onUpdated(this) if $.isFunction(@options.onUpdated)
33
+
34
+ # Default model handling
35
+ handleDefaultModal: ($modal) ->
36
+ $body = $('body')
37
+
38
+ closeFromBody = (e) ->
39
+ if $(e.target).closest("[data-warning]").length == 0
40
+ close()
41
+
42
+ close = ->
43
+ $modal.fadeOut(200, -> $modal.remove());
44
+ $body.off "click", closeFromBody
45
+ false
46
+
47
+ $modal.on "click", "[data-dismiss=warning]", close
48
+ $body.on "click", closeFromBody
49
+
50
+ $.fn.glysellinCart = (options) ->
51
+ @each ->
52
+ $cart = $(this)
53
+ data = $cart.data('glysellin.cart')
54
+ $cart.data('glysellin.cart', new GlysellinCart($cart, options)) unless data
File without changes
File without changes
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,17 @@
1
+ module Glysellin
2
+ module Cart
3
+ class AddressesController < CartController
4
+ def update
5
+ current_cart.update(params[:glysellin_cart_basket])
6
+
7
+ if current_cart.valid?
8
+ current_cart.addresses_filled!
9
+ redirect_to cart_path
10
+ else
11
+ current_cart.state = "addresses"
12
+ render "glysellin/cart/show"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end