camaleon_ecommerce 1.1 → 1.2
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 +4 -4
- data/app/assets/javascripts/plugins/ecommerce/admin_product.js.coffee +83 -0
- data/app/assets/javascripts/plugins/ecommerce/cart.js +3 -0
- data/app/controllers/plugins/ecommerce/admin/coupons_controller.rb +6 -12
- data/app/controllers/plugins/ecommerce/admin/orders_controller.rb +2 -8
- data/app/controllers/plugins/ecommerce/admin/payment_methods_controller.rb +7 -12
- data/app/controllers/plugins/ecommerce/admin/prices_controller.rb +0 -8
- data/app/controllers/plugins/ecommerce/admin/settings_controller.rb +0 -8
- data/app/controllers/plugins/ecommerce/admin/shipping_methods_controller.rb +6 -14
- data/app/controllers/plugins/ecommerce/admin/tax_rates_controller.rb +6 -12
- data/app/controllers/plugins/ecommerce/admin_controller.rb +27 -8
- data/app/controllers/plugins/ecommerce/front/checkout_controller.rb +42 -75
- data/app/controllers/plugins/ecommerce/front/orders_controller.rb +2 -10
- data/app/controllers/plugins/ecommerce/front_controller.rb +0 -8
- data/app/decorators/plugins/ecommerce/coupon_decorator.rb +0 -8
- data/app/decorators/plugins/ecommerce/product_decorator.rb +86 -35
- data/app/decorators/plugins/ecommerce/product_item_decorator.rb +27 -3
- data/app/decorators/plugins/ecommerce/product_variation_decorator.rb +18 -0
- data/app/helpers/plugins/ecommerce/ecommerce_email_helper.rb +11 -13
- data/app/helpers/plugins/ecommerce/ecommerce_functions_helper.rb +25 -11
- data/app/helpers/plugins/ecommerce/ecommerce_helper.rb +22 -27
- data/app/helpers/plugins/ecommerce/ecommerce_payment_helper.rb +1 -56
- data/app/models/plugins/ecommerce/attribute.rb +9 -0
- data/app/models/plugins/ecommerce/cart.rb +46 -28
- data/app/models/plugins/ecommerce/coupon.rb +0 -8
- data/app/models/plugins/ecommerce/legacy_cart.rb +50 -0
- data/app/models/plugins/ecommerce/legacy_order.rb +48 -0
- data/app/models/plugins/ecommerce/order.rb +0 -8
- data/app/models/plugins/ecommerce/order_detail.rb +0 -9
- data/app/models/plugins/ecommerce/payment_method.rb +0 -8
- data/app/models/plugins/ecommerce/product_item.rb +3 -10
- data/app/models/plugins/ecommerce/product_variation.rb +9 -0
- data/app/models/plugins/ecommerce/shipping_method.rb +0 -8
- data/app/models/plugins/ecommerce/tax_rate.rb +0 -8
- data/app/services/plugins/ecommerce/cart_service.rb +149 -0
- data/app/services/plugins/ecommerce/order_service.rb +26 -0
- data/app/services/plugins/ecommerce/product_item_service.rb +29 -0
- data/app/services/plugins/ecommerce/product_service.rb +17 -0
- data/app/services/plugins/ecommerce/site_service.rb +21 -0
- data/app/services/plugins/ecommerce/user_cart_service.rb +12 -0
- data/app/services/plugins/ecommerce/user_product_service.rb +29 -0
- data/app/services/plugins/ecommerce/util_service.rb +5 -0
- data/app/views/plugins/ecommerce/admin/orders/form.html.erb +28 -16
- data/app/views/plugins/ecommerce/admin/orders/index.html.erb +7 -1
- data/app/views/plugins/ecommerce/admin/payment_methods/form.html.erb +11 -1
- data/app/views/plugins/ecommerce/admin/product_attributes.html.erb +95 -0
- data/app/views/plugins/ecommerce/admin/products/_variations.html.erb +72 -0
- data/app/views/plugins/ecommerce/front/checkout/cart_index.html.erb +5 -5
- data/app/views/plugins/ecommerce/front/orders/show.html.erb +96 -89
- data/app/views/plugins/ecommerce/partials/_cart_widget.html.erb +3 -3
- data/app/views/plugins/ecommerce/partials/checkout/_details.html.erb +1 -1
- data/app/views/plugins/ecommerce/partials/checkout/_payments.html.erb +6 -1
- data/app/views/plugins/ecommerce/partials/checkout/_products_detail.html.erb +1 -1
- data/app/views/plugins/ecommerce/partials/checkout/_user_info.html.erb +26 -22
- data/app/views/post_types/commerce/single.html.erb +28 -12
- data/config/camaleon_plugin.json +4 -12
- data/config/custom_models.rb +10 -0
- data/config/locales/en.yml +3 -0
- data/config/locales/es.yml +112 -54
- data/config/routes.rb +2 -0
- data/db/migrate/20160527184747_add_new_cart_structure.rb +7 -4
- data/db/migrate/20160620200501_add_product_attributes_structure.rb +21 -0
- data/db/migrate/20160825174848_set_cama_post_decorator_class.rb +13 -0
- data/db/migrate/20160825232739_migrate_order_data.rb +87 -0
- data/lib/ecommerce/version.rb +1 -1
- metadata +22 -7
- data/app/assets/javascripts/plugins/ecommerce/admin.js +0 -0
- data/app/assets/javascripts/plugins/ecommerce/fix_form.js +0 -7
- data/config/currency_en.json +0 -154
- data/config/currency_es.json +0 -154
@@ -1,61 +1,6 @@
|
|
1
1
|
module Plugins::Ecommerce::EcommercePaymentHelper
|
2
|
-
include Plugins::Ecommerce::EcommerceHelper
|
3
|
-
|
4
|
-
def payment_pay_by_credit_card_authorize_net(order, payment_method)
|
5
|
-
billing_address = order.get_meta("billing_address")
|
6
|
-
details = order.get_meta("details")
|
7
|
-
amount = commerce_to_cents(order.total_amount)
|
8
|
-
payment_params = {
|
9
|
-
:order_id => order.slug,
|
10
|
-
:currency => current_site.currency_code,
|
11
|
-
:email => order.user.email,
|
12
|
-
:billing_address => {:name => "#{order.user.fullname}",
|
13
|
-
:address1 => billing_address[:address1],
|
14
|
-
:address2 => billing_address[:address2],
|
15
|
-
:city => billing_address[:city],
|
16
|
-
:state => billing_address[:state],
|
17
|
-
:country => billing_address[:country],
|
18
|
-
:zip => billing_address[:zip]
|
19
|
-
},
|
20
|
-
:description => 'Buy Products',
|
21
|
-
:ip => request.remote_ip
|
22
|
-
}
|
23
|
-
|
24
|
-
authorize_net_options = {
|
25
|
-
:login => payment_method.options[:authorize_net_login_id],
|
26
|
-
:password => payment_method.options[:authorize_net_transaction_key]
|
27
|
-
}
|
28
|
-
|
29
|
-
ActiveMerchant::Billing::Base.mode = payment_method.options[:authorize_net_sandbox].to_s.to_bool ? :test : :production
|
30
|
-
|
31
|
-
credit_card = ActiveMerchant::Billing::CreditCard.new(
|
32
|
-
:first_name => params[:firstName],
|
33
|
-
:last_name => params[:lastName],
|
34
|
-
:number => params[:cardNumber],
|
35
|
-
:month => params[:expMonth],
|
36
|
-
:year => "20#{params[:expYear]}",
|
37
|
-
:verification_value => params[:cvCode]
|
38
|
-
)
|
39
|
-
if credit_card.validate.empty?
|
40
|
-
gateway = ActiveMerchant::Billing::AuthorizeNetGateway.new(authorize_net_options)
|
41
|
-
response = gateway.purchase(amount, credit_card, payment_params)
|
42
|
-
if response.success?
|
43
|
-
order.set_meta('pay_authorize_net', payment_params)
|
44
|
-
return {}
|
45
|
-
else
|
46
|
-
return {error: response.message}
|
47
|
-
end
|
48
|
-
else
|
49
|
-
return {error: credit_card.validate.map{|k, v| "#{k}: #{v.join(', ')}"}.join('<br>')}
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
2
|
def commerce_to_cents(money)
|
54
|
-
(money
|
55
|
-
end
|
56
|
-
|
57
|
-
def commerce_current_currency
|
58
|
-
current_site.get_meta("_setting_ecommerce", {})[:current_unit] || 'USD'
|
3
|
+
Plugins::Ecommerce::UtilService.ecommerce_money_to_cents(money)
|
59
4
|
end
|
60
5
|
|
61
6
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class Plugins::Ecommerce::Attribute < ActiveRecord::Base
|
2
|
+
self.table_name='plugins_ecommerce_attributes'
|
3
|
+
belongs_to :site
|
4
|
+
has_many :values, class_name: 'Plugins::Ecommerce::Attribute', foreign_key: :parent_id, dependent: :destroy
|
5
|
+
belongs_to :product_attribute, class_name: 'Plugins::Ecommerce::Attribute', foreign_key: :parent_id
|
6
|
+
scope :only_group, ->{ where(parent_id: nil) }
|
7
|
+
scope :only_value, ->{ where.not(parent_id: nil) }
|
8
|
+
default_scope ->{ order(position: :ASC) }
|
9
|
+
end
|
@@ -1,11 +1,3 @@
|
|
1
|
-
=begin
|
2
|
-
Camaleon CMS is a content management system
|
3
|
-
Copyright (C) 2015 by Owen Peredo Diaz
|
4
|
-
Email: owenperedo@gmail.com
|
5
|
-
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
6
|
-
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
7
|
-
See the GNU Affero General Public License (GPLv3) for more details.
|
8
|
-
=end
|
9
1
|
class Plugins::Ecommerce::Cart < ActiveRecord::Base
|
10
2
|
self.table_name = 'plugins_ecommerce_orders'
|
11
3
|
default_scope { where(kind: 'cart') }
|
@@ -16,25 +8,23 @@ class Plugins::Ecommerce::Cart < ActiveRecord::Base
|
|
16
8
|
|
17
9
|
belongs_to :site, :class_name => "CamaleonCms::Site", foreign_key: :site_id
|
18
10
|
belongs_to :user, :class_name => "CamaleonCms::User", foreign_key: :user_id
|
11
|
+
scope :active_cart, ->{ where("#{Plugins::Ecommerce::Cart.table_name}.updated_at >= ?", 24.hours.ago) }
|
12
|
+
|
19
13
|
after_create :generate_slug
|
20
14
|
|
21
|
-
def add_product(product, qty = 1)
|
22
|
-
pi = product_items.where(product_id: product.id).first
|
15
|
+
def add_product(product, qty = 1, variation_id = nil)
|
16
|
+
pi = product_items.where(product_id: product.id, variation_id: variation_id).first
|
23
17
|
if pi.present?
|
24
18
|
pi.update_column(:qty, qty)
|
25
19
|
else
|
26
|
-
pi = product_items.create(product_id: product.id, qty: qty)
|
20
|
+
pi = product_items.create(product_id: product.id, qty: qty, variation_id: variation_id)
|
27
21
|
end
|
28
22
|
pi
|
29
23
|
end
|
30
24
|
|
31
|
-
def remove_product(product_id)
|
32
|
-
product_items.where(product_id: product_id).destroy_all
|
33
|
-
end
|
34
|
-
|
35
25
|
# return the product titles in array format
|
36
26
|
def products_title
|
37
|
-
|
27
|
+
product_items.map{|i| p=i.product.decorate; p.the_variation_title(i.variation_id) }.join(', ')
|
38
28
|
end
|
39
29
|
|
40
30
|
def items_total
|
@@ -43,16 +33,15 @@ class Plugins::Ecommerce::Cart < ActiveRecord::Base
|
|
43
33
|
|
44
34
|
# price of all products (no include taxes)
|
45
35
|
def sub_total
|
46
|
-
|
47
|
-
product_items.map{|item| product = item.product.decorate; (product.price) * item.qty }.inject{|sum,x| sum + x } || 0
|
36
|
+
product_items.map{|item| product = item.product.decorate; (product.price(item.variation_id)) * item.qty }.inject{|sum,x| sum + x } || 0
|
48
37
|
end
|
49
38
|
|
50
39
|
def tax_total
|
51
|
-
product_items.map{|item| product = item.product.decorate; (product.tax) * item.qty }.inject{|sum,x| sum + x } || 0
|
40
|
+
product_items.map{|item| product = item.product.decorate; (product.tax(item.variation_id)) * item.qty }.inject{|sum,x| sum + x } || 0
|
52
41
|
end
|
53
42
|
|
54
43
|
def weight_total
|
55
|
-
product_items.map{|item| product = item.product.decorate; (product.weight) * item.qty }.inject{|sum,x| sum + x } || 0
|
44
|
+
product_items.map{|item| product = item.product.decorate; (product.weight(item.variation_id)) * item.qty }.inject{|sum,x| sum + x } || 0
|
56
45
|
end
|
57
46
|
|
58
47
|
# verify an return {error: (error code), discount: amount of discount} coupon for current cart
|
@@ -72,8 +61,10 @@ class Plugins::Ecommerce::Cart < ActiveRecord::Base
|
|
72
61
|
res[:error] = 'required_minimum_price'
|
73
62
|
else
|
74
63
|
case opts[:discount_type]
|
75
|
-
when '
|
64
|
+
when 'free'
|
76
65
|
res[:discount] = price || sub_total
|
66
|
+
when 'free_ship'
|
67
|
+
res[:discount] = total_shipping
|
77
68
|
when 'percent'
|
78
69
|
res[:discount] = sub_total * opts[:amount].to_f / 100
|
79
70
|
when 'money'
|
@@ -86,8 +77,17 @@ class Plugins::Ecommerce::Cart < ActiveRecord::Base
|
|
86
77
|
res
|
87
78
|
end
|
88
79
|
|
80
|
+
def prepare_to_pay
|
81
|
+
self.class.transaction do
|
82
|
+
self.update_columns(
|
83
|
+
status: 'qtys_taken',
|
84
|
+
)
|
85
|
+
self.product_items.decorate.each{|p_item| p_item.decrement_qty! }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
89
|
# convert into order current cart
|
90
|
-
def
|
90
|
+
def convert_to_order
|
91
91
|
self.update_columns(kind: 'order', created_at: Time.current)
|
92
92
|
site.orders.find(self.id)
|
93
93
|
end
|
@@ -137,23 +137,41 @@ class Plugins::Ecommerce::Cart < ActiveRecord::Base
|
|
137
137
|
total_amount <= 0
|
138
138
|
end
|
139
139
|
|
140
|
-
|
141
|
-
def make_paid!(status = 'paid')
|
140
|
+
def update_amounts
|
142
141
|
product_items.decorate.each do |item|
|
143
142
|
p = item.product.decorate
|
144
|
-
item.update_columns(
|
143
|
+
item.update_columns(
|
144
|
+
cache_the_price: p.the_price(item.variation_id),
|
145
|
+
cache_the_title: p.the_variation_title(item.variation_id),
|
146
|
+
cache_the_tax: p.the_tax(item.variation_id),
|
147
|
+
cache_the_sub_total: item.the_sub_total,
|
148
|
+
)
|
145
149
|
end
|
146
150
|
|
147
151
|
if self.coupon.present?
|
148
152
|
res_coupon = self.discount_for(self.coupon, total_to_pay_without_discounts)
|
149
153
|
unless res_coupon[:error].present?
|
150
|
-
update_columns(the_coupon_amount: res_coupon[:coupon].decorate.the_amount
|
154
|
+
update_columns(the_coupon_amount: res_coupon[:coupon].decorate.the_amount)
|
151
155
|
res_coupon[:coupon].mark_as_used(user)
|
152
156
|
end
|
153
157
|
end
|
154
158
|
c = self.decorate
|
155
|
-
self.update_columns(
|
156
|
-
|
159
|
+
self.update_columns(
|
160
|
+
amount: total_amount,
|
161
|
+
cache_the_total: c.the_price,
|
162
|
+
cache_the_sub_total: c.the_sub_total,
|
163
|
+
cache_the_tax: c.the_tax_total,
|
164
|
+
cache_the_weight: c.the_weight_total,
|
165
|
+
cache_the_discounts: c.the_total_discounts,
|
166
|
+
cache_the_shipping: c.the_total_shipping,
|
167
|
+
)
|
168
|
+
end
|
169
|
+
|
170
|
+
def mark_paid(status = 'paid')
|
171
|
+
self.update_columns(
|
172
|
+
status: status,
|
173
|
+
paid_at: Time.current,
|
174
|
+
)
|
157
175
|
end
|
158
176
|
|
159
177
|
|
@@ -1,11 +1,3 @@
|
|
1
|
-
=begin
|
2
|
-
Camaleon CMS is a content management system
|
3
|
-
Copyright (C) 2015 by Owen Peredo Diaz
|
4
|
-
Email: owenperedo@gmail.com
|
5
|
-
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
6
|
-
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
7
|
-
See the GNU Affero General Public License (GPLv3) for more details.
|
8
|
-
=end
|
9
1
|
class Plugins::Ecommerce::Coupon < CamaleonCms::TermTaxonomy
|
10
2
|
default_scope { where(taxonomy: :ecommerce_coupon) }
|
11
3
|
belongs_to :site, :class_name => "CamaleonCms::Site", foreign_key: :parent_id
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class Plugins::Ecommerce::LegacyCart < CamaleonCms::TermTaxonomy
|
2
|
+
default_scope { where(taxonomy: :ecommerce_cart) }
|
3
|
+
has_many :products, foreign_key: :objectid, through: :term_relationships, :source => :objects
|
4
|
+
belongs_to :site, :class_name => "CamaleonCms::Site", foreign_key: :parent_id
|
5
|
+
|
6
|
+
def add_product(object)
|
7
|
+
post_id = defined?(object.id) ? object.id : object.to_i
|
8
|
+
term_relationships.where(objectid: post_id).first_or_create if post_id > 0
|
9
|
+
end
|
10
|
+
|
11
|
+
# update or set product quantity
|
12
|
+
# return true if it is possible to add the quantity
|
13
|
+
# return false if quantity is not enough
|
14
|
+
def set_product_qty(product, qty)
|
15
|
+
_options = self.get_option("product_#{product.id}")
|
16
|
+
if qty.to_f <= product.the_qty_real.to_f
|
17
|
+
_options['qty'] = qty
|
18
|
+
self.set_option("product_#{product.id}", _options)
|
19
|
+
true
|
20
|
+
else
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def remove_product(object)
|
26
|
+
post_id = defined?(object.id) ? object.id : object.to_i
|
27
|
+
term_relationships.where(objectid: post_id).destroy_all if post_id > 0
|
28
|
+
end
|
29
|
+
|
30
|
+
def the_items_count
|
31
|
+
options.map{|k, p| p[:qty].to_i}.inject{|sum,x| sum + x } || 0 rescue 0
|
32
|
+
end
|
33
|
+
|
34
|
+
def the_amount_total
|
35
|
+
options.map{|k, p| (p[:price].to_f + p[:tax])* p[:qty].to_f}.inject{|sum,x| sum + x } || 0 rescue 0
|
36
|
+
end
|
37
|
+
|
38
|
+
# return the price of current cart ($10)
|
39
|
+
def the_price
|
40
|
+
"#{self.site.decorate.current_unit}#{sprintf('%.2f', the_amount_total)}"
|
41
|
+
end
|
42
|
+
|
43
|
+
# set user in filter
|
44
|
+
def self.set_user(user)
|
45
|
+
user_id = defined?(user.id) ? user.id : user.to_i
|
46
|
+
self.where(user_id: user_id)
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class Plugins::Ecommerce::LegacyOrder < CamaleonCms::TermTaxonomy
|
2
|
+
default_scope { where(taxonomy: :ecommerce_order) }
|
3
|
+
has_one :details, class_name: "Plugins::Ecommerce::OrderDetail", foreign_key: :order_id, dependent: :destroy
|
4
|
+
has_many :products, foreign_key: :objectid, through: :term_relationships, :source => :objects
|
5
|
+
belongs_to :customer, class_name: "CamaleonCms::User", foreign_key: :user_id
|
6
|
+
|
7
|
+
def add_product(object)
|
8
|
+
post_id = defined?(object.id) ? object.id : object.to_i
|
9
|
+
term_relationships.where(objectid: post_id).first_or_create if post_id > 0
|
10
|
+
end
|
11
|
+
def remove_product(object)
|
12
|
+
post_id = defined?(object.id) ? object.id : object.to_i
|
13
|
+
term_relationships.where(objectid: post_id).destroy_all if post_id > 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def payment_method
|
17
|
+
Plugins::Ecommerce::PaymentMethod.find_by_id get_meta("payment")[:payment_id]
|
18
|
+
end
|
19
|
+
|
20
|
+
def payment
|
21
|
+
payment = get_meta("payment")
|
22
|
+
get_meta("pay_#{payment[:type]}".to_sym)
|
23
|
+
end
|
24
|
+
|
25
|
+
def shipping_method
|
26
|
+
Plugins::Ecommerce::ShippingMethod.find_by_id get_meta("payment", {})[:shipping_method]
|
27
|
+
end
|
28
|
+
|
29
|
+
def canceled?
|
30
|
+
status == 'canceled'
|
31
|
+
end
|
32
|
+
def unpaid?
|
33
|
+
status == 'unpaid'
|
34
|
+
end
|
35
|
+
|
36
|
+
def paid?
|
37
|
+
payment.present?
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# set user in filter
|
42
|
+
def self.set_user(user)
|
43
|
+
user_id = defined?(user.id) ? user.id : user.to_i
|
44
|
+
self.where(user_id: user_id)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
@@ -1,11 +1,3 @@
|
|
1
|
-
=begin
|
2
|
-
Camaleon CMS is a content management system
|
3
|
-
Copyright (C) 2015 by Owen Peredo Diaz
|
4
|
-
Email: owenperedo@gmail.com
|
5
|
-
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
6
|
-
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
7
|
-
See the GNU Affero General Public License (GPLv3) for more details.
|
8
|
-
=end
|
9
1
|
class Plugins::Ecommerce::Order < Plugins::Ecommerce::Cart
|
10
2
|
self.table_name = 'plugins_ecommerce_orders'
|
11
3
|
has_many :metas, ->{ where(object_class: 'Plugins::Ecommerce::Cart')}, :class_name => "CamaleonCms::Meta", foreign_key: :objectid, dependent: :delete_all
|
@@ -1,13 +1,4 @@
|
|
1
|
-
=begin
|
2
|
-
Camaleon CMS is a content management system
|
3
|
-
Copyright (C) 2015 by Owen Peredo Diaz
|
4
|
-
Email: owenperedo@gmail.com
|
5
|
-
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
6
|
-
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
7
|
-
See the GNU Affero General Public License (GPLv3) for more details.
|
8
|
-
=end
|
9
1
|
class Plugins::Ecommerce::OrderDetail < ActiveRecord::Base
|
10
2
|
self.table_name = "plugins_order_details"
|
11
|
-
attr_accessible :order_id, :customer, :email, :phone, :status, :received_at, :accepted_at, :shipped_at, :closed_at
|
12
3
|
belongs_to :order, class_name: "Plugins::Ecommerce::Order", foreign_key: :order_id
|
13
4
|
end
|
@@ -1,11 +1,3 @@
|
|
1
|
-
=begin
|
2
|
-
Camaleon CMS is a content management system
|
3
|
-
Copyright (C) 2015 by Owen Peredo Diaz
|
4
|
-
Email: owenperedo@gmail.com
|
5
|
-
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
6
|
-
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
7
|
-
See the GNU Affero General Public License (GPLv3) for more details.
|
8
|
-
=end
|
9
1
|
class Plugins::Ecommerce::PaymentMethod < CamaleonCms::TermTaxonomy
|
10
2
|
default_scope { where(taxonomy: :ecommerce_payment_method) }
|
11
3
|
belongs_to :site, :class_name => "CamaleonCms::Site", foreign_key: :parent_id
|
@@ -1,20 +1,13 @@
|
|
1
|
-
=begin
|
2
|
-
Camaleon CMS is a content management system
|
3
|
-
Copyright (C) 2015 by Owen Peredo Diaz
|
4
|
-
Email: owenperedo@gmail.com
|
5
|
-
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
6
|
-
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
7
|
-
See the GNU Affero General Public License (GPLv3) for more details.
|
8
|
-
=end
|
9
1
|
class Plugins::Ecommerce::ProductItem < ActiveRecord::Base
|
10
2
|
include CamaleonCms::Metas
|
11
3
|
self.table_name = 'plugins_ecommerce_products'
|
12
|
-
belongs_to :cart, class_name: 'Plugins::Ecommerce::Cart', foreign_key: :order_id
|
4
|
+
belongs_to :cart, class_name: 'Plugins::Ecommerce::Cart', foreign_key: :order_id, touch: true
|
13
5
|
belongs_to :order, class_name: 'Plugins::Ecommerce::Order'
|
14
6
|
belongs_to :product, foreign_key: :product_id, class_name: 'CamaleonCms::Post'
|
7
|
+
belongs_to :product_variation, class_name: 'Plugins::Ecommerce::ProductVariation', foreign_key: :variation_id
|
15
8
|
|
16
9
|
def sub_total
|
17
10
|
p = self.product.decorate
|
18
|
-
(p.price + p.tax) * self.qty
|
11
|
+
(p.price(self.variation_id) + p.tax(self.variation_id)) * self.qty
|
19
12
|
end
|
20
13
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class Plugins::Ecommerce::ProductVariation < ActiveRecord::Base
|
2
|
+
self.table_name='plugins_ecommerce_product_variations'
|
3
|
+
belongs_to :product, class_name: "CamaleonCms::Post"
|
4
|
+
|
5
|
+
# return all attribute values assigned to this product
|
6
|
+
def attribute_values
|
7
|
+
Plugins::Ecommerce::Attribute.only_value.where(id: self.attribute_ids.to_s.split(','))
|
8
|
+
end
|
9
|
+
end
|
@@ -1,11 +1,3 @@
|
|
1
|
-
=begin
|
2
|
-
Camaleon CMS is a content management system
|
3
|
-
Copyright (C) 2015 by Owen Peredo Diaz
|
4
|
-
Email: owenperedo@gmail.com
|
5
|
-
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
6
|
-
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
7
|
-
See the GNU Affero General Public License (GPLv3) for more details.
|
8
|
-
=end
|
9
1
|
class Plugins::Ecommerce::ShippingMethod < CamaleonCms::TermTaxonomy
|
10
2
|
default_scope { where(taxonomy: :ecommerce_shipping_method) }
|
11
3
|
belongs_to :site, :class_name => "CamaleonCms::Site", foreign_key: :parent_id
|
@@ -1,11 +1,3 @@
|
|
1
|
-
=begin
|
2
|
-
Camaleon CMS is a content management system
|
3
|
-
Copyright (C) 2015 by Owen Peredo Diaz
|
4
|
-
Email: owenperedo@gmail.com
|
5
|
-
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
6
|
-
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
7
|
-
See the GNU Affero General Public License (GPLv3) for more details.
|
8
|
-
=end
|
9
1
|
class Plugins::Ecommerce::TaxRate < CamaleonCms::TermTaxonomy
|
10
2
|
default_scope { where(taxonomy: :ecommerce_tax_rate) }
|
11
3
|
belongs_to :site, :class_name => "CamaleonCms::Site", foreign_key: :parent_id
|
@@ -0,0 +1,149 @@
|
|
1
|
+
class Plugins::Ecommerce::CartService
|
2
|
+
def initialize(site, cart)
|
3
|
+
@site = site
|
4
|
+
@cart = cart
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_reader :site, :cart
|
8
|
+
|
9
|
+
def pay_with_authorize_net(options={})
|
10
|
+
payment_method = options[:payment_method] || site_service.payment_method('authorize_net')
|
11
|
+
billing_address = cart.get_meta("billing_address")
|
12
|
+
details = cart.get_meta("details")
|
13
|
+
amount = Plugins::Ecommerce::UtilService.ecommerce_money_to_cents(cart.total_amount)
|
14
|
+
payment_params = {
|
15
|
+
order_id: cart.slug,
|
16
|
+
currency: site.currency_code,
|
17
|
+
email: cart.user.email,
|
18
|
+
billing_address: {name: "#{cart.user.fullname}",
|
19
|
+
address1: billing_address[:address1],
|
20
|
+
address2: billing_address[:address2],
|
21
|
+
city: billing_address[:city],
|
22
|
+
state: billing_address[:state],
|
23
|
+
country: billing_address[:country],
|
24
|
+
zip: billing_address[:zip]
|
25
|
+
},
|
26
|
+
description: 'Buy Products',
|
27
|
+
ip: options[:ip]
|
28
|
+
}
|
29
|
+
|
30
|
+
if options[:ip]
|
31
|
+
payment_params[:ip] = options[:ip]
|
32
|
+
end
|
33
|
+
|
34
|
+
authorize_net_options = {
|
35
|
+
login: payment_method.options[:authorize_net_login_id],
|
36
|
+
password: payment_method.options[:authorize_net_transaction_key]
|
37
|
+
}
|
38
|
+
|
39
|
+
ActiveMerchant::Billing::Base.mode = payment_method.options[:authorize_net_sandbox].to_s.to_bool ? :test : :production
|
40
|
+
|
41
|
+
credit_card = ActiveMerchant::Billing::CreditCard.new(
|
42
|
+
first_name: options[:first_name],
|
43
|
+
last_name: options[:last_name],
|
44
|
+
number: options[:number],
|
45
|
+
month: options[:exp_month],
|
46
|
+
year: "20#{options[:exp_year]}",
|
47
|
+
verification_value: options[:cvc]
|
48
|
+
)
|
49
|
+
if credit_card.validate.empty?
|
50
|
+
gateway = ActiveMerchant::Billing::AuthorizeNetGateway.new(authorize_net_options)
|
51
|
+
response = gateway.purchase(amount, credit_card, payment_params)
|
52
|
+
if response.success?
|
53
|
+
cart.set_meta('pay_authorize_net', payment_params)
|
54
|
+
return {}
|
55
|
+
else
|
56
|
+
return {error: response.message}
|
57
|
+
end
|
58
|
+
else
|
59
|
+
return {error: credit_card.validate.map{|k, v| "#{k}: #{v.join(', ')}"}.join('<br>')}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def pay_with_paypal(options={})
|
64
|
+
payment_method = options[:payment_method] || site_service.payment_method('paypal')
|
65
|
+
billing_address = cart.get_meta("billing_address")
|
66
|
+
ActiveMerchant::Billing::Base.mode = payment_method.options[:paypal_sandbox].to_s.to_bool ? :test : :production
|
67
|
+
paypal_options = {
|
68
|
+
login: payment_method.options[:paypal_login],
|
69
|
+
password: payment_method.options[:paypal_password],
|
70
|
+
signature: payment_method.options[:paypal_signature]
|
71
|
+
}
|
72
|
+
gateway = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
|
73
|
+
amount_in_cents = Plugins::Ecommerce::UtilService.ecommerce_money_to_cents(cart.total_amount)
|
74
|
+
gateway_request = {
|
75
|
+
brand_name: site.name,
|
76
|
+
items: [{
|
77
|
+
number: cart.slug,
|
78
|
+
name: "Buy Products from #{site.the_title}: #{cart.products_title}",
|
79
|
+
amount: amount_in_cents,
|
80
|
+
}],
|
81
|
+
order_id: cart.slug,
|
82
|
+
currency: site.currency_code,
|
83
|
+
email: cart.user.email,
|
84
|
+
billing_address: {name: "#{billing_address[:first_name]} #{billing_address[:last_name]}",
|
85
|
+
address1: billing_address[:address1],
|
86
|
+
address2: billing_address[:address2],
|
87
|
+
city: billing_address[:city],
|
88
|
+
state: billing_address[:state],
|
89
|
+
country: billing_address[:country],
|
90
|
+
zip: billing_address[:zip]
|
91
|
+
},
|
92
|
+
description: "Buy Products from #{site.the_title}: #{cart.total_amount}",
|
93
|
+
ip: options[:ip],
|
94
|
+
return_url: options[:return_url],
|
95
|
+
cancel_return_url: options[:cancel_return_url]
|
96
|
+
}
|
97
|
+
|
98
|
+
if options[:ip]
|
99
|
+
gateway_request[:ip] = options[:ip]
|
100
|
+
end
|
101
|
+
|
102
|
+
response = gateway.setup_purchase(amount_in_cents, gateway_request)
|
103
|
+
# TODO handle errors
|
104
|
+
{redirect_url: gateway.redirect_url_for(response.token)}
|
105
|
+
end
|
106
|
+
|
107
|
+
def pay_with_stripe(options)
|
108
|
+
require 'stripe'
|
109
|
+
payment_method = options[:payment_method] || site_service.payment_method('stripe')
|
110
|
+
Stripe.api_key = payment_method.options[:stripe_id]
|
111
|
+
customer = Stripe::Customer.create(
|
112
|
+
email: options[:email], source: options[:stripe_token])
|
113
|
+
amount_in_cents = Plugins::Ecommerce::UtilService.ecommerce_money_to_cents(cart.total_amount)
|
114
|
+
begin
|
115
|
+
charge = Stripe::Charge.create(
|
116
|
+
customer: customer.id,
|
117
|
+
amount: amount_in_cents,
|
118
|
+
description: "Payment Products: #{cart.products_title}",
|
119
|
+
currency: site_service.currency,
|
120
|
+
)
|
121
|
+
payment_data = {
|
122
|
+
email: options[:email],
|
123
|
+
customer: customer.id,
|
124
|
+
charge: charge.id,
|
125
|
+
}
|
126
|
+
cart.set_meta("payment_data", payment_data)
|
127
|
+
{}
|
128
|
+
rescue Stripe::CardError => e
|
129
|
+
{error: e.message, payment_error: true}
|
130
|
+
rescue => e
|
131
|
+
{error: e.message}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def convert_to_order(status = 'paid')
|
136
|
+
Plugins::Ecommerce::Cart.transaction do
|
137
|
+
cart.prepare_to_pay
|
138
|
+
cart.update_amounts
|
139
|
+
cart.mark_paid(status)
|
140
|
+
cart.convert_to_order
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def site_service
|
147
|
+
@site_service ||= Plugins::Ecommerce::SiteService.new(site)
|
148
|
+
end
|
149
|
+
end
|