effective_orders 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +856 -0
- data/Rakefile +24 -0
- data/app/assets/images/effective_orders/stripe_connect.png +0 -0
- data/app/assets/javascripts/effective_orders/shipping_address_toggle.js.coffee +30 -0
- data/app/assets/javascripts/effective_orders/stripe_charges.js.coffee +26 -0
- data/app/assets/javascripts/effective_orders/stripe_subscriptions.js.coffee +28 -0
- data/app/assets/javascripts/effective_orders.js +2 -0
- data/app/assets/stylesheets/effective_orders/_order.scss +30 -0
- data/app/assets/stylesheets/effective_orders.css.scss +1 -0
- data/app/controllers/admin/customers_controller.rb +15 -0
- data/app/controllers/admin/orders_controller.rb +22 -0
- data/app/controllers/effective/carts_controller.rb +70 -0
- data/app/controllers/effective/orders_controller.rb +191 -0
- data/app/controllers/effective/providers/moneris.rb +94 -0
- data/app/controllers/effective/providers/paypal.rb +29 -0
- data/app/controllers/effective/providers/stripe.rb +125 -0
- data/app/controllers/effective/providers/stripe_connect.rb +47 -0
- data/app/controllers/effective/subscriptions_controller.rb +123 -0
- data/app/controllers/effective/webhooks_controller.rb +86 -0
- data/app/helpers/effective_carts_helper.rb +90 -0
- data/app/helpers/effective_orders_helper.rb +108 -0
- data/app/helpers/effective_paypal_helper.rb +37 -0
- data/app/helpers/effective_stripe_helper.rb +63 -0
- data/app/mailers/effective/orders_mailer.rb +64 -0
- data/app/models/concerns/acts_as_purchasable.rb +134 -0
- data/app/models/effective/access_denied.rb +17 -0
- data/app/models/effective/cart.rb +65 -0
- data/app/models/effective/cart_item.rb +40 -0
- data/app/models/effective/customer.rb +61 -0
- data/app/models/effective/datatables/customers.rb +45 -0
- data/app/models/effective/datatables/orders.rb +53 -0
- data/app/models/effective/order.rb +247 -0
- data/app/models/effective/order_item.rb +69 -0
- data/app/models/effective/stripe_charge.rb +35 -0
- data/app/models/effective/subscription.rb +95 -0
- data/app/models/inputs/price_field.rb +63 -0
- data/app/models/inputs/price_form_input.rb +7 -0
- data/app/models/inputs/price_formtastic_input.rb +9 -0
- data/app/models/inputs/price_input.rb +19 -0
- data/app/models/inputs/price_simple_form_input.rb +8 -0
- data/app/models/validators/effective/sold_out_validator.rb +7 -0
- data/app/views/active_admin/effective_orders/orders/_show.html.haml +70 -0
- data/app/views/admin/customers/_actions.html.haml +2 -0
- data/app/views/admin/customers/index.html.haml +10 -0
- data/app/views/admin/orders/index.html.haml +7 -0
- data/app/views/admin/orders/show.html.haml +11 -0
- data/app/views/effective/carts/_cart.html.haml +33 -0
- data/app/views/effective/carts/show.html.haml +18 -0
- data/app/views/effective/orders/_checkout_step_1.html.haml +39 -0
- data/app/views/effective/orders/_checkout_step_2.html.haml +18 -0
- data/app/views/effective/orders/_my_purchases.html.haml +15 -0
- data/app/views/effective/orders/_order.html.haml +4 -0
- data/app/views/effective/orders/_order_header.html.haml +21 -0
- data/app/views/effective/orders/_order_items.html.haml +39 -0
- data/app/views/effective/orders/_order_payment_details.html.haml +11 -0
- data/app/views/effective/orders/_order_shipping.html.haml +19 -0
- data/app/views/effective/orders/_order_user_fields.html.haml +10 -0
- data/app/views/effective/orders/checkout.html.haml +3 -0
- data/app/views/effective/orders/declined.html.haml +10 -0
- data/app/views/effective/orders/moneris/_form.html.haml +34 -0
- data/app/views/effective/orders/my_purchases.html.haml +6 -0
- data/app/views/effective/orders/my_sales.html.haml +28 -0
- data/app/views/effective/orders/new.html.haml +4 -0
- data/app/views/effective/orders/paypal/_form.html.haml +5 -0
- data/app/views/effective/orders/purchased.html.haml +10 -0
- data/app/views/effective/orders/show.html.haml +17 -0
- data/app/views/effective/orders/stripe/_form.html.haml +8 -0
- data/app/views/effective/orders/stripe/_subscription_fields.html.haml +7 -0
- data/app/views/effective/orders_mailer/order_receipt_to_admin.html.haml +8 -0
- data/app/views/effective/orders_mailer/order_receipt_to_buyer.html.haml +8 -0
- data/app/views/effective/orders_mailer/order_receipt_to_seller.html.haml +30 -0
- data/app/views/effective/subscriptions/index.html.haml +16 -0
- data/app/views/effective/subscriptions/new.html.haml +10 -0
- data/app/views/effective/subscriptions/show.html.haml +49 -0
- data/config/routes.rb +57 -0
- data/db/migrate/01_create_effective_orders.rb.erb +91 -0
- data/db/upgrade/02_upgrade_effective_orders_from03x.rb.erb +29 -0
- data/db/upgrade/upgrade_price_column_on_table.rb.erb +17 -0
- data/lib/effective_orders/engine.rb +52 -0
- data/lib/effective_orders/version.rb +3 -0
- data/lib/effective_orders.rb +76 -0
- data/lib/generators/effective_orders/install_generator.rb +38 -0
- data/lib/generators/effective_orders/upgrade_from03x_generator.rb +34 -0
- data/lib/generators/effective_orders/upgrade_price_column_generator.rb +34 -0
- data/lib/generators/templates/README +1 -0
- data/lib/generators/templates/effective_orders.rb +210 -0
- data/spec/controllers/carts_controller_spec.rb +143 -0
- data/spec/controllers/moneris_orders_controller_spec.rb +245 -0
- data/spec/controllers/orders_controller_spec.rb +418 -0
- data/spec/controllers/stripe_orders_controller_spec.rb +127 -0
- data/spec/controllers/webhooks_controller_spec.rb +79 -0
- data/spec/dummy/README.rdoc +8 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/product.rb +17 -0
- data/spec/dummy/app/models/product_with_float_price.rb +17 -0
- data/spec/dummy/app/models/user.rb +28 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config/application.rb +31 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +83 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/devise.rb +254 -0
- data/spec/dummy/config/initializers/effective_addresses.rb +15 -0
- data/spec/dummy/config/initializers/effective_orders.rb +22 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/schema.rb +142 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +487 -0
- data/spec/dummy/log/test.log +347 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/helpers/effective_orders_helper_spec.rb +21 -0
- data/spec/models/acts_as_purchasable_spec.rb +107 -0
- data/spec/models/customer_spec.rb +71 -0
- data/spec/models/factories_spec.rb +13 -0
- data/spec/models/order_item_spec.rb +35 -0
- data/spec/models/order_spec.rb +323 -0
- data/spec/models/stripe_charge_spec.rb +39 -0
- data/spec/models/subscription_spec.rb +103 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/support/factories.rb +118 -0
- metadata +387 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
class CreateEffectiveOrders < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table <%= @orders_table_name %> do |t|
|
4
|
+
t.integer :user_id
|
5
|
+
t.string :purchase_state
|
6
|
+
t.datetime :purchased_at
|
7
|
+
|
8
|
+
t.text :payment
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index <%= @orders_table_name %>, :user_id
|
14
|
+
|
15
|
+
|
16
|
+
create_table <%= @order_items_table_name %> do |t|
|
17
|
+
t.integer :order_id
|
18
|
+
t.integer :seller_id
|
19
|
+
t.string :purchasable_type
|
20
|
+
t.integer :purchasable_id
|
21
|
+
|
22
|
+
t.string :title
|
23
|
+
t.integer :quantity
|
24
|
+
t.integer :price, :default => 0
|
25
|
+
t.boolean :tax_exempt
|
26
|
+
t.decimal :tax_rate, :precision => 5, :scale => 3, :default => 0.0
|
27
|
+
|
28
|
+
t.timestamps
|
29
|
+
end
|
30
|
+
|
31
|
+
add_index <%= @order_items_table_name %>, :order_id
|
32
|
+
add_index <%= @order_items_table_name %>, :purchasable_id
|
33
|
+
add_index <%= @order_items_table_name %>, [:purchasable_type, :purchasable_id]
|
34
|
+
|
35
|
+
|
36
|
+
create_table <%= @carts_table_name %> do |t|
|
37
|
+
t.integer :user_id
|
38
|
+
t.timestamps
|
39
|
+
end
|
40
|
+
|
41
|
+
add_index <%= @carts_table_name %>, :user_id
|
42
|
+
|
43
|
+
create_table <%= @cart_items_table_name %> do |t|
|
44
|
+
t.integer :cart_id
|
45
|
+
t.string :purchasable_type
|
46
|
+
t.integer :purchasable_id
|
47
|
+
|
48
|
+
t.integer :quantity
|
49
|
+
|
50
|
+
t.timestamps
|
51
|
+
end
|
52
|
+
|
53
|
+
add_index <%= @cart_items_table_name %>, :cart_id
|
54
|
+
add_index <%= @cart_items_table_name %>, :purchasable_id
|
55
|
+
add_index <%= @cart_items_table_name %>, [:purchasable_type, :purchasable_id]
|
56
|
+
|
57
|
+
create_table <%= @customers_table_name %> do |t|
|
58
|
+
t.integer :user_id
|
59
|
+
t.string :stripe_customer_id
|
60
|
+
t.string :stripe_active_card
|
61
|
+
t.string :stripe_connect_access_token
|
62
|
+
|
63
|
+
t.timestamps
|
64
|
+
end
|
65
|
+
|
66
|
+
add_index <%= @customers_table_name %>, :user_id
|
67
|
+
|
68
|
+
create_table <%= @subscriptions_table_name %> do |t|
|
69
|
+
t.integer :customer_id
|
70
|
+
t.string :stripe_plan_id
|
71
|
+
t.string :stripe_subscription_id
|
72
|
+
t.string :stripe_coupon_id
|
73
|
+
t.string :title
|
74
|
+
t.integer :price, :default => 0
|
75
|
+
|
76
|
+
t.timestamps
|
77
|
+
end
|
78
|
+
|
79
|
+
add_index <%= @subscriptions_table_name %>, :customer_id
|
80
|
+
add_index <%= @subscriptions_table_name %>, :stripe_subscription_id
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.down
|
84
|
+
drop_table <%= @orders_table_name %>
|
85
|
+
drop_table <%= @order_items_table_name %>
|
86
|
+
drop_table <%= @carts_table_name %>
|
87
|
+
drop_table <%= @cart_items_table_name %>
|
88
|
+
drop_table <%= @customers_table_name %>
|
89
|
+
drop_table <%= @subscriptions_table_name %>
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class UpgradeEffectiveOrdersFrom03x < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
prices = ActiveRecord::Base.connection.execute("SELECT price from <%= @order_items_table_name.gsub(':', '') %> LIMIT 10").values.flatten
|
4
|
+
if prices.blank? || prices.any? { |price| price.to_s.include?('.') }
|
5
|
+
ActiveRecord::Base.connection.execute("UPDATE <%= @order_items_table_name.gsub(':', '') %> O SET price = (O.price * 100.0)")
|
6
|
+
change_column <%= @order_items_table_name %>, :price, :integer, :default => 0
|
7
|
+
end
|
8
|
+
|
9
|
+
prices = ActiveRecord::Base.connection.execute("SELECT price from <%= @subscriptions_table_name.gsub(':', '') %> LIMIT 10").values.flatten
|
10
|
+
if prices.blank? || prices.any? { |price| price.to_s.include?('.') }
|
11
|
+
ActiveRecord::Base.connection.execute("UPDATE <%= @subscriptions_table_name.gsub(':', '') %> O SET price = (O.price * 100.0)")
|
12
|
+
change_column <%= @subscriptions_table_name %>, :price, :integer, :default => 0
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
prices = ActiveRecord::Base.connection.execute("SELECT price from <%= @order_items_table_name.gsub(':', '') %> LIMIT 10").values.flatten
|
18
|
+
if prices.none? { |price| price.to_s.include?('.') }
|
19
|
+
change_column <%= @order_items_table_name %>, :price, :decimal, :precision => 8, :scale => 2, :default => 0.0
|
20
|
+
ActiveRecord::Base.connection.execute("UPDATE <%= @order_items_table_name.gsub(':', '') %> O SET price = (O.price / 100.0)")
|
21
|
+
end
|
22
|
+
|
23
|
+
prices = ActiveRecord::Base.connection.execute("SELECT price from <%= @subscriptions_table_name.gsub(':', '') %> LIMIT 10").values.flatten
|
24
|
+
if prices.none? { |price| price.to_s.include?('.') }
|
25
|
+
change_column <%= @subscriptions_table_name %>, :price, :decimal, :precision => 8, :scale => 2, :default => 0.0
|
26
|
+
ActiveRecord::Base.connection.execute("UPDATE <%= @subscriptions_table_name.gsub(':', '') %> O SET price = (O.price / 100.0)")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class UpgradePriceColumnOn<%= @table.capitalize %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
prices = ActiveRecord::Base.connection.execute("SELECT <%= @column %> FROM <%= @table %> LIMIT 10").values.flatten
|
4
|
+
if prices.blank? || prices.any? { |<%= @column %>| <%= @column %>.to_s.include?('.') }
|
5
|
+
ActiveRecord::Base.connection.execute("UPDATE <%= @table %> O SET <%= @column %> = (O.<%= @column %> * 100.0)")
|
6
|
+
change_column :<%= @table %>, :<%= @column %>, :integer, :default => 0
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
prices = ActiveRecord::Base.connection.execute("SELECT price FROM <%= @table %> LIMIT 10").values.flatten
|
12
|
+
if prices.none? { |<%= @column %>| <%= @column %>.to_s.include?('.') }
|
13
|
+
change_column :<%= @table %>, :<%= @column %>, :decimal, :precision => 8, :scale => 2, :default => 0.0
|
14
|
+
ActiveRecord::Base.connection.execute("UPDATE <%= @table %> O SET <%= @column %> = (O.<%= @column %> / 100.0)")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module EffectiveOrders
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
engine_name 'effective_orders'
|
4
|
+
|
5
|
+
config.autoload_paths += Dir["#{config.root}/app/models/**/"]
|
6
|
+
|
7
|
+
# Include Helpers to base application
|
8
|
+
initializer 'effective_orders.action_controller' do |app|
|
9
|
+
ActiveSupport.on_load :action_controller do
|
10
|
+
helper EffectiveOrdersHelper
|
11
|
+
helper EffectiveCartsHelper
|
12
|
+
helper EffectivePaypalHelper if EffectiveOrders.paypal_enabled
|
13
|
+
helper EffectiveStripeHelper if EffectiveOrders.stripe_enabled
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Include acts_as_addressable concern and allow any ActiveRecord object to call it
|
18
|
+
initializer 'effective_orders.active_record' do |app|
|
19
|
+
ActiveSupport.on_load :active_record do
|
20
|
+
ActiveRecord::Base.extend(ActsAsPurchasable::ActiveRecord)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
initializer 'effective_orders.action_view' do |app|
|
25
|
+
ActiveSupport.on_load :action_view do
|
26
|
+
ActionView::Helpers::FormBuilder.send(:include, Inputs::PriceFormInput)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Set up our default configuration options.
|
31
|
+
initializer "effective_orders.defaults", :before => :load_config_initializers do |app|
|
32
|
+
eval File.read("#{config.root}/lib/generators/templates/effective_orders.rb")
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set up our Stripe API Key
|
36
|
+
initializer "effective_orders.stripe_api_key", :after => :load_config_initializers do |app|
|
37
|
+
if EffectiveOrders.stripe_enabled
|
38
|
+
require 'stripe'
|
39
|
+
::Stripe.api_key = EffectiveOrders.stripe[:secret_key]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# ActiveAdmin (optional)
|
44
|
+
# This prepends the load path so someone can override the assets.rb if they want.
|
45
|
+
initializer 'effective_orders.active_admin' do
|
46
|
+
if defined?(ActiveAdmin) && EffectiveOrders.use_active_admin == true
|
47
|
+
ActiveAdmin.application.load_paths.unshift Dir["#{config.root}/active_admin"]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'effective_addresses'
|
2
|
+
require "effective_orders/engine"
|
3
|
+
require 'migrant' # Required for rspec to run properly
|
4
|
+
|
5
|
+
module EffectiveOrders
|
6
|
+
PURCHASED = 'purchased'
|
7
|
+
DECLINED = 'declined'
|
8
|
+
|
9
|
+
# The following are all valid config keys
|
10
|
+
mattr_accessor :orders_table_name
|
11
|
+
mattr_accessor :order_items_table_name
|
12
|
+
mattr_accessor :carts_table_name
|
13
|
+
mattr_accessor :cart_items_table_name
|
14
|
+
mattr_accessor :customers_table_name
|
15
|
+
mattr_accessor :subscriptions_table_name
|
16
|
+
|
17
|
+
mattr_accessor :authorization_method
|
18
|
+
mattr_accessor :tax_rate_method
|
19
|
+
|
20
|
+
mattr_accessor :layout
|
21
|
+
mattr_accessor :simple_form_options
|
22
|
+
mattr_accessor :use_active_admin
|
23
|
+
mattr_accessor :obfuscate_order_ids
|
24
|
+
mattr_accessor :silence_deprecation_warnings
|
25
|
+
mattr_accessor :allow_pretend_purchase_in_production
|
26
|
+
|
27
|
+
mattr_accessor :require_billing_address
|
28
|
+
mattr_accessor :require_shipping_address
|
29
|
+
|
30
|
+
mattr_accessor :collect_user_fields
|
31
|
+
mattr_accessor :skip_user_validation
|
32
|
+
|
33
|
+
mattr_accessor :minimum_charge
|
34
|
+
mattr_accessor :allow_free_orders
|
35
|
+
|
36
|
+
mattr_accessor :paypal_enabled
|
37
|
+
mattr_accessor :moneris_enabled
|
38
|
+
|
39
|
+
# application fee is required if stripe_connect_enabled is true
|
40
|
+
mattr_accessor :stripe_enabled
|
41
|
+
|
42
|
+
mattr_accessor :stripe_subscriptions_enabled
|
43
|
+
mattr_accessor :stripe_connect_enabled
|
44
|
+
mattr_accessor :stripe_connect_application_fee_method
|
45
|
+
|
46
|
+
# These are hashes of configs
|
47
|
+
mattr_accessor :mailer
|
48
|
+
mattr_accessor :paypal
|
49
|
+
mattr_accessor :moneris
|
50
|
+
mattr_accessor :stripe
|
51
|
+
|
52
|
+
def self.setup
|
53
|
+
yield self
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.authorized?(controller, action, resource)
|
57
|
+
if authorization_method.respond_to?(:call) || authorization_method.kind_of?(Symbol)
|
58
|
+
raise Effective::AccessDenied.new() unless (controller || self).instance_exec(controller, action, resource, &authorization_method)
|
59
|
+
end
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.minimum_charge
|
64
|
+
if @@minimum_charge.nil? || @@minimum_charge.kind_of?(Integer)
|
65
|
+
@@minimum_charge
|
66
|
+
else
|
67
|
+
ActiveSupport::Deprecation.warn('EffectiveOrders.minimum_charge config option is a non-integer. It should be an Integer representing the number of cents. Continuing with (price * 100.0).floor conversion') unless EffectiveOrders.silence_deprecation_warnings
|
68
|
+
((@@minimum_charge * 100.0).floor rescue nil)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class SoldOutException < Exception; end
|
73
|
+
class AlreadyPurchasedException < Exception; end
|
74
|
+
class AlreadyDeclinedException < Exception; end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module EffectiveOrders
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
|
6
|
+
desc "Creates an EffectiveOrders initializer in your application."
|
7
|
+
|
8
|
+
source_root File.expand_path("../../templates", __FILE__)
|
9
|
+
|
10
|
+
def self.next_migration_number(dirname)
|
11
|
+
if not ActiveRecord::Base.timestamped_migrations
|
12
|
+
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
13
|
+
else
|
14
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def copy_initializer
|
19
|
+
template "effective_orders.rb", "config/initializers/effective_orders.rb"
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_migration_file
|
23
|
+
@orders_table_name = ':' + EffectiveOrders.orders_table_name.to_s
|
24
|
+
@order_items_table_name = ':' + EffectiveOrders.order_items_table_name.to_s
|
25
|
+
@carts_table_name = ':' + EffectiveOrders.carts_table_name.to_s
|
26
|
+
@cart_items_table_name = ':' + EffectiveOrders.cart_items_table_name.to_s
|
27
|
+
@customers_table_name = ':' + EffectiveOrders.customers_table_name.to_s
|
28
|
+
@subscriptions_table_name = ':' + EffectiveOrders.subscriptions_table_name.to_s
|
29
|
+
|
30
|
+
migration_template '../../../db/migrate/01_create_effective_orders.rb.erb', 'db/migrate/create_effective_orders.rb'
|
31
|
+
end
|
32
|
+
|
33
|
+
def show_readme
|
34
|
+
readme "README" if behavior == :invoke
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module EffectiveOrders
|
2
|
+
module Generators
|
3
|
+
class UpgradeFrom03xGenerator < Rails::Generators::Base
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
|
6
|
+
desc "Upgrade effective_orders from the 0.3.x branch"
|
7
|
+
|
8
|
+
source_root File.expand_path("../../templates", __FILE__)
|
9
|
+
|
10
|
+
def self.next_migration_number(dirname)
|
11
|
+
if not ActiveRecord::Base.timestamped_migrations
|
12
|
+
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
13
|
+
else
|
14
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def create_migration_file
|
19
|
+
@orders_table_name = ':' + EffectiveOrders.orders_table_name.to_s
|
20
|
+
@order_items_table_name = ':' + EffectiveOrders.order_items_table_name.to_s
|
21
|
+
@carts_table_name = ':' + EffectiveOrders.carts_table_name.to_s
|
22
|
+
@cart_items_table_name = ':' + EffectiveOrders.cart_items_table_name.to_s
|
23
|
+
@customers_table_name = ':' + EffectiveOrders.customers_table_name.to_s
|
24
|
+
@subscriptions_table_name = ':' + EffectiveOrders.subscriptions_table_name.to_s
|
25
|
+
|
26
|
+
migration_template '../../../db/upgrade/02_upgrade_effective_orders_from03x.rb.erb', 'db/migrate/upgrade_effective_orders_from03x.rb'
|
27
|
+
end
|
28
|
+
|
29
|
+
def show_readme
|
30
|
+
readme "README" if behavior == :invoke
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# bundle exec rails generate effective_orders:upgrade_price_column TABLE COLUMN
|
2
|
+
|
3
|
+
module EffectiveOrders
|
4
|
+
module Generators
|
5
|
+
class UpgradePriceColumn < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
|
8
|
+
desc "Upgrade a table with a decimal column to integer"
|
9
|
+
|
10
|
+
source_root File.expand_path("../../templates", __FILE__)
|
11
|
+
argument :table, :type => :string, :default => nil
|
12
|
+
argument :column, :type => :string, :default => :price
|
13
|
+
|
14
|
+
def self.next_migration_number(dirname)
|
15
|
+
if not ActiveRecord::Base.timestamped_migrations
|
16
|
+
Time.new.utc.strftime("%Y%m%d%H%M%S")
|
17
|
+
else
|
18
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_migration_file
|
23
|
+
@table = table.to_s.downcase
|
24
|
+
@column = column.to_s.downcase
|
25
|
+
|
26
|
+
migration_template '../../../db/upgrade/upgrade_price_column_on_table.rb.erb', "db/migrate/upgrade_price_column_on_#{table}.rb"
|
27
|
+
end
|
28
|
+
|
29
|
+
def show_readme
|
30
|
+
readme "README" if behavior == :invoke
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Thanks for using EffectiveOrders
|
@@ -0,0 +1,210 @@
|
|
1
|
+
# EffectiveOrders Rails Engine
|
2
|
+
|
3
|
+
EffectiveOrders.setup do |config|
|
4
|
+
# Configure Database Tables
|
5
|
+
config.orders_table_name = :orders
|
6
|
+
config.order_items_table_name = :order_items
|
7
|
+
config.carts_table_name = :carts
|
8
|
+
config.cart_items_table_name = :cart_items
|
9
|
+
config.customers_table_name = :customers
|
10
|
+
config.subscriptions_table_name = :subscriptions
|
11
|
+
|
12
|
+
# Authorization Method
|
13
|
+
#
|
14
|
+
# This method is called by all controller actions with the appropriate action and resource
|
15
|
+
# If the method returns false, an Effective::AccessDenied Error will be raised (see README.md for complete info)
|
16
|
+
#
|
17
|
+
# Use via Proc (and with CanCan):
|
18
|
+
# config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) }
|
19
|
+
#
|
20
|
+
# Use via custom method:
|
21
|
+
# config.authorization_method = :my_authorization_method
|
22
|
+
#
|
23
|
+
# And then in your application_controller.rb:
|
24
|
+
#
|
25
|
+
# def my_authorization_method(action, resource)
|
26
|
+
# current_user.is?(:admin)
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# Or disable the check completely:
|
30
|
+
# config.authorization_method = false
|
31
|
+
config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) } # CanCan gem
|
32
|
+
|
33
|
+
# Register Effective::Order with ActiveAdmin if ActiveAdmin is present
|
34
|
+
config.use_active_admin = true
|
35
|
+
|
36
|
+
# Use effective_obfuscation gem to change order.id into a seemingly random 10-digit number
|
37
|
+
config.obfuscate_order_ids = true
|
38
|
+
|
39
|
+
# Silence the price deprecation warnings
|
40
|
+
config.silence_deprecation_warnings = false
|
41
|
+
|
42
|
+
# Require these addresses when creating a new Order. Works with effective_addresses gem
|
43
|
+
config.require_billing_address = true
|
44
|
+
config.require_shipping_address = false
|
45
|
+
|
46
|
+
# If set, the orders#new screen will render effective/orders/user_fields partial and capture this User Info
|
47
|
+
# The partial can be overridden to customize the form, but the following fields are also fed into strong_paramters
|
48
|
+
config.collect_user_fields = []
|
49
|
+
#config.collect_user_fields = [:salutation, :first_name, :last_name] # Must be valid fields on the User object
|
50
|
+
|
51
|
+
# Don't validate_associated :user when saving an Order
|
52
|
+
config.skip_user_validation = false
|
53
|
+
|
54
|
+
# Tax Calculation Method
|
55
|
+
config.tax_rate_method = Proc.new { |acts_as_purchasable| 0.05 } # Regardless of the object, charge 5% tax (GST)
|
56
|
+
|
57
|
+
# Minimum Charge
|
58
|
+
# Prevent orders less than this value from being purchased
|
59
|
+
# Stripe doesn't allow orders less than $0.50
|
60
|
+
# Set to nil for no minimum charge
|
61
|
+
# Default value is 50 cents, or $0.50
|
62
|
+
config.minimum_charge = 50
|
63
|
+
|
64
|
+
# Free Orders
|
65
|
+
# Allow orders with a total of 0.00 to be purchased (regardless of the minimum charge setting)
|
66
|
+
# When enabled, the checkout process will skip the paypal/stripe/purchasing step
|
67
|
+
# and just display the 'Thank You' after checkout is clicked
|
68
|
+
config.allow_free_orders = true
|
69
|
+
|
70
|
+
# Allow Pretend Purchase in Production
|
71
|
+
# WARNING: Setting this option to true will allow users to purchase! an Order without entering a credit card
|
72
|
+
# WARNING: When true, users can purchase! anything without paying money
|
73
|
+
#
|
74
|
+
# This should basically always be false, but sometimes you want to make a Beta/Demo site
|
75
|
+
# where users may test the purchase workflow without actually paying money
|
76
|
+
#
|
77
|
+
# When true, there will be a 'Process Order' button on the Checkout screen.
|
78
|
+
# Clicking this button will mark an Order purchased and redirect the user to the
|
79
|
+
# Thank You page just as if they had successfully Checked Out through a payment processor
|
80
|
+
config.allow_pretend_purchase_in_production = false
|
81
|
+
|
82
|
+
|
83
|
+
# Layout Settings
|
84
|
+
# Configure the Layout per controller, or all at once
|
85
|
+
|
86
|
+
# config.layout = 'application' # All EffectiveOrders controllers will use this layout
|
87
|
+
config.layout = {
|
88
|
+
:carts => 'application',
|
89
|
+
:orders => 'application',
|
90
|
+
:subscriptions => 'application',
|
91
|
+
:admin_customers => 'application',
|
92
|
+
:admin_orders => 'application'
|
93
|
+
}
|
94
|
+
|
95
|
+
# SimpleForm Options
|
96
|
+
# This Hash of options will be passed into any simple_form_for() calls
|
97
|
+
config.simple_form_options = {}
|
98
|
+
|
99
|
+
# config.simple_form_options = {
|
100
|
+
# :html => {:class => 'form-horizontal'},
|
101
|
+
# :wrapper => :horizontal_form,
|
102
|
+
# :wrapper_mappings => {
|
103
|
+
# :boolean => :horizontal_boolean,
|
104
|
+
# :check_boxes => :horizontal_radio_and_checkboxes,
|
105
|
+
# :radio_buttons => :horizontal_radio_and_checkboxes
|
106
|
+
# }
|
107
|
+
# }
|
108
|
+
|
109
|
+
# Mailer Settings
|
110
|
+
# effective_orders will send out receipts to the buyer, seller and admins.
|
111
|
+
# For all the emails, the same :subject_prefix will be prefixed. Leave as nil / empty string if you don't want any prefix
|
112
|
+
#
|
113
|
+
# The subject_for_admin_receipt, subject_for_buyer_receipt and subject_for_seller_receipt can be one of:
|
114
|
+
# - nil / empty string to use the built in defaults
|
115
|
+
# - A string with the full subject line for this email
|
116
|
+
# - A Proc to create the subject line based on the email
|
117
|
+
# In all three of these cases, the subject_prefix will still be used.
|
118
|
+
|
119
|
+
# The Procs are the same for admin & buyer receipt, the seller Proc is different
|
120
|
+
# :subject_for_admin_receipt => Proc.new { |order| "Order #{order.to_param} has been purchased"}
|
121
|
+
# :subject_for_buyer_receipt => Proc.new { |order| "Order #{order.to_param} has been purchased"}
|
122
|
+
# :subject_for_seller_receipt => Proc.new { |order, order_items, seller| "Order #{order.to_param} has been purchased"}
|
123
|
+
|
124
|
+
config.mailer = {
|
125
|
+
:send_order_receipt_to_admin => true,
|
126
|
+
:send_order_receipt_to_buyer => true,
|
127
|
+
:send_order_receipt_to_seller => true, # Only applies to StripeConnect
|
128
|
+
:admin_email => 'admin@example.com',
|
129
|
+
:default_from => 'info@example.com',
|
130
|
+
:subject_prefix => '[example]',
|
131
|
+
:subject_for_admin_receipt => '',
|
132
|
+
:subject_for_buyer_receipt => '',
|
133
|
+
:subject_for_seller_receipt => ''
|
134
|
+
}
|
135
|
+
|
136
|
+
# Moneris configuration
|
137
|
+
config.moneris_enabled = false
|
138
|
+
|
139
|
+
if Rails.env.production?
|
140
|
+
config.moneris = {
|
141
|
+
:ps_store_id => '',
|
142
|
+
:hpp_key => '',
|
143
|
+
:hpp_url => 'https://www3.moneris.com/HPPDP/index.php',
|
144
|
+
:verify_url => 'https://www3.moneris.com/HPPDP/verifyTxn.php',
|
145
|
+
:order_nudge => 0
|
146
|
+
}
|
147
|
+
else
|
148
|
+
config.moneris = {
|
149
|
+
:ps_store_id => '',
|
150
|
+
:hpp_key => '',
|
151
|
+
:hpp_url => 'https://esqa.moneris.com/HPPDP/index.php',
|
152
|
+
:verify_url => 'https://esqa.moneris.com/HPPDP/verifyTxn.php',
|
153
|
+
:order_nudge => 0
|
154
|
+
}
|
155
|
+
end
|
156
|
+
|
157
|
+
# Paypal configuration
|
158
|
+
config.paypal_enabled = false
|
159
|
+
|
160
|
+
if Rails.env.production?
|
161
|
+
config.paypal = {
|
162
|
+
:seller_email => '',
|
163
|
+
:secret => '',
|
164
|
+
:cert_id => '',
|
165
|
+
:paypal_url => 'https://www.paypal.com/cgi-bin/webscr',
|
166
|
+
:currency => 'CAD',
|
167
|
+
:paypal_cert => "#{Rails.root}/config/paypalcerts/production/paypal_cert.pem",
|
168
|
+
:app_cert => "#{Rails.root}/config/paypalcerts/production/app_cert.pem",
|
169
|
+
:app_key => "#{Rails.root}/config/paypalcerts/production/app_key.pem"
|
170
|
+
}
|
171
|
+
else
|
172
|
+
config.paypal = {
|
173
|
+
:seller_email => '',
|
174
|
+
:secret => '',
|
175
|
+
:cert_id => '',
|
176
|
+
:paypal_url => 'https://www.sandbox.paypal.com/cgi-bin/webscr',
|
177
|
+
:currency => 'CAD',
|
178
|
+
:paypal_cert => "#{Rails.root}/config/paypalcerts/#{Rails.env}/paypal_cert.pem",
|
179
|
+
:app_cert => "#{Rails.root}/config/paypalcerts/#{Rails.env}/app_cert.pem",
|
180
|
+
:app_key => "#{Rails.root}/config/paypalcerts/#{Rails.env}/app_key.pem"
|
181
|
+
}
|
182
|
+
end
|
183
|
+
|
184
|
+
# Stripe configuration
|
185
|
+
config.stripe_enabled = false
|
186
|
+
config.stripe_subscriptions_enabled = false # https://stripe.com/docs/subscriptions
|
187
|
+
config.stripe_connect_enabled = false # https://stripe.com/docs/connect
|
188
|
+
config.stripe_connect_application_fee_method = Proc.new { |order_item| order_item.total * 0.10 } # 10 percent
|
189
|
+
|
190
|
+
if Rails.env.production?
|
191
|
+
config.stripe = {
|
192
|
+
:secret_key => '',
|
193
|
+
:publishable_key => '',
|
194
|
+
:currency => 'usd',
|
195
|
+
:site_title => 'My Site',
|
196
|
+
:site_image => '', # A relative URL pointing to a square image of your brand or product. The recommended minimum size is 128x128px.
|
197
|
+
:connect_client_id => ''
|
198
|
+
}
|
199
|
+
else
|
200
|
+
config.stripe = {
|
201
|
+
:secret_key => '',
|
202
|
+
:publishable_key => '',
|
203
|
+
:currency => 'usd',
|
204
|
+
:site_title => 'My Development Site', # Displayed on the Embedded Stripe Form
|
205
|
+
:site_image => '', # A relative URL pointing to a square image of your brand or product. The recommended minimum size is 128x128px.
|
206
|
+
:connect_client_id => ''
|
207
|
+
}
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|