Skip to content

Commit

Permalink
Merge branch 'dev' into 491_Event_list_date_bug
Browse files Browse the repository at this point in the history
  • Loading branch information
nilsthamm committed Feb 4, 2017
2 parents 5e8407a + 8d9c84c commit 98e66dc
Show file tree
Hide file tree
Showing 39 changed files with 539 additions and 162 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -45,3 +45,6 @@ config/database.yml

# Ignore application configuration
/config/application.yml

# Ignore image uplaods
/public/uploads
4 changes: 4 additions & 0 deletions Gemfile
Expand Up @@ -108,6 +108,10 @@ gem 'will_paginate-bootstrap'
# Markdown renderer
gem 'redcarpet'

# Image Upload and Processing
gem 'carrierwave'
gem 'mini_magick'

# Ical generator
gem 'icalendar'

Expand Down
10 changes: 10 additions & 0 deletions Gemfile.lock
Expand Up @@ -73,6 +73,10 @@ GEM
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
carrierwave (1.0.0)
activemodel (>= 4.0.0)
activesupport (>= 4.0.0)
mime-types (>= 1.16)
cliver (0.3.2)
codeclimate-test-reporter (1.0.3)
simplecov
Expand Down Expand Up @@ -149,6 +153,7 @@ GEM
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mini_magick (4.6.0)
mini_portile2 (2.1.0)
minitest (5.10.1)
nokogiri (1.6.8.1)
Expand Down Expand Up @@ -318,6 +323,7 @@ DEPENDENCIES
byebug
cancancan
capybara (~> 2.5)
carrierwave
codeclimate-test-reporter (~> 1.0.0)
combine_pdf
coveralls
Expand All @@ -335,6 +341,7 @@ DEPENDENCIES
jquery-turbolinks
jquery-ui-rails
less-rails
mini_magick
parser (~> 2.2.2.5)
pdf-inspector
pg
Expand All @@ -361,5 +368,8 @@ DEPENDENCIES
web-console (~> 2.0)
will_paginate-bootstrap

RUBY VERSION
ruby 2.2.2p95

BUNDLED WITH
1.13.7
3 changes: 2 additions & 1 deletion Vagrantfile
Expand Up @@ -26,5 +26,6 @@ Vagrant.configure("2") do |config|
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y phantomjs
apt-get install -y imagemagick
SHELL
end
end
5 changes: 1 addition & 4 deletions app/assets/stylesheets/events.css
Expand Up @@ -48,9 +48,6 @@
margin: 15px 0;
padding-bottom: 15px;
}
.event-preview.event-past {
opacity: 0.7;
}
.front-section:nth-child(even) .event-preview {
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
Expand Down Expand Up @@ -108,4 +105,4 @@
width: 100%;
height: 150px;
margin-bottom: 15px;
}
}
14 changes: 8 additions & 6 deletions app/controllers/emails_controller.rb
Expand Up @@ -6,7 +6,7 @@ def show

@templates = EmailTemplate.with_status(get_email_template_status)
application_letter_status = get_corresponding_application_letter_status
@addresses = @event.email_addresses_of_type(application_letter_status)
@addresses = @event.email_addresses_of_type_without_notification_sent(application_letter_status)

@email = Email.new(hide_recipients: true, reply_to: Rails.configuration.reply_to_address, recipients: @addresses.join(','),
subject: '', content: '')
Expand All @@ -29,24 +29,26 @@ def submit
def send_email
@email = Email.new(email_params)
@event = Event.find(params[:event_id])

status = get_email_template_status
if @email.valid?
if get_corresponding_application_letter_status == :accepted
application_letter_status = get_corresponding_application_letter_status
if application_letter_status == :accepted
@email.send_email_with_ical @event
else
@email.send_email
end

if get_email_template_status == :acceptance
@event.set_status_notification_flag_for_applications_with_status(application_letter_status)
if status == :acceptance
@event.acceptances_have_been_sent = true
elsif get_email_template_status == :rejection
elsif status == :rejection
@event.rejections_have_been_sent = true
end
@event.save

