-
Notifications
You must be signed in to change notification settings - Fork 13
/
events_controller.rb
317 lines (273 loc) · 10.8 KB
/
events_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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
require 'pdf_generation/applications_pdf'
require 'rubygems'
require 'zip'
class EventsController < ApplicationController
before_action :set_event, only: [:show, :edit, :update, :destroy, :participants, :participants_pdf, :print_applications]
# GET /events
def index
@events = Event.sorted_by_start_date(!can?(:edit, Event)).reverse
end
# GET /events/1
def show
@free_places = @event.compute_free_places
@occupied_places = @event.compute_occupied_places
@application_letters = filter_application_letters(@event.application_letters)
@material_files = get_material_files(@event)
end
# GET /events/new
def new
@event = Event.new
end
# GET /events/1/edit
def edit
end
# POST /events
def create
@event = Event.new(event_params)
@event.draft = (params[:draft] != nil)
if @event.save
redirect_to @event, notice: I18n.t('.events.notices.created')
else
render :new
end
end
# PATCH/PUT /events/1
def update
attrs = event_params
@event.draft = (params[:commit] == "draft")
if @event.update(attrs)
redirect_to @event, notice: I18n.t('events.notices.updated')
else
render :edit
end
end
# DELETE /events/1
def destroy
@event.destroy
redirect_to events_url, notice: I18n.t('events.notices.destroyed')
end
# GET /events/1/badges
def badges
@event = Event.find(params[:event_id])
@participants = @event.participants
end
# POST /events/1/badges
def print_badges
names = badges_name_params
# pdf document initialization
pdf = Prawn::Document.new(:page_size => 'A4')
pdf.stroke_color "000000"
# divide in pieces of 10 names
badge_pages = names.each_slice(10).to_a
badge_pages.each_with_index do | page, index |
create_badge_page(pdf, page, index)
end
send_data pdf.render, filename: "badges.pdf", type: "application/pdf", disposition: "inline"
end
# GET /events/1/participants
def participants
@participants = @event.participants_by_agreement_letter
@has_agreement_letters = @event.agreement_letters.any?
end
# GET /events/1/print_applications
def print_applications
authorize! :print_applications, @event
pdf = ApplicationsPDF.generate(@event)
send_data pdf, filename: "applications_#{@event.name}_#{Date.today}.pdf", type: "application/pdf", disposition: "inline"
end
# GET /events/1/send-acceptances-email
def send_acceptance_emails
event = Event.find(params[:id])
event.lock_application_status
@email = event.generate_acceptances_email
@templates = [{subject: 'Zusage 1', content: 'Lorem Ispum...'}, {subject: 'Zusage 2', content: 'Lorem Ispum...'}, {subject: 'Zusage 3', content: 'Lorem Ispum...'}]
render :email
end
# GET /events/1/send-rejections-email
def send_rejection_emails
event = Event.find(params[:id])
event.lock_application_status
@email = event.generate_rejections_email
@templates = [{subject: 'Absage 1', content: 'Lorem Ispum...'}, {subject: 'Absage 2', content: 'Lorem Ispum...'}, {subject: 'Absage 3', content: 'Lorem Ispum...'}]
render :email
end
# GET /events/1/accept-all-applicants
def accept_all_applicants
event = Event.find(params[:id])
event.accept_all_application_letters
redirect_to event_path(event)
end
#POST /events/1/participants/agreement_letters
# creates either a zip or a pdf containing all agreement letters for all selected participants
def download_agreement_letters
@event = Event.find(params[:id])
if not params.has_key?(:selected_participants)
redirect_to event_participants_url(@event), notice: I18n.t('events.agreement_letters_download.notices.no_participants_selected') and return
end
authorize! :print_agreement_letters, @event
if params[:download_type] == "zip"
filename = "agreement_letters_#{@event.name}_#{Date.today}.zip"
temp_file = Tempfile.new(filename)
number_of_files = 0
begin
Zip::OutputStream.open(temp_file) { |zos| }
Zip::File.open(temp_file.path, Zip::File::CREATE) do |zipfile|
params[:selected_participants].each do |participant_id|
user = User.find(participant_id)
agreement_letter = user.agreement_letter_for_event(@event)
unless agreement_letter.nil?
number_of_files += 1
zipfile.add(number_of_files.to_s + "_" + user.name + ".pdf", agreement_letter.path)
end
end
end
zip_data = File.read(temp_file.path)
if number_of_files != 0
send_data(zip_data, :type => 'application/zip', :filename => filename)
end
ensure
temp_file.close
temp_file.unlink
end
if number_of_files == 0
redirect_to event_participants_url(@event), notice: I18n.t('events.agreement_letters_download.notices.no_agreement_letters') and return
end
end
if params[:download_type] == "pdf"
empty = true
pdf = CombinePDF.new
params[:selected_participants].each do |participant_id|
agreement_letter = User.find(participant_id).agreement_letter_for_event(@event)
unless agreement_letter.nil?
pdf << CombinePDF.load(agreement_letter.path)
empty = false
end
end
if empty
redirect_to event_participants_url(@event), notice: I18n.t('events.agreement_letters_download.notices.no_agreement_letters') and return
end
send_data pdf.to_pdf, filename: "agreement_letters_#{@event.name}_#{Date.today}.pdf", type: "application/pdf", disposition: "inline" unless pdf.nil?
end
end
# POST /events/1/upload_material
def upload_material
event = Event.find(params[:event_id])
material_path = event.material_path
Dir.mkdir(material_path) unless File.exists?(material_path)
file = params[:file_upload]
unless is_file?(file)
redirect_to event_path(event), alert: t("events.material_area.no_file_given")
return false
end
begin
File.write(File.join(material_path, file.original_filename), file.read, mode: "wb")
rescue IOError
redirect_to event_path(event), alert: I18n.t("events.material_area.saving_fails")
return false
end
redirect_to event_path(event), notice: I18n.t("events.material_area.success_message")
end
# GET /event/1/participants_pdf
def participants_pdf
default = {:order_by => 'email', :order_direction => 'asc'}
default = default.merge(params)
@application_letters = @event.application_letters_ordered(default[:order_by], default[:order_direction])
.where(:status => ApplicationLetter.statuses[:accepted])
data = @application_letters.collect do |application_letter|
[
application_letter.user.profile.first_name,
application_letter.user.profile.last_name,
application_letter.user.profile.birth_date,
application_letter.allergies
]
end
data.unshift([
I18n.t('controllers.events.participants_pdf.first_name'),
I18n.t('controllers.events.participants_pdf.last_name'),
I18n.t('controllers.events.participants_pdf.first_name'),
I18n.t('controllers.events.participants_pdf.allergies')
])
name = @event.name
doc = Prawn::Document.new(:page_size => 'A4') do
text "Teilnehmerliste - " + name
table(data, width: bounds.width)
end
send_data doc.render, :filename => "participants.pdf", :type => "application/pdf", disposition: "inline"
end
# POST /events/1/download_material
def download_material
event = Event.find(params[:event_id])
unless params.has_key?(:file)
redirect_to event_path(event), alert: I18n.t('events.material_area.no_file_given') and return
end
authorize! :download_material, event
file_full_path = File.join(event.material_path, params[:file])
unless File.exists?(file_full_path)
redirect_to event_path(event), alert: t("events.material_area.download_file_not_found") and return
end
send_file file_full_path, :x_sendfile => true
end
private
# Use callbacks to share common setup or constraints between actions.
def set_event
@event = Event.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def event_params
params.require(:event).permit(:name, :description, :max_participants, :participants_are_unlimited, :kind, :organizer, :knowledge_level, :application_deadline, :custom_application_fields => [], date_ranges_attributes: [:start_date, :end_date, :id])
end
# Generate all names to print from the query-params
#
# @return participant_names as array of strings
def badges_name_params
params.select { |key, value| key.include? "_print" }.values
end
# Create a name badge in a given pdf
#
# @param pdf, is a prawn pdf-object
# @param name [String] is the name label of the new badge
# @param x [Integer] is the x-coordinate of the upper left corner of the new badge
# @param y [Integer] is the y-coordinate of the upper left corner of the new badge
def create_badge(pdf, name, x, y)
width = 260
height = 150
pdf.stroke_rectangle [x, y], width, height
pdf.text_box name, :at => [x + width / 2 - 50 , y - 20], :width => width - 100, :height => height - 100, :overflow => :shrink_to_fit
end
def filter_application_letters(application_letters)
application_letters = application_letters.to_a
filters = (params[:filter] || {}).select { |k, v| v == '1' }.map{ |k, v| k.to_s }
if filters.count > 0 # skip filtering if no filters have been set
application_letters.keep_if { |l| filters.include?(l.status) }
end
application_letters
end
# Create a page with maximum 10 badges
#
# @param pdf, is a prawn pdf-object
# @param names [Array of Strings] are the name which are printed to the badges
# @param index [Number] the page number
def create_badge_page(pdf, names, index)
# create no pagebreak for first page
pdf.start_new_page if index > 0
names.each_slice(2).with_index do |(left, right), row|
create_badge(pdf, left, 0, 750 - row * 150)
create_badge(pdf, right, 260, 750 - row * 150) unless right.nil?
end
end
# Checks if a file is valid and not empty
#
# @param [ActionDispatch::Http::UploadedFile] is a file object
# @return [Boolean] whether @file is a valid file
def is_file?(file)
file.respond_to?(:open) && file.respond_to?(:content_type) && file.respond_to?(:size)
end
# Gets all file names stored in the material storage of the event
#
# @param [Event]
# @return [Array of Strings]
def get_material_files(event)
material_path = event.material_path
File.exists?(material_path) ? Dir.glob(File.join(material_path, "*")) : []
end
end