camaleon_ecommerce 1.1 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|