effective_orders 6.11.1 → 6.12.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/assets/javascripts/effective_orders/providers/deluxe_delayed.js +32 -0
- data/app/assets/stylesheets/effective_orders/_order.scss +4 -0
- data/app/controllers/effective/concerns/purchase.rb +17 -0
- data/app/controllers/effective/orders_controller.rb +2 -0
- data/app/controllers/effective/providers/deluxe.rb +13 -25
- data/app/controllers/effective/providers/deluxe_delayed.rb +48 -0
- data/app/controllers/effective/providers/deluxe_delayed_purchase.rb +50 -0
- data/app/datatables/admin/effective_orders_datatable.rb +8 -0
- data/app/datatables/effective_orders_datatable.rb +6 -0
- data/app/helpers/effective_deluxe_delayed_helper.rb +15 -0
- data/app/helpers/effective_orders_helper.rb +2 -0
- data/app/models/effective/deluxe_api.rb +61 -0
- data/app/models/effective/order.rb +126 -43
- data/app/views/effective/orders/_checkout_step2.html.haml +7 -0
- data/app/views/effective/orders/_datatable_actions.html.haml +1 -1
- data/app/views/effective/orders/_order_deferred.html.haml +5 -1
- data/app/views/effective/orders/delayed/_form.html.haml +25 -0
- data/app/views/effective/orders/delayed/_form_purchase.html.haml +30 -0
- data/app/views/effective/orders/deluxe_delayed/_css.html.haml +12 -0
- data/app/views/effective/orders/deluxe_delayed/_element.html.haml +9 -0
- data/app/views/effective/orders/deluxe_delayed/_form.html.haml +10 -0
- data/app/views/effective/orders/deluxe_delayed/_form_purchase.html.haml +18 -0
- data/app/views/effective/orders/mark_as_paid/_form.html.haml +2 -0
- data/config/effective_orders.rb +9 -0
- data/config/routes.rb +4 -1
- data/db/migrate/101_create_effective_orders.rb +6 -0
- data/lib/effective_orders/version.rb +1 -1
- data/lib/effective_orders.rb +14 -2
- data/lib/tasks/effective_orders_tasks.rake +6 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4fac0b561dd727abc645294816cf623fb2c9bd345645b19272e510d064b0c3e8
|
4
|
+
data.tar.gz: 63728a03677c11b462de51955b4add5434fcbdd0cd7e015013ab81f1672d3da0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 78754fcf99effaba035ec15bb3ae31f322b84991c9b3a40d80c995493016589d5bdfd28bab4655a5a4f8a0a01c99e5c16a01c95bc275e04ecc33e72bf499b590
|
7
|
+
data.tar.gz: 5d2ed250eca616729e602f5f5b3374ad16b71f00e8701ac70e5545b3c370900a36d58ab507835f611aab9caa5b3cf114c40ebb4f1bad4e45d6efe61b2bb727c3
|
@@ -0,0 +1,32 @@
|
|
1
|
+
// https://developer.deluxe.com/s/article-hosted-payment-form
|
2
|
+
|
3
|
+
function initializeDeluxeDelayed() {
|
4
|
+
let $deluxe = $('form[data-deluxe-delayed-checkout]:not(.initialized)');
|
5
|
+
if($deluxe.length == 0) return;
|
6
|
+
|
7
|
+
let options = $deluxe.data('deluxe-delayed-checkout');
|
8
|
+
|
9
|
+
HostedForm.init(options, {
|
10
|
+
onFailure: (data) => { $('#deluxe-delayed-checkout-errors').text(JSON.stringify(data)); },
|
11
|
+
onInvalid: (data) => { $('#deluxe-delayed-checkout-errors').text(JSON.stringify(data)); },
|
12
|
+
|
13
|
+
onSuccess: (data) => {
|
14
|
+
let value = btoa(JSON.stringify(data)); // A base64 encoded JSON object
|
15
|
+
|
16
|
+
$form = $('form[data-deluxe-delayed-checkout]').first();
|
17
|
+
$form.find('input[name="deluxe_delayed[payment_intent]"]').val(value);
|
18
|
+
$form.submit();
|
19
|
+
|
20
|
+
$('#deluxeDelayedCheckout').fadeOut('slow');
|
21
|
+
$('#deluxe-delayed-checkout-loading').text('Thank you! Saving card information. Please wait...');
|
22
|
+
},
|
23
|
+
}).then((instance) => {
|
24
|
+
$('#deluxe-delayed-checkout-loading').text('');
|
25
|
+
instance.renderHpf();
|
26
|
+
});
|
27
|
+
|
28
|
+
$deluxe.addClass('initialized');
|
29
|
+
};
|
30
|
+
|
31
|
+
$(document).ready(function() { initializeDeluxeDelayed() });
|
32
|
+
$(document).on('turbolinks:load', function() { initializeDeluxeDelayed() });
|
@@ -50,6 +50,23 @@ module Effective
|
|
50
50
|
redirect_to deferred_url.gsub(':id', @order.to_param.to_s)
|
51
51
|
end
|
52
52
|
|
53
|
+
def order_delayed(payment:, payment_intent:, provider:, card: 'none', deferred_url: nil, email: false)
|
54
|
+
@order.delay!(payment: payment, payment_intent: payment_intent, provider: provider, card: card, email: email)
|
55
|
+
|
56
|
+
Effective::Cart.where(user: current_user).destroy_all if current_user.present?
|
57
|
+
|
58
|
+
if flash[:success].blank?
|
59
|
+
if email
|
60
|
+
flash[:success] = "Delayed payment created! An email has been sent to #{@order.emails_send_to}"
|
61
|
+
else
|
62
|
+
flash[:success] = "Delayed payment created!"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
deferred_url = effective_orders.deferred_order_path(':id') if deferred_url.blank?
|
67
|
+
redirect_to deferred_url.gsub(':id', @order.to_param.to_s)
|
68
|
+
end
|
69
|
+
|
53
70
|
def order_declined(payment:, provider:, card: 'none', declined_url: nil)
|
54
71
|
@order.decline!(payment: payment, provider: provider, card: card)
|
55
72
|
|
@@ -11,41 +11,33 @@ module Effective
|
|
11
11
|
EffectiveResources.authorize!(self, :update, @order)
|
12
12
|
|
13
13
|
## Process Payment Intent
|
14
|
+
api = Effective::DeluxeApi.new
|
14
15
|
|
15
16
|
# The payment_intent is set by the Deluxe HostedPaymentForm
|
16
|
-
|
17
|
+
payment_intent_payload = deluxe_params[:payment_intent]
|
17
18
|
|
18
|
-
if
|
19
|
+
if payment_intent_payload.blank?
|
19
20
|
flash[:danger] = 'Unable to process deluxe order without payment. please try again.'
|
20
|
-
return order_not_processed(declined_url:
|
21
|
+
return order_not_processed(declined_url: deluxe_params[:declined_url])
|
21
22
|
end
|
22
23
|
|
23
24
|
# Decode the base64 encoded JSON object into a Hash
|
24
|
-
payment_intent =
|
25
|
-
|
26
|
-
raise('expected a token payment') unless payment_intent['type'] == 'Token'
|
25
|
+
payment_intent = api.decode_payment_intent_payload(payment_intent_payload)
|
26
|
+
card_info = api.card_info(payment_intent)
|
27
27
|
|
28
|
-
valid = payment_intent['status'] == 'success'
|
28
|
+
valid = (payment_intent['status'] == 'success')
|
29
29
|
|
30
30
|
if valid == false
|
31
|
-
card_info
|
32
|
-
return order_declined(payment: card_info, provider: 'deluxe', card: card_info['card'], declined_url: declined_url)
|
31
|
+
return order_declined(payment: card_info, provider: 'deluxe', card: card_info['card'], declined_url: deluxe_params[:declined_url])
|
33
32
|
end
|
34
33
|
|
35
|
-
##
|
36
|
-
|
37
|
-
valid = [0].include?(authorization['responseCode'])
|
34
|
+
## Purchase Order right now
|
35
|
+
purchased = api.purchase!(@order, payment_intent)
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
return order_declined(payment: authorization, provider: 'deluxe', card: authorization['card'], declined_url: deluxe_params[:declined_url])
|
42
|
-
end
|
43
|
-
|
44
|
-
## Complete Payment
|
45
|
-
payment = deluxe_api.complete_payment(@order, authorization)
|
46
|
-
valid = [0].include?(payment['responseCode'])
|
37
|
+
payment = api.payment
|
38
|
+
raise('expected a payment Hash') unless payment.kind_of?(Hash)
|
47
39
|
|
48
|
-
if
|
40
|
+
if purchased == false
|
49
41
|
flash[:danger] = "Payment was unsuccessful. The credit card payment failed with message: #{Array(payment['responseMessage']).to_sentence.presence || 'none'}. Please try again."
|
50
42
|
return order_declined(payment: payment, provider: 'deluxe', card: payment['card'], declined_url: deluxe_params[:declined_url])
|
51
43
|
end
|
@@ -66,10 +58,6 @@ module Effective
|
|
66
58
|
params.require(:deluxe).permit(:payment_intent, :purchased_url, :declined_url)
|
67
59
|
end
|
68
60
|
|
69
|
-
def deluxe_api
|
70
|
-
@deluxe_api ||= Effective::DeluxeApi.new
|
71
|
-
end
|
72
|
-
|
73
61
|
end
|
74
62
|
end
|
75
63
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Effective
|
2
|
+
module Providers
|
3
|
+
module DeluxeDelayed
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def deluxe_delayed
|
7
|
+
raise('deluxe provider is not available') unless EffectiveOrders.deluxe?
|
8
|
+
raise('deluxe_delayed provider is not available') unless EffectiveOrders.deluxe_delayed?
|
9
|
+
|
10
|
+
@order = Effective::Order.deep.find(params[:id])
|
11
|
+
|
12
|
+
EffectiveResources.authorize!(self, :update, @order)
|
13
|
+
|
14
|
+
## Process Payment Intent
|
15
|
+
api = Effective::DeluxeApi.new
|
16
|
+
|
17
|
+
# The payment_intent is set by the Deluxe HostedPaymentForm
|
18
|
+
payment_intent_payload = deluxe_delayed_params[:payment_intent]
|
19
|
+
|
20
|
+
if payment_intent_payload.blank?
|
21
|
+
flash[:danger] = 'Unable to process deluxe delayed order without payment intent. please try again.'
|
22
|
+
return order_not_processed(declined_url: deluxe_delayed_params[:declined_url])
|
23
|
+
end
|
24
|
+
|
25
|
+
# Decode the base64 encoded JSON object into a Hash
|
26
|
+
payment_intent = api.decode_payment_intent_payload(payment_intent_payload)
|
27
|
+
card_info = api.card_info(payment_intent)
|
28
|
+
|
29
|
+
valid = payment_intent['status'] == 'success'
|
30
|
+
|
31
|
+
if valid == false
|
32
|
+
return order_declined(payment: card_info, provider: 'deluxe_delayed', card: card_info['card'], declined_url: deluxe_delayed_params[:declined_url])
|
33
|
+
end
|
34
|
+
|
35
|
+
flash[:success] = EffectiveOrders.deluxe_delayed[:success]
|
36
|
+
|
37
|
+
order_delayed(payment: card_info, payment_intent: payment_intent_payload, provider: 'deluxe_delayed', card: card_info['card'], deferred_url: deluxe_delayed_params[:deferred_url])
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def deluxe_delayed_params
|
43
|
+
params.require(:deluxe_delayed).permit(:payment_intent, :deferred_url, :declined_url)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Effective
|
2
|
+
module Providers
|
3
|
+
module DeluxeDelayedPurchase
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
# Admin action
|
7
|
+
def deluxe_delayed_purchase
|
8
|
+
raise('deluxe_delayed_purchase provider is not available') unless EffectiveOrders.deluxe_delayed?
|
9
|
+
|
10
|
+
@order ||= Order.deep.find(params[:id])
|
11
|
+
|
12
|
+
EffectiveResources.authorize!(self, :update, @order)
|
13
|
+
EffectiveResources.authorize!(self, :admin, :effective_orders)
|
14
|
+
|
15
|
+
raise('expected a delayed? and deferred? order') unless @order.delayed? && @order.deferred?
|
16
|
+
|
17
|
+
## Purchase Order right now
|
18
|
+
api = Effective::DeluxeApi.new
|
19
|
+
|
20
|
+
purchased = api.purchase!(@order, @order.delayed_payment_intent)
|
21
|
+
payment = api.payment
|
22
|
+
|
23
|
+
if purchased == false
|
24
|
+
flash[:danger] = "Payment was unsuccessful. The credit card payment failed with message: #{Array(payment['responseMessage']).to_sentence.presence || 'none'}. Please try again."
|
25
|
+
return order_declined(payment: payment, provider: 'deluxe_delayed', card: payment['card'], declined_url: deluxe_delayed_purchase_params[:declined_url])
|
26
|
+
end
|
27
|
+
|
28
|
+
@order.assign_attributes(deluxe_delayed_purchase_params.except(:purchased_url, :declined_url, :id))
|
29
|
+
|
30
|
+
order_purchased(
|
31
|
+
payment: payment,
|
32
|
+
provider: 'deluxe_delayed',
|
33
|
+
card: payment['card'],
|
34
|
+
email: @order.send_mark_as_paid_email_to_buyer?,
|
35
|
+
skip_buyer_validations: true,
|
36
|
+
purchased_url: effective_orders.admin_order_path(@order),
|
37
|
+
current_user: nil # Admin action, we don't want to assign current_user to the order
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def deluxe_delayed_purchase_params
|
42
|
+
params.require(:effective_order).permit(
|
43
|
+
:id, :note_to_buyer, :note_internal, :send_mark_as_paid_email_to_buyer,
|
44
|
+
:purchased_url, :declined_url
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -100,6 +100,14 @@ module Admin
|
|
100
100
|
|
101
101
|
col :total, as: :price
|
102
102
|
|
103
|
+
if EffectiveOrders.delayed?
|
104
|
+
col :delayed_payment, visible: false
|
105
|
+
col :delayed_payment_date
|
106
|
+
col :delayed_payment_intent, visible: false
|
107
|
+
col :delayed_payment_purchase_ran_at, visible: false
|
108
|
+
col :delayed_payment_purchase_result, visible: false
|
109
|
+
end
|
110
|
+
|
103
111
|
if EffectiveOrders.collect_note
|
104
112
|
col :note, visible: false
|
105
113
|
end
|
@@ -60,6 +60,12 @@ class EffectiveOrdersDatatable < Effective::Datatable
|
|
60
60
|
col :surcharge, as: :price, visible: false
|
61
61
|
col(:surcharge_percent, visible: false) { |order| rate_to_percentage(order.surcharge_percent) }
|
62
62
|
|
63
|
+
if EffectiveOrders.delayed?
|
64
|
+
col :delayed_payment
|
65
|
+
col :delayed_payment_date
|
66
|
+
col :delayed_payment_intent
|
67
|
+
end
|
68
|
+
|
63
69
|
col :total, as: :price
|
64
70
|
|
65
71
|
if EffectiveOrders.collect_note
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module EffectiveDeluxeDelayedHelper
|
2
|
+
|
3
|
+
# https://developer.deluxe.com/s/article-hosted-payment-form
|
4
|
+
def deluxe_delayed_hosted_payment_form_options(order)
|
5
|
+
{
|
6
|
+
xtoken: EffectiveOrders.deluxe.fetch(:access_token),
|
7
|
+
containerId: "deluxeDelayedCheckout",
|
8
|
+
xcssid: "deluxeDelayedCheckoutCss",
|
9
|
+
xrtype: "Generate Token",
|
10
|
+
xpm: "1", # 0 = CC & ACH, 1 = CC, 2 = ACH
|
11
|
+
xautoprompt: false,
|
12
|
+
xbtntext: order_checkout_label(:deluxe_delayed)
|
13
|
+
}
|
14
|
+
end
|
15
|
+
end
|
@@ -13,6 +13,8 @@ module Effective
|
|
13
13
|
attr_accessor :access_token
|
14
14
|
attr_accessor :currency
|
15
15
|
|
16
|
+
attr_accessor :purchase_response
|
17
|
+
|
16
18
|
def initialize(environment: nil, client_id: nil, client_secret: nil, access_token: nil, currency: nil)
|
17
19
|
self.environment = environment || EffectiveOrders.deluxe.fetch(:environment)
|
18
20
|
self.client_id = client_id || EffectiveOrders.deluxe.fetch(:client_id)
|
@@ -21,11 +23,58 @@ module Effective
|
|
21
23
|
self.currency = currency || EffectiveOrders.deluxe.fetch(:currency)
|
22
24
|
end
|
23
25
|
|
26
|
+
def payment
|
27
|
+
raise('expected purchase response to be present') unless purchase_response.kind_of?(Hash)
|
28
|
+
purchase_response
|
29
|
+
end
|
30
|
+
|
31
|
+
# This calls Authorize Payment and Complete Payment
|
32
|
+
# Returns true if all good.
|
33
|
+
# Returns false if there was an error.
|
34
|
+
# Always sets the @purchase_response which is api.payment
|
35
|
+
def purchase!(order, payment_intent)
|
36
|
+
raise('expected a deluxe_delayed payment provider') unless order.payment_provider == 'deluxe_delayed'
|
37
|
+
|
38
|
+
payment_intent = decode_payment_intent_payload(payment_intent) if payment_intent.kind_of?(String)
|
39
|
+
raise('expected payment_intent to be a Hash') unless payment_intent.kind_of?(Hash)
|
40
|
+
raise('expected a token payment') unless payment_intent['type'] == 'Token'
|
41
|
+
|
42
|
+
# Start a purchase. Which is an Authorization and a Completion
|
43
|
+
self.purchase_response = nil
|
44
|
+
|
45
|
+
# Process Authorization
|
46
|
+
authorization = authorize_payment(order, payment_intent)
|
47
|
+
self.purchase_response = authorization
|
48
|
+
|
49
|
+
valid = [0].include?(authorization['responseCode'])
|
50
|
+
return false unless valid
|
51
|
+
|
52
|
+
## Complete Payment
|
53
|
+
payment = complete_payment(order, authorization)
|
54
|
+
self.purchase_response = payment
|
55
|
+
|
56
|
+
valid = [0].include?(payment['responseCode'])
|
57
|
+
return false unless valid
|
58
|
+
|
59
|
+
# Valid purchase. This is authorized and completed.
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
24
63
|
# Health Check
|
25
64
|
def health_check
|
26
65
|
get('/')
|
27
66
|
end
|
28
67
|
|
68
|
+
def healthy?
|
69
|
+
response = health_check()
|
70
|
+
|
71
|
+
return false unless response.kind_of?(Hash)
|
72
|
+
return false unless response['timestamp'].to_s.start_with?(Time.zone.now.strftime('%Y-%m-%d'))
|
73
|
+
return false unless response['environment'].present?
|
74
|
+
|
75
|
+
true
|
76
|
+
end
|
77
|
+
|
29
78
|
# Authorize Payment
|
30
79
|
def authorize_payment(order, payment_intent)
|
31
80
|
response = post('/payments/authorize', params: authorize_payment_params(order, payment_intent))
|
@@ -191,6 +240,18 @@ module Effective
|
|
191
240
|
{ 'active_card' => active_card, 'card' => card, 'expDate' => date, 'cvv' => cvv }.compact
|
192
241
|
end
|
193
242
|
|
243
|
+
# Decode the base64 encoded JSON object into a Hash
|
244
|
+
def decode_payment_intent_payload(payload)
|
245
|
+
raise('expected a string') unless payload.kind_of?(String)
|
246
|
+
|
247
|
+
payment_intent = (JSON.parse(Base64.decode64(payload)) rescue nil)
|
248
|
+
|
249
|
+
raise('expected payment_intent to be a Hash') unless payment_intent.kind_of?(Hash)
|
250
|
+
raise('expected a token payment') unless payment_intent['type'] == 'Token'
|
251
|
+
|
252
|
+
payment_intent
|
253
|
+
end
|
254
|
+
|
194
255
|
private
|
195
256
|
|
196
257
|
def headers
|
@@ -15,7 +15,7 @@ module Effective
|
|
15
15
|
acts_as_statused(
|
16
16
|
:pending, # New orders are created in a pending state
|
17
17
|
:confirmed, # Once the order has passed checkout step 1
|
18
|
-
:deferred, # Deferred providers. cheque, etransfer or
|
18
|
+
:deferred, # Deferred providers. cheque, etransfer, phone or deluxe_delayed was selected.
|
19
19
|
:purchased, # Purchased by provider
|
20
20
|
:declined, # Declined by provider
|
21
21
|
:voided, # Voided by admin
|
@@ -94,6 +94,21 @@ module Effective
|
|
94
94
|
|
95
95
|
total :integer # Subtotal + Tax + Surcharge + Surcharge Tax
|
96
96
|
|
97
|
+
# For use with the Deluxe Delayed Payment feature
|
98
|
+
|
99
|
+
# When an order is created. These two attributes can be set to create a delayed? order
|
100
|
+
delayed_payment :boolean
|
101
|
+
delayed_payment_date :date
|
102
|
+
|
103
|
+
# When the order goes to checkout we require the delayed_payment_intent
|
104
|
+
# This stores the user's card information in a secure way
|
105
|
+
# This is required for the order to become deferred?
|
106
|
+
delayed_payment_intent :text
|
107
|
+
|
108
|
+
# Set by the rake task that runs 1/day and processes any delayed orders before or on that day
|
109
|
+
delayed_payment_purchase_ran_at :datetime
|
110
|
+
delayed_payment_purchase_result :text
|
111
|
+
|
97
112
|
timestamps
|
98
113
|
end
|
99
114
|
|
@@ -135,6 +150,16 @@ module Effective
|
|
135
150
|
scope :refunds, -> { purchased.where('total < ?', 0) }
|
136
151
|
scope :pending_refunds, -> { not_purchased.where('total < ?', 0) }
|
137
152
|
|
153
|
+
scope :delayed, -> { where(delayed_payment: true).where.not(delayed_payment_date: nil) }
|
154
|
+
scope :delayed_payment_date_past, -> { delayed.where(arel_table[:delayed_payment_date].lteq(Time.zone.today)) }
|
155
|
+
scope :delayed_payment_date_upcoming, -> { delayed.where(arel_table[:delayed_payment_date].gt(Time.zone.today)) }
|
156
|
+
|
157
|
+
# Used by the rake effective_orders:purchase_delayed_orders task
|
158
|
+
scope :delayed_ready_to_purchase, -> {
|
159
|
+
delayed.deferred.delayed_payment_date_past.where(delayed_payment_purchase_ran_at: nil)
|
160
|
+
}
|
161
|
+
|
162
|
+
|
138
163
|
# effective_reports
|
139
164
|
def reportable_scopes
|
140
165
|
{ purchased: nil, not_purchased: nil, deferred: nil, refunds: nil, pending_refunds: nil }
|
@@ -165,6 +190,11 @@ module Effective
|
|
165
190
|
|
166
191
|
validates :order_items, presence: { message: 'No items are present. Please add additional items.' }
|
167
192
|
|
193
|
+
# Delayed Payment Validations
|
194
|
+
validates :delayed_payment_date, presence: true, if: -> { delayed_payment? }
|
195
|
+
validates :delayed_payment_date, absence: true, unless: -> { delayed_payment? }
|
196
|
+
validates :delayed_payment_intent, presence: { message: 'please provide your card information' }, if: -> { delayed? && deferred? }
|
197
|
+
|
168
198
|
validate do
|
169
199
|
if EffectiveOrders.organization_enabled?
|
170
200
|
errors.add(:base, "must have a User or #{EffectiveOrders.organization_class_name || 'Organization'}") if user_id.blank? && organization_id.blank?
|
@@ -392,46 +422,12 @@ module Effective
|
|
392
422
|
purchased? ? 'Total Paid' : 'Total Due'
|
393
423
|
end
|
394
424
|
|
395
|
-
# Visa - 1234
|
396
425
|
def payment_method
|
397
|
-
|
398
|
-
|
399
|
-
provider = payment_provider if ['cheque', 'etransfer', 'phone', 'credit card'].include?(payment_provider)
|
400
|
-
|
401
|
-
# Normalize payment card
|
402
|
-
card = case payment_card.to_s.downcase.gsub(' ', '').strip
|
403
|
-
when '' then nil
|
404
|
-
when 'v', 'visa' then 'Visa'
|
405
|
-
when 'm', 'mc', 'master', 'mastercard' then 'MasterCard'
|
406
|
-
when 'a', 'ax', 'american', 'americanexpress' then 'American Express'
|
407
|
-
when 'd', 'discover' then 'Discover'
|
408
|
-
else payment_card.to_s
|
409
|
-
end
|
410
|
-
|
411
|
-
# Try again
|
412
|
-
if card == 'none' && payment['card_type'].present?
|
413
|
-
card = case payment['card_type'].to_s.downcase.gsub(' ', '').strip
|
414
|
-
when '' then nil
|
415
|
-
when 'v', 'visa' then 'Visa'
|
416
|
-
when 'm', 'mc', 'master', 'mastercard' then 'MasterCard'
|
417
|
-
when 'a', 'ax', 'american', 'americanexpress' then 'American Express'
|
418
|
-
when 'd', 'discover' then 'Discover'
|
419
|
-
else payment_card.to_s
|
420
|
-
end
|
421
|
-
end
|
422
|
-
|
423
|
-
last4 = if payment[:active_card] && payment[:active_card].include?('**** **** ****')
|
424
|
-
payment[:active_card][15,4]
|
425
|
-
end
|
426
|
-
|
427
|
-
last4 ||= if payment['active_card'] && payment['active_card'].include?('**** **** ****')
|
428
|
-
payment['active_card'][15,4]
|
429
|
-
end
|
430
|
-
|
431
|
-
# stripe, moneris, moneris_checkout
|
432
|
-
last4 ||= (payment['f4l4'] || payment['first6last4']).to_s.last(4)
|
426
|
+
payment_method_value if purchased?
|
427
|
+
end
|
433
428
|
|
434
|
-
|
429
|
+
def delayed_payment_method
|
430
|
+
payment_method_value if delayed?
|
435
431
|
end
|
436
432
|
|
437
433
|
def duplicate
|
@@ -538,6 +534,39 @@ module Effective
|
|
538
534
|
def refund?
|
539
535
|
total.to_i < 0
|
540
536
|
end
|
537
|
+
|
538
|
+
# A new order is created.
|
539
|
+
# If the delayed_payment and delayed_payment date are set, it's a delayed order
|
540
|
+
# A delayed order is one in which we have to capture a payment intent for the amount of the order.
|
541
|
+
# Once it's delayed and deferred we can purchase it at anytime.
|
542
|
+
def delayed?
|
543
|
+
delayed_payment? && delayed_payment_date.present?
|
544
|
+
end
|
545
|
+
|
546
|
+
def delayed_ready_to_purchase?
|
547
|
+
return false unless delayed?
|
548
|
+
return false unless deferred?
|
549
|
+
return false unless delayed_payment_intent.present?
|
550
|
+
return false if delayed_payment_date_future?
|
551
|
+
return false if delayed_payment_purchase_ran_at.present? # We ran before and probably failed
|
552
|
+
|
553
|
+
true
|
554
|
+
end
|
555
|
+
|
556
|
+
def delayed_payment_date_future?
|
557
|
+
return false unless delayed?
|
558
|
+
delayed_payment_date > Time.zone.now.to_date
|
559
|
+
end
|
560
|
+
|
561
|
+
def delayed_payment_date_today?
|
562
|
+
return false unless delayed?
|
563
|
+
delayed_payment_date == Time.zone.now.to_date
|
564
|
+
end
|
565
|
+
|
566
|
+
def delayed_payment_date_past?
|
567
|
+
return false unless delayed?
|
568
|
+
delayed_payment_date < Time.zone.now.to_date
|
569
|
+
end
|
541
570
|
|
542
571
|
def pending_refund?
|
543
572
|
return false if EffectiveOrders.buyer_purchases_refund?
|
@@ -696,6 +725,23 @@ module Effective
|
|
696
725
|
sync_quickbooks!(skip: true)
|
697
726
|
end
|
698
727
|
|
728
|
+
# This was submitted via the deluxe_delayed provider checkout
|
729
|
+
# This is a special case of a deferred provider. We require the payment_intent and payment info
|
730
|
+
def delay!(payment:, payment_intent:, provider:, card:, email: false, validate: true)
|
731
|
+
raise('expected payment intent to be a String') unless payment_intent.kind_of?(String)
|
732
|
+
raise('expected a delayed payment provider') unless EffectiveOrders.delayed_providers.include?(provider)
|
733
|
+
raise('expected a delayed payment order with a delayed_payment_date') unless delayed_payment? && delayed_payment_date.present?
|
734
|
+
|
735
|
+
assign_attributes(
|
736
|
+
delayed_payment_intent: payment_intent,
|
737
|
+
|
738
|
+
payment: payment_to_h(payment),
|
739
|
+
payment_card: (card.presence || 'none')
|
740
|
+
)
|
741
|
+
|
742
|
+
defer!(provider: provider, email: email, validate: validate)
|
743
|
+
end
|
744
|
+
|
699
745
|
def defer!(provider: 'none', email: true, validate: true)
|
700
746
|
raise('order already purchased') if purchased?
|
701
747
|
|
@@ -725,9 +771,7 @@ module Effective
|
|
725
771
|
end
|
726
772
|
rescue ActiveRecord::RecordInvalid => e
|
727
773
|
self.status = status_was
|
728
|
-
|
729
774
|
error = e.message
|
730
|
-
raise ::ActiveRecord::Rollback
|
731
775
|
end
|
732
776
|
|
733
777
|
raise "Failed to defer order: #{error || errors.full_messages.to_sentence}" unless error.nil?
|
@@ -766,9 +810,7 @@ module Effective
|
|
766
810
|
run_purchasable_callbacks(:after_decline)
|
767
811
|
rescue ActiveRecord::RecordInvalid => e
|
768
812
|
self.status = status_was
|
769
|
-
|
770
813
|
error = e.message
|
771
|
-
raise ::ActiveRecord::Rollback
|
772
814
|
end
|
773
815
|
end
|
774
816
|
|
@@ -884,6 +926,47 @@ module Effective
|
|
884
926
|
subtotal + tax
|
885
927
|
end
|
886
928
|
|
929
|
+
# Visa - 1234
|
930
|
+
def payment_method_value
|
931
|
+
provider = payment_provider if ['cheque', 'etransfer', 'phone', 'credit card'].include?(payment_provider)
|
932
|
+
provider = 'credit card' if ['deluxe_delayed'].include?(payment_provider)
|
933
|
+
|
934
|
+
# Normalize payment card
|
935
|
+
card = case payment_card.to_s.downcase.gsub(' ', '').strip
|
936
|
+
when '' then nil
|
937
|
+
when 'v', 'visa' then 'Visa'
|
938
|
+
when 'm', 'mc', 'master', 'mastercard' then 'MasterCard'
|
939
|
+
when 'a', 'ax', 'american', 'americanexpress' then 'American Express'
|
940
|
+
when 'd', 'discover' then 'Discover'
|
941
|
+
else payment_card.to_s
|
942
|
+
end
|
943
|
+
|
944
|
+
# Try again
|
945
|
+
if card == 'none' && payment['card_type'].present?
|
946
|
+
card = case payment['card_type'].to_s.downcase.gsub(' ', '').strip
|
947
|
+
when '' then nil
|
948
|
+
when 'v', 'visa' then 'Visa'
|
949
|
+
when 'm', 'mc', 'master', 'mastercard' then 'MasterCard'
|
950
|
+
when 'a', 'ax', 'american', 'americanexpress' then 'American Express'
|
951
|
+
when 'd', 'discover' then 'Discover'
|
952
|
+
else payment_card.to_s
|
953
|
+
end
|
954
|
+
end
|
955
|
+
|
956
|
+
last4 = if payment[:active_card] && payment[:active_card].include?('**** **** ****')
|
957
|
+
payment[:active_card][15,4]
|
958
|
+
end
|
959
|
+
|
960
|
+
last4 ||= if payment['active_card'] && payment['active_card'].include?('**** **** ****')
|
961
|
+
payment['active_card'][15,4]
|
962
|
+
end
|
963
|
+
|
964
|
+
# stripe, moneris, moneris_checkout
|
965
|
+
last4 ||= (payment['f4l4'] || payment['first6last4']).to_s.last(4)
|
966
|
+
|
967
|
+
[provider.presence, card.presence, last4.presence].compact.join(' - ')
|
968
|
+
end
|
969
|
+
|
887
970
|
private
|
888
971
|
|
889
972
|
def present_order_items
|
@@ -14,6 +14,9 @@
|
|
14
14
|
- elsif EffectiveOrders.refund? && order.refund?
|
15
15
|
= render partial: '/effective/orders/refund/form', locals: provider_locals
|
16
16
|
|
17
|
+
- elsif EffectiveOrders.delayed? && order.delayed?
|
18
|
+
= render partial: '/effective/orders/delayed/form', locals: provider_locals
|
19
|
+
|
17
20
|
- else
|
18
21
|
- if EffectiveOrders.pretend?
|
19
22
|
= render partial: '/effective/orders/pretend/form', locals: provider_locals
|
@@ -38,6 +41,10 @@
|
|
38
41
|
= render partial: '/effective/orders/deferred/form', locals: provider_locals
|
39
42
|
|
40
43
|
- if EffectiveResources.authorized?(controller, :admin, :effective_orders) && order.user != current_user
|
44
|
+
- if EffectiveOrders.delayed? && order.delayed? && order.deferred?
|
45
|
+
.effective-order-admin-purchase-actions
|
46
|
+
= render partial: '/effective/orders/delayed/form_purchase', locals: provider_locals
|
47
|
+
|
41
48
|
- if EffectiveOrders.mark_as_paid?
|
42
49
|
.effective-order-admin-purchase-actions
|
43
50
|
= render partial: '/effective/orders/mark_as_paid/form', locals: provider_locals
|
@@ -1,6 +1,6 @@
|
|
1
1
|
= dropdown(variation: :dropleft) do
|
2
2
|
- if EffectiveResources.authorized?(controller, :checkout, order)
|
3
|
-
= dropdown_link_to 'Checkout', effective_orders.order_path(order)
|
3
|
+
= dropdown_link_to 'Checkout', effective_orders.order_path(order), 'data-turbolinks': false
|
4
4
|
- else
|
5
5
|
= dropdown_link_to 'View', effective_orders.order_path(order)
|
6
6
|
|
@@ -6,4 +6,8 @@
|
|
6
6
|
%th Payment
|
7
7
|
%tbody
|
8
8
|
%tr
|
9
|
-
%td
|
9
|
+
%td
|
10
|
+
- if order.delayed?
|
11
|
+
Your #{order.delayed_payment_method} will be charged on #{order.delayed_payment_date.strftime('%F')} for the full amount
|
12
|
+
- else
|
13
|
+
Waiting for payment by #{order.payment_provider}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
.card
|
2
|
+
.card-body
|
3
|
+
%h2 Save Card Info
|
4
|
+
|
5
|
+
%p
|
6
|
+
= succeed('.') do
|
7
|
+
- distance = distance_of_time_in_words(Time.zone.now, order.delayed_payment_date)
|
8
|
+
|
9
|
+
The payment date for this order
|
10
|
+
|
11
|
+
- if order.delayed_payment_date_future?
|
12
|
+
is in #{distance} from now on #{order.delayed_payment_date.strftime('%F')}
|
13
|
+
- elsif order.delayed_payment_date_today?
|
14
|
+
was today
|
15
|
+
- else
|
16
|
+
was #{distance} ago on #{order.delayed_payment_date.strftime('%F')}
|
17
|
+
|
18
|
+
%p
|
19
|
+
Instead of charging your card right away, the following action will securely save a token
|
20
|
+
representing your card information. The full amount will be charged on the payment date.
|
21
|
+
|
22
|
+
- provider_locals = { order: order, deferred_url: deferred_url, declined_url: declined_url }
|
23
|
+
|
24
|
+
- EffectiveOrders.delayed_providers.each do |provider|
|
25
|
+
= render partial: "/effective/orders/#{provider}/form", locals: provider_locals
|
@@ -0,0 +1,30 @@
|
|
1
|
+
.card
|
2
|
+
.card-body
|
3
|
+
%h2 Admin: Purchase Delayed Order
|
4
|
+
|
5
|
+
- raise('unexpected purchased order') if order.purchased?
|
6
|
+
- raise('expected a deferred delayed order') unless order.delayed? && order.deferred?
|
7
|
+
- raise('expecting a payment intent') unless order.delayed_payment_intent.present?
|
8
|
+
- raise('expecting a payment method') unless order.delayed_payment_method.present?
|
9
|
+
|
10
|
+
%p
|
11
|
+
= succeed('.') do
|
12
|
+
- distance = distance_of_time_in_words(Time.zone.now, order.delayed_payment_date)
|
13
|
+
|
14
|
+
The payment date for this order
|
15
|
+
|
16
|
+
- if order.delayed_payment_date_future?
|
17
|
+
is in #{distance} from now on #{order.delayed_payment_date.strftime('%F')}
|
18
|
+
- elsif order.delayed_payment_date_today?
|
19
|
+
was today
|
20
|
+
- else
|
21
|
+
was #{distance} ago on #{order.delayed_payment_date.strftime('%F')}
|
22
|
+
|
23
|
+
%p The #{order.delayed_payment_method} on file will be charged automatically on the payment date.
|
24
|
+
|
25
|
+
%p You can also charge it right now.
|
26
|
+
|
27
|
+
- provider_locals = { order: order, purchased_url: purchased_url, declined_url: declined_url }
|
28
|
+
|
29
|
+
- EffectiveOrders.delayed_providers.each do |provider|
|
30
|
+
= render partial: "/effective/orders/#{provider}/form_purchase", locals: provider_locals
|
@@ -0,0 +1,9 @@
|
|
1
|
+
.effective-deluxe-delayed-checkout
|
2
|
+
#deluxe-delayed-checkout-loading.text-center Loading...
|
3
|
+
#deluxe-delayed-checkout-errors.text-danger
|
4
|
+
|
5
|
+
%style#deluxeDelayedCheckoutCss
|
6
|
+
-# Pass in custom CSS to the Deluxe Delayed hosted payment form iframe
|
7
|
+
= render('effective/orders/deluxe_delayed/css')
|
8
|
+
|
9
|
+
#deluxeDelayedCheckout
|
@@ -0,0 +1,10 @@
|
|
1
|
+
- deluxe_delayed = deluxe_delayed_hosted_payment_form_options(order)
|
2
|
+
|
3
|
+
= effective_form_with(scope: :deluxe_delayed, url: effective_orders.deluxe_delayed_order_path(order), data: { 'deluxe-delayed-checkout': deluxe_delayed.to_json }) do |f|
|
4
|
+
= f.hidden_field :declined_url, value: declined_url
|
5
|
+
= f.hidden_field :deferred_url, value: deferred_url
|
6
|
+
|
7
|
+
-# This is set by the deluxe.js javascript on Submit
|
8
|
+
= f.hidden_field :payment_intent, required: true
|
9
|
+
|
10
|
+
= render('effective/orders/deluxe_delayed/element')
|
@@ -0,0 +1,18 @@
|
|
1
|
+
= effective_form_with(model: order, url: effective_orders.deluxe_delayed_purchase_order_path(order), method: :post) do |f|
|
2
|
+
= f.hidden_field :id
|
3
|
+
|
4
|
+
= f.hidden_field :purchased_url, value: purchased_url
|
5
|
+
= f.hidden_field :declined_url, value: declined_url
|
6
|
+
|
7
|
+
= f.check_box :send_mark_as_paid_email_to_buyer,
|
8
|
+
label: 'Yes, send a receipt email to the buyer.',
|
9
|
+
input_html: { checked: (f.object.send_mark_as_paid_email_to_buyer.nil? ? EffectiveOrders.send_order_receipts_when_mark_as_paid : f.object.send_mark_as_paid_email_to_buyer?) }
|
10
|
+
|
11
|
+
.row
|
12
|
+
.col
|
13
|
+
= f.text_area :note_to_buyer, hint: 'This message will be displayed to the buyer on the receipt.'
|
14
|
+
.col
|
15
|
+
= f.text_area :note_internal, hint: 'For or internal admin use only. This note will never be displayed to the buyer.'
|
16
|
+
|
17
|
+
= f.submit(center: true) do
|
18
|
+
= f.save 'Purchase Order from Saved Card'
|
data/config/effective_orders.rb
CHANGED
@@ -133,6 +133,15 @@ EffectiveOrders.setup do |config|
|
|
133
133
|
# currency: 'CAD'
|
134
134
|
# }
|
135
135
|
|
136
|
+
# Deluxe Delayed
|
137
|
+
# This is a deferred payment
|
138
|
+
config.deluxe_delayed = false
|
139
|
+
|
140
|
+
# config.deluxe_delayed = {
|
141
|
+
# confirm: 'Save card info for later payment',
|
142
|
+
# success: 'Thank you! You have indicated that this order will be purchased by credit card at a later date. We will save your card information securely and process the payment when the order is ready'
|
143
|
+
# }
|
144
|
+
|
136
145
|
# E-transfer
|
137
146
|
# This is an deferred payment
|
138
147
|
config.etransfer = false
|
data/config/routes.rb
CHANGED
@@ -8,7 +8,10 @@ EffectiveOrders::Engine.routes.draw do
|
|
8
8
|
post :send_buyer_receipt
|
9
9
|
|
10
10
|
post :cheque
|
11
|
-
post :deluxe
|
11
|
+
post :deluxe # 1-off payment and purchase
|
12
|
+
post :deluxe_delayed # 1-off payment_intent saving
|
13
|
+
post :deluxe_delayed_purchase # Admin action to purchase a delayed order
|
14
|
+
|
12
15
|
post :etransfer
|
13
16
|
post :free
|
14
17
|
post :mark_as_paid
|
@@ -40,6 +40,12 @@ class CreateEffectiveOrders < ActiveRecord::Migration[6.0]
|
|
40
40
|
t.integer :surcharge_tax
|
41
41
|
t.integer :total
|
42
42
|
|
43
|
+
t.boolean :delayed_payment, default: false
|
44
|
+
t.date :delayed_payment_date
|
45
|
+
t.text :delayed_payment_intent
|
46
|
+
t.datetime :delayed_payment_purchase_ran_at
|
47
|
+
t.text :delayed_payment_purchase_result
|
48
|
+
|
43
49
|
t.timestamps
|
44
50
|
end
|
45
51
|
|
data/lib/effective_orders.rb
CHANGED
@@ -42,7 +42,7 @@ module EffectiveOrders
|
|
42
42
|
:free_enabled, :mark_as_paid_enabled, :pretend_enabled, :pretend_message, :buyer_purchases_refund,
|
43
43
|
|
44
44
|
# Payment processors. false or Hash
|
45
|
-
:cheque, :deluxe, :etransfer, :moneris, :moneris_checkout, :paypal, :phone, :refund, :stripe, :subscriptions, :trial
|
45
|
+
:cheque, :deluxe, :deluxe_delayed, :etransfer, :moneris, :moneris_checkout, :paypal, :phone, :refund, :stripe, :subscriptions, :trial
|
46
46
|
]
|
47
47
|
end
|
48
48
|
|
@@ -85,10 +85,18 @@ module EffectiveOrders
|
|
85
85
|
deluxe.kind_of?(Hash)
|
86
86
|
end
|
87
87
|
|
88
|
+
def self.deluxe_delayed?
|
89
|
+
deluxe_delayed.kind_of?(Hash)
|
90
|
+
end
|
91
|
+
|
88
92
|
def self.deferred?
|
89
93
|
deferred_providers.present?
|
90
94
|
end
|
91
95
|
|
96
|
+
def self.delayed?
|
97
|
+
delayed_providers.present?
|
98
|
+
end
|
99
|
+
|
92
100
|
def self.mark_as_paid?
|
93
101
|
mark_as_paid_enabled == true
|
94
102
|
end
|
@@ -178,7 +186,11 @@ module EffectiveOrders
|
|
178
186
|
end
|
179
187
|
|
180
188
|
def self.deferred_providers
|
181
|
-
[('cheque' if cheque?), ('etransfer' if etransfer?), ('phone' if phone?)].compact
|
189
|
+
[('cheque' if cheque?), ('deluxe_delayed' if deluxe_delayed?), ('etransfer' if etransfer?), ('phone' if phone?)].compact
|
190
|
+
end
|
191
|
+
|
192
|
+
def self.delayed_providers
|
193
|
+
[('deluxe_delayed' if deluxe_delayed?)].compact
|
182
194
|
end
|
183
195
|
|
184
196
|
def self.credit_card_payment_providers
|
@@ -66,4 +66,10 @@ namespace :effective_orders do
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
+
# rake effective_orders:purchase_delayed_orders
|
70
|
+
desc 'Purchases delayed orders on their delayed_payment_date for effective orders'
|
71
|
+
task purchase_delayed_orders: :environment do
|
72
|
+
puts 'Todo'
|
73
|
+
end
|
74
|
+
|
69
75
|
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.12.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: 2024-05-
|
11
|
+
date: 2024-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -194,6 +194,7 @@ files:
|
|
194
194
|
- app/assets/javascripts/effective_orders.js
|
195
195
|
- app/assets/javascripts/effective_orders/customers.js.coffee
|
196
196
|
- app/assets/javascripts/effective_orders/providers/deluxe.js
|
197
|
+
- app/assets/javascripts/effective_orders/providers/deluxe_delayed.js
|
197
198
|
- app/assets/javascripts/effective_orders/providers/moneris_checkout.js.coffee
|
198
199
|
- app/assets/javascripts/effective_orders/providers/stripe.js.coffee
|
199
200
|
- app/assets/javascripts/effective_orders/subscriptions.js.coffee
|
@@ -210,6 +211,8 @@ files:
|
|
210
211
|
- app/controllers/effective/orders_controller.rb
|
211
212
|
- app/controllers/effective/providers/cheque.rb
|
212
213
|
- app/controllers/effective/providers/deluxe.rb
|
214
|
+
- app/controllers/effective/providers/deluxe_delayed.rb
|
215
|
+
- app/controllers/effective/providers/deluxe_delayed_purchase.rb
|
213
216
|
- app/controllers/effective/providers/etransfer.rb
|
214
217
|
- app/controllers/effective/providers/free.rb
|
215
218
|
- app/controllers/effective/providers/mark_as_paid.rb
|
@@ -230,6 +233,7 @@ files:
|
|
230
233
|
- app/datatables/admin/report_transactions_grouped_by_qb_name_datatable.rb
|
231
234
|
- app/datatables/effective_orders_datatable.rb
|
232
235
|
- app/helpers/effective_carts_helper.rb
|
236
|
+
- app/helpers/effective_deluxe_delayed_helper.rb
|
233
237
|
- app/helpers/effective_deluxe_helper.rb
|
234
238
|
- app/helpers/effective_moneris_checkout_helper.rb
|
235
239
|
- app/helpers/effective_orders_helper.rb
|
@@ -295,9 +299,15 @@ files:
|
|
295
299
|
- app/views/effective/orders/declined.html.haml
|
296
300
|
- app/views/effective/orders/deferred.html.haml
|
297
301
|
- app/views/effective/orders/deferred/_form.html.haml
|
302
|
+
- app/views/effective/orders/delayed/_form.html.haml
|
303
|
+
- app/views/effective/orders/delayed/_form_purchase.html.haml
|
298
304
|
- app/views/effective/orders/deluxe/_css.html.haml
|
299
305
|
- app/views/effective/orders/deluxe/_element.html.haml
|
300
306
|
- app/views/effective/orders/deluxe/_form.html.haml
|
307
|
+
- app/views/effective/orders/deluxe_delayed/_css.html.haml
|
308
|
+
- app/views/effective/orders/deluxe_delayed/_element.html.haml
|
309
|
+
- app/views/effective/orders/deluxe_delayed/_form.html.haml
|
310
|
+
- app/views/effective/orders/deluxe_delayed/_form_purchase.html.haml
|
301
311
|
- app/views/effective/orders/edit.html.haml
|
302
312
|
- app/views/effective/orders/etransfer/_form.html.haml
|
303
313
|
- app/views/effective/orders/free/_form.html.haml
|