This repository has been archived by the owner on Oct 27, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
order_controller.rb
156 lines (132 loc) · 6.6 KB
/
order_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
class OrderController < ApplicationController
include WorldpayHelper
include RegistrationsHelper
# Used only when the system gets into a state where it cannot allow further
# processing of an order.
def contact_us_to_complete_payment
# Horrible hack: when the user triggers a £40 edit charge, chooses a payment
# method but then navigates backward, we get into a state where we can no
# longer compare the "old" and "new" carrier types (because we no longer
# know what the "old" type was as its now been overwritten in Mongo). This
# means the new charge determination will output no charge, potentially
# making the change of carrier type free.
setup_registration('payment', true)
render_not_found and return unless @registration
end
# GET /your-registration/:reg_uuid/order
def new
@order ||= Order.new
setup_registration('payment', true)
render_not_found and return unless @registration
order_type_param = params[:order_type]
@registration.update(copy_cards: 0)
if Order.extra_copycards_identifier == order_type_param
@registration.update(copy_card_only_order: 'yes')
end
@show_copy_cards = show_copy_cards(order_type_param)
# The Order Builder is not cached by the Registration, so we'll cache it
# here (and use the cached version in the view too).
@order_builder = @registration.order_builder
if (@order_builder.total_fee == 0) && (Order.extra_copycards_identifier != order_type_param)
# Somehow we have a non copy-card-only order with a total cost of 0, which
# can happen if a user abandons a payment. Our architecture doesn't allow
# us to handle this elegantly, so lets just get them to call NCCC.
redirect_to contact_us_to_complete_payment_path
return
end
@order_builder.current_user = (current_user || current_agency_user)
@registration.registration_fee = @order_builder.registration_fee
@registration.total_fee = @order_builder.total_fee
end
# POST /your-registration/:reg_uuid/order
def create
setup_registration 'payment'
@registration.copy_cards ||= 0
@order_builder = @registration.order_builder
@order_builder.current_user = (current_user || current_agency_user)
order_type_param = params[:order_type]
@show_copy_cards = show_copy_cards(order_type_param)
# HERE is the place where we determine whether we need to update an order
# that already exists against the registration (and is in the database),
# or create a new one.
if @order_builder.indicates_new_registration?
# This order is for the initial registration, and has already been
# committed to the database at the time the registration was written.
# Therefore we need to update the existing order.
new_order_code = @registration.finance_details.first.orders.first.orderCode
#elsif session.has_key?(:orderCode)
# The user has returned to this page by cancelling in Worldpay, or via
# using the back button. To avoid creating a duplicate order, we re-use
# the last order-code.
# new_order_code = session[:orderCode]
else
# This must be a new order; we'll let the Order Builder generate a new
# order code.
new_order_code = nil
end
# Generate the new order, and store its key in the session, so that we can
# handle the case where a user Cancels in Worldpay or uses the browser
# back button.
@order = @order_builder.order(new_order_code)
unless @registration.valid? && @order.valid?
logger.debug "registration validation errors: #{@registration.errors.messages.to_s}"
logger.debug "order validation errors: #{@registration.errors.messages.to_s}"
render 'new', status: :bad_request
return
end
# Save the registration to the services so that any paid-for edits take
# effect now.
unless @registration.save && @registration.save!
@order.errors.add(:exception, t('order.new.failed_to_save_registration'))
logger.warn 'The registration was not saved to Redis or the Services'
render 'new', status: '500'
return
end
# Does the session order with orderCode exist already?
existing_order = @registration.getOrder(@order.orderCode)
if existing_order.present?
# We must update the newly-generated order to contain the ID of the existing
# order, as this is how the services decides which order to overwrite.
@order.orderId = existing_order.orderId
@order.save!(@registration.uuid)
else
@order.commit(@registration.uuid)
end
# Re-get registration from the database to update the local redis version
@registration = Registration.find_by_id(@registration.uuid)
unless @registration.save
@order.errors.add(:exception, @order.exception.to_s)
logger.warn 'The update order was not saved to services.'
render 'new', status: :bad_request
return
end
# The @registration loaded above is a new Ohm object, so we need to update
# the ID referencing it that we store in the session. The UUID will not
# have changed. This blocks some "hacks" that the user could trigger if
# they now navigated back to the confirmation page using the browser history,
# where the system would load the OLD version of the registration (which has
# changes from the previous edit, but WITHOUT the corresponding Order), then
# confirm their changes, which would trick the system into thinking that a
# free edit had taken place, and thus overwrite the NEW version that we've
# just loaded from Mongo, in effect creating a "free" edit.
# session[:registration_id] = @registration.id
logger.debug "About to redirect to Worldpay or Offline payment"
set_google_analytics_payment_indicator(session, @order)
if @order.paymentMethod == 'OFFLINE'
logger.debug "The registration is valid - redirecting to Offline payment page..."
redirect_to offline_payment_path(reg_uuid: @registration.reg_uuid, orderCode: @order.orderCode, orderType: order_type_param)
else
logger.debug "The registration is valid - redirecting to Worldpay..."
response = send_xml(create_xml(@registration, @order))
render('new', status: :bad_request) and return unless response
redirect_to get_redirect_url(parse_xml(response.body), @registration, @order.orderCode, order_type_param)
end
end
private
def show_copy_cards(order_type)
order_type.eql?(Order.new_registration_identifier) ||
order_type.eql?(Order.renew_registration_identifier) ||
order_type.eql?(Order.editrenew_caused_new_identifier) ||
order_type.eql?(Order.extra_copycards_identifier)
end
end