redirect_to @event, notice: t('.sending_successful')
else
@templates = EmailTemplate.with_status(get_email_template_status)
@templates = EmailTemplate.with_status(status)

flash.now[:alert] = t('.sending_failed')
render :email
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/events_controller.rb
Expand Up @@ -3,6 +3,7 @@
require 'pdf_generation/participants_pdf'
require 'rubygems'
require 'zip'
require 'carrierwave'

class EventsController < ApplicationController

Expand Down Expand Up @@ -252,7 +253,7 @@ def set_event
end

def event_params
params.require(:event).permit(:name, :description, :max_participants, :organizer, :knowledge_level, :application_deadline, :published, :hidden, :custom_application_fields => [], date_ranges_attributes: [:start_date, :end_date, :id])
params.require(:event).permit(:name, :description, :image, :max_participants, :organizer, :knowledge_level, :application_deadline, :published, :hidden, :custom_application_fields => [], date_ranges_attributes: [:start_date, :end_date, :id])
end

def add_event_query_conditions(query)
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/requests_controller.rb
Expand Up @@ -25,8 +25,9 @@ def edit
# POST /requests
def create
@request = Request.new(request_params)

if @request.save
Mailer.send_generic_email(false, @request.email, Rails.configuration.reply_to_address, I18n.t('requests.email.topic'),
I18n.t('requests.email.content'))
redirect_to root_path, notice: I18n.t('requests.notice.was_created')
else
render :new
Expand Down
43 changes: 38 additions & 5 deletions app/models/application_letter.rb
Expand Up @@ -25,13 +25,22 @@ class ApplicationLetter < ActiveRecord::Base
validates_inclusion_of :grade, in: (VALID_GRADES.to_a.push(0))
validates :vegetarian, :vegan, :allergic, inclusion: { in: [true, false] }
validates :vegetarian, :vegan, :allergic, exclusion: { in: [nil] }
validate :deadline_cannot_be_in_the_past, :if => Proc.new { |letter| !(letter.status_changed?) }
validate :status_cannot_be_changed, :if => Proc.new { |letter| letter.status_changed?}
validate :deadline_cannot_be_in_the_past, :if => Proc.new { |letter| !(letter.status_changed? || letter.status_notification_sent_changed?) }
validate :status_notification_sent_cannot_be_changed, :if => Proc.new { |letter| letter.status_notification_sent_changed? }
validate :status_cannot_be_changed, :if => Proc.new { |letter| letter.status_changed? }

enum status: {accepted: 1, rejected: 0, pending: 2, alternative: 3}
enum status: {accepted: 1, rejected: 0, pending: 2, alternative: 3, canceled: 4}
validates :status, inclusion: { in: statuses.keys }


# Returns an array of selectable statuses
#
# @param none
# @return [Array <String>] array of selectable statuses
def self.selectable_statuses
["accepted","rejected","pending","alternative"]
end

# Checks if the deadline is over
# additionally only return if event and event.application_deadline is present
#
Expand All @@ -46,7 +55,21 @@ def after_deadline?
# @param none
# @return [Boolean] true if status changes are allowed
def status_change_allowed?
!event.participant_selection_locked
if event.phase == :execution
(status_was == 'accepted' && status == 'canceled') || (status_was == 'alternative' && status == 'accepted')
elsif event.phase == :selection && event.participant_selection_locked
false
else
true
end
end

# Checks if it is allowed to set the status_notification_sent flag
#
# @param none
# @return [Boolean] true if it can be changed
def status_notification_sent_change_allowed?
event.phase == :selection || event.phase == :execution
end

