effective_orders 4.6.3 → 5.0.4
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/MIT-LICENSE +1 -1
- data/README.md +14 -86
- data/app/controllers/admin/customers_controller.rb +5 -16
- data/app/controllers/admin/order_items_controller.rb +6 -9
- data/app/controllers/admin/orders_controller.rb +18 -82
- data/app/controllers/effective/carts_controller.rb +10 -6
- data/app/controllers/effective/concerns/purchase.rb +12 -19
- data/app/controllers/effective/customers_controller.rb +4 -2
- data/app/controllers/effective/orders_controller.rb +26 -23
- data/app/controllers/effective/providers/cheque.rb +3 -1
- data/app/controllers/effective/providers/free.rb +3 -2
- data/app/controllers/effective/providers/mark_as_paid.rb +5 -4
- data/app/controllers/effective/providers/moneris.rb +3 -1
- data/app/controllers/effective/providers/paypal.rb +3 -2
- data/app/controllers/effective/providers/phone.rb +3 -1
- data/app/controllers/effective/providers/pretend.rb +4 -3
- data/app/controllers/effective/providers/refund.rb +4 -3
- data/app/controllers/effective/providers/stripe.rb +4 -3
- data/app/controllers/effective/subscripter_controller.rb +4 -2
- data/app/controllers/effective/webhooks_controller.rb +12 -3
- data/app/datatables/admin/effective_customers_datatable.rb +7 -3
- data/app/datatables/admin/effective_orders_datatable.rb +4 -7
- data/app/datatables/effective_orders_datatable.rb +3 -7
- data/app/helpers/effective_orders_helper.rb +1 -7
- data/app/mailers/effective/orders_mailer.rb +131 -96
- data/app/models/concerns/acts_as_purchasable.rb +0 -11
- data/app/models/concerns/acts_as_subscribable.rb +0 -6
- data/app/models/effective/cart.rb +7 -5
- data/app/models/effective/cart_item.rb +7 -4
- data/app/models/effective/customer.rb +7 -6
- data/app/models/effective/order.rb +58 -61
- data/app/models/effective/order_item.rb +20 -8
- data/app/models/effective/product.rb +11 -6
- data/app/models/effective/subscription.rb +13 -12
- data/app/views/admin/orders/_form.html.haml +5 -9
- data/app/views/admin/orders/_order_item_fields.html.haml +8 -12
- data/app/views/effective/orders/_checkout_step2.html.haml +1 -2
- data/app/views/effective/orders/_order_actions.html.haml +2 -2
- data/app/views/effective/orders/show.html.haml +4 -0
- data/config/effective_orders.rb +8 -32
- data/config/routes.rb +16 -17
- data/db/migrate/01_create_effective_orders.rb.erb +4 -0
- data/lib/effective_orders.rb +34 -76
- data/lib/effective_orders/engine.rb +0 -7
- data/lib/effective_orders/version.rb +1 -1
- data/lib/generators/templates/effective_orders_mailer_preview.rb +13 -13
- data/lib/tasks/effective_orders_tasks.rake +2 -2
- metadata +2 -3
- data/app/models/effective/access_denied.rb +0 -17
@@ -2,15 +2,21 @@ module Effective
|
|
2
2
|
class OrderItem < ActiveRecord::Base
|
3
3
|
self.table_name = EffectiveOrders.order_items_table_name.to_s
|
4
4
|
|
5
|
-
belongs_to :order
|
5
|
+
belongs_to :order
|
6
6
|
belongs_to :purchasable, polymorphic: true
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
if defined?(EffectiveQbSync)
|
9
|
+
has_one :qb_order_item
|
10
|
+
end
|
11
|
+
|
12
|
+
effective_resource do
|
13
|
+
name :string
|
14
|
+
quantity :integer
|
15
|
+
price :integer
|
16
|
+
tax_exempt :boolean
|
17
|
+
|
18
|
+
timestamps
|
19
|
+
end
|
14
20
|
|
15
21
|
validates :purchasable, associated: true, presence: true
|
16
22
|
accepts_nested_attributes_for :purchasable
|
@@ -24,7 +30,7 @@ module Effective
|
|
24
30
|
scope :purchased_by, lambda { |user| where(order_id: Effective::Order.purchased_by(user)) }
|
25
31
|
|
26
32
|
def to_s
|
27
|
-
(quantity || 0) > 1 ? "#{quantity}x #{name}" : name
|
33
|
+
((quantity || 0) > 1 ? "#{quantity}x #{name}" : name) || 'order item'
|
28
34
|
end
|
29
35
|
|
30
36
|
def purchased_download_url
|
@@ -59,5 +65,11 @@ module Effective
|
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
68
|
+
# first or build
|
69
|
+
def qb_item_name
|
70
|
+
raise('expected EffectiveQbSync gem') unless defined?(EffectiveQbSync)
|
71
|
+
(qb_order_item || build_qb_order_item(name: purchasable.qb_item_name)).name
|
72
|
+
end
|
73
|
+
|
62
74
|
end
|
63
75
|
end
|
@@ -4,12 +4,17 @@ module Effective
|
|
4
4
|
|
5
5
|
acts_as_purchasable
|
6
6
|
|
7
|
-
#
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
# belongs_to :purchased_order_id
|
8
|
+
|
9
|
+
effective_resource do
|
10
|
+
name :string
|
11
|
+
qb_item_name :string
|
12
|
+
|
13
|
+
price :integer
|
14
|
+
tax_exempt :boolean
|
15
|
+
|
16
|
+
timestamps
|
17
|
+
end
|
13
18
|
|
14
19
|
validates :name, presence: true
|
15
20
|
validates :price, presence: true
|
@@ -4,20 +4,21 @@ module Effective
|
|
4
4
|
|
5
5
|
attr_accessor :stripe_subscription
|
6
6
|
|
7
|
-
belongs_to :customer,
|
7
|
+
belongs_to :customer, counter_cache: true
|
8
8
|
belongs_to :subscribable, polymorphic: true
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
effective_resource do
|
11
|
+
stripe_plan_id :string
|
12
|
+
stripe_subscription_id :string
|
13
|
+
name :string
|
14
|
+
description :string
|
15
|
+
interval :string
|
16
|
+
quantity :integer
|
17
|
+
|
18
|
+
status :string
|
19
|
+
|
20
|
+
timestamps
|
21
|
+
end
|
21
22
|
|
22
23
|
before_validation(if: -> { plan && (stripe_plan_id_changed? || new_record?) }) do
|
23
24
|
self.name = plan[:name]
|
@@ -1,19 +1,15 @@
|
|
1
1
|
= effective_form_with(model: [:admin, order], url: (order.persisted? ? effective_orders.admin_order_path(order) : effective_orders.admin_orders_path)) do |f|
|
2
2
|
- if f.object.new_record?
|
3
|
-
=
|
3
|
+
- user_collection = current_user.class.respond_to?(:sorted) ? current_user.class.sorted : current_user.class.all
|
4
|
+
|
5
|
+
= f.select :user_id, (@users || user_collection),
|
4
6
|
label: 'Buyer', required: true, hint: 'The user that should purchase this order.'
|
5
7
|
|
6
8
|
= f.email_cc_field :cc, hint: "Cc the above on any emailed receipts or payment requests."
|
7
9
|
|
8
10
|
%h2 Order Items
|
9
|
-
.order_items
|
10
|
-
|
11
|
-
|
12
|
-
= f.fields_for :order_items, f.object.order_items do |order_item|
|
13
|
-
= render 'order_item_fields', f: order_item
|
14
|
-
|
15
|
-
.links
|
16
|
-
= link_to_add_association (icon('plus') + 'Add item'), f, :order_items, class: 'btn btn-secondary', partial: 'order_item_fields'
|
11
|
+
= f.has_many :order_items do |fc|
|
12
|
+
= render 'order_item_fields', f: fc
|
17
13
|
|
18
14
|
%hr
|
19
15
|
|
@@ -1,14 +1,10 @@
|
|
1
|
-
.
|
2
|
-
.
|
3
|
-
= f.
|
4
|
-
|
5
|
-
|
6
|
-
.col-md-2= pf.price_field :price
|
1
|
+
.row.align-items-center
|
2
|
+
= f.fields_for :purchasable, (f.object.purchasable || Effective::Product.new) do |pf|
|
3
|
+
.col= f.number_field :quantity, input_html: { value: f.object.quantity || 1, min: 1 }
|
4
|
+
.col= pf.text_field :name
|
5
|
+
.col= pf.price_field :price
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
- if EffectiveOrders.use_effective_qb_sync
|
8
|
+
.col= pf.text_field :qb_item_name, label: 'Quickbooks Item'
|
10
9
|
|
11
|
-
|
12
|
-
.col-md-1
|
13
|
-
= link_to_remove_association(f, 'data-confirm': 'Remove?') do
|
14
|
-
= icon('trash-2', class: 'text-danger')
|
10
|
+
.col= pf.check_box :tax_exempt, label: "Tax Exempt", title: 'When checked, tax will not be applied to this item'
|
@@ -30,8 +30,7 @@
|
|
30
30
|
%p.my-4.text-center - or -
|
31
31
|
= render partial: '/effective/orders/deferred/form', locals: provider_locals
|
32
32
|
|
33
|
-
- if
|
33
|
+
- if EffectiveResources.authorized?(controller, :admin, :effective_orders) && order.user != current_user
|
34
34
|
- if EffectiveOrders.mark_as_paid?
|
35
35
|
.effective-order-admin-purchase-actions
|
36
36
|
= render partial: '/effective/orders/mark_as_paid/form', locals: provider_locals
|
37
|
-
|
@@ -3,11 +3,11 @@
|
|
3
3
|
= link_to 'Print', '#', class: 'btn btn-primary print-button', data: { role: 'print-button' }, onClick: 'window.print(); false;'
|
4
4
|
|
5
5
|
- if order.purchased?
|
6
|
-
= link_to '
|
6
|
+
= link_to 'E-mail Receipt', effective_orders.send_buyer_receipt_order_path(order),
|
7
7
|
class: 'btn btn-secondary',
|
8
8
|
data: { confirm: "Send receipt to #{order.emails_send_to}?" }
|
9
9
|
|
10
|
-
- if order.persisted? &&
|
10
|
+
- if order.persisted? && EffectiveResources.authorized?(controller, :admin, :effective_orders)
|
11
11
|
- if order.pending? || order.confirmed? || order.deferred?
|
12
12
|
= link_to 'Email request for payment to buyer', effective_orders.send_payment_request_admin_order_path(order),
|
13
13
|
class: 'btn btn-secondary',
|
data/config/effective_orders.rb
CHANGED
@@ -10,38 +10,8 @@ EffectiveOrders.setup do |config|
|
|
10
10
|
config.subscriptions_table_name = :subscriptions
|
11
11
|
config.products_table_name = :products
|
12
12
|
|
13
|
-
# Authorization Method
|
14
|
-
#
|
15
|
-
# This method is called by all controller actions with the appropriate action and resource
|
16
|
-
# If the method returns false, an Effective::AccessDenied Error will be raised (see README.md for complete info)
|
17
|
-
#
|
18
|
-
# Use via Proc (and with CanCan):
|
19
|
-
# config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) }
|
20
|
-
#
|
21
|
-
# Use via custom method:
|
22
|
-
# config.authorization_method = :my_authorization_method
|
23
|
-
#
|
24
|
-
# And then in your application_controller.rb:
|
25
|
-
#
|
26
|
-
# def my_authorization_method(action, resource)
|
27
|
-
# current_user.is?(:admin)
|
28
|
-
# end
|
29
|
-
#
|
30
|
-
# Or disable the check completely:
|
31
|
-
# config.authorization_method = false
|
32
|
-
config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) } # CanCanCan
|
33
|
-
|
34
13
|
# Layout Settings
|
35
|
-
#
|
36
|
-
|
37
|
-
# config.layout = 'application' # All EffectiveOrders controllers will use this layout
|
38
|
-
config.layout = {
|
39
|
-
carts: 'application',
|
40
|
-
orders: 'application',
|
41
|
-
subscriptions: 'application',
|
42
|
-
admin_customers: 'admin',
|
43
|
-
admin_orders: 'admin'
|
44
|
-
}
|
14
|
+
# config.layout = { application: 'application', admin: 'admin' }
|
45
15
|
|
46
16
|
# Filter the @orders on admin/orders#index screen
|
47
17
|
# config.orders_collection_scope = Proc.new { |scope| scope.where(...) }
|
@@ -54,6 +24,9 @@ EffectiveOrders.setup do |config|
|
|
54
24
|
# Use effective_obfuscation gem to change order.id into a seemingly random 10-digit number
|
55
25
|
config.obfuscate_order_ids = false
|
56
26
|
|
27
|
+
# Synchronize with Quickbooks
|
28
|
+
config.use_effective_qb_sync = false
|
29
|
+
|
57
30
|
# If set, the orders#new screen will render effective/orders/_order_note_fields to capture any Note info
|
58
31
|
config.collect_note = false
|
59
32
|
config.collect_note_required = false
|
@@ -113,6 +86,9 @@ EffectiveOrders.setup do |config|
|
|
113
86
|
|
114
87
|
# subject_for_subscription_trialing: Proc.new { |subscribable| "Pending Order #{order.to_param}"}
|
115
88
|
|
89
|
+
# Use this mailer class. You can extend.
|
90
|
+
config.mailer_class_name = 'Effective::OrdersMailer'
|
91
|
+
|
116
92
|
config.mailer = {
|
117
93
|
send_order_receipt_to_admin: true,
|
118
94
|
send_order_receipt_to_buyer: true,
|
@@ -155,7 +131,7 @@ EffectiveOrders.setup do |config|
|
|
155
131
|
default_from: 'info@example.com',
|
156
132
|
admin_email: 'admin@example.com', # Refund notifications will also be sent here
|
157
133
|
|
158
|
-
deliver_method: nil # When nil, will
|
134
|
+
deliver_method: nil # When nil, will try deliver_later and fallback to deliver_now
|
159
135
|
}
|
160
136
|
|
161
137
|
#######################################
|
data/config/routes.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
EffectiveOrders::Engine.routes.draw do
|
2
|
-
scope :
|
2
|
+
scope module: 'effective' do
|
3
3
|
resources :orders, except: [:destroy] do
|
4
4
|
member do
|
5
5
|
get :purchased
|
@@ -7,33 +7,32 @@ EffectiveOrders::Engine.routes.draw do
|
|
7
7
|
get :declined
|
8
8
|
get :send_buyer_receipt
|
9
9
|
|
10
|
-
post :free
|
11
|
-
post :mark_as_paid
|
12
|
-
post :cheque
|
13
|
-
post :phone
|
14
|
-
post :pretend
|
15
|
-
post :refund
|
16
|
-
post :stripe
|
10
|
+
post :free
|
11
|
+
post :mark_as_paid
|
12
|
+
post :cheque
|
13
|
+
post :phone
|
14
|
+
post :pretend
|
15
|
+
post :refund
|
16
|
+
post :stripe
|
17
17
|
end
|
18
18
|
|
19
19
|
collection do
|
20
20
|
post :bulk_send_buyer_receipt
|
21
21
|
|
22
|
-
post :moneris_postback
|
23
|
-
post :paypal_postback
|
22
|
+
post :moneris_postback
|
23
|
+
post :paypal_postback
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
27
|
post 'orders/:id', to: 'orders#update'
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
match 'webhooks/stripe', to: 'webhooks#stripe', via: [:get, :post, :put]
|
35
|
-
end
|
29
|
+
# Subscriptions
|
30
|
+
match 'subscribe', to: 'subscripter#update', via: :post, as: :subscripter
|
31
|
+
match 'customer/settings', to: 'customers#edit', as: :customer_settings, via: [:get]
|
32
|
+
match 'customer/settings', to: 'customers#update', via: [:patch, :put, :post]
|
33
|
+
match 'webhooks/stripe', to: 'webhooks#stripe', via: [:get, :post, :put]
|
36
34
|
|
35
|
+
# Carts
|
37
36
|
match 'cart', to: 'carts#show', as: 'cart', via: :get
|
38
37
|
match 'cart', to: 'carts#destroy', via: :delete
|
39
38
|
|
@@ -2,6 +2,7 @@ class CreateEffectiveOrders < ActiveRecord::Migration[4.2]
|
|
2
2
|
def self.up
|
3
3
|
create_table <%= @orders_table_name %> do |t|
|
4
4
|
t.integer :user_id
|
5
|
+
t.string :user_type
|
5
6
|
|
6
7
|
t.integer :parent_id
|
7
8
|
t.string :parent_type
|
@@ -53,6 +54,8 @@ class CreateEffectiveOrders < ActiveRecord::Migration[4.2]
|
|
53
54
|
|
54
55
|
create_table <%= @carts_table_name %> do |t|
|
55
56
|
t.integer :user_id
|
57
|
+
t.string :user_type
|
58
|
+
|
56
59
|
t.integer :cart_items_count, :default => 0
|
57
60
|
t.timestamps
|
58
61
|
end
|
@@ -76,6 +79,7 @@ class CreateEffectiveOrders < ActiveRecord::Migration[4.2]
|
|
76
79
|
|
77
80
|
create_table <%= @customers_table_name %> do |t|
|
78
81
|
t.integer :user_id
|
82
|
+
t.string :user_type
|
79
83
|
|
80
84
|
t.string :stripe_customer_id
|
81
85
|
t.string :payment_method_id
|
data/lib/effective_orders.rb
CHANGED
@@ -1,94 +1,47 @@
|
|
1
1
|
require 'effective_addresses'
|
2
|
+
require 'effective_resources'
|
2
3
|
require 'effective_orders/engine'
|
3
4
|
require 'effective_orders/version'
|
4
5
|
|
5
6
|
module EffectiveOrders
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
# Order states
|
8
|
+
PENDING = 'pending' # New orders are created in a pending state
|
9
|
+
CONFIRMED = 'confirmed' # Once the order has passed checkout step 1
|
10
|
+
DEFERRED = 'deferred' # Deferred providers. Cheque or Phone was selected.
|
11
|
+
PURCHASED = 'purchased' # Purchased by provider
|
12
|
+
DECLINED = 'declined' # Declined by provider
|
12
13
|
STATES = { PENDING => PENDING, CONFIRMED => CONFIRMED, DEFERRED => DEFERRED, PURCHASED => PURCHASED, DECLINED => DECLINED }
|
13
14
|
|
14
15
|
# Subscription statuses (as per stripe)
|
15
|
-
ACTIVE = 'active'
|
16
|
-
PAST_DUE = 'past_due'
|
17
|
-
TRIALING = 'trialing'
|
18
|
-
CANCELED = 'canceled'
|
16
|
+
ACTIVE = 'active'
|
17
|
+
PAST_DUE = 'past_due'
|
18
|
+
TRIALING = 'trialing'
|
19
|
+
CANCELED = 'canceled'
|
19
20
|
|
20
21
|
STATUSES = { ACTIVE => ACTIVE, PAST_DUE => PAST_DUE, CANCELED => CANCELED, TRIALING => TRIALING }
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
mattr_accessor :obfuscate_order_ids
|
40
|
-
mattr_accessor :billing_address
|
41
|
-
mattr_accessor :shipping_address
|
42
|
-
mattr_accessor :use_address_full_name
|
43
|
-
|
44
|
-
mattr_accessor :collect_note
|
45
|
-
mattr_accessor :collect_note_required
|
46
|
-
mattr_accessor :collect_note_message
|
47
|
-
|
48
|
-
mattr_accessor :terms_and_conditions
|
49
|
-
mattr_accessor :terms_and_conditions_label
|
50
|
-
|
51
|
-
mattr_accessor :minimum_charge
|
52
|
-
|
53
|
-
# Features
|
54
|
-
mattr_accessor :free_enabled
|
55
|
-
mattr_accessor :mark_as_paid_enabled
|
56
|
-
mattr_accessor :pretend_enabled
|
57
|
-
mattr_accessor :pretend_message
|
58
|
-
|
59
|
-
# Payment processors. false or Hash
|
60
|
-
mattr_accessor :cheque
|
61
|
-
mattr_accessor :moneris
|
62
|
-
mattr_accessor :paypal
|
63
|
-
mattr_accessor :phone
|
64
|
-
mattr_accessor :refund
|
65
|
-
mattr_accessor :stripe
|
66
|
-
mattr_accessor :subscriptions # Stripe subscriptions
|
67
|
-
mattr_accessor :trial # Trial mode
|
68
|
-
|
69
|
-
def self.setup
|
70
|
-
yield self
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.authorized?(controller, action, resource)
|
74
|
-
@_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact
|
75
|
-
|
76
|
-
return !!authorization_method unless authorization_method.respond_to?(:call)
|
77
|
-
controller = controller.controller if controller.respond_to?(:controller)
|
78
|
-
|
79
|
-
begin
|
80
|
-
!!(controller || self).instance_exec((controller || self), action, resource, &authorization_method)
|
81
|
-
rescue *@_exceptions
|
82
|
-
false
|
83
|
-
end
|
23
|
+
def self.config_keys
|
24
|
+
[
|
25
|
+
:orders_table_name, :order_items_table_name, :carts_table_name, :cart_items_table_name,
|
26
|
+
:customers_table_name, :subscriptions_table_name, :products_table_name,
|
27
|
+
:layout, :mailer_class_name, :mailer,
|
28
|
+
:orders_collection_scope, :order_tax_rate_method,
|
29
|
+
:obfuscate_order_ids, :use_effective_qb_sync,
|
30
|
+
:billing_address, :shipping_address, :use_address_full_name,
|
31
|
+
:collect_note, :collect_note_required, :collect_note_message,
|
32
|
+
:terms_and_conditions, :terms_and_conditions_label, :minimum_charge,
|
33
|
+
|
34
|
+
# Features
|
35
|
+
:free_enabled, :mark_as_paid_enabled, :pretend_enabled, :pretend_message,
|
36
|
+
# Payment processors. false or Hash
|
37
|
+
:cheque, :moneris, :paypal, :phone, :refund, :stripe, :subscriptions, :trial
|
38
|
+
]
|
84
39
|
end
|
85
40
|
|
86
|
-
|
87
|
-
raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
|
88
|
-
end
|
41
|
+
include EffectiveGem
|
89
42
|
|
90
43
|
def self.permitted_params
|
91
|
-
[
|
44
|
+
@permitted_params ||= [
|
92
45
|
:cc, :note, :terms_and_conditions, :confirmed_checkout,
|
93
46
|
billing_address: EffectiveAddresses.permitted_params,
|
94
47
|
shipping_address: EffectiveAddresses.permitted_params,
|
@@ -169,6 +122,11 @@ module EffectiveOrders
|
|
169
122
|
[('cheque' if cheque?), ('phone' if phone?)].compact
|
170
123
|
end
|
171
124
|
|
125
|
+
def self.mailer_klass
|
126
|
+
name = mailer_class_name.presence || 'Effective::OrdersMailer'
|
127
|
+
name.safe_constantize || raise("unable to constantize mailer class. check config.mailer_class_name")
|
128
|
+
end
|
129
|
+
|
172
130
|
def self.can_skip_checkout_step1?
|
173
131
|
return false if require_billing_address
|
174
132
|
return false if require_shipping_address
|