effective_orders 6.4.4 → 6.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/admin/orders_controller.rb +1 -7
- data/app/controllers/effective/concerns/purchase.rb +4 -4
- data/app/controllers/effective/providers/free.rb +2 -1
- data/app/controllers/effective/providers/mark_as_paid.rb +2 -1
- data/app/controllers/effective/providers/moneris.rb +3 -2
- data/app/controllers/effective/providers/moneris_checkout.rb +5 -2
- data/app/controllers/effective/providers/paypal.rb +3 -2
- data/app/controllers/effective/providers/pretend.rb +2 -1
- data/app/controllers/effective/providers/stripe.rb +3 -2
- data/app/helpers/effective_orders_helper.rb +2 -1
- data/app/mailers/effective/orders_mailer.rb +5 -5
- data/app/models/effective/order.rb +54 -11
- data/app/views/admin/orders/_form_order.html.haml +12 -4
- data/app/views/effective/orders/_orders_table.html.haml +1 -1
- data/app/views/effective/orders/show.html.haml +1 -1
- data/config/effective_orders.rb +5 -0
- data/db/migrate/01_create_effective_orders.rb.erb +3 -0
- data/lib/effective_orders/version.rb +1 -1
- data/lib/effective_orders.rb +15 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 658dc93673ea1d94b4ef09a9ad65fc267a58d36c7560f8e70a12a8719ee1f917
|
4
|
+
data.tar.gz: 190fcc09c8cd4de5ff184c54bc5612a3ccba50f2c97ea6b579d9cf3ec6b32fd5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a75d33e8b848a0a64d1e73617cc45a57070b98bcdf93ebe872d63f2e3f1f1158d697b6fe8786195de74068479c1e7e999b47d0ef25fa1c1482b405c671b53c59
|
7
|
+
data.tar.gz: e13b5214ba7fe0da6e68c981c89a391aedf6e0fbfb0bf1365689f4cb885b9342cca7b32ab21a31d91d215f6ac81fb4b66fc7fe1337daedcf3ccfd38ac0bfc217
|
@@ -85,13 +85,7 @@ module Admin
|
|
85
85
|
flash[:danger] = 'Unable to send payment request'
|
86
86
|
end
|
87
87
|
|
88
|
-
|
89
|
-
redirect_back(fallback_location: effective_orders.admin_order_path(@order))
|
90
|
-
elsif request.referrer.present?
|
91
|
-
redirect_to :back
|
92
|
-
else
|
93
|
-
redirect_to effective_orders.admin_order_path(@order)
|
94
|
-
end
|
88
|
+
redirect_back(fallback_location: effective_orders.admin_order_path(@order))
|
95
89
|
end
|
96
90
|
|
97
91
|
def bulk_send_payment_request
|
@@ -5,10 +5,10 @@ module Effective
|
|
5
5
|
|
6
6
|
protected
|
7
7
|
|
8
|
-
def order_purchased(payment:, provider:, card: 'none', email: true, skip_buyer_validations: false, purchased_url: nil)
|
9
|
-
@order.purchase!(payment: payment, provider: provider, card: card, email: email, skip_buyer_validations: skip_buyer_validations)
|
8
|
+
def order_purchased(payment:, provider:, card: 'none', email: true, skip_buyer_validations: false, purchased_url: nil, current_user: nil)
|
9
|
+
@order.purchase!(payment: payment, provider: provider, card: card, email: email, skip_buyer_validations: skip_buyer_validations, current_user: current_user)
|
10
10
|
|
11
|
-
Effective::Cart.where(user:
|
11
|
+
Effective::Cart.where(user: current_user).destroy_all if current_user.present?
|
12
12
|
|
13
13
|
if flash[:success].blank?
|
14
14
|
if email && @order.send_order_receipt_to_buyer?
|
@@ -25,7 +25,7 @@ module Effective
|
|
25
25
|
def order_deferred(provider:, email: true, deferred_url: nil)
|
26
26
|
@order.defer!(provider: provider, email: email)
|
27
27
|
|
28
|
-
Effective::Cart.where(user: @order.user).destroy_all
|
28
|
+
Effective::Cart.where(user: @order.user).destroy_all if @order.user.present?
|
29
29
|
|
30
30
|
if flash[:success].blank?
|
31
31
|
if email
|
@@ -19,7 +19,8 @@ module Effective
|
|
19
19
|
card: mark_as_paid_params[:payment_card],
|
20
20
|
email: @order.send_mark_as_paid_email_to_buyer?,
|
21
21
|
skip_buyer_validations: true,
|
22
|
-
purchased_url: effective_orders.admin_order_path(@order)
|
22
|
+
purchased_url: effective_orders.admin_order_path(@order),
|
23
|
+
current_user: nil # Admin action, we don't want to assign current_user to the order
|
23
24
|
)
|
24
25
|
end
|
25
26
|
|
@@ -14,7 +14,8 @@ module Effective
|
|
14
14
|
|
15
15
|
@order ||= Effective::Order.find(params[:response_order_id])
|
16
16
|
|
17
|
-
|
17
|
+
# We do this even if we're not authorized
|
18
|
+
EffectiveResources.authorized?(self, :update, @order)
|
18
19
|
|
19
20
|
# Delete the Purchased and Declined Redirect URLs
|
20
21
|
purchased_url = params.delete(:rvar_purchased_url)
|
@@ -37,7 +38,7 @@ module Effective
|
|
37
38
|
return order_declined(payment: payment, provider: 'moneris', card: params[:card], declined_url: declined_url)
|
38
39
|
end
|
39
40
|
|
40
|
-
order_purchased(payment: payment, provider: 'moneris', card: params[:card], purchased_url: purchased_url)
|
41
|
+
order_purchased(payment: payment, provider: 'moneris', card: params[:card], purchased_url: purchased_url, current_user: current_user)
|
41
42
|
end
|
42
43
|
|
43
44
|
private
|
@@ -7,7 +7,9 @@ module Effective
|
|
7
7
|
raise('moneris_checkout provider is not available') unless EffectiveOrders.moneris_checkout?
|
8
8
|
|
9
9
|
@order = Order.find(params[:id])
|
10
|
-
|
10
|
+
|
11
|
+
# We do this even if we're not authorized.
|
12
|
+
EffectiveResources.authorized?(self, :update, @order)
|
11
13
|
|
12
14
|
payment = moneris_checkout_receipt_request(moneris_checkout_params[:ticket])
|
13
15
|
purchased = (1..49).include?(payment['response_code'].to_i) # Must be > 0 and < 50 to be valid. Sometimes we get the string 'null'
|
@@ -24,7 +26,8 @@ module Effective
|
|
24
26
|
payment: payment,
|
25
27
|
provider: 'moneris_checkout',
|
26
28
|
card: payment['card_type'],
|
27
|
-
purchased_url: moneris_checkout_params[:purchased_url]
|
29
|
+
purchased_url: moneris_checkout_params[:purchased_url],
|
30
|
+
current_user: current_user
|
28
31
|
)
|
29
32
|
end
|
30
33
|
|
@@ -14,13 +14,14 @@ module Effective
|
|
14
14
|
|
15
15
|
@order ||= Effective::Order.where(id: (params[:invoice].to_i rescue 0)).first
|
16
16
|
|
17
|
-
|
17
|
+
# We do this even if we're not authorized
|
18
|
+
EffectiveResources.authorized?(self, :update, @order)
|
18
19
|
|
19
20
|
if @order.present?
|
20
21
|
if @order.purchased?
|
21
22
|
order_purchased(payment: params, provider: 'paypal', card: params[:payment_type])
|
22
23
|
elsif (params[:payment_status] == 'Completed' && params[:custom] == EffectiveOrders.paypal[:secret])
|
23
|
-
order_purchased(payment: params, provider: 'paypal', card: params[:payment_type])
|
24
|
+
order_purchased(payment: params, provider: 'paypal', card: params[:payment_type], current_user: current_user)
|
24
25
|
else
|
25
26
|
order_declined(payment: params, provider: 'paypal', card: params[:payment_type])
|
26
27
|
end
|
@@ -7,7 +7,7 @@ module Effective
|
|
7
7
|
raise('stripe provider is not available') unless EffectiveOrders.stripe?
|
8
8
|
|
9
9
|
@order = Order.find(params[:id])
|
10
|
-
@customer = Effective::Customer.for_user(
|
10
|
+
@customer = Effective::Customer.for_user(current_user)
|
11
11
|
|
12
12
|
EffectiveResources.authorize!(self, :update, @order)
|
13
13
|
|
@@ -33,7 +33,8 @@ module Effective
|
|
33
33
|
payment: payment,
|
34
34
|
provider: 'stripe',
|
35
35
|
card: payment[:card],
|
36
|
-
purchased_url: stripe_params[:purchased_url]
|
36
|
+
purchased_url: stripe_params[:purchased_url],
|
37
|
+
current_user: current_user
|
37
38
|
)
|
38
39
|
end
|
39
40
|
|
@@ -83,7 +83,8 @@ module EffectiveOrdersHelper
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def render_checkout(order, namespace: nil, purchased_url: nil, declined_url: nil, deferred_url: nil)
|
86
|
-
raise '
|
86
|
+
raise 'expected an order' unless order.kind_of?(Effective::Order)
|
87
|
+
raise 'unable to checkout an order without a user or organization' if order && (order.user.blank? && order.organization.blank?)
|
87
88
|
|
88
89
|
locals = { order: order, purchased_url: purchased_url, declined_url: declined_url, deferred_url: deferred_url, namespace: namespace }
|
89
90
|
|
@@ -21,7 +21,7 @@ module Effective
|
|
21
21
|
subject = subject_for(__method__, "Order Receipt: ##{@order.to_param}", resource, opts)
|
22
22
|
headers = headers_for(resource, opts)
|
23
23
|
|
24
|
-
mail(to: @order.
|
24
|
+
mail(to: @order.emails, cc: @order.cc.presence, subject: subject, **headers)
|
25
25
|
end
|
26
26
|
|
27
27
|
# This is sent when an admin creates a new order or /admin/orders/new
|
@@ -34,7 +34,7 @@ module Effective
|
|
34
34
|
subject = subject_for(__method__, "Payment request - Order ##{@order.to_param}", resource, opts)
|
35
35
|
headers = headers_for(resource, opts)
|
36
36
|
|
37
|
-
mail(to: @order.
|
37
|
+
mail(to: @order.emails, cc: @order.cc.presence, subject: subject, **headers)
|
38
38
|
end
|
39
39
|
|
40
40
|
# This is sent when someone chooses to Pay by Cheque
|
@@ -45,7 +45,7 @@ module Effective
|
|
45
45
|
subject = subject_for(__method__, "Pending Order: ##{@order.to_param}", resource, opts)
|
46
46
|
headers = headers_for(resource, opts)
|
47
47
|
|
48
|
-
mail(to: @order.
|
48
|
+
mail(to: @order.emails, cc: @order.cc.presence, subject: subject, **headers)
|
49
49
|
end
|
50
50
|
|
51
51
|
# This is sent to admin when someone Accepts Refund
|
@@ -158,8 +158,8 @@ module Effective
|
|
158
158
|
|
159
159
|
to ||= EffectiveOrders.mailer_admin
|
160
160
|
from ||= EffectiveOrders.mailer_sender
|
161
|
-
subject ||= subject_for(__method__,"An error occurred with order: ##{@order.to_param}",
|
162
|
-
headers = headers_for(
|
161
|
+
subject ||= subject_for(__method__,"An error occurred with order: ##{@order.to_param}", @order, opts)
|
162
|
+
headers = headers_for(@order, opts)
|
163
163
|
|
164
164
|
mail(to: to, from: from, subject: subject, **headers) do |format|
|
165
165
|
format.html { render(template) }
|
@@ -31,9 +31,13 @@ module Effective
|
|
31
31
|
# If we want to use orders in a has_many way
|
32
32
|
belongs_to :parent, polymorphic: true, optional: true
|
33
33
|
|
34
|
-
belongs_to :user, polymorphic: true, validate: false # This is the buyer
|
34
|
+
belongs_to :user, polymorphic: true, optional: true, validate: false # This is the buyer of the order. We validate it below.
|
35
35
|
accepts_nested_attributes_for :user, allow_destroy: false, update_only: true
|
36
36
|
|
37
|
+
# When an organization is present, any user with role :billing in that organization can purchase this order
|
38
|
+
belongs_to :organization, polymorphic: true, optional: true, validate: false
|
39
|
+
accepts_nested_attributes_for :organization, allow_destroy: false, update_only: true
|
40
|
+
|
37
41
|
has_many :order_items, -> { order(:id) }, inverse_of: :order, dependent: :delete_all
|
38
42
|
accepts_nested_attributes_for :order_items, allow_destroy: true, reject_if: :all_blank
|
39
43
|
|
@@ -71,7 +75,7 @@ module Effective
|
|
71
75
|
|
72
76
|
serialize :payment, Hash
|
73
77
|
|
74
|
-
scope :deep, -> { includes(:addresses, :user, order_items: :purchasable) }
|
78
|
+
scope :deep, -> { includes(:addresses, :user, :organization, order_items: :purchasable) }
|
75
79
|
scope :sorted, -> { order(:id) }
|
76
80
|
|
77
81
|
scope :purchased, -> { where(state: EffectiveOrders::PURCHASED) }
|
@@ -98,22 +102,35 @@ module Effective
|
|
98
102
|
self.state = EffectiveOrders::CONFIRMED if pending? && confirmed_checkout
|
99
103
|
end
|
100
104
|
|
105
|
+
before_validation do
|
106
|
+
assign_attributes(user_type: nil) if user_type.present? && user_id.blank?
|
107
|
+
assign_attributes(organization_type: nil) if organization_type.present? && organization_id.blank?
|
108
|
+
end
|
109
|
+
|
101
110
|
with_options(unless: -> { done? }) do
|
102
|
-
before_validation {
|
111
|
+
before_validation { assign_organization_address }
|
103
112
|
before_validation { assign_user_address }
|
104
113
|
before_validation { assign_billing_name }
|
114
|
+
before_validation { assign_billing_email }
|
105
115
|
before_validation { assign_order_values }
|
106
116
|
before_validation { assign_order_charges }
|
107
117
|
end
|
108
118
|
|
109
119
|
# Order validations
|
110
|
-
validates :
|
111
|
-
validates :email, presence: true, email: true # email and cc validators are from effective_resources
|
120
|
+
validates :email, presence: true, email: true, if: -> { user_id.present? } # email and cc validators are from effective_resources
|
112
121
|
validates :cc, email_cc: true
|
113
122
|
|
114
123
|
validates :order_items, presence: { message: 'No items are present. Please add additional items.' }
|
115
124
|
validates :state, inclusion: { in: EffectiveOrders::STATES.keys }
|
116
125
|
|
126
|
+
validate do
|
127
|
+
if EffectiveOrders.organization_enabled?
|
128
|
+
errors.add(:base, "must have a User or #{EffectiveOrders.organization_class_name || 'Organization'}") if user_id.blank? && organization_id.blank?
|
129
|
+
else
|
130
|
+
errors.add(:base, "must have a User") if user_id.blank?
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
117
134
|
# Price validations
|
118
135
|
validates :subtotal, presence: true
|
119
136
|
validates :total, presence: true, if: -> { EffectiveOrders.minimum_charge.to_i > 0 }
|
@@ -164,7 +181,7 @@ module Effective
|
|
164
181
|
raise('cannot change subtotal of a purchased order') if changes[:subtotal].present?
|
165
182
|
|
166
183
|
raise('cannot change tax of a purchased order') if changes[:tax].present?
|
167
|
-
raise('cannot change tax of a purchased order') if changes[:tax_rate].present?
|
184
|
+
raise('cannot change tax rate of a purchased order') if changes[:tax_rate].present?
|
168
185
|
|
169
186
|
raise('cannot change surcharge of a purchased order') if changes[:surcharge].present?
|
170
187
|
raise('cannot change surcharge percent of a purchased order') if changes[:surcharge_percent].present?
|
@@ -573,7 +590,7 @@ module Effective
|
|
573
590
|
end
|
574
591
|
|
575
592
|
# Effective::Order.new(items: Product.first, user: User.first).purchase!(email: false)
|
576
|
-
def purchase!(payment: nil, provider: nil, card: nil, email: true, skip_buyer_validations: false, skip_quickbooks: false)
|
593
|
+
def purchase!(payment: nil, provider: nil, card: nil, email: true, skip_buyer_validations: false, skip_quickbooks: false, current_user: nil)
|
577
594
|
return true if purchased?
|
578
595
|
|
579
596
|
# Assign attributes
|
@@ -588,6 +605,10 @@ module Effective
|
|
588
605
|
payment_card: (card.presence || 'none')
|
589
606
|
)
|
590
607
|
|
608
|
+
if current_user&.email.present?
|
609
|
+
assign_attributes(email: current_user.email)
|
610
|
+
end
|
611
|
+
|
591
612
|
# Updates surcharge and total based on payment_provider
|
592
613
|
assign_order_charges()
|
593
614
|
|
@@ -677,9 +698,14 @@ module Effective
|
|
677
698
|
true
|
678
699
|
end
|
679
700
|
|
701
|
+
# These are all the emails we send all notifications to
|
702
|
+
def emails
|
703
|
+
([email] + [user.try(:email)] + Array(organization.try(:billing_emails))).map(&:presence).compact.uniq
|
704
|
+
end
|
705
|
+
|
680
706
|
# Doesn't control anything. Purely for the flash messaging
|
681
707
|
def emails_send_to
|
682
|
-
[
|
708
|
+
(emails + [cc.presence]).compact.uniq.to_sentence
|
683
709
|
end
|
684
710
|
|
685
711
|
def send_order_receipts!
|
@@ -775,12 +801,29 @@ module Effective
|
|
775
801
|
order_items.reject { |oi| oi.marked_for_destruction? }
|
776
802
|
end
|
777
803
|
|
804
|
+
# Organization first
|
778
805
|
def assign_billing_name
|
779
|
-
self.billing_name = billing_address.try(:full_name).presence || user.to_s.presence
|
806
|
+
self.billing_name = billing_address.try(:full_name).presence || organization.to_s.presence || user.to_s.presence
|
807
|
+
end
|
808
|
+
|
809
|
+
# User first
|
810
|
+
def assign_billing_email
|
811
|
+
email = emails.first
|
812
|
+
assign_attributes(email: email) if email.present?
|
780
813
|
end
|
781
814
|
|
782
|
-
def
|
783
|
-
|
815
|
+
def assign_organization_address
|
816
|
+
return unless organization.present?
|
817
|
+
|
818
|
+
if EffectiveOrders.billing_address && billing_address.blank? && organization.try(:billing_address).present?
|
819
|
+
self.billing_address = organization.billing_address
|
820
|
+
self.billing_address.full_name ||= organization.to_s.presence
|
821
|
+
end
|
822
|
+
|
823
|
+
if EffectiveOrders.shipping_address && shipping_address.blank? && organization.try(:shipping_address).present?
|
824
|
+
self.shipping_address = organization.shipping_address
|
825
|
+
self.shipping_address.full_name ||= organization.to_s.presence
|
826
|
+
end
|
784
827
|
end
|
785
828
|
|
786
829
|
def assign_user_address
|
@@ -1,10 +1,18 @@
|
|
1
1
|
= effective_form_with(model: [:admin, order], engine: true) do |f|
|
2
|
-
|
2
|
+
-# User
|
3
|
+
- klass = (f.object.user || current_user).class
|
4
|
+
- ajax_url = (@select2_users_ajax_path || effective_resources.users_admin_select2_ajax_index_path) unless Rails.env.test?
|
3
5
|
|
4
|
-
|
6
|
+
= f.hidden_field :user_type, value: klass.name
|
7
|
+
= f.select :user_id, klass.all, ajax_url: ajax_url
|
5
8
|
|
6
|
-
|
7
|
-
|
9
|
+
-# Organization
|
10
|
+
- if EffectiveOrders.organization_enabled?
|
11
|
+
- klass = (f.object.organization || EffectiveOrders.Organization.new).class
|
12
|
+
- ajax_url = (@select2_organizations_ajax_path || effective_resources.organizations_admin_select2_ajax_index_path) unless Rails.env.test?
|
13
|
+
|
14
|
+
= f.hidden_field :organization_type, value: klass.name
|
15
|
+
= f.select :organization_id, klass.all, ajax_url: ajax_url
|
8
16
|
|
9
17
|
= f.email_cc_field :cc, hint: "Cc the above on any emailed receipts or payment requests."
|
10
18
|
|
@@ -15,7 +15,7 @@
|
|
15
15
|
= (order.purchased_at || order.created_at).strftime("%F %H:%M")
|
16
16
|
%td= order_summary(order)
|
17
17
|
%td
|
18
|
-
- if order.pending?
|
18
|
+
- if order.pending? || order.confirmed?
|
19
19
|
= link_to_checkout(order: order)
|
20
20
|
- else
|
21
21
|
= link_to 'View', effective_orders.order_path(order)
|
data/config/effective_orders.rb
CHANGED
@@ -23,6 +23,11 @@ EffectiveOrders.setup do |config|
|
|
23
23
|
# Use effective_obfuscation gem to change order.id into a seemingly random 10-digit number
|
24
24
|
config.obfuscate_order_ids = false
|
25
25
|
|
26
|
+
# Allow orders to be purchased by organization members
|
27
|
+
# This will fallback to EffectiveMemberships.Organization if you have that gem installed
|
28
|
+
# config.organization_enabled = false
|
29
|
+
# config.organization_class_name = 'Example::Organization'
|
30
|
+
|
26
31
|
# Synchronize with Quickbooks
|
27
32
|
config.use_effective_qb_sync = false
|
28
33
|
config.use_effective_qb_online = false
|
data/lib/effective_orders.rb
CHANGED
@@ -41,6 +41,9 @@ module EffectiveOrders
|
|
41
41
|
:terms_and_conditions, :terms_and_conditions_label, :minimum_charge,
|
42
42
|
:credit_card_surcharge_percent, :credit_card_surcharge_qb_item_name,
|
43
43
|
|
44
|
+
# Organization mode
|
45
|
+
:organization_enabled, :organization_class_name,
|
46
|
+
|
44
47
|
# Mailer
|
45
48
|
:mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject,
|
46
49
|
|
@@ -70,6 +73,18 @@ module EffectiveOrders
|
|
70
73
|
]
|
71
74
|
end
|
72
75
|
|
76
|
+
def self.organization_enabled?
|
77
|
+
organization_enabled == true
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.Organization
|
81
|
+
klass = organization_class_name&.constantize
|
82
|
+
klass ||= (EffectiveMemberships.Organization if defined?(EffectiveMemberships))
|
83
|
+
raise('Please set the effective_orders config.organization_class_name') if klass.blank?
|
84
|
+
|
85
|
+
klass
|
86
|
+
end
|
87
|
+
|
73
88
|
def self.cheque?
|
74
89
|
cheque.kind_of?(Hash)
|
75
90
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_orders
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-06-
|
11
|
+
date: 2023-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|