# Validator for after_deadline?
Expand Down Expand Up @@ -85,6 +108,8 @@ def status_type
else
return I18n.t("application_status.pending_before_deadline")
end
when ApplicationLetter.statuses[:canceled]
return I18n.t("application_status.canceled")
else
return I18n.t("application_status.alternative")
end
Expand All @@ -94,7 +119,15 @@ def status_type
# Adds error
def status_cannot_be_changed
unless status_change_allowed?
errors.add(:event, "Die Bewerbungen wurden bereits bearbeitet, eine Statusänderung ist nicht mehr erlaubt.")
errors.add(:event, I18n.t('application_letters.validation.status_cannot_be_changed'))
end
end

# Validator for status_change_allowed?
# Adds error
def status_notification_sent_cannot_be_changed
unless status_notification_sent_change_allowed?
errors.add(:event, I18n.t('application_letters.validation.status_notification_sent_cannot_be_changed'))
end
end

Expand Down
28 changes: 23 additions & 5 deletions app/models/event.rb
Expand Up @@ -21,6 +21,8 @@ class Event < ActiveRecord::Base

serialize :custom_application_fields, Array

mount_uploader :image, EventImageUploader

has_many :application_letters
has_many :agreement_letters
has_many :participant_groups
Expand All @@ -34,6 +36,13 @@ class Event < ActiveRecord::Base
validates :hidden, exclusion: { in: [nil] }
validates :published, inclusion: { in: [true, false] }
validates :published, exclusion: { in: [nil] }
validate :check_image_dimensions

# Use the image dimensions as returned from our uploader
# to verify that the image has sufficient size
def check_image_dimensions
errors.add(:image, I18n.t("events.errors.image_too_small")) if image.upload_width.present? && image.upload_height.present? && (image.upload_width < 200 || image.upload_height < 155)
end


# Returns all participants for this event in following order:
Expand Down Expand Up @@ -145,17 +154,26 @@ def send_mails_tooltip
# @param none
# @return none
def accept_all_application_letters
application_letters.each do |application_letter|
application_letter.update(status: :accepted)
application_letters.map { |application| application.update(status: :accepted) }
end

# Sets the status_notification_sent flag for all application letters of the given type
#
# @param status [Type] the desired application status the flag should be set for
# @return none
def set_status_notification_flag_for_applications_with_status(status)
applications = application_letters.select {|application| application.status == status.to_s}
applications.each do |application_letter|
application_letter.update(status_notification_sent: true)
end
end

# Returns an array of strings of all email addresses of applications with a given status type
#
# @param type [Type] the status type of the email addresses that will be returned
# @return [Array<String>] Array of all email addresses of applications with given type
def email_addresses_of_type(type)
applications = application_letters.where(status: ApplicationLetter.statuses[type])
# @return [Array<String>] Array of all email addresses of applications with given type, that don't have status_notification_sent set
def email_addresses_of_type_without_notification_sent(type)
applications = application_letters.where(status: ApplicationLetter.statuses[type], status_notification_sent: false)
applications.collect { |a| a.user.email }
end

Expand Down
9 changes: 5 additions & 4 deletions app/models/user.rb
Expand Up @@ -119,15 +119,16 @@ def older_than_required_age_at_start_date_of_event?(given_event, age)
# @param [Event] current event (which application status will be excluded)
# @return [Int] of number of currently accepted applications
def accepted_applications_count(event)
ApplicationLetter.where(user_id: id, status: true).where.not(event: event).count()
ApplicationLetter.where(user_id: id, status: ApplicationLetter.statuses[:accepted])
.where.not(event: event).count()
end

# Returns the number of accepted applications from the user without counting status of current event application
# Returns the number of rejected applications from the user without counting status of current event application
#
# @param current event (which application status will be excluded)
# @return [Int] of number of currently accepted applications
# @return [Int] of number of currently rejected applications
def rejected_applications_count(event)
ApplicationLetter.where(user_id: id, status: false).where.not(event: event).count()
ApplicationLetter.where(user_id: id, status: ApplicationLetter.statuses[:rejected]).where.not(event: event).count()
end

