glysellin 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/MIT-LICENSE +20 -0
- data/README.md +100 -0
- data/Rakefile +29 -0
- data/app/assets/javascripts/glysellin/address.coffee +38 -0
- data/app/assets/javascripts/glysellin/async-cart.coffee +139 -0
- data/app/assets/javascripts/glysellin/base.js +6 -0
- data/app/assets/javascripts/glysellin/cart.coffee +54 -0
- data/app/assets/javascripts/glysellin/main.coffee +0 -0
- data/app/assets/javascripts/glysellin/product.coffee +0 -0
- data/app/assets/stylesheets/glysellin/application.css +13 -0
- data/app/assets/stylesheets/glysellin/orders.css +4 -0
- data/app/assets/stylesheets/glysellin/products.css +4 -0
- data/app/controllers/glysellin/cart/addresses_controller.rb +17 -0
- data/app/controllers/glysellin/cart/discount_code_controller.rb +10 -0
- data/app/controllers/glysellin/cart/payment_method_controller.rb +17 -0
- data/app/controllers/glysellin/cart/products_controller.rb +37 -0
- data/app/controllers/glysellin/cart/shipping_method_controller.rb +18 -0
- data/app/controllers/glysellin/cart/state_controller.rb +15 -0
- data/app/controllers/glysellin/cart_controller.rb +53 -0
- data/app/controllers/glysellin/orders_controller.rb +53 -0
- data/app/controllers/glysellin/products_controller.rb +12 -0
- data/app/helpers/glysellin/application_helper.rb +4 -0
- data/app/helpers/glysellin/cart_helper.rb +21 -0
- data/app/helpers/glysellin/orders_helper.rb +35 -0
- data/app/helpers/glysellin/products_helper.rb +4 -0
- data/app/mailers/glysellin/order_admin_mailer.rb +17 -0
- data/app/mailers/glysellin/order_customer_mailer.rb +27 -0
- data/app/models/glysellin/address.rb +35 -0
- data/app/models/glysellin/brand.rb +14 -0
- data/app/models/glysellin/discount_code.rb +36 -0
- data/app/models/glysellin/discount_type.rb +9 -0
- data/app/models/glysellin/order.rb +243 -0
- data/app/models/glysellin/order_adjustment.rb +19 -0
- data/app/models/glysellin/order_item.rb +38 -0
- data/app/models/glysellin/orderer.rb +28 -0
- data/app/models/glysellin/payment.rb +46 -0
- data/app/models/glysellin/payment_method.rb +36 -0
- data/app/models/glysellin/product.rb +136 -0
- data/app/models/glysellin/product_image.rb +11 -0
- data/app/models/glysellin/product_property.rb +22 -0
- data/app/models/glysellin/product_property_type.rb +11 -0
- data/app/models/glysellin/product_type.rb +11 -0
- data/app/models/glysellin/shipping_method.rb +22 -0
- data/app/models/glysellin/taxonomy.rb +35 -0
- data/app/models/glysellin/variant.rb +100 -0
- data/app/views/glysellin/cart/_added_to_cart_warning.html.erb +21 -0
- data/app/views/glysellin/cart/_cart.html.erb +13 -0
- data/app/views/glysellin/cart/_navigation.html.erb +11 -0
- data/app/views/glysellin/cart/_products.html.erb +125 -0
- data/app/views/glysellin/cart/_recap.html.erb +16 -0
- data/app/views/glysellin/cart/recap/_addresses.html.erb +13 -0
- data/app/views/glysellin/cart/recap/_products.html.erb +63 -0
- data/app/views/glysellin/cart/show.html.erb +13 -0
- data/app/views/glysellin/cart/states/_addresses.html.erb +25 -0
- data/app/views/glysellin/cart/states/_choose_payment_method.html.erb +14 -0
- data/app/views/glysellin/cart/states/_choose_shipping_method.html.erb +14 -0
- data/app/views/glysellin/cart/states/_filled.html.erb +3 -0
- data/app/views/glysellin/cart/states/_init.html.erb +5 -0
- data/app/views/glysellin/cart/states/_ready.html.erb +1 -0
- data/app/views/glysellin/order_admin_mailer/_order_header.text.erb +5 -0
- data/app/views/glysellin/order_admin_mailer/send_check_order_created_email.text.erb +8 -0
- data/app/views/glysellin/order_admin_mailer/send_order_paid_email.text.erb +8 -0
- data/app/views/glysellin/order_customer_mailer/_order_footer.text.erb +3 -0
- data/app/views/glysellin/order_customer_mailer/_order_header.text.erb +5 -0
- data/app/views/glysellin/order_customer_mailer/send_order_created_email.text.erb +7 -0
- data/app/views/glysellin/order_customer_mailer/send_order_paid_email.text.erb +7 -0
- data/app/views/glysellin/order_customer_mailer/send_order_shipped_email.text.erb +8 -0
- data/app/views/glysellin/orders/_addresses_fields.html.erb +29 -0
- data/app/views/glysellin/orders/_order.html.erb +18 -0
- data/app/views/glysellin/orders/_payment_canceled.html.erb +13 -0
- data/app/views/glysellin/orders/_payment_successful.html.erb +6 -0
- data/app/views/glysellin/orders/payment_response.html.erb +5 -0
- data/app/views/glysellin/payment_methods/_paypal-integral.html.erb +22 -0
- data/app/views/glysellin/products/_add_to_cart.html.erb +16 -0
- data/app/views/glysellin/products/_item.html.erb +21 -0
- data/app/views/glysellin/products/filter.html.erb +0 -0
- data/app/views/glysellin/products/index.html.erb +3 -0
- data/app/views/glysellin/products/show.html.erb +3 -0
- data/app/views/glysellin/shared/_address.html.erb +11 -0
- data/app/views/glysellin/shared/_address.text.erb +7 -0
- data/app/views/glysellin/shared/_order.text.erb +56 -0
- data/app/views/glysellin/shared/mailer/_footer.text.erb +2 -0
- data/app/views/layouts/glysellin/application.html.erb +14 -0
- data/config/locales/glysellin.en.yml +113 -0
- data/config/locales/glysellin.fr.yml +119 -0
- data/db/migrate/20120206115004_create_glysellin_orders.rb +16 -0
- data/db/migrate/20120206115132_create_glysellin_customers.rb +8 -0
- data/db/migrate/20120206115657_create_glysellin_addresses.rb +22 -0
- data/db/migrate/20120206124505_create_glysellin_products.rb +20 -0
- data/db/migrate/20120206124545_create_glysellin_order_items.rb +15 -0
- data/db/migrate/20120206124630_create_glysellin_product_images.rb +10 -0
- data/db/migrate/20120206125210_add_attachment_image_to_product_image.rb +15 -0
- data/db/migrate/20120206130920_create_glysellin_payments.rb +13 -0
- data/db/migrate/20120206131042_create_glysellin_payment_methods.rb +10 -0
- data/db/migrate/20120207175050_create_glysellin_taxonomies.rb +11 -0
- data/db/migrate/20120207175158_create_products_taxonomies_table.rb +12 -0
- data/db/migrate/20120515143231_create_brands.rb +9 -0
- data/db/migrate/20120515143233_add_attachment_image_to_brands.rb +15 -0
- data/db/migrate/20120620151705_create_product_properties.rb +12 -0
- data/db/migrate/20130204121211_create_glysellin_discount_types.rb +10 -0
- data/db/migrate/20130204121228_create_glysellin_discount_codes.rb +15 -0
- data/db/migrate/20130204125310_create_glysellin_order_adjustments.rb +13 -0
- data/db/migrate/20130204202102_create_glysellin_shipping_methods.rb +12 -0
- data/db/migrate/20130204202109_add_shipping_method_id_to_glysellin_orders.rb +5 -0
- data/db/migrate/20130205110036_add_weight_to_glysellin_products.rb +5 -0
- data/db/migrate/20130205120541_add_weight_to_glysellin_order_items.rb +5 -0
- data/db/migrate/20130208162813_create_glysellin_variants.rb +17 -0
- data/db/migrate/20130208165020_create_glysellin_product_property_types.rb +7 -0
- data/db/migrate/20130211105557_add_type_id_to_glysellin_product_properties.rb +5 -0
- data/db/migrate/20130211112302_add_variant_id_to_glysellin_product_properties.rb +13 -0
- data/db/migrate/20130211152651_add_product_id_to_glysellin_variants.rb +5 -0
- data/db/migrate/20130212131658_add_weight_to_glysellin_variants.rb +5 -0
- data/db/migrate/20130212132253_remove_variant_columns_from_glysellin_products.rb +15 -0
- data/db/migrate/20130212154943_remove_eot_price_from_glysellin_products.rb +9 -0
- data/db/migrate/20130214184204_create_glysellin_product_types.rb +9 -0
- data/db/migrate/20130214184352_create_product_type_behavior.rb +15 -0
- data/db/migrate/20130221102200_add_unmarked_price_to_glysellin_variants.rb +5 -0
- data/db/migrate/20130311135842_add_addressable_to_glysellin_addresses.rb +6 -0
- data/db/migrate/20130314114048_change_addressable_associations_in_glysellin_addresses.rb +15 -0
- data/db/migrate/20130325113903_remove_address_ids_from_glysellin_orders.rb +11 -0
- data/db/seeds/shipping_carrier/rates/colissimo.csv +16 -0
- data/db/seeds/shipping_carrier/rates/lettre-max.csv +9 -0
- data/lib/active_model/model.rb +101 -0
- data/lib/generators/glysellin/install/USAGE +8 -0
- data/lib/generators/glysellin/install/install_generator.rb +50 -0
- data/lib/generators/glysellin/install/templates/initializer.rb +119 -0
- data/lib/generators/glysellin/install/templates/order_observer.rb +12 -0
- data/lib/generators/glysellin/install/utils.rb +11 -0
- data/lib/glysellin.rb +124 -0
- data/lib/glysellin/acts_as_sellable.rb +14 -0
- data/lib/glysellin/cart.rb +21 -0
- data/lib/glysellin/cart/address.rb +16 -0
- data/lib/glysellin/cart/adjustment.rb +17 -0
- data/lib/glysellin/cart/adjustment/base.rb +41 -0
- data/lib/glysellin/cart/adjustment/discount_code.rb +43 -0
- data/lib/glysellin/cart/adjustment/shipping_method.rb +31 -0
- data/lib/glysellin/cart/basket.rb +482 -0
- data/lib/glysellin/cart/customer.rb +36 -0
- data/lib/glysellin/cart/model_wrapper.rb +90 -0
- data/lib/glysellin/cart/nested_resource.rb +39 -0
- data/lib/glysellin/cart/payment_method.rb +8 -0
- data/lib/glysellin/cart/product.rb +16 -0
- data/lib/glysellin/cart/select.rb +31 -0
- data/lib/glysellin/cart/serializable.rb +30 -0
- data/lib/glysellin/cart/shipping_method.rb +8 -0
- data/lib/glysellin/discount_type_calculator.rb +7 -0
- data/lib/glysellin/discount_type_calculator/base.rb +30 -0
- data/lib/glysellin/discount_type_calculator/order_percentage.rb +16 -0
- data/lib/glysellin/engine.rb +14 -0
- data/lib/glysellin/engine/routes.rb +61 -0
- data/lib/glysellin/gateway.rb +16 -0
- data/lib/glysellin/gateway/atos.rb +111 -0
- data/lib/glysellin/gateway/base.rb +43 -0
- data/lib/glysellin/gateway/check.rb +34 -0
- data/lib/glysellin/gateway/paypal_integral.rb +71 -0
- data/lib/glysellin/helpers.rb +15 -0
- data/lib/glysellin/helpers/controller.rb +22 -0
- data/lib/glysellin/helpers/countries.rb +261 -0
- data/lib/glysellin/helpers/views.rb +28 -0
- data/lib/glysellin/product_methods.rb +66 -0
- data/lib/glysellin/products_list.rb +72 -0
- data/lib/glysellin/property_finder.rb +13 -0
- data/lib/glysellin/shipping_carrier.rb +14 -0
- data/lib/glysellin/shipping_carrier/base.rb +55 -0
- data/lib/glysellin/shipping_carrier/colissimo.rb +19 -0
- data/lib/glysellin/shipping_carrier/flat_rate.rb +19 -0
- data/lib/glysellin/shipping_carrier/free_shipping.rb +14 -0
- data/lib/glysellin/shipping_carrier/helpers/country_weight_table.rb +65 -0
- data/lib/glysellin/shipping_carrier/lettre_max.rb +19 -0
- data/lib/glysellin/version.rb +3 -0
- data/lib/tasks/glysellin_tasks.rake +37 -0
- metadata +341 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
module Glysellin
|
2
|
+
class ProductImage < ActiveRecord::Base
|
3
|
+
self.table_name = 'glysellin_product_images'
|
4
|
+
|
5
|
+
attr_accessible :image, :imageable_id, :imageable_type, :name
|
6
|
+
|
7
|
+
belongs_to :imageable, :polymorphic => true
|
8
|
+
|
9
|
+
has_attached_file :image, :styles => Glysellin.product_images_styles
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Glysellin
|
2
|
+
class ProductProperty < ActiveRecord::Base
|
3
|
+
self.table_name = 'glysellin_product_properties'
|
4
|
+
attr_accessible :adjustement, :name, :value, :variant, :variant_id, :type, :type_id
|
5
|
+
|
6
|
+
belongs_to :variant, polymorphic: true, foreign_key: 'variant_id'
|
7
|
+
belongs_to :type, class_name: 'Glysellin::ProductPropertyType', foreign_key: 'type_id'
|
8
|
+
|
9
|
+
# validate :check_uniqueness_of_type
|
10
|
+
|
11
|
+
validates_presence_of :type, :value
|
12
|
+
# validates_associated :type, :if => Proc.new { |type| !self.variant.properties.map(&:type).include?(type) }
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def check_uniqueness_of_type
|
17
|
+
if self.variant.properties.map(&:type).include? self.type
|
18
|
+
errors.add(:type, I18n.t("glysellin.controllers.errors.double_property"))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Glysellin
|
2
|
+
class ProductPropertyType < ActiveRecord::Base
|
3
|
+
self.table_name = 'glysellin_product_property_types'
|
4
|
+
attr_accessible :eot_price, :in_stock, :name, :position, :price, :published, :sku, :slug, :unlimited_stock
|
5
|
+
|
6
|
+
has_many :properties, class_name: "Glysellin::ProductProperty"
|
7
|
+
|
8
|
+
has_and_belongs_to_many :product_types, class_name: 'Glysellin::ProductType',
|
9
|
+
join_table: 'glysellin_product_types_property_types'
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Glysellin::ProductType < ActiveRecord::Base
|
2
|
+
self.table_name = 'glysellin_product_types'
|
3
|
+
|
4
|
+
has_and_belongs_to_many :property_types,
|
5
|
+
class_name: 'Glysellin::ProductPropertyType',
|
6
|
+
join_table: 'glysellin_product_types_property_types'
|
7
|
+
|
8
|
+
has_many :products
|
9
|
+
|
10
|
+
attr_accessible :name, :product_ids, :property_type_ids
|
11
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Glysellin
|
2
|
+
class ShippingMethod < ActiveRecord::Base
|
3
|
+
self.table_name = "glysellin_shipping_methods"
|
4
|
+
|
5
|
+
attr_accessible :identifier, :name
|
6
|
+
|
7
|
+
has_many :orders, inverse_of: :shipping_method
|
8
|
+
has_many :order_adjustments, as: :adjustment
|
9
|
+
|
10
|
+
scope :ordered, order("name ASC")
|
11
|
+
|
12
|
+
def to_adjustment order
|
13
|
+
calculator = Glysellin.shipping_carriers[identifier].new(order)
|
14
|
+
|
15
|
+
{
|
16
|
+
name: name,
|
17
|
+
value: calculator.calculate,
|
18
|
+
adjustment: self
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Glysellin
|
2
|
+
class Taxonomy < ActiveRecord::Base
|
3
|
+
extend FriendlyId
|
4
|
+
|
5
|
+
self.table_name = 'glysellin_taxonomies'
|
6
|
+
|
7
|
+
friendly_id :name, use: :slugged
|
8
|
+
|
9
|
+
has_and_belongs_to_many :products,
|
10
|
+
join_table: 'glysellin_products_taxonomies'
|
11
|
+
has_many :sub_taxonomies, class_name: 'Taxonomy',
|
12
|
+
foreign_key: 'parent_taxonomy_id'
|
13
|
+
belongs_to :parent_taxonomy, foreign_key: 'parent_taxonomy_id',
|
14
|
+
class_name: 'Taxonomy'
|
15
|
+
|
16
|
+
attr_accessible :name, :parent_taxonomy, :sub_taxonomies, :products,
|
17
|
+
:product_ids, :sub_taxonomy_ids, :parent_taxonomy_id
|
18
|
+
|
19
|
+
def all_products
|
20
|
+
Product.includes(:taxonomies).where(
|
21
|
+
'glysellin_products_taxonomies.taxonomy_id IN (?)',
|
22
|
+
taxonomy_tree_ids
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def taxonomy_tree_ids
|
27
|
+
if sub_taxonomies.length > 0
|
28
|
+
ts = sub_taxonomies.includes(:sub_taxonomies).map(&:taxonomy_tree_ids)
|
29
|
+
ts.flatten << self.id
|
30
|
+
else
|
31
|
+
self.id
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'friendly_id'
|
2
|
+
|
3
|
+
module Glysellin
|
4
|
+
class Variant < ActiveRecord::Base
|
5
|
+
include ProductMethods
|
6
|
+
extend FriendlyId
|
7
|
+
|
8
|
+
friendly_id :name, use: :slugged
|
9
|
+
|
10
|
+
self.table_name = 'glysellin_variants'
|
11
|
+
|
12
|
+
attr_accessible :eot_price, :in_stock, :name, :position, :price,
|
13
|
+
:published, :sku, :slug, :unlimited_stock, :product, :product_id,
|
14
|
+
:properties_attributes, :properties, :weight, :unmarked_price
|
15
|
+
|
16
|
+
belongs_to :product, class_name: 'Glysellin::Product',
|
17
|
+
foreign_key: 'product_id'
|
18
|
+
|
19
|
+
has_many :properties, class_name: 'Glysellin::ProductProperty',
|
20
|
+
as: :variant, extend: Glysellin::PropertyFinder, dependent: :destroy
|
21
|
+
|
22
|
+
accepts_nested_attributes_for :properties, allow_destroy: true
|
23
|
+
|
24
|
+
validates_presence_of :name, if: proc { |v| v.product.variants.length > 1 }
|
25
|
+
validates_numericality_of :price
|
26
|
+
validates_numericality_of :in_stock, if: proc { |v| v.in_stock.presence }
|
27
|
+
|
28
|
+
before_validation :check_prices
|
29
|
+
|
30
|
+
after_initialize :prepare_properties
|
31
|
+
|
32
|
+
AVAILABLE_QUERY = <<-SQL
|
33
|
+
glysellin_variants.published = ? AND (
|
34
|
+
glysellin_variants.unlimited_stock = ? OR
|
35
|
+
glysellin_variants.in_stock > ?
|
36
|
+
)
|
37
|
+
SQL
|
38
|
+
|
39
|
+
scope :available, where(AVAILABLE_QUERY, true, true, 0)
|
40
|
+
|
41
|
+
def prepare_properties
|
42
|
+
if product && product.product_type
|
43
|
+
product.product_type.property_types.each do |type|
|
44
|
+
properties.build(type: type) if properties.send(type.name) == false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def description
|
50
|
+
product.description
|
51
|
+
end
|
52
|
+
|
53
|
+
def vat_rate
|
54
|
+
product.vat_rate
|
55
|
+
end
|
56
|
+
|
57
|
+
def check_prices
|
58
|
+
vat_ratio = self.product.vat_ratio rescue Glysellin.default_vat_rate
|
59
|
+
# If we have to fill one of the prices when changed
|
60
|
+
if eot_changed_alone?
|
61
|
+
self.price = (self.eot_price * vat_ratio).round(2)
|
62
|
+
elsif price_changed_alone?
|
63
|
+
self.eot_price = (self.price / vat_ratio).round(2)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def eot_changed_alone?
|
68
|
+
eot_changed_alone = self.eot_price_changed? && !self.price_changed?
|
69
|
+
new_record_eot_alone = self.new_record? && self.eot_price && !self.price
|
70
|
+
|
71
|
+
eot_changed_alone || new_record_eot_alone
|
72
|
+
end
|
73
|
+
|
74
|
+
def price_changed_alone?
|
75
|
+
self.price_changed? || (self.new_record? && self.price)
|
76
|
+
end
|
77
|
+
|
78
|
+
def in_stock?
|
79
|
+
unlimited_stock || in_stock > 0
|
80
|
+
end
|
81
|
+
|
82
|
+
def available_for quantity
|
83
|
+
unlimited_stock || in_stock >= quantity
|
84
|
+
end
|
85
|
+
|
86
|
+
def name fullname = true
|
87
|
+
variant_name, product_name = super().presence, product.name
|
88
|
+
|
89
|
+
if fullname
|
90
|
+
variant_name ? "#{ product_name } - #{ variant_name }" : product_name
|
91
|
+
else
|
92
|
+
variant_name ? variant_name : product_name
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def marked_down?
|
97
|
+
(p = unmarked_price.presence) && p != price
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<%#
|
2
|
+
To implement custom behavior, just replace this view, keeping the .added-to-cart-warning container
|
3
|
+
Default behavior is triggered when [data-warning] attribute is present on the container
|
4
|
+
%>
|
5
|
+
<div class="added-to-cart-warning" style="position:fixed;width:500px;height:400px;top:50%;left:50%;margin-left:-250px;margin-top:-200px;border:1px solid #CCC;border-radius:2px;padding:10px;box-shadow:0 0 15px #DDD;z-index:100;background:white;" data-warning>
|
6
|
+
<h3><%= t('glysellin.labels.cart.added_to_cart') %></h3>
|
7
|
+
<hr>
|
8
|
+
|
9
|
+
<% product = current_cart.product(params[:cart][:product_id]).variant %>
|
10
|
+
<%= params[:cart][:quantity] %> × <%= product.name %> - <%= number_to_currency product.price %>
|
11
|
+
<br>
|
12
|
+
|
13
|
+
<hr>
|
14
|
+
<%= link_to "#", data: { dismiss: "warning" } do %>
|
15
|
+
<%= t('glysellin.labels.cart.continue_shopping') %>
|
16
|
+
<% end %>
|
17
|
+
|
|
18
|
+
<%= link_to cart_path do %>
|
19
|
+
<%= t('glysellin.labels.cart.create_order_form') %>
|
20
|
+
<% end %>
|
21
|
+
</div>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div class="cart-wrapper">
|
2
|
+
<div class="cart-container warn">
|
3
|
+
<% if cart.empty? %>
|
4
|
+
<%= t('glysellin.labels.cart.no_products_in_cart') %>
|
5
|
+
<% else %>
|
6
|
+
<%= t('glysellin.labels.cart.products_count', count: cart.products_total) %>
|
7
|
+
-
|
8
|
+
<%= link_to t('glysellin.labels.cart.create_order'), cart_path %>
|
9
|
+
<% end %>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<%= added_to_cart_warning if @product_added_to_cart %>
|
13
|
+
</div>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<ul class="cart-navigation">
|
2
|
+
<% @states.each_with_index do |state, index| %>
|
3
|
+
<li data-state="<%= state %>">
|
4
|
+
<% if index < current_cart.state_index %>
|
5
|
+
<%= link_to t("glysellin.cart.states.#{ state }"), set_cart_state_path(state) %>
|
6
|
+
<% else %>
|
7
|
+
<%= t("glysellin.cart.states.#{ state }") %>
|
8
|
+
<% end %>
|
9
|
+
</li>
|
10
|
+
<% end %>
|
11
|
+
</ul>
|
@@ -0,0 +1,125 @@
|
|
1
|
+
<% editable = false unless defined?(editable) && editable == true %>
|
2
|
+
<% remote = Glysellin.async_cart %>
|
3
|
+
|
4
|
+
<%= simple_form_for cart, url: validate_cart_products_path, method: "put", html: { class: "products-recap-form#{ ' editable' if editable }", data: { "cart-url" => cart_path } } do |form| %>
|
5
|
+
<table id="order_recap_table" class="table table-bordered table-striped">
|
6
|
+
<tr>
|
7
|
+
<th><%= t('glysellin.labels.order.name') %></th>
|
8
|
+
<th><%= t('glysellin.labels.order.unit_price') %></th>
|
9
|
+
<th><%= t('glysellin.labels.order.quantity') %></th>
|
10
|
+
<th><%= t('glysellin.labels.order.eot_price') %></th>
|
11
|
+
<th><%= t('glysellin.labels.order.price') %></th>
|
12
|
+
<% if editable %>
|
13
|
+
<th></th>
|
14
|
+
<% end %>
|
15
|
+
</tr>
|
16
|
+
<% cart.each_items do |item, quantity| %>
|
17
|
+
<tr>
|
18
|
+
<td>
|
19
|
+
<%= item.name %>
|
20
|
+
</td>
|
21
|
+
<td>
|
22
|
+
<%= number_to_currency(item.price) %>
|
23
|
+
</td>
|
24
|
+
<td>
|
25
|
+
<% if editable %>
|
26
|
+
<%= form.fields_for :products do |fp| %>
|
27
|
+
<%= fp.number_field :quantity, index: item.id, value: quantity, class: 'quantity-input', data: { id: item.id } %>
|
28
|
+
<% end %>
|
29
|
+
<% else %>
|
30
|
+
<%= quantity %>
|
31
|
+
<% end %>
|
32
|
+
</td>
|
33
|
+
<td class="product-eot-price">
|
34
|
+
<%= number_to_currency(quantity * item.eot_price) %>
|
35
|
+
</td>
|
36
|
+
<td class="product-price">
|
37
|
+
<%= number_to_currency(quantity * item.price) %>
|
38
|
+
</td>
|
39
|
+
<% if editable %>
|
40
|
+
<td>
|
41
|
+
<%= link_to cart_product_path(item.id), method: "delete" do %>
|
42
|
+
<%= t('glysellin.labels.cart.remove_from_cart') %>
|
43
|
+
<% end %>
|
44
|
+
</td>
|
45
|
+
<% end %>
|
46
|
+
</tr>
|
47
|
+
<% end %>
|
48
|
+
<tr class="products-subtotal-row" style="<%= "display:none;" unless cart.subtotal != cart.total_price || Glysellin.show_subtotal_if_identical %>">
|
49
|
+
<td colspan="2">
|
50
|
+
<%= t('glysellin.labels.order.subtotal') %>
|
51
|
+
</td>
|
52
|
+
<td>
|
53
|
+
|
54
|
+
</td>
|
55
|
+
<td class="eot-subtotal">
|
56
|
+
<%= number_to_currency(cart.eot_subtotal) %>
|
57
|
+
</td>
|
58
|
+
<td class="subtotal">
|
59
|
+
<%= number_to_currency(cart.subtotal) %>
|
60
|
+
</td>
|
61
|
+
<% if editable %>
|
62
|
+
<td></td>
|
63
|
+
<% end %>
|
64
|
+
</tr>
|
65
|
+
<% if cart.adjustments_total != 0 %>
|
66
|
+
<% cart.adjustments.each do |adjustment| %>
|
67
|
+
<% if adjustment.valid %>
|
68
|
+
<tr class="adjustment-row" data-type="<%= adjustment.type %>">
|
69
|
+
<td colspan="4" class="adjustment-name">
|
70
|
+
<%= adjustment.name %>
|
71
|
+
</td>
|
72
|
+
<td class="adjustment-value">
|
73
|
+
<%= number_to_currency(adjustment.value) %>
|
74
|
+
</td>
|
75
|
+
<% if editable %>
|
76
|
+
<td></td>
|
77
|
+
<% end %>
|
78
|
+
</tr>
|
79
|
+
<% end %>
|
80
|
+
<% end %>
|
81
|
+
<% end %>
|
82
|
+
<% if editable && Glysellin.async_cart && !cart.discount %>
|
83
|
+
<tr class="adjustment-row" data-type="discount-code" style="display:none;">
|
84
|
+
<td colspan="4" class="adjustment-name">
|
85
|
+
</td>
|
86
|
+
<td class="adjustment-value">
|
87
|
+
</td>
|
88
|
+
<td></td>
|
89
|
+
</tr>
|
90
|
+
<% end %>
|
91
|
+
<tr class="products-total-row">
|
92
|
+
<td colspan="3">
|
93
|
+
<%= t('glysellin.labels.order.total') %>
|
94
|
+
</td>
|
95
|
+
<td class="total-eot-price">
|
96
|
+
<%= number_to_currency(cart.total_eot_price) %>
|
97
|
+
</td>
|
98
|
+
<td class="total-price">
|
99
|
+
<%= number_to_currency(cart.total_price) %>
|
100
|
+
</td>
|
101
|
+
<% if editable %>
|
102
|
+
<td></td>
|
103
|
+
<% end %>
|
104
|
+
</tr>
|
105
|
+
</table>
|
106
|
+
|
107
|
+
<% if editable %>
|
108
|
+
<div class="discount-code">
|
109
|
+
<%= form.input :discount_code do %>
|
110
|
+
<%= form.text_field :discount_code %>
|
111
|
+
<% if remote %>
|
112
|
+
<%= form.button :button, t('glysellin.labels.cart.update_discount'), class: "update-discount-code-btn", type: "button", name: "update_discount" %>
|
113
|
+
<% end %>
|
114
|
+
<% end %>
|
115
|
+
</div>
|
116
|
+
<% unless remote %>
|
117
|
+
<!-- Update cart contents -->
|
118
|
+
<button type="submit" name="update_order">
|
119
|
+
<%= t('glysellin.labels.cart.update') %>
|
120
|
+
</button>
|
121
|
+
<% end %>
|
122
|
+
<!-- Submit order from cart -->
|
123
|
+
<%= form.button :button, t('glysellin.labels.cart.create_order_form'), name: "submit_order", type: "submit" %>
|
124
|
+
<% end %>
|
125
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<div class="cart-recap" style="float:right;width:400px;">
|
2
|
+
<div class="title">
|
3
|
+
<h3>
|
4
|
+
<%= t('glysellin.labels.cart.your_cart') %>
|
5
|
+
</h3>
|
6
|
+
</div>
|
7
|
+
|
8
|
+
<!-- Products recap table -->
|
9
|
+
<% if current_cart.products.length > 0 %>
|
10
|
+
<%= render partial: "glysellin/cart/recap/products", locals: { cart: cart } %>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<% if current_cart.state_index > current_cart.available_states.index("addresses") %>
|
14
|
+
<%= render partial: "glysellin/cart/recap/addresses", locals: { cart: cart } %>
|
15
|
+
<% end %>
|
16
|
+
</div>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<div class="cart-addresses">
|
2
|
+
<h4><%= t("glysellin.labels.cart.informations") %></h4>
|
3
|
+
<div class="billing-address" style="float:left;width:200px;">
|
4
|
+
<h5><%= t("glysellin.labels.order.billing_address") %></h5>
|
5
|
+
<%= render partial: "glysellin/shared/address", locals: { address: cart.billing_address } %>
|
6
|
+
</div>
|
7
|
+
<div class="shipping-address" style="float:left;width:200px;">
|
8
|
+
<h5><%= t("glysellin.labels.order.shipping_address") %></h5>
|
9
|
+
<% address = (cart.use_another_address_for_shipping ? cart.shipping_address : cart.billing_address) %>
|
10
|
+
<%= render partial: "glysellin/shared/address", locals: { address: address } %>
|
11
|
+
</div>
|
12
|
+
<div style="clear:both;"></div>
|
13
|
+
</div>
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<div class="cart-products">
|
2
|
+
<h4><%= t("glysellin.labels.cart.products") %></h4>
|
3
|
+
<table class="table table-bordered table-striped">
|
4
|
+
|
5
|
+
<!-- Headers -->
|
6
|
+
<thead>
|
7
|
+
<tr>
|
8
|
+
<th><%= t('glysellin.labels.order.name') %></th>
|
9
|
+
<th><%= t('glysellin.labels.order.quantity') %></th>
|
10
|
+
<th><%= t('glysellin.labels.order.price') %></th>
|
11
|
+
</tr>
|
12
|
+
</thead>
|
13
|
+
<tbody>
|
14
|
+
|
15
|
+
<!-- Products -->
|
16
|
+
<% current_cart.each_items do |product, quantity| %>
|
17
|
+
<tr>
|
18
|
+
<td><%= product.name %></td>
|
19
|
+
<td>x <%= quantity %></td>
|
20
|
+
<td><%= number_to_currency(product.price * quantity) %></td>
|
21
|
+
</tr>
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<!-- Subtotal -->
|
25
|
+
<tr>
|
26
|
+
<td colspan="2">
|
27
|
+
<%= t("glysellin.labels.order.subtotal") %>
|
28
|
+
</td>
|
29
|
+
<td>
|
30
|
+
<%= number_to_currency(current_cart.subtotal) %>
|
31
|
+
</td>
|
32
|
+
</tr>
|
33
|
+
|
34
|
+
<!-- Adjustments -->
|
35
|
+
<% current_cart.adjustments.each do |adjustment| %>
|
36
|
+
<% if adjustment.valid %>
|
37
|
+
<tr>
|
38
|
+
<td colspan="2">
|
39
|
+
<%= adjustment.name %>
|
40
|
+
</td>
|
41
|
+
<td>
|
42
|
+
<%= number_to_currency(adjustment.value) %>
|
43
|
+
</td>
|
44
|
+
</tr>
|
45
|
+
<% end %>
|
46
|
+
<% end %>
|
47
|
+
|
48
|
+
<!-- Total row -->
|
49
|
+
<tr>
|
50
|
+
<td colspan="2">
|
51
|
+
<strong>
|
52
|
+
<%= t("glysellin.labels.order.total") %>
|
53
|
+
</strong>
|
54
|
+
</td>
|
55
|
+
<td>
|
56
|
+
<strong>
|
57
|
+
<%= number_to_currency(current_cart.total_price) %>
|
58
|
+
</strong>
|
59
|
+
</td>
|
60
|
+
</tr>
|
61
|
+
</tbody>
|
62
|
+
</table>
|
63
|
+
</div>
|