effective_orders 6.4.4 → 6.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/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
|