1require 'postcode_sanitizer' |
|
3class PetitionCreator |
|
4 extend ActiveModel::Naming |
|
5 extend ActiveModel::Translation |
|
6 include ActiveModel::Conversion |
|
8 STAGES = %w[petition replay_petition creator replay_email] |
|
10 PETITION_PARAMS = [:action, :background, :additional_details] |
|
11 SIGNATURE_PARAMS = [:name, :email, :postcode, :location_code, :uk_citizenship, :notify_by_email] |
|
12 PERMITTED_PARAMS = [:q, :stage, :move_back, :move_next, petition_creator: PETITION_PARAMS + SIGNATURE_PARAMS] |
|
14 attr_reader :params, :errors, :request |
|
|
16 def initialize(params, request) |
17 @params = params.permit(*PERMITTED_PARAMS) |
|
18 @errors = ActiveModel::Errors.new(self) |
|
19 @request = request |
|
20 end |
|
|
22 def read_attribute_for_validation(attribute) |
23 public_send(attribute)
|
|
24 end |
|
|
26 def to_partial_path |
27 "petitions/create/#{stage}_stage" |
|
28 end |
|
|
30 def duplicates |
31 Petition.current.search(q: action, count: 3).presence |
|
32 end |
|
|
34 def stage |
35 @stage ||= stage_param.in?(STAGES) ? stage_param : STAGES.first |
|
36 end |
|
|
38 def save |
39 if moving_backwards? |
|
40 @stage = previous_stage and return false |
|
41 end |
|
43 unless valid? |
|
44 return false |
|
45 end |
|
47 if done? |
|
48 @petition = Petition.new do |p| |
|
49 p.action = action
|
|
50 p.background = background
|
|
51 p.additional_details = additional_details
|
|
53 p.build_creator do |c| |
|
54 c.name = name
|
|
55 c.email = email
|
|
56 c.postcode = postcode
|
|
57 c.location_code = location_code
|
|
58 c.uk_citizenship = uk_citizenship
|
|
59 c.constituency_id = constituency_id
|
|
60 c.notify_by_email = notify_by_email
|
|
61 c.ip_address = request.remote_ip
|
|
62 end |
|
63 end |
|
65 @petition.save! |
|
66 send_email_to_gather_sponsors(@petition) |
|
68 return true |
|
69 else |
|
70 @stage = next_stage and return false |
|
71 end |
|
72 end |
|
|
74 def to_param |
75 if @petition && @petition.persisted? |
|
76 @petition.to_param |
|
77 else |
|
78 raise RuntimeError, "PetitionCreator#to_param called before petition was created" |
|
79 end |
|
80 end |
|
|
82 def action |
83 (petition_creator_params[:action] || query_param).to_s.strip |
|
84 end |
|
|
86 def action? |
87 action.present?
|
|
88 end |
|
|
90 def background |
91 petition_creator_params[:background].to_s.strip |
|
92 end |
|
|
94 def background? |
95 background.present?
|
|
96 end |
|
|
98 def additional_details |
99 petition_creator_params[:additional_details].to_s.strip |
|
100 end |
|
|
102 def name |
103 petition_creator_params[:name].to_s.strip |
|
104 end |
|
|
106 def email |
107 petition_creator_params[:email].to_s.strip |
|
108 end |
|
|
110 def postcode |
111 PostcodeSanitizer.call(petition_creator_params[:postcode]) |
|
112 end |
|
|
114 def location_code |
115 petition_creator_params[:location_code] || "GB" |
|
116 end |
|
|
118 def uk_citizenship |
119 petition_creator_params[:uk_citizenship] || "0" |
|
120 end |
|
|
122 def notify_by_email |
123 petition_creator_params[:notify_by_email] || "0" |
|
124 end |
|
126 private
|
|
|
128 def query_param |
129 @query_param ||= params[:q].to_s.first(255) |
|
130 end |
|
|
132 def stage_param |
133 @stage_param ||= params[:stage].to_s |
|
134 end |
|
|
136 def petition_creator_params |
137 params[:petition_creator] || {} |
|
138 end |
|
|
140 def moving_backwards? |
141 params.key?(:move_back) |
|
142 end |
|
|
144 def stage_index |
145 STAGES.index(stage) |
|
146 end |
|
|
148 def previous_stage |
149 STAGES[[stage_index - 1, 0].max] |
|
150 end |
|
|
152 def next_stage |
153 STAGES[[stage_index + 1, 3].min] |
|
154 end |
|
|
156 def validate_petition |
157 errors.add(:action, :blank) unless action.present? |
|
158 errors.add(:action, :too_long, count: 80) if action.length > 80 |
|
159 errors.add(:background, :blank) unless background.present? |
|
160 errors.add(:background, :too_long, count: 300) if background.length > 300 |
|
161 errors.add(:additional_details, :too_long, count: 800) if additional_details.length > 800 |
|
163 if errors.any? |
|
164 @stage = "petition" |
|
165 end |
|
166 end |
|
|
168 def validate_creator |
169 errors.add(:name, :blank) unless name.present? |
|
170 errors.add(:name, :too_long, count: 255) if action.length > 255 |
|
171 errors.add(:email, :blank) unless email.present? |
|
172 errors.add(:location_code, :blank) unless location_code.present? |
|
173 errors.add(:uk_citizenship, :accepted) unless uk_citizenship == "1" |
|
174 errors.add(:postcode, :too_long, count: 255) if postcode.length > 255 |
|
176 if email.present? |
|
177 email_validator.validate(self) |
|
178 end |
|
180 if location_code == "GB" |
|
181 errors.add(:postcode, :blank) unless postcode.present? |
|
183 if postcode.present? |
|
184 postcode_validator.validate(self) |
|
185 end |
|
186 end |
|
188 if replay_email? |
|
189 @stage = "replay_email" |
|
190 elsif errors.any? |
|
191 @stage = "creator" |
|
192 end |
|
193 end |
|
|
195 def validate |
196 validate_petition
|
|
198 if errors.empty? && stage_index > 1 |
|
199 validate_creator
|
|
200 end |
|
201 end |
|
|
203 def valid? |
204 errors.clear
|
|
205 validate
|
|
206 errors.empty?
|
|
207 end |
|
|
209 def replay_email? |
210 stage == "replay_email" && errors.keys == [:email] |
|
211 end |
|
|
213 def done? |
214 stage == "replay_email" |
|
215 end |
|
|
217 def email_validator |
218 EmailValidator.new(attributes: [:email]) |
|
219 end |
|
|
221 def postcode_validator |
222 PostcodeValidator.new(attributes: [:postcode]) |
|
223 end |
|
|
225 def constituency |
226 @constituency ||= Constituency.find_by_postcode(postcode) |
|
227 end |
|
|
229 def constituency_id |
230 constituency.try(:external_id) |
|
231 end |
|
|
233 def send_email_to_gather_sponsors(petition) |
234 GatherSponsorsForPetitionEmailJob.perform_later(petition) |
|
235 end |
|
236end |