# Searches all users with last/first_name containing pattern
Expand Down
43 changes: 43 additions & 0 deletions app/uploaders/event_image_uploader.rb
@@ -0,0 +1,43 @@
class EventImageUploader < CarrierWave::Uploader::Base
attr_reader :upload_width, :upload_height

# image processing
include CarrierWave::MiniMagick

storage :file

# Return the directory that images will be uploaded to
# @return [String] the path relative to the `public` folder
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end

before :cache, :capture_size_before_cache

# Fill in the upload sizes once the image has been uploaded, so that
# our model can use them for validation
def capture_size_before_cache(new_file)
# Only do this once, to the original version
if version_name.blank?
@upload_width, @upload_height = `identify -format "%wx %h" #{new_file.path}`.split(/x/).map { |dim| dim.to_i }
end
end

version :list_view do
process resize_to_fill: [200, 155]
end

version :detail_view do
process resize_to_fill: [1140, 200]
end

version :thumb do
process resize_to_fill: [50, 50]
end

# white list of extensions which are allowed to be uploaded
def extension_whitelist
%w(jpg jpeg gif png)
end

end
Expand Up @@ -2,7 +2,7 @@
<%= form_for :application_letter, url: update_application_letter_status_path(application_letter), html: {method: :put} do |f| %>
<div class="form-group">
<div class="btn-group" data-toggle="buttons">
<% ApplicationLetter.statuses.keys.each do |key| %>
<% ApplicationLetter.selectable_statuses.each do |key| %>
<label class="btn btn-xs btn-default <%= 'active' if application_letter.status == key %>">
<%= f.radio_button :status,
key,
Expand Down
25 changes: 15 additions & 10 deletions app/views/events/_applicants_overview.html.erb
Expand Up @@ -64,22 +64,27 @@
</div>

<% if (can? :send_email, Email) && (@event.phase == :selection) %>
<div class="btn-group send-emails-buttons pull-right tooltip-wrapper has-tooltip" role="group" data-toggle="tooltip" title="<%= @event.send_mails_tooltip %>">
<%= form_tag event_email_show_path(@event), method: :get do %>
<%= hidden_field_tag "status", "acceptance" %>
<%= button_tag t('.sending_acceptances'), class: 'send-emails-button btn btn-default', disabled: @event.send_mails_tooltip.present? %>
<% if not @event.acceptances_have_been_sent %>
<div class="btn-group send-emails-buttons pull-right tooltip-wrapper has-tooltip" role="group" data-toggle="tooltip" title="<%= @event.send_mails_tooltip %>">
<%= form_tag event_email_show_path(@event), method: :get do %>
<%= hidden_field_tag "status", "acceptance" %>
<%= button_tag t('.sending_acceptances'), class: 'send-emails-button btn btn-default', disabled: @event.send_mails_tooltip.present? %>
<% end %>
</div>
<% end %>
<%= form_tag event_email_show_path(@event), method: :get do %>
<%= hidden_field_tag "status", "rejection" %>
<%= button_tag t('.sending_rejections'), class: 'send-emails-button btn btn-default', disabled: @event.send_mails_tooltip.present? %>
<% if not @event.rejections_have_been_sent %>
<div class="btn-group send-emails-buttons pull-right tooltip-wrapper has-tooltip" role="group" data-toggle="tooltip" title="<%= @event.send_mails_tooltip %>">
<%= form_tag event_email_show_path(@event), method: :get do %>
<%= hidden_field_tag "status", "rejection" %>
<%= button_tag t('.sending_rejections'), class: 'send-emails-button btn btn-default', disabled: @event.send_mails_tooltip.present? %>
<% end %>
</div>
<% end %>

</div>
<% end %>
<% if (can? :view_participants, Event) && (@event.phase == :execution) %>
<%= link_to t('events.participants.show_participants'),
event_path(@event) + "/participants" , :class => 'btn btn-primary btn-sm pull-right' %>
<% end %>

</div>
</div>

0 comments on commit 98e66dc

Please sign in to comment.