Merge branch 'master' into master
This commit is contained in:
commit
7048a37eb6
294 changed files with 10474 additions and 3147 deletions
2
.dockerignore
Normal file
2
.dockerignore
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
Dockerfile
|
||||||
|
docker-compose.*
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -36,3 +36,7 @@ pickle-email-*.html
|
||||||
.env.development
|
.env.development
|
||||||
.env.test
|
.env.test
|
||||||
.env.local
|
.env.local
|
||||||
|
docker-compose.env
|
||||||
|
docker-compose.yml
|
||||||
|
.DS_Store
|
||||||
|
.byebug_history
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# This configuration was generated by
|
# This configuration was generated by
|
||||||
# `haml-lint --auto-gen-config`
|
# `haml-lint --auto-gen-config`
|
||||||
# on 2017-04-25 04:36:49 +0530 using Haml-Lint version 0.24.0.
|
# on 2017-06-09 04:02:20 +0530 using Haml-Lint version 0.24.0.
|
||||||
# The point is for the user to remove these configuration records
|
# The point is for the user to remove these configuration records
|
||||||
# one by one as the lints are removed from the code base.
|
# one by one as the lints are removed from the code base.
|
||||||
# Note that changes in the inspected code, or installation of new
|
# Note that changes in the inspected code, or installation of new
|
||||||
|
|
@ -8,9 +8,13 @@
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
|
|
||||||
# Offense count: 952
|
# Offense count: 945
|
||||||
LineLength:
|
LineLength:
|
||||||
exclude:
|
exclude:
|
||||||
|
- "app/views/admin/booths/_change_state_dropdown.html.haml"
|
||||||
|
- "app/views/admin/booths/_form.html.haml"
|
||||||
|
- "app/views/admin/booths/index.html.haml"
|
||||||
|
- "app/views/admin/booths/show.html.haml"
|
||||||
- "app/views/admin/campaigns/_form.html.haml"
|
- "app/views/admin/campaigns/_form.html.haml"
|
||||||
- "app/views/admin/campaigns/index.html.haml"
|
- "app/views/admin/campaigns/index.html.haml"
|
||||||
- "app/views/admin/cfps/_form.html.haml"
|
- "app/views/admin/cfps/_form.html.haml"
|
||||||
|
|
@ -49,10 +53,11 @@ linters:
|
||||||
- "app/views/admin/events/_voting_index.html.haml"
|
- "app/views/admin/events/_voting_index.html.haml"
|
||||||
- "app/views/admin/events/index.html.haml"
|
- "app/views/admin/events/index.html.haml"
|
||||||
- "app/views/admin/events/registrations.html.haml"
|
- "app/views/admin/events/registrations.html.haml"
|
||||||
- "app/views/admin/events/reports.html.haml"
|
|
||||||
- "app/views/admin/events/show.html.haml"
|
- "app/views/admin/events/show.html.haml"
|
||||||
- "app/views/admin/lodgings/_form.html.haml"
|
- "app/views/admin/lodgings/_form.html.haml"
|
||||||
- "app/views/admin/lodgings/index.html.haml"
|
- "app/views/admin/lodgings/index.html.haml"
|
||||||
|
- "app/views/admin/organizations/_form.html.haml"
|
||||||
|
- "app/views/admin/organizations/index.html.haml"
|
||||||
- "app/views/admin/programs/_form.html.haml"
|
- "app/views/admin/programs/_form.html.haml"
|
||||||
- "app/views/admin/programs/show.html.haml"
|
- "app/views/admin/programs/show.html.haml"
|
||||||
- "app/views/admin/questions/_form.html.haml"
|
- "app/views/admin/questions/_form.html.haml"
|
||||||
|
|
@ -73,6 +78,7 @@ linters:
|
||||||
- "app/views/admin/resources/show.html.haml"
|
- "app/views/admin/resources/show.html.haml"
|
||||||
- "app/views/admin/roles/_form.html.haml"
|
- "app/views/admin/roles/_form.html.haml"
|
||||||
- "app/views/admin/roles/_users.html.haml"
|
- "app/views/admin/roles/_users.html.haml"
|
||||||
|
- "app/views/admin/roles/_users_with_org_admin_role.haml"
|
||||||
- "app/views/admin/roles/index.html.haml"
|
- "app/views/admin/roles/index.html.haml"
|
||||||
- "app/views/admin/roles/show.html.haml"
|
- "app/views/admin/roles/show.html.haml"
|
||||||
- "app/views/admin/rooms/_form.html.haml"
|
- "app/views/admin/rooms/_form.html.haml"
|
||||||
|
|
@ -105,6 +111,9 @@ linters:
|
||||||
- "app/views/admin/versions/_object_desc_and_link.html.haml"
|
- "app/views/admin/versions/_object_desc_and_link.html.haml"
|
||||||
- "app/views/admin/versions/index.html.haml"
|
- "app/views/admin/versions/index.html.haml"
|
||||||
- "app/views/admin/volunteers/index.html.haml"
|
- "app/views/admin/volunteers/index.html.haml"
|
||||||
|
- "app/views/booths/_form.html.haml"
|
||||||
|
- "app/views/booths/index.html.haml"
|
||||||
|
- "app/views/booths/show.html.haml"
|
||||||
- "app/views/commercials/edit.html.haml"
|
- "app/views/commercials/edit.html.haml"
|
||||||
- "app/views/commercials/new.html.haml"
|
- "app/views/commercials/new.html.haml"
|
||||||
- "app/views/conference_registrations/_form.html.haml"
|
- "app/views/conference_registrations/_form.html.haml"
|
||||||
|
|
@ -112,6 +121,7 @@ linters:
|
||||||
- "app/views/conference_registrations/_registration_info.html.haml"
|
- "app/views/conference_registrations/_registration_info.html.haml"
|
||||||
- "app/views/conference_registrations/_volunteer.html.haml"
|
- "app/views/conference_registrations/_volunteer.html.haml"
|
||||||
- "app/views/conference_registrations/show.html.haml"
|
- "app/views/conference_registrations/show.html.haml"
|
||||||
|
- "app/views/conferences/_booths.html.haml"
|
||||||
- "app/views/conferences/_call_for_paper.html.haml"
|
- "app/views/conferences/_call_for_paper.html.haml"
|
||||||
- "app/views/conferences/_conference_details.html.haml"
|
- "app/views/conferences/_conference_details.html.haml"
|
||||||
- "app/views/conferences/_gallery.html.haml"
|
- "app/views/conferences/_gallery.html.haml"
|
||||||
|
|
@ -143,7 +153,9 @@ linters:
|
||||||
- "app/views/layouts/_admin_sidebar_index.html.haml"
|
- "app/views/layouts/_admin_sidebar_index.html.haml"
|
||||||
- "app/views/layouts/_messages.html.haml"
|
- "app/views/layouts/_messages.html.haml"
|
||||||
- "app/views/layouts/_navigation.html.haml"
|
- "app/views/layouts/_navigation.html.haml"
|
||||||
|
- "app/views/layouts/_user_menu.html.haml"
|
||||||
- "app/views/layouts/application.html.haml"
|
- "app/views/layouts/application.html.haml"
|
||||||
|
- "app/views/organizations/index.html.haml"
|
||||||
- "app/views/payments/_payment.html.haml"
|
- "app/views/payments/_payment.html.haml"
|
||||||
- "app/views/proposals/_form.html.haml"
|
- "app/views/proposals/_form.html.haml"
|
||||||
- "app/views/proposals/_proposal_form.html.haml"
|
- "app/views/proposals/_proposal_form.html.haml"
|
||||||
|
|
@ -169,11 +181,21 @@ linters:
|
||||||
- "app/views/tickets/index.html.haml"
|
- "app/views/tickets/index.html.haml"
|
||||||
- "app/views/users/edit.html.haml"
|
- "app/views/users/edit.html.haml"
|
||||||
- "app/views/users/show.html.haml"
|
- "app/views/users/show.html.haml"
|
||||||
|
- "app/views/admin/cfps/index.html.haml"
|
||||||
|
- "app/views/tracks/_form.html.haml"
|
||||||
|
- "app/views/tracks/index.html.haml"
|
||||||
|
- "app/views/tracks/show.html.haml"
|
||||||
|
- "app/views/conferences/_call_for_tracks.html.haml"
|
||||||
|
- "app/views/admin/tracks/_change_state_dropdown.html.haml"
|
||||||
|
- "app/views/proposals/_encouragement_text.html.haml"
|
||||||
|
- "app/views/admin/schedules/_form.html.haml"
|
||||||
|
|
||||||
# Offense count: 222
|
# Offense count: 223
|
||||||
InstanceVariables:
|
InstanceVariables:
|
||||||
exclude:
|
exclude:
|
||||||
|
- "app/views/admin/booths/_change_state_dropdown.html.haml"
|
||||||
- "app/views/admin/campaigns/_form.html.haml"
|
- "app/views/admin/campaigns/_form.html.haml"
|
||||||
|
- "app/views/admin/cfps/_booths_cfp.html.haml"
|
||||||
- "app/views/admin/cfps/_form.html.haml"
|
- "app/views/admin/cfps/_form.html.haml"
|
||||||
- "app/views/admin/conferences/_todo_list.html.haml"
|
- "app/views/admin/conferences/_todo_list.html.haml"
|
||||||
- "app/views/admin/difficulty_levels/_form.html.haml"
|
- "app/views/admin/difficulty_levels/_form.html.haml"
|
||||||
|
|
@ -184,6 +206,7 @@ linters:
|
||||||
- "app/views/admin/events/_voting.html.haml"
|
- "app/views/admin/events/_voting.html.haml"
|
||||||
- "app/views/admin/events/_voting_index.html.haml"
|
- "app/views/admin/events/_voting_index.html.haml"
|
||||||
- "app/views/admin/lodgings/_form.html.haml"
|
- "app/views/admin/lodgings/_form.html.haml"
|
||||||
|
- "app/views/admin/organizations/_form.html.haml"
|
||||||
- "app/views/admin/questions/_questions.html.haml"
|
- "app/views/admin/questions/_questions.html.haml"
|
||||||
- "app/views/admin/registration_periods/_form.html.haml"
|
- "app/views/admin/registration_periods/_form.html.haml"
|
||||||
- "app/views/admin/reports/_all_events.html.haml"
|
- "app/views/admin/reports/_all_events.html.haml"
|
||||||
|
|
@ -226,6 +249,12 @@ linters:
|
||||||
- "app/views/schedules/_schedule.html.haml"
|
- "app/views/schedules/_schedule.html.haml"
|
||||||
- "app/views/schedules/_schedule_item.html.haml"
|
- "app/views/schedules/_schedule_item.html.haml"
|
||||||
- "app/views/schedules/_schedule_tabs.html.haml"
|
- "app/views/schedules/_schedule_tabs.html.haml"
|
||||||
|
- "app/views/admin/cfps/_events_cfp.html.haml"
|
||||||
|
- "app/views/tracks/_form.html.haml"
|
||||||
|
- "app/views/admin/cfps/_tracks_cfp.html.haml"
|
||||||
|
- "app/views/conferences/_call_for_tracks.html.haml"
|
||||||
|
- "app/views/admin/tracks/_change_state_dropdown.html.haml"
|
||||||
|
- "app/views/admin/schedules/_form.html.haml"
|
||||||
|
|
||||||
# Offense count: 32
|
# Offense count: 32
|
||||||
IdNames:
|
IdNames:
|
||||||
|
|
@ -244,15 +273,14 @@ linters:
|
||||||
- "app/views/admin/users/_event_registrations.html.haml"
|
- "app/views/admin/users/_event_registrations.html.haml"
|
||||||
- "app/views/admin/users/show.html.haml"
|
- "app/views/admin/users/show.html.haml"
|
||||||
- "app/views/users/edit.html.haml"
|
- "app/views/users/edit.html.haml"
|
||||||
|
- "app/views/admin/cfps/_events_cfp.html.haml"
|
||||||
|
- "app/views/admin/cfps/_tracks_cfp.html.haml"
|
||||||
|
|
||||||
# Offense count: 8
|
# Offense count: 4
|
||||||
UnnecessaryInterpolation:
|
UnnecessaryInterpolation:
|
||||||
exclude:
|
exclude:
|
||||||
- "app/views/admin/conferences/_doughnut_chart.html.haml"
|
- "app/views/admin/conferences/_doughnut_chart.html.haml"
|
||||||
- "app/views/admin/conferences/_recent_submissions.html.haml"
|
- "app/views/admin/conferences/_recent_submissions.html.haml"
|
||||||
- "app/views/admin/events/reports.html.haml"
|
|
||||||
- "app/views/admin/reports/_events_with_requirements.html.haml"
|
|
||||||
- "app/views/admin/reports/_events_without_commercials.html.haml"
|
|
||||||
- "app/views/proposals/_proposal_form.html.haml"
|
- "app/views/proposals/_proposal_form.html.haml"
|
||||||
- "app/views/proposals/new.html.haml"
|
- "app/views/proposals/new.html.haml"
|
||||||
|
|
||||||
|
|
@ -282,6 +310,7 @@ linters:
|
||||||
SpaceInsideHashAttributes:
|
SpaceInsideHashAttributes:
|
||||||
exclude:
|
exclude:
|
||||||
- "app/views/admin/conferences/_todo_list.html.haml"
|
- "app/views/admin/conferences/_todo_list.html.haml"
|
||||||
|
- "app/views/admin/emails/index.html.haml"
|
||||||
- "app/views/admin/questions/_form.html.haml"
|
- "app/views/admin/questions/_form.html.haml"
|
||||||
- "app/views/admin/questions/index.html.haml"
|
- "app/views/admin/questions/index.html.haml"
|
||||||
- "app/views/admin/registrations/index.html.haml"
|
- "app/views/admin/registrations/index.html.haml"
|
||||||
|
|
@ -327,12 +356,13 @@ linters:
|
||||||
- "app/views/shared/_object_changes.html.haml"
|
- "app/views/shared/_object_changes.html.haml"
|
||||||
- "app/views/tickets/_ticket.html.haml"
|
- "app/views/tickets/_ticket.html.haml"
|
||||||
- "app/views/tickets/index.html.haml"
|
- "app/views/tickets/index.html.haml"
|
||||||
|
- "app/views/tracks/index.html.haml"
|
||||||
|
- "app/views/tracks/show.html.haml"
|
||||||
|
|
||||||
# Offense count: 27
|
# Offense count: 23
|
||||||
ClassesBeforeIds:
|
ClassesBeforeIds:
|
||||||
exclude:
|
exclude:
|
||||||
- "app/views/admin/emails/index.html.haml"
|
- "app/views/admin/emails/index.html.haml"
|
||||||
- "app/views/admin/events/reports.html.haml"
|
|
||||||
- "app/views/admin/events/show.html.haml"
|
- "app/views/admin/events/show.html.haml"
|
||||||
- "app/views/admin/reports/index.html.haml"
|
- "app/views/admin/reports/index.html.haml"
|
||||||
- "app/views/admin/users/show.html.haml"
|
- "app/views/admin/users/show.html.haml"
|
||||||
|
|
@ -356,6 +386,7 @@ linters:
|
||||||
- "app/views/admin/tracks/show.html.haml"
|
- "app/views/admin/tracks/show.html.haml"
|
||||||
- "app/views/admin/venues/show.html.haml"
|
- "app/views/admin/venues/show.html.haml"
|
||||||
- "app/views/admin/versions/index.html.haml"
|
- "app/views/admin/versions/index.html.haml"
|
||||||
|
- "app/views/booths/index.html.haml"
|
||||||
- "app/views/conference_registrations/_form.html.haml"
|
- "app/views/conference_registrations/_form.html.haml"
|
||||||
- "app/views/conference_registrations/_ticket.html.haml"
|
- "app/views/conference_registrations/_ticket.html.haml"
|
||||||
- "app/views/conference_registrations/show.html.haml"
|
- "app/views/conference_registrations/show.html.haml"
|
||||||
|
|
@ -380,12 +411,27 @@ linters:
|
||||||
# Offense count: 14
|
# Offense count: 14
|
||||||
ConsecutiveSilentScripts:
|
ConsecutiveSilentScripts:
|
||||||
exclude:
|
exclude:
|
||||||
|
- "app/views/admin/booths/_change_state_dropdown.html.haml"
|
||||||
- "app/views/admin/events/index.html.haml"
|
- "app/views/admin/events/index.html.haml"
|
||||||
- "app/views/admin/schedules/_day_tab.html.haml"
|
- "app/views/admin/schedules/_day_tab.html.haml"
|
||||||
- "app/views/admin/schedules/_event.html.haml"
|
- "app/views/admin/schedules/_event.html.haml"
|
||||||
- "app/views/admin/versions/_object_desc_and_link.html.haml"
|
- "app/views/admin/versions/_object_desc_and_link.html.haml"
|
||||||
|
- "app/views/booths/index.html.haml"
|
||||||
- "app/views/schedules/_carousel.html.haml"
|
- "app/views/schedules/_carousel.html.haml"
|
||||||
|
|
||||||
|
# Offense count: 29
|
||||||
|
TrailingWhitespace:
|
||||||
|
exclude:
|
||||||
|
- "app/views/admin/organizations/_form.html.haml"
|
||||||
|
- "app/views/admin/users/index.html.haml"
|
||||||
|
- "app/views/admin/users/show.html.haml"
|
||||||
|
- "app/views/admin/volunteers/index.html.haml"
|
||||||
|
- "app/views/admin/volunteers/show.html.haml"
|
||||||
|
- "app/views/conference_registrations/_volunteer.html.haml"
|
||||||
|
- "app/views/devise/passwords/new.html.haml"
|
||||||
|
- "app/views/payments/new.html.haml"
|
||||||
|
- "app/views/tickets/index.html.haml"
|
||||||
|
|
||||||
# Offense count: 2
|
# Offense count: 2
|
||||||
FinalNewline:
|
FinalNewline:
|
||||||
exclude:
|
exclude:
|
||||||
|
|
@ -406,19 +452,6 @@ linters:
|
||||||
- "app/views/schedules/_event.html.haml"
|
- "app/views/schedules/_event.html.haml"
|
||||||
- "app/views/schedules/_schedule_item.html.haml"
|
- "app/views/schedules/_schedule_item.html.haml"
|
||||||
|
|
||||||
# Offense count: 38
|
|
||||||
TrailingWhitespace:
|
|
||||||
exclude:
|
|
||||||
- "app/views/admin/users/_form.html.haml"
|
|
||||||
- "app/views/admin/users/index.html.haml"
|
|
||||||
- "app/views/admin/users/show.html.haml"
|
|
||||||
- "app/views/admin/volunteers/index.html.haml"
|
|
||||||
- "app/views/admin/volunteers/show.html.haml"
|
|
||||||
- "app/views/conference_registrations/_volunteer.html.haml"
|
|
||||||
- "app/views/devise/passwords/new.html.haml"
|
|
||||||
- "app/views/payments/new.html.haml"
|
|
||||||
- "app/views/tickets/index.html.haml"
|
|
||||||
|
|
||||||
# Offense count: 7
|
# Offense count: 7
|
||||||
ClassAttributeWithStaticValue:
|
ClassAttributeWithStaticValue:
|
||||||
exclude:
|
exclude:
|
||||||
|
|
|
||||||
171
.rubocop.yml
171
.rubocop.yml
|
|
@ -13,100 +13,6 @@ AllCops:
|
||||||
- 'config/**/*'
|
- 'config/**/*'
|
||||||
- 'bin/*'
|
- 'bin/*'
|
||||||
|
|
||||||
#################### Style ###############################
|
|
||||||
|
|
||||||
# Align the elements of a hash literal if they span more than one line
|
|
||||||
Style/AlignHash:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Align the parameters of a method call if they span more than one line
|
|
||||||
Style/AlignParameters:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use && instead of and, use || instead of or
|
|
||||||
Style/AndOr:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Avoid redundunt curly braces when it is obvious that hash is used
|
|
||||||
Style/BracesAroundHashParameters:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Avoid the use of the case equality operator `===`
|
|
||||||
Style/CaseEquality:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use nested module/class definitions instead of compact style
|
|
||||||
Style/ClassAndModuleChildren:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks the . position in multi-line method calls.
|
|
||||||
Style/DotPosition:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks for uses of double negation (!!) to convert something to a boolean value.
|
|
||||||
Style/DoubleNegation:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use one empty line between method definitions
|
|
||||||
Style/EmptyLineBetweenDefs:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# There should be only one empty line in designated place
|
|
||||||
Style/EmptyLines:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Keep a blank line before and after private.
|
|
||||||
Style/EmptyLinesAroundAccessModifier:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use hash literal {} instead of Hash.new
|
|
||||||
Style/EmptyLiteral:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Prefer `each` over `for i`
|
|
||||||
Style/For:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use the new Ruby 1.9 hash syntax
|
|
||||||
Style/HashSyntax:
|
|
||||||
Enabled: true
|
|
||||||
EnforcedStyle: ruby19
|
|
||||||
|
|
||||||
# Checks for uses of if with negated condition. Use unless instead
|
|
||||||
Style/NegatedIf:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Do not compare with nil. Use .nil? instead
|
|
||||||
Style/NilComparison:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks for redundant uses of self.
|
|
||||||
Style/RedundantSelf:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Checks that operators have space around them, except for ** which should not have surrounding space.
|
|
||||||
Style/SpaceAroundOperators:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use single quotes unless there's string interpolation
|
|
||||||
Style/StringLiterals:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# This cop checks for tabs where spaces should be used.
|
|
||||||
Style/Tab:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Avoid trailing blank lines
|
|
||||||
Style/TrailingBlankLines:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Avoid trailing whitespace
|
|
||||||
Style/TrailingWhitespace:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# This cop checks for numeric comparisons that can be replaced by a predicate method.
|
|
||||||
Style/ZeroLengthPredicate:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
#################### Metrics ###############################
|
#################### Metrics ###############################
|
||||||
|
|
||||||
|
|
@ -123,77 +29,6 @@ Metrics/ClassLength:
|
||||||
Metrics/BlockLength:
|
Metrics/BlockLength:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'spec/models/conference_spec.rb'
|
- 'spec/models/conference_spec.rb'
|
||||||
|
- 'spec/features/ability_spec.rb'
|
||||||
#################### Lint ###############################
|
- 'spec/models/ability_spec.rb'
|
||||||
|
- 'spec/models/admin_ability_spec.rb'
|
||||||
# Wrap your assignment in condition if you mean it, otherwise it is most likely equality check
|
|
||||||
Lint/AssignmentInCondition:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Align blocks of code properly
|
|
||||||
Lint/BlockAlignment:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Things deprecated in current ruby API
|
|
||||||
Lint/DeprecatedClassMethods:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Do not use literal in conditions. We have it enabled for now
|
|
||||||
Lint/LiteralInCondition:
|
|
||||||
Enabled: false
|
|
||||||
|
|
||||||
# Prefer `Kernel#loop -> break` over `begin -> while`
|
|
||||||
Lint/Loop:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Do not put space before arguments when they are in parentheses
|
|
||||||
Lint/ParenthesesAsGroupedExpression:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Do not rescue Exceptions class itself
|
|
||||||
Lint/RescueException:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Do not shadow local variables in blocks, choose other name
|
|
||||||
Lint/ShadowingOuterLocalVariable:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use _ or variable_name to explicitly mark variable as unused
|
|
||||||
Lint/UnusedBlockArgument:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Use _ or _argument_name to explicitly mark argument as unused
|
|
||||||
Lint/UnusedMethodArgument:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Avoid useless assignment
|
|
||||||
Lint/UselessAssignment:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Do not use variables in void context
|
|
||||||
Lint/Void:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Do not use duplicated keys in hash literals.
|
|
||||||
Lint/DuplicatedKey:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
#################### Rails ###############################
|
|
||||||
|
|
||||||
# Enforce Rails specific style
|
|
||||||
Rails:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Avoid use of old-style attribute validation
|
|
||||||
Rails/Validation:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
# Looks for delegations, that could have been created automatically with delegate method
|
|
||||||
Rails/Delegate:
|
|
||||||
Enabled: true
|
|
||||||
|
|
||||||
#################### Performance ###############################
|
|
||||||
|
|
||||||
# Identifies places where gsub can be replaced by tr or delete.
|
|
||||||
Performance/StringReplacement:
|
|
||||||
Enabled: true
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
13
.travis.yml
13
.travis.yml
|
|
@ -3,12 +3,12 @@ dist: trusty
|
||||||
language: ruby
|
language: ruby
|
||||||
cache: bundler
|
cache: bundler
|
||||||
rvm:
|
rvm:
|
||||||
- 2.2.3
|
- 2.4.0
|
||||||
before_install:
|
before_install:
|
||||||
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
|
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
|
||||||
- "echo `phantomjs -v`"
|
- "echo `phantomjs -v`"
|
||||||
addons:
|
addons:
|
||||||
mariadb: '10.1'
|
mariadb: '10.2'
|
||||||
notifications:
|
notifications:
|
||||||
email:
|
email:
|
||||||
on_success: change
|
on_success: change
|
||||||
|
|
@ -24,6 +24,9 @@ before_script:
|
||||||
- mysql -u root -e 'create database osem_test;'
|
- mysql -u root -e 'create database osem_test;'
|
||||||
- RAILS_ENV=test bundle exec rake db:migrate --trace
|
- RAILS_ENV=test bundle exec rake db:migrate --trace
|
||||||
script:
|
script:
|
||||||
- 'bundle exec rubocop -Dc .rubocop.yml'
|
- "./travis_script.sh $TEST_SUITE"
|
||||||
- 'bundle exec haml-lint app/views'
|
env:
|
||||||
- 'bundle exec rspec --color --format documentation'
|
- TEST_SUITE=rspec
|
||||||
|
- TEST_SUITE=linters
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
|
|
||||||
1
CODE_OF_CONDUCT.md
Normal file
1
CODE_OF_CONDUCT.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
OSEM is part of the openSUSE project. We follow all the [openSUSE Guiding Principles!](http://en.opensuse.org/openSUSE:Guiding_principles) If you think someone doesn't do that, please let us know at maintainers@osem.io
|
||||||
101
CONTRIBUTING.md
101
CONTRIBUTING.md
|
|
@ -71,59 +71,6 @@ You can access the app [localhost:3000](http://localhost:3000). Whatever you cha
|
||||||
* If you are already a contributor and you get a positive review, you can merge your pull-request yourself
|
* If you are already a contributor and you get a positive review, you can merge your pull-request yourself
|
||||||
* If you are not already a contributor please request a merge via the pull-request comments
|
* If you are not already a contributor please request a merge via the pull-request comments
|
||||||
|
|
||||||
### Getting Started
|
|
||||||
|
|
||||||
* When you get involved with OSEM for the first time, you can choose issues labeled as [Junior]( https://github.com/openSUSE/osem/issues?q=is%3Aissue+is%3Aopen+label%3AJunior)
|
|
||||||
* Leave a comment on the issue that you want to work on it
|
|
||||||
* We expect you to work on it and show progress by either opening a PR or commenting on the issue
|
|
||||||
* If you change your mind, and do not want to work on the issue any more, please be fair to others and leave a comment to let us know
|
|
||||||
* Do **not** work on issues that are assigned to others. If you are uncertain, ask and wait for a **contributor** to reply
|
|
||||||
* Avoid working on issues that have no label
|
|
||||||
* If you have opened a new issue, please wait for a contributor to add relevant labels
|
|
||||||
* If an issue is a feature, we should first have a rough idea on how we want to implement it
|
|
||||||
* If there is already such a discussion on the issue, you can go ahead and pick this up
|
|
||||||
* If not, please first leave a comment on how you want to implement it and wait for contributors' feedback
|
|
||||||
|
|
||||||
### Commits
|
|
||||||
* Commit title should be short and descriptive
|
|
||||||
* title (or summary line) is the first line of the commit message
|
|
||||||
* that says what the commit is doing
|
|
||||||
* in no more than 50 characters
|
|
||||||
* starting with a word like 'Fix' or 'Add' or 'Change'
|
|
||||||
* **without** a period (.) at the end
|
|
||||||
* followed by a blank line
|
|
||||||
* Commit messages are
|
|
||||||
* up to 72 characters
|
|
||||||
* with break lines
|
|
||||||
* Reference the issue(s) the commit closes
|
|
||||||
* https://help.github.com/articles/closing-issues-via-commit-messages
|
|
||||||
* If you haven't done so since the beginning, you should reference the issue when you squash your commits
|
|
||||||
|
|
||||||
### Pull Requests workflow
|
|
||||||
Please open a pull request (PR) only when you have finished coding, and your changes are ready to be reviewed for merging.
|
|
||||||
|
|
||||||
* Title
|
|
||||||
* Include a comprehensive title about what this PR is doing
|
|
||||||
* Referencing the issue number on the PR title is not giving any information about what this PR is about
|
|
||||||
* The title should be short (50 characters maximum); you can add more information in the description
|
|
||||||
* Description
|
|
||||||
* Add a couple of lines about what is the problem you are trying to solve and how you have addressed it
|
|
||||||
* Add bullet points about the new things you are introducing, if applicable
|
|
||||||
* Reference the issue(s) you are solving
|
|
||||||
* Add a screenshot of your change, if you are working on something that changes how the app looks like
|
|
||||||
* Automated checks
|
|
||||||
* We automatically run the [test suite](https://github.com/openSUSE/osem/blob/master/CONTRIBUTING.md#test-suite) and security checks on every PR
|
|
||||||
* Check back later to see if all checks were successful, if not, address them or leave a comment to ask for help
|
|
||||||
* Pushing new changes to your PR
|
|
||||||
* Always add **new** commits; this tremendously helps reviewers
|
|
||||||
* Do not squash commits, unless explicitly requested by the reviewer
|
|
||||||
* Take care of your PR
|
|
||||||
* Make sure you check the status of your PR regularly
|
|
||||||
* Address your reviews, make the necessary changes, ask if something is not clear to you
|
|
||||||
* Rebase against newest changes, when needed; we cannot properly review PRs that are not rebased
|
|
||||||
|
|
||||||
Reviewing your PR might take some time, as we are all volunteers. Please be responsive and respectful.
|
|
||||||
|
|
||||||
### Coding Style
|
### Coding Style
|
||||||
We are using [rubocop](https://github.com/bbatsov/rubocop) as a style checker. It is checking code style each time the test suite runs. You can run it locally with
|
We are using [rubocop](https://github.com/bbatsov/rubocop) as a style checker. It is checking code style each time the test suite runs. You can run it locally with
|
||||||
|
|
||||||
|
|
@ -141,16 +88,6 @@ We are using [rspec](http://rspec.info/)+[capybara](http://jnicklas.github.io/ca
|
||||||
vagrant exec bundle exec rspec
|
vagrant exec bundle exec rspec
|
||||||
```
|
```
|
||||||
|
|
||||||
### Review App of your PR
|
|
||||||
|
|
||||||
OSEM uses [Review Apps](https://devcenter.heroku.com/articles/github-integration-review-apps) on Heroku.
|
|
||||||
|
|
||||||
* The review app can be manually created by a maintainer, and when that happens you will see a relevant message in the PR
|
|
||||||
|
|
||||||
* Please help reviewers by adding the necessary data relevant to your PR,
|
|
||||||
eg. if your PR is doing something related to conference registrations, go to the review app and make sure there is a conference with registrations.
|
|
||||||
|
|
||||||
|
|
||||||
### Email Notifications
|
### Email Notifications
|
||||||
**Note**: We use [letter_opener](https://github.com/ryanb/letter_opener) in development environment. You can check out your mails by visiting [localhost:3000/letter_opener](http://localhost:3000/letter_opener).
|
**Note**: We use [letter_opener](https://github.com/ryanb/letter_opener) in development environment. You can check out your mails by visiting [localhost:3000/letter_opener](http://localhost:3000/letter_opener).
|
||||||
|
|
||||||
|
|
@ -181,44 +118,6 @@ OSEM_GITHUB_SECRET='sample'
|
||||||
|
|
||||||
If you don't already have a `.env` file you can use the `dotenv.example` as a template.
|
If you don't already have a `.env` file you can use the `dotenv.example` as a template.
|
||||||
|
|
||||||
## Labels for issues and PRs
|
|
||||||
...and what they mean!
|
|
||||||
|
|
||||||
1. **Bug**
|
|
||||||
* A bug in the application, something is wrong and needs to be fixed!
|
|
||||||
* Ideally the issue includes details on how to reproduce the bug
|
|
||||||
* Reproduce the bug in master branch, and send a PR that solves it
|
|
||||||
2. **Design**
|
|
||||||
* Related to the looks and/or usability of the application; needs attention from someone who understands front-end and UX
|
|
||||||
* If you are good with graphics and design, give it a shot!
|
|
||||||
3. **Documentation**
|
|
||||||
* Related to the documentation of our application, eg our INSTALL.md file or a wiki page with instructions on how to use the app, or part of it.
|
|
||||||
* If you are working on a documentation issue, make sure you are covering all cases.
|
|
||||||
4. **Epic**
|
|
||||||
* We may, or may not, solve this, thus it is epic. It's bigger than a feature request, because it fundamentally changes or affects the app, or a significant part of it.
|
|
||||||
* Do **not** work on this without prior discussion with the maintainers, it's called epic for a reason!
|
|
||||||
5. **Feature**
|
|
||||||
* This is a new feature for something new in the app!
|
|
||||||
* If an issue is labeled *Feature*, don't work on the issue, unless the maintainers have decided on how to proceed
|
|
||||||
* Ideally, leave a comment with your proposed solution in the issue and wait for feedback
|
|
||||||
6. **Grooming**
|
|
||||||
* This is working, but could look better, thus needs some attention and grooming.
|
|
||||||
7. **Hacktoberfest**
|
|
||||||
* This is for the issues included in the coding event of Hacktoberfest. You can ignore it, when the event is not on
|
|
||||||
8. **in progress**
|
|
||||||
9. **Junior**
|
|
||||||
* For new comers! RoR beginners or people unfamiliar with the application. Where you must start if you are interested in a mentoring program we participate in.
|
|
||||||
10. **need feedback**
|
|
||||||
* Maintainers' attention is needed to decide if this is something we want in the app, and/or how it should be implemented
|
|
||||||
11. **Operation**
|
|
||||||
12. **ready**
|
|
||||||
13. **Refactorization**
|
|
||||||
* Our code needs to be re-written; to avoid code duplication, or make the code more readable, or do things in a simpler way!
|
|
||||||
14. **Research**
|
|
||||||
* Ideas to explore; and think if there is anything we want to include in our app.
|
|
||||||
15. **GSoC**
|
|
||||||
* To group all the issues and PRs related to Google Summer of Code together.
|
|
||||||
|
|
||||||
## Code of Conduct
|
## Code of Conduct
|
||||||
OSEM is part of the openSUSE project. We follow all the [openSUSE Guiding Principles!](http://en.opensuse.org/openSUSE:Guiding_principles) If you think someone doesn't do that, please let us know at maintainers@osem.io
|
OSEM is part of the openSUSE project. We follow all the [openSUSE Guiding Principles!](http://en.opensuse.org/openSUSE:Guiding_principles) If you think someone doesn't do that, please let us know at maintainers@osem.io
|
||||||
|
|
||||||
|
|
|
||||||
45
Dockerfile
Normal file
45
Dockerfile
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
FROM ruby:2.3
|
||||||
|
|
||||||
|
MAINTAINER TheAssassin <theassassin@users.noreply.github.com>
|
||||||
|
|
||||||
|
# required for compiling assets
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y nodejs nodejs-legacy mariadb-client imagemagick
|
||||||
|
|
||||||
|
# used to run the container without root permissions
|
||||||
|
RUN adduser --home /osem/ --system --group --disabled-login --disabled-password osem
|
||||||
|
|
||||||
|
# required to detect when the database is up and running in init.sh
|
||||||
|
RUN cd /usr/bin && \
|
||||||
|
wget https://github.com/jwilder/dockerize/releases/download/v0.3.0/dockerize-linux-amd64-v0.3.0.tar.gz -O dockerize.tar.gz && \
|
||||||
|
echo "36e8319cdf9d2b07340f456ec61cfa0f495ec6c130b02ad9c116fd55a5c43fa1 dockerize.tar.gz" | sha256sum -c && \
|
||||||
|
tar -xf dockerize.tar.gz && \
|
||||||
|
rm dockerize.tar.gz
|
||||||
|
|
||||||
|
# explicitly add Gemfile and install dependencies using bundler to make use of
|
||||||
|
# Docker's caching
|
||||||
|
WORKDIR /osem/
|
||||||
|
COPY Gemfile /osem/
|
||||||
|
COPY Gemfile.lock /osem/
|
||||||
|
RUN bundle install --without test development
|
||||||
|
|
||||||
|
# add OSEM files and prepare them for use inside a Docker container
|
||||||
|
COPY . /osem/
|
||||||
|
RUN chown osem.osem /osem/ -R && \
|
||||||
|
mv /osem/config/database.yml.docker /osem/config/database.yml
|
||||||
|
|
||||||
|
# data directory is used to cache the secret key in a file
|
||||||
|
ENV DATA_DIR /data
|
||||||
|
RUN install -d -m 0700 -o osem $DATA_DIR
|
||||||
|
VOLUME ["$DATA_DIR"]
|
||||||
|
|
||||||
|
USER osem
|
||||||
|
EXPOSE 9292
|
||||||
|
|
||||||
|
COPY docker/init.sh /init.sh
|
||||||
|
|
||||||
|
# a user could override this if they wanted to serve the static files directly
|
||||||
|
# from a webserver
|
||||||
|
ENV RAILS_SERVE_STATIC_FILES 1
|
||||||
|
|
||||||
|
CMD ["bash", "/init.sh"]
|
||||||
25
Gemfile
25
Gemfile
|
|
@ -6,7 +6,7 @@ if Gem::Version.new(Bundler::VERSION) < Gem::Version.new('1.8.4')
|
||||||
end
|
end
|
||||||
|
|
||||||
# as web framework
|
# as web framework
|
||||||
gem 'rails', '~> 4.2'
|
gem 'rails', '~> 4.2.8'
|
||||||
|
|
||||||
# enables serving assets in production and setting your logger to standard out
|
# enables serving assets in production and setting your logger to standard out
|
||||||
# both of which are required to run an application on a twelve-factor provider
|
# both of which are required to run an application on a twelve-factor provider
|
||||||
|
|
@ -18,10 +18,9 @@ gem 'rails_12factor', group: :production
|
||||||
gem 'responders', '~> 2.0'
|
gem 'responders', '~> 2.0'
|
||||||
|
|
||||||
# as the database for Active Record
|
# as the database for Active Record
|
||||||
|
# choose only one
|
||||||
gem 'mysql2'
|
gem 'mysql2'
|
||||||
|
# gem 'pg'
|
||||||
# for observing records
|
|
||||||
gem 'rails-observers'
|
|
||||||
|
|
||||||
# for tracking data changes
|
# for tracking data changes
|
||||||
gem 'paper_trail'
|
gem 'paper_trail'
|
||||||
|
|
@ -58,7 +57,7 @@ gem 'unobtrusive_flash', '>=3'
|
||||||
gem 'transitions', :require => %w( transitions active_record/transitions )
|
gem 'transitions', :require => %w( transitions active_record/transitions )
|
||||||
|
|
||||||
# for comments
|
# for comments
|
||||||
gem 'awesome_nested_set', '~> 3.0.0.rc.5'
|
gem 'awesome_nested_set', '~> 3.1.3'
|
||||||
gem 'acts_as_commentable_with_threading'
|
gem 'acts_as_commentable_with_threading'
|
||||||
|
|
||||||
# as templating language
|
# as templating language
|
||||||
|
|
@ -84,6 +83,8 @@ gem 'jquery-ui-rails', '~> 4.2.1'
|
||||||
# for languages validation
|
# for languages validation
|
||||||
gem 'iso-639'
|
gem 'iso-639'
|
||||||
|
|
||||||
|
gem 'thor', '0.19.1'
|
||||||
|
|
||||||
# frontend javascripts
|
# frontend javascripts
|
||||||
source 'https://rails-assets.org' do
|
source 'https://rails-assets.org' do
|
||||||
# for placeholder images
|
# for placeholder images
|
||||||
|
|
@ -126,8 +127,11 @@ gem 'country_select'
|
||||||
|
|
||||||
# as PDF generator
|
# as PDF generator
|
||||||
gem 'prawn_rails'
|
gem 'prawn_rails'
|
||||||
|
gem 'rqrcode'
|
||||||
|
gem 'prawn-qrcode', '~> 0.2.2.1'
|
||||||
|
|
||||||
# to render XLS spreadsheets
|
# to render XLS spreadsheets
|
||||||
|
gem 'axlsx', git: 'https://github.com/randym/axlsx.git'
|
||||||
gem 'axlsx_rails'
|
gem 'axlsx_rails'
|
||||||
|
|
||||||
# as error catcher
|
# as error catcher
|
||||||
|
|
@ -196,14 +200,19 @@ gem 'sprockets-rails'
|
||||||
# for multiple speakers select on proposal/event forms
|
# for multiple speakers select on proposal/event forms
|
||||||
gem 'selectize-rails'
|
gem 'selectize-rails'
|
||||||
|
|
||||||
|
# Nokogiri < 1.8.1 is subject to:
|
||||||
|
# CVE-2017-0663, CVE-2017-7375, CVE-2017-7376, CVE-2017-9047, CVE-2017-9048,
|
||||||
|
# CVE-2017-9049, CVE-2017-9050
|
||||||
|
gem 'nokogiri', '>= 1.8.1'
|
||||||
|
|
||||||
# Use guard and spring for testing in development
|
# Use guard and spring for testing in development
|
||||||
group :development do
|
group :development do
|
||||||
# to launch specs when files are modified
|
# to launch specs when files are modified
|
||||||
gem 'guard-rspec', '~> 4.2.8'
|
gem 'guard-rspec'
|
||||||
gem 'spring-commands-rspec'
|
gem 'spring-commands-rspec'
|
||||||
gem 'haml_lint', '~> 0.24.0'
|
gem 'haml_lint', '~> 0.24.0'
|
||||||
# for static code analisys
|
# for static code analisys
|
||||||
gem 'rubocop', '~> 0.48.1', require: false
|
gem 'rubocop', '~> 0.49.0', require: false
|
||||||
# as database
|
# as database
|
||||||
gem 'sqlite3'
|
gem 'sqlite3'
|
||||||
# to open mails
|
# to open mails
|
||||||
|
|
@ -218,7 +227,7 @@ end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
# as test framework
|
# as test framework
|
||||||
gem 'rspec-rails'
|
gem 'rspec-rails', '~> 3.5', '>= 3.5.2'
|
||||||
gem 'database_cleaner'
|
gem 'database_cleaner'
|
||||||
gem 'capybara'
|
gem 'capybara'
|
||||||
gem 'poltergeist'
|
gem 'poltergeist'
|
||||||
|
|
|
||||||
354
Gemfile.lock
354
Gemfile.lock
|
|
@ -1,41 +1,50 @@
|
||||||
|
GIT
|
||||||
|
remote: https://github.com/randym/axlsx.git
|
||||||
|
revision: c8ac844572b25fda358cc01d2104720c4c42f450
|
||||||
|
specs:
|
||||||
|
axlsx (2.1.0.pre)
|
||||||
|
htmlentities (~> 4.3.4)
|
||||||
|
mimemagic (~> 0.3)
|
||||||
|
nokogiri (>= 1.6.6)
|
||||||
|
rubyzip (>= 1.2.1)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
remote: https://rails-assets.org/
|
remote: https://rails-assets.org/
|
||||||
specs:
|
specs:
|
||||||
actionmailer (4.2.7.1)
|
actionmailer (4.2.9)
|
||||||
actionpack (= 4.2.7.1)
|
actionpack (= 4.2.9)
|
||||||
actionview (= 4.2.7.1)
|
actionview (= 4.2.9)
|
||||||
activejob (= 4.2.7.1)
|
activejob (= 4.2.9)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
actionpack (4.2.7.1)
|
actionpack (4.2.9)
|
||||||
actionview (= 4.2.7.1)
|
actionview (= 4.2.9)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.9)
|
||||||
rack (~> 1.6)
|
rack (~> 1.6)
|
||||||
rack-test (~> 0.6.2)
|
rack-test (~> 0.6.2)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
actionview (4.2.7.1)
|
actionview (4.2.9)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.9)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubis (~> 2.7.0)
|
erubis (~> 2.7.0)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||||
active_model_serializers (0.9.4)
|
active_model_serializers (0.9.4)
|
||||||
activemodel (>= 3.2)
|
activemodel (>= 3.2)
|
||||||
activejob (4.2.7.1)
|
activejob (4.2.9)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.9)
|
||||||
globalid (>= 0.3.0)
|
globalid (>= 0.3.0)
|
||||||
activemodel (4.2.7.1)
|
activemodel (4.2.9)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.9)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
activerecord (4.2.7.1)
|
activerecord (4.2.9)
|
||||||
activemodel (= 4.2.7.1)
|
activemodel (= 4.2.9)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.9)
|
||||||
arel (~> 6.0)
|
arel (~> 6.0)
|
||||||
activesupport (4.2.7.1)
|
activesupport (4.2.9)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
json (~> 1.7, >= 1.7.7)
|
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
thread_safe (~> 0.3, >= 0.3.4)
|
thread_safe (~> 0.3, >= 0.3.4)
|
||||||
tzinfo (~> 1.1)
|
tzinfo (~> 1.1)
|
||||||
|
|
@ -48,7 +57,8 @@ GEM
|
||||||
awesome_nested_set (>= 2.0)
|
awesome_nested_set (>= 2.0)
|
||||||
acts_as_list (0.4.0)
|
acts_as_list (0.4.0)
|
||||||
activerecord (>= 3.0)
|
activerecord (>= 3.0)
|
||||||
addressable (2.3.6)
|
addressable (2.5.1)
|
||||||
|
public_suffix (~> 2.0, >= 2.0.2)
|
||||||
ahoy_matey (1.0.0)
|
ahoy_matey (1.0.0)
|
||||||
addressable
|
addressable
|
||||||
browser (>= 0.4.0)
|
browser (>= 0.4.0)
|
||||||
|
|
@ -57,18 +67,13 @@ GEM
|
||||||
request_store
|
request_store
|
||||||
user_agent_parser
|
user_agent_parser
|
||||||
uuidtools
|
uuidtools
|
||||||
arel (6.0.3)
|
arel (6.0.4)
|
||||||
ast (2.3.0)
|
ast (2.3.0)
|
||||||
autoprefixer-rails (5.1.9)
|
autoprefixer-rails (7.1.1)
|
||||||
execjs
|
execjs
|
||||||
json
|
awesome_nested_set (3.1.3)
|
||||||
awesome_nested_set (3.0.0.rc.5)
|
activerecord (>= 4.0.0, < 5.2)
|
||||||
activerecord (>= 4.0.0, < 5)
|
|
||||||
aws_cf_signer (0.1.3)
|
aws_cf_signer (0.1.3)
|
||||||
axlsx (2.0.1)
|
|
||||||
htmlentities (~> 4.3.1)
|
|
||||||
nokogiri (>= 1.4.1)
|
|
||||||
rubyzip (~> 1.2.1)
|
|
||||||
axlsx_rails (0.2.0)
|
axlsx_rails (0.2.0)
|
||||||
axlsx (>= 2.0.1)
|
axlsx (>= 2.0.1)
|
||||||
rails (>= 3.1)
|
rails (>= 3.1)
|
||||||
|
|
@ -82,10 +87,8 @@ GEM
|
||||||
bootstrap3-datetimepicker-rails (3.0.3)
|
bootstrap3-datetimepicker-rails (3.0.3)
|
||||||
momentjs-rails (>= 2.8.1)
|
momentjs-rails (>= 2.8.1)
|
||||||
browser (0.6.0)
|
browser (0.6.0)
|
||||||
builder (3.2.2)
|
builder (3.2.3)
|
||||||
byebug (3.1.2)
|
byebug (9.0.6)
|
||||||
columnize (~> 0.8)
|
|
||||||
debugger-linecache (~> 1.2)
|
|
||||||
cancancan (1.13.1)
|
cancancan (1.13.1)
|
||||||
capybara (2.6.2)
|
capybara (2.6.2)
|
||||||
addressable
|
addressable
|
||||||
|
|
@ -103,28 +106,24 @@ GEM
|
||||||
activesupport (>= 3.2.0)
|
activesupport (>= 3.2.0)
|
||||||
carrierwave
|
carrierwave
|
||||||
fastimage
|
fastimage
|
||||||
celluloid (0.15.2)
|
|
||||||
timers (~> 1.1.0)
|
|
||||||
celluloid-io (0.15.0)
|
|
||||||
celluloid (>= 0.15.0)
|
|
||||||
nio4r (>= 0.5.0)
|
|
||||||
chart-js-rails (0.0.6)
|
chart-js-rails (0.0.6)
|
||||||
railties (> 3.1)
|
railties (> 3.1)
|
||||||
chronic (0.10.2)
|
chronic (0.10.2)
|
||||||
|
chunky_png (1.3.8)
|
||||||
cliver (0.3.2)
|
cliver (0.3.2)
|
||||||
cloudinary (1.1.6)
|
cloudinary (1.1.6)
|
||||||
aws_cf_signer
|
aws_cf_signer
|
||||||
rest-client
|
rest-client
|
||||||
cocoon (1.2.6)
|
cocoon (1.2.6)
|
||||||
coderay (1.1.0)
|
coderay (1.1.1)
|
||||||
coffee-rails (4.1.1)
|
coffee-rails (4.2.2)
|
||||||
coffee-script (>= 2.2.0)
|
coffee-script (>= 2.2.0)
|
||||||
railties (>= 4.0.0, < 5.1.x)
|
railties (>= 4.0.0)
|
||||||
coffee-script (2.4.1)
|
coffee-script (2.4.1)
|
||||||
coffee-script-source
|
coffee-script-source
|
||||||
execjs
|
execjs
|
||||||
coffee-script-source (1.10.0)
|
coffee-script-source (1.12.2)
|
||||||
columnize (0.8.9)
|
concurrent-ruby (1.0.5)
|
||||||
countable-rails (0.0.1)
|
countable-rails (0.0.1)
|
||||||
railties (>= 3.1)
|
railties (>= 3.1)
|
||||||
countries (1.2.5)
|
countries (1.2.5)
|
||||||
|
|
@ -139,18 +138,17 @@ GEM
|
||||||
term-ansicolor (~> 1.3)
|
term-ansicolor (~> 1.3)
|
||||||
thor (~> 0.19.1)
|
thor (~> 0.19.1)
|
||||||
tins (~> 1.6.0)
|
tins (~> 1.6.0)
|
||||||
crack (0.4.2)
|
crack (0.4.3)
|
||||||
safe_yaml (~> 1.0.0)
|
safe_yaml (~> 1.0.0)
|
||||||
currencies (0.4.2)
|
currencies (0.4.2)
|
||||||
daemons (1.1.9)
|
daemons (1.1.9)
|
||||||
dante (0.2.0)
|
dante (0.2.0)
|
||||||
database_cleaner (1.3.0)
|
database_cleaner (1.3.0)
|
||||||
debug_inspector (0.0.2)
|
debug_inspector (0.0.2)
|
||||||
debugger-linecache (1.2.0)
|
delayed_job (4.1.3)
|
||||||
delayed_job (4.1.1)
|
activesupport (>= 3.0, < 5.2)
|
||||||
activesupport (>= 3.0, < 5.0)
|
delayed_job_active_record (4.1.2)
|
||||||
delayed_job_active_record (4.1.0)
|
activerecord (>= 3.0, < 5.2)
|
||||||
activerecord (>= 3.0, < 5)
|
|
||||||
delayed_job (>= 3.0, < 5)
|
delayed_job (>= 3.0, < 5)
|
||||||
devise (4.2.0)
|
devise (4.2.0)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
|
|
@ -160,14 +158,14 @@ GEM
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
devise_ichain_authenticatable (0.3.1)
|
devise_ichain_authenticatable (0.3.1)
|
||||||
devise (>= 2.2)
|
devise (>= 2.2)
|
||||||
diff-lcs (1.2.5)
|
diff-lcs (1.3)
|
||||||
docile (1.1.5)
|
docile (1.1.5)
|
||||||
domain_name (0.5.20160310)
|
domain_name (0.5.20160310)
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
dotenv (2.1.1)
|
dotenv (2.2.1)
|
||||||
dotenv-rails (2.1.1)
|
dotenv-rails (2.2.1)
|
||||||
dotenv (= 2.1.1)
|
dotenv (= 2.2.1)
|
||||||
railties (>= 4.0, < 5.1)
|
railties (>= 3.2, < 5.2)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
execjs (2.6.0)
|
execjs (2.6.0)
|
||||||
factory_girl (4.5.0)
|
factory_girl (4.5.0)
|
||||||
|
|
@ -181,27 +179,32 @@ GEM
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (>= 1.2, < 3)
|
||||||
fastimage (2.0.0)
|
fastimage (2.0.0)
|
||||||
addressable (~> 2)
|
addressable (~> 2)
|
||||||
ffi (1.9.3)
|
ffi (1.9.18)
|
||||||
font-awesome-rails (4.1.0.0)
|
font-awesome-rails (4.7.0.2)
|
||||||
railties (>= 3.2, < 5.0)
|
railties (>= 3.2, < 5.2)
|
||||||
formatador (0.2.4)
|
formatador (0.2.5)
|
||||||
formtastic (3.1.3)
|
formtastic (3.1.3)
|
||||||
actionpack (>= 3.2.13)
|
actionpack (>= 3.2.13)
|
||||||
formtastic-bootstrap (3.1.1)
|
formtastic-bootstrap (3.1.1)
|
||||||
formtastic (>= 3.0)
|
formtastic (>= 3.0)
|
||||||
geocoder (1.2.2)
|
geocoder (1.2.2)
|
||||||
globalid (0.3.6)
|
globalid (0.4.0)
|
||||||
activesupport (>= 4.1.0)
|
activesupport (>= 4.2.0)
|
||||||
gravtastic (3.2.6)
|
gravtastic (3.2.6)
|
||||||
guard (2.6.0)
|
guard (2.14.1)
|
||||||
formatador (>= 0.2.4)
|
formatador (>= 0.2.4)
|
||||||
listen (~> 2.7)
|
listen (>= 2.7, < 4.0)
|
||||||
lumberjack (~> 1.0)
|
lumberjack (~> 1.0)
|
||||||
|
nenv (~> 0.1)
|
||||||
|
notiffany (~> 0.0)
|
||||||
pry (>= 0.9.12)
|
pry (>= 0.9.12)
|
||||||
|
shellany (~> 0.0)
|
||||||
thor (>= 0.18.1)
|
thor (>= 0.18.1)
|
||||||
guard-rspec (4.2.8)
|
guard-compat (1.2.1)
|
||||||
|
guard-rspec (4.7.3)
|
||||||
guard (~> 2.1)
|
guard (~> 2.1)
|
||||||
rspec (>= 2.14, < 4.0)
|
guard-compat (~> 1.1)
|
||||||
|
rspec (>= 2.99.0, < 4.0)
|
||||||
haml (4.0.5)
|
haml (4.0.5)
|
||||||
tilt
|
tilt
|
||||||
haml-rails (0.5.3)
|
haml-rails (0.5.3)
|
||||||
|
|
@ -215,8 +218,8 @@ GEM
|
||||||
rake (>= 10, < 13)
|
rake (>= 10, < 13)
|
||||||
rubocop (>= 0.47.0)
|
rubocop (>= 0.47.0)
|
||||||
sysexits (~> 1.1)
|
sysexits (~> 1.1)
|
||||||
hashie (2.1.1)
|
hashdiff (0.3.4)
|
||||||
hike (1.2.3)
|
hashie (3.5.5)
|
||||||
hoptoad_notifier (2.4.11)
|
hoptoad_notifier (2.4.11)
|
||||||
activesupport
|
activesupport
|
||||||
builder
|
builder
|
||||||
|
|
@ -225,14 +228,15 @@ GEM
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
i18n (0.7.0)
|
i18n (0.7.0)
|
||||||
i18n_data (0.7.0)
|
i18n_data (0.7.0)
|
||||||
inversion (0.12.3)
|
inversion (1.0.0)
|
||||||
loggability (~> 0.4)
|
loggability (~> 0.12)
|
||||||
iso-639 (0.2.5)
|
iso-639 (0.2.5)
|
||||||
jquery-datatables-rails (2.2.3)
|
jquery-datatables-rails (2.2.3)
|
||||||
jquery-rails
|
jquery-rails
|
||||||
sass-rails
|
sass-rails
|
||||||
jquery-rails (3.1.4)
|
jquery-rails (4.3.1)
|
||||||
railties (>= 3.0, < 5.0)
|
rails-dom-testing (>= 1, < 3)
|
||||||
|
railties (>= 4.2.0)
|
||||||
thor (>= 0.14, < 2.0)
|
thor (>= 0.14, < 2.0)
|
||||||
jquery-ui-rails (4.2.1)
|
jquery-ui-rails (4.2.1)
|
||||||
railties (>= 3.2.16)
|
railties (>= 3.2.16)
|
||||||
|
|
@ -249,25 +253,25 @@ GEM
|
||||||
actionmailer (>= 3.2)
|
actionmailer (>= 3.2)
|
||||||
letter_opener (~> 1.0)
|
letter_opener (~> 1.0)
|
||||||
railties (>= 3.2)
|
railties (>= 3.2)
|
||||||
listen (2.7.2)
|
listen (3.1.5)
|
||||||
celluloid (>= 0.15.2)
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
celluloid-io (>= 0.15.0)
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
rb-fsevent (>= 0.9.3)
|
ruby_dep (~> 1.2)
|
||||||
rb-inotify (>= 0.9)
|
loggability (0.14.0)
|
||||||
loggability (0.11.0)
|
|
||||||
loofah (2.0.3)
|
loofah (2.0.3)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
lumberjack (1.0.5)
|
lumberjack (1.0.12)
|
||||||
mail (2.6.3)
|
mail (2.6.6)
|
||||||
mime-types (>= 1.16, < 3)
|
mime-types (>= 1.16, < 4)
|
||||||
method_source (0.8.2)
|
method_source (0.8.2)
|
||||||
mime-types (2.99.1)
|
mime-types (2.99.3)
|
||||||
|
mimemagic (0.3.2)
|
||||||
mina (0.3.8)
|
mina (0.3.8)
|
||||||
open4 (~> 1.3.4)
|
open4 (~> 1.3.4)
|
||||||
rake
|
rake
|
||||||
mini_magick (4.5.1)
|
mini_magick (4.5.1)
|
||||||
mini_portile2 (2.1.0)
|
mini_portile2 (2.3.0)
|
||||||
minitest (5.10.1)
|
minitest (5.10.2)
|
||||||
momentjs-rails (2.8.1)
|
momentjs-rails (2.8.1)
|
||||||
railties (>= 3.1)
|
railties (>= 3.1)
|
||||||
monetize (1.4.0)
|
monetize (1.4.0)
|
||||||
|
|
@ -280,23 +284,26 @@ GEM
|
||||||
monetize (~> 1.4.0)
|
monetize (~> 1.4.0)
|
||||||
money (~> 6.7)
|
money (~> 6.7)
|
||||||
railties (>= 3.0)
|
railties (>= 3.0)
|
||||||
multi_json (1.11.2)
|
multi_json (1.12.1)
|
||||||
multi_xml (0.5.5)
|
multi_xml (0.5.5)
|
||||||
multipart-post (2.0.0)
|
multipart-post (2.0.0)
|
||||||
mysql2 (0.4.2)
|
mysql2 (0.4.9)
|
||||||
|
nenv (0.3.0)
|
||||||
netrc (0.11.0)
|
netrc (0.11.0)
|
||||||
nio4r (1.2.1)
|
nokogiri (1.8.1)
|
||||||
nokogiri (1.7.1)
|
mini_portile2 (~> 2.3.0)
|
||||||
mini_portile2 (~> 2.1.0)
|
notiffany (0.1.1)
|
||||||
oauth2 (0.9.4)
|
nenv (~> 0.1)
|
||||||
faraday (>= 0.8, < 0.10)
|
shellany (~> 0.0)
|
||||||
|
oauth2 (1.3.1)
|
||||||
|
faraday (>= 0.8, < 0.12)
|
||||||
jwt (~> 1.0)
|
jwt (~> 1.0)
|
||||||
multi_json (~> 1.3)
|
multi_json (~> 1.3)
|
||||||
multi_xml (~> 0.5)
|
multi_xml (~> 0.5)
|
||||||
rack (~> 1.2)
|
rack (>= 1.2, < 3)
|
||||||
omniauth (1.2.1)
|
omniauth (1.6.1)
|
||||||
hashie (>= 1.2, < 3)
|
hashie (>= 3.4.6, < 3.6.0)
|
||||||
rack (~> 1.0)
|
rack (>= 1.6.2, < 3)
|
||||||
omniauth-facebook (1.6.0)
|
omniauth-facebook (1.6.0)
|
||||||
omniauth-oauth2 (~> 1.1)
|
omniauth-oauth2 (~> 1.1)
|
||||||
omniauth-github (1.1.2)
|
omniauth-github (1.1.2)
|
||||||
|
|
@ -305,20 +312,19 @@ GEM
|
||||||
omniauth-google-oauth2 (0.2.4)
|
omniauth-google-oauth2 (0.2.4)
|
||||||
omniauth (~> 1.0)
|
omniauth (~> 1.0)
|
||||||
omniauth-oauth2 (~> 1.1)
|
omniauth-oauth2 (~> 1.1)
|
||||||
omniauth-oauth2 (1.1.2)
|
omniauth-oauth2 (1.4.0)
|
||||||
faraday (>= 0.8, < 0.10)
|
oauth2 (~> 1.0)
|
||||||
multi_json (~> 1.3)
|
|
||||||
oauth2 (~> 0.9.3)
|
|
||||||
omniauth (~> 1.2)
|
omniauth (~> 1.2)
|
||||||
omniauth-openid (1.0.1)
|
omniauth-openid (1.0.1)
|
||||||
omniauth (~> 1.0)
|
omniauth (~> 1.0)
|
||||||
rack-openid (~> 1.3.1)
|
rack-openid (~> 1.3.1)
|
||||||
open4 (1.3.4)
|
open4 (1.3.4)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
paper_trail (5.0.1)
|
paper_trail (5.2.1)
|
||||||
activerecord (>= 3.0, < 6.0)
|
activerecord (>= 3.0, < 6.0)
|
||||||
activesupport (>= 3.0, < 6.0)
|
activesupport (>= 3.0, < 6.0)
|
||||||
request_store (~> 1.1)
|
request_store (~> 1.1)
|
||||||
|
parallel (1.11.2)
|
||||||
parser (2.4.0.0)
|
parser (2.4.0.0)
|
||||||
ast (~> 2.2)
|
ast (~> 2.2)
|
||||||
pdf-core (0.2.5)
|
pdf-core (0.2.5)
|
||||||
|
|
@ -336,29 +342,33 @@ GEM
|
||||||
prawn (1.0.0)
|
prawn (1.0.0)
|
||||||
pdf-core (~> 0.2.2)
|
pdf-core (~> 0.2.2)
|
||||||
ttfunk (~> 1.1.1)
|
ttfunk (~> 1.1.1)
|
||||||
|
prawn-qrcode (0.2.2.1)
|
||||||
|
prawn (>= 0.11.1)
|
||||||
|
rqrcode (>= 0.4.1)
|
||||||
prawn_rails (0.0.11)
|
prawn_rails (0.0.11)
|
||||||
prawn (>= 0.11.1)
|
prawn (>= 0.11.1)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
pry (0.9.12.6)
|
pry (0.10.4)
|
||||||
coderay (~> 1.0)
|
coderay (~> 1.1.0)
|
||||||
method_source (~> 0.8)
|
method_source (~> 0.8.1)
|
||||||
slop (~> 3.4)
|
slop (~> 3.4)
|
||||||
rack (1.6.4)
|
public_suffix (2.0.5)
|
||||||
|
rack (1.6.8)
|
||||||
rack-openid (1.3.1)
|
rack-openid (1.3.1)
|
||||||
rack (>= 1.1.0)
|
rack (>= 1.1.0)
|
||||||
ruby-openid (>= 2.1.8)
|
ruby-openid (>= 2.1.8)
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (4.2.7.1)
|
rails (4.2.9)
|
||||||
actionmailer (= 4.2.7.1)
|
actionmailer (= 4.2.9)
|
||||||
actionpack (= 4.2.7.1)
|
actionpack (= 4.2.9)
|
||||||
actionview (= 4.2.7.1)
|
actionview (= 4.2.9)
|
||||||
activejob (= 4.2.7.1)
|
activejob (= 4.2.9)
|
||||||
activemodel (= 4.2.7.1)
|
activemodel (= 4.2.9)
|
||||||
activerecord (= 4.2.7.1)
|
activerecord (= 4.2.9)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.9)
|
||||||
bundler (>= 1.3.0, < 2.0)
|
bundler (>= 1.3.0, < 2.0)
|
||||||
railties (= 4.2.7.1)
|
railties (= 4.2.9)
|
||||||
sprockets-rails
|
sprockets-rails
|
||||||
rails-assets-bootstrap (3.3.6)
|
rails-assets-bootstrap (3.3.6)
|
||||||
rails-assets-jquery (>= 1.9.1, < 3)
|
rails-assets-jquery (>= 1.9.1, < 3)
|
||||||
|
|
@ -388,65 +398,68 @@ GEM
|
||||||
rails-i18n (4.0.8)
|
rails-i18n (4.0.8)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
railties (~> 4.0)
|
railties (~> 4.0)
|
||||||
rails-observers (0.1.2)
|
|
||||||
activemodel (~> 4.0)
|
|
||||||
rails_12factor (0.0.3)
|
rails_12factor (0.0.3)
|
||||||
rails_serve_static_assets
|
rails_serve_static_assets
|
||||||
rails_stdout_logging
|
rails_stdout_logging
|
||||||
rails_serve_static_assets (0.0.4)
|
rails_serve_static_assets (0.0.4)
|
||||||
rails_stdout_logging (0.0.3)
|
rails_stdout_logging (0.0.3)
|
||||||
railties (4.2.7.1)
|
railties (4.2.9)
|
||||||
actionpack (= 4.2.7.1)
|
actionpack (= 4.2.9)
|
||||||
activesupport (= 4.2.7.1)
|
activesupport (= 4.2.9)
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rainbow (2.2.1)
|
rainbow (2.2.2)
|
||||||
rake (10.5.0)
|
rake
|
||||||
rb-fsevent (0.9.4)
|
rake (12.0.0)
|
||||||
rb-inotify (0.9.4)
|
rb-fsevent (0.10.2)
|
||||||
ffi (>= 0.5.0)
|
rb-inotify (0.9.10)
|
||||||
rdoc (4.1.1)
|
ffi (>= 0.5.0, < 2)
|
||||||
json (~> 1.4)
|
rdoc (5.1.0)
|
||||||
rdoc-generator-fivefish (0.1.0)
|
rdoc-generator-fivefish (0.3.0)
|
||||||
inversion (~> 0.12)
|
inversion (~> 1.0)
|
||||||
loggability (~> 0.6)
|
loggability (~> 0.12)
|
||||||
rdoc (~> 4.0)
|
rdoc (~> 5.0)
|
||||||
yajl-ruby (~> 1.1)
|
yajl-ruby (~> 1.3)
|
||||||
redcarpet (3.2.3)
|
redcarpet (3.2.3)
|
||||||
referer-parser (0.2.1)
|
referer-parser (0.2.1)
|
||||||
request_store (1.1.0)
|
request_store (1.1.0)
|
||||||
responders (2.1.1)
|
responders (2.4.0)
|
||||||
railties (>= 4.2.0, < 5.1)
|
actionpack (>= 4.2.0, < 5.3)
|
||||||
|
railties (>= 4.2.0, < 5.3)
|
||||||
rest-client (1.8.0)
|
rest-client (1.8.0)
|
||||||
http-cookie (>= 1.0.2, < 2.0)
|
http-cookie (>= 1.0.2, < 2.0)
|
||||||
mime-types (>= 1.16, < 3.0)
|
mime-types (>= 1.16, < 3.0)
|
||||||
netrc (~> 0.7)
|
netrc (~> 0.7)
|
||||||
rolify (5.1.0)
|
rolify (5.1.0)
|
||||||
rspec (3.0.0)
|
rqrcode (0.10.1)
|
||||||
rspec-core (~> 3.0.0)
|
chunky_png (~> 1.0)
|
||||||
rspec-expectations (~> 3.0.0)
|
rspec (3.6.0)
|
||||||
rspec-mocks (~> 3.0.0)
|
rspec-core (~> 3.6.0)
|
||||||
|
rspec-expectations (~> 3.6.0)
|
||||||
|
rspec-mocks (~> 3.6.0)
|
||||||
rspec-activemodel-mocks (1.0.1)
|
rspec-activemodel-mocks (1.0.1)
|
||||||
activemodel (>= 3.0)
|
activemodel (>= 3.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
rspec-mocks (>= 2.99, < 4.0)
|
rspec-mocks (>= 2.99, < 4.0)
|
||||||
rspec-core (3.0.2)
|
rspec-core (3.6.0)
|
||||||
rspec-support (~> 3.0.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-expectations (3.0.2)
|
rspec-expectations (3.6.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.0.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-mocks (3.0.2)
|
rspec-mocks (3.6.0)
|
||||||
rspec-support (~> 3.0.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-rails (3.0.0)
|
rspec-support (~> 3.6.0)
|
||||||
|
rspec-rails (3.6.0)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 3.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
railties (>= 3.0)
|
railties (>= 3.0)
|
||||||
rspec-core (~> 3.0.0)
|
rspec-core (~> 3.6.0)
|
||||||
rspec-expectations (~> 3.0.0)
|
rspec-expectations (~> 3.6.0)
|
||||||
rspec-mocks (~> 3.0.0)
|
rspec-mocks (~> 3.6.0)
|
||||||
rspec-support (~> 3.0.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-support (3.0.2)
|
rspec-support (3.6.0)
|
||||||
rubocop (0.48.1)
|
rubocop (0.49.1)
|
||||||
|
parallel (~> 1.10)
|
||||||
parser (>= 2.3.3.1, < 3.0)
|
parser (>= 2.3.3.1, < 3.0)
|
||||||
powerpack (~> 0.1)
|
powerpack (~> 0.1)
|
||||||
rainbow (>= 1.99.1, < 3.0)
|
rainbow (>= 1.99.1, < 3.0)
|
||||||
|
|
@ -455,16 +468,19 @@ GEM
|
||||||
ruby-oembed (0.8.14)
|
ruby-oembed (0.8.14)
|
||||||
ruby-openid (2.5.0)
|
ruby-openid (2.5.0)
|
||||||
ruby-progressbar (1.8.1)
|
ruby-progressbar (1.8.1)
|
||||||
|
ruby_dep (1.5.0)
|
||||||
rubyzip (1.2.1)
|
rubyzip (1.2.1)
|
||||||
safe_yaml (1.0.4)
|
safe_yaml (1.0.4)
|
||||||
sass (3.2.19)
|
sass (3.2.19)
|
||||||
sass-rails (4.0.4)
|
sass-rails (5.0.6)
|
||||||
railties (>= 4.0.0, < 5.0)
|
railties (>= 4.0.0, < 6)
|
||||||
sass (~> 3.2.2)
|
sass (~> 3.1)
|
||||||
sprockets (~> 2.8, < 2.12)
|
sprockets (>= 2.8, < 4.0)
|
||||||
sprockets-rails (~> 2.0)
|
sprockets-rails (>= 2.0, < 4.0)
|
||||||
|
tilt (>= 1.1, < 3)
|
||||||
selectize-rails (0.12.4)
|
selectize-rails (0.12.4)
|
||||||
shoulda-matchers (2.6.1)
|
shellany (0.0.1)
|
||||||
|
shoulda-matchers (2.8.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
simplecov (0.11.2)
|
simplecov (0.11.2)
|
||||||
docile (~> 1.1.0)
|
docile (~> 1.1.0)
|
||||||
|
|
@ -478,11 +494,9 @@ GEM
|
||||||
spring (1.6.3)
|
spring (1.6.3)
|
||||||
spring-commands-rspec (1.0.4)
|
spring-commands-rspec (1.0.4)
|
||||||
spring (>= 0.9.1)
|
spring (>= 0.9.1)
|
||||||
sprockets (2.11.3)
|
sprockets (3.7.1)
|
||||||
hike (~> 1.2)
|
concurrent-ruby (~> 1.0)
|
||||||
multi_json (~> 1.0)
|
rack (> 1, < 3)
|
||||||
rack (~> 1.0)
|
|
||||||
tilt (~> 1.1, != 1.3.0)
|
|
||||||
sprockets-rails (2.3.3)
|
sprockets-rails (2.3.3)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 3.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
|
|
@ -501,7 +515,6 @@ GEM
|
||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
tilt (1.4.1)
|
tilt (1.4.1)
|
||||||
timecop (0.7.1)
|
timecop (0.7.1)
|
||||||
timers (1.1.0)
|
|
||||||
tins (1.6.0)
|
tins (1.6.0)
|
||||||
transitions (0.1.12)
|
transitions (0.1.12)
|
||||||
ttfunk (1.1.1)
|
ttfunk (1.1.1)
|
||||||
|
|
@ -514,7 +527,7 @@ GEM
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.7.2)
|
unf_ext (0.0.7.2)
|
||||||
unicode-display_width (1.2.1)
|
unicode-display_width (1.3.0)
|
||||||
unicode_utils (1.4.0)
|
unicode_utils (1.4.0)
|
||||||
unobtrusive_flash (3.1.0)
|
unobtrusive_flash (3.1.0)
|
||||||
railties
|
railties
|
||||||
|
|
@ -527,9 +540,10 @@ GEM
|
||||||
binding_of_caller (>= 0.7.2)
|
binding_of_caller (>= 0.7.2)
|
||||||
railties (>= 4.0)
|
railties (>= 4.0)
|
||||||
sprockets-rails (>= 2.0, < 4.0)
|
sprockets-rails (>= 2.0, < 4.0)
|
||||||
webmock (1.20.4)
|
webmock (3.0.1)
|
||||||
addressable (>= 2.3.6)
|
addressable (>= 2.3.6)
|
||||||
crack (>= 0.3.2)
|
crack (>= 0.3.2)
|
||||||
|
hashdiff
|
||||||
websocket-driver (0.6.3)
|
websocket-driver (0.6.3)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.2)
|
websocket-extensions (0.1.2)
|
||||||
|
|
@ -550,7 +564,8 @@ DEPENDENCIES
|
||||||
acts_as_list
|
acts_as_list
|
||||||
ahoy_matey
|
ahoy_matey
|
||||||
autoprefixer-rails
|
autoprefixer-rails
|
||||||
awesome_nested_set (~> 3.0.0.rc.5)
|
awesome_nested_set (~> 3.1.3)
|
||||||
|
axlsx!
|
||||||
axlsx_rails
|
axlsx_rails
|
||||||
bootstrap-sass (~> 3.3.4.1)
|
bootstrap-sass (~> 3.3.4.1)
|
||||||
bootstrap-switch-rails (~> 3.0.0)
|
bootstrap-switch-rails (~> 3.0.0)
|
||||||
|
|
@ -578,7 +593,7 @@ DEPENDENCIES
|
||||||
formtastic (~> 3.1.1)
|
formtastic (~> 3.1.1)
|
||||||
formtastic-bootstrap
|
formtastic-bootstrap
|
||||||
gravtastic
|
gravtastic
|
||||||
guard-rspec (~> 4.2.8)
|
guard-rspec
|
||||||
haml-rails
|
haml-rails
|
||||||
haml_lint (~> 0.24.0)
|
haml_lint (~> 0.24.0)
|
||||||
hoptoad_notifier (~> 2.3)
|
hoptoad_notifier (~> 2.3)
|
||||||
|
|
@ -594,6 +609,7 @@ DEPENDENCIES
|
||||||
mini_magick
|
mini_magick
|
||||||
money-rails
|
money-rails
|
||||||
mysql2
|
mysql2
|
||||||
|
nokogiri (>= 1.8.1)
|
||||||
omniauth
|
omniauth
|
||||||
omniauth-facebook
|
omniauth-facebook
|
||||||
omniauth-github
|
omniauth-github
|
||||||
|
|
@ -603,8 +619,9 @@ DEPENDENCIES
|
||||||
phantomjs
|
phantomjs
|
||||||
piwik_analytics (~> 1.0.1)
|
piwik_analytics (~> 1.0.1)
|
||||||
poltergeist
|
poltergeist
|
||||||
|
prawn-qrcode (~> 0.2.2.1)
|
||||||
prawn_rails
|
prawn_rails
|
||||||
rails (~> 4.2)
|
rails (~> 4.2.8)
|
||||||
rails-assets-bootstrap-markdown!
|
rails-assets-bootstrap-markdown!
|
||||||
rails-assets-date.format!
|
rails-assets-date.format!
|
||||||
rails-assets-holderjs!
|
rails-assets-holderjs!
|
||||||
|
|
@ -617,15 +634,15 @@ DEPENDENCIES
|
||||||
rails-assets-trianglify!
|
rails-assets-trianglify!
|
||||||
rails-assets-waypoints!
|
rails-assets-waypoints!
|
||||||
rails-i18n (~> 4.0.0)
|
rails-i18n (~> 4.0.0)
|
||||||
rails-observers
|
|
||||||
rails_12factor
|
rails_12factor
|
||||||
rdoc-generator-fivefish
|
rdoc-generator-fivefish
|
||||||
redcarpet
|
redcarpet
|
||||||
responders (~> 2.0)
|
responders (~> 2.0)
|
||||||
rolify
|
rolify
|
||||||
|
rqrcode
|
||||||
rspec-activemodel-mocks
|
rspec-activemodel-mocks
|
||||||
rspec-rails
|
rspec-rails (~> 3.5, >= 3.5.2)
|
||||||
rubocop (~> 0.48.1)
|
rubocop (~> 0.49.0)
|
||||||
ruby-oembed
|
ruby-oembed
|
||||||
sass-rails (>= 4.0.2)
|
sass-rails (>= 4.0.2)
|
||||||
selectize-rails
|
selectize-rails
|
||||||
|
|
@ -635,6 +652,7 @@ DEPENDENCIES
|
||||||
sqlite3
|
sqlite3
|
||||||
stripe
|
stripe
|
||||||
stripe-ruby-mock
|
stripe-ruby-mock
|
||||||
|
thor (= 0.19.1)
|
||||||
timecop
|
timecop
|
||||||
transitions
|
transitions
|
||||||
turbolinks
|
turbolinks
|
||||||
|
|
@ -645,4 +663,4 @@ DEPENDENCIES
|
||||||
whenever
|
whenever
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.14.5
|
1.15.4
|
||||||
|
|
|
||||||
51
INSTALL.md
51
INSTALL.md
|
|
@ -11,7 +11,9 @@ OSEM is an [semantic versioned](http://semver.org/) app. That means given a vers
|
||||||
## Download
|
## Download
|
||||||
You can find the latest OSEM releases on our [release page](https://github.com/openSUSE/osem/releases/latest) ([older release here](https://github.com/openSUSE/osem/releases))
|
You can find the latest OSEM releases on our [release page](https://github.com/openSUSE/osem/releases/latest) ([older release here](https://github.com/openSUSE/osem/releases))
|
||||||
|
|
||||||
|
|
||||||
## Deploy
|
## Deploy
|
||||||
|
|
||||||
OSEM is a *Ruby on Rails* application. We recommend to run OSEM in production with [mod_passenger](https://www.phusionpassenger.com/download/#open_source)
|
OSEM is a *Ruby on Rails* application. We recommend to run OSEM in production with [mod_passenger](https://www.phusionpassenger.com/download/#open_source)
|
||||||
and the [apache web-server](https://www.apache.org/). There are tons of guides on how to deploy rails apps on various
|
and the [apache web-server](https://www.apache.org/). There are tons of guides on how to deploy rails apps on various
|
||||||
base operating systems. [Check Google](https://encrypted.google.com/search?hl=en&q=ruby%20on%20rails%20apache%20passenger) ;-)
|
base operating systems. [Check Google](https://encrypted.google.com/search?hl=en&q=ruby%20on%20rails%20apache%20passenger) ;-)
|
||||||
|
|
@ -24,6 +26,55 @@ If you have an heroku account you can also
|
||||||
<img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy">
|
<img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
### Deploy with Docker
|
||||||
|
|
||||||
|
You can deploy OSEM using [Docker](https://docker.com/) and [Docker-Compose](https://docs.docker.com/compose/overview/).
|
||||||
|
|
||||||
|
*This is just a short guide and does not explain how to use Docker and/or Docker-Compose. You need some experience with these tools to be able to deploy OSEM with Docker properly.*
|
||||||
|
|
||||||
|
First of all, copy `docker-compose.yml.example` to `docker-compose.yml` and `docker-compose.env.example` to `docker-compose.env`. You should immediately change
|
||||||
|
`docker-compose.env`'s permissions to `0600` to make sure all the passphrases in it are kept secret.
|
||||||
|
(Tip: the easiest and most secure way to do it is to do it with a single command, for example `install -m 0600 docker-compose.env.example docker-compose.env`).
|
||||||
|
|
||||||
|
There are two configurations to deploy OSEM with Docker: *evaluation mode* and *production mode*.
|
||||||
|
|
||||||
|
#### Evaluation mode
|
||||||
|
|
||||||
|
If you want to evaluate OSEM to see if it fits your needs, the default configuration in `docker-compose.env` will work perfectly fine for you.
|
||||||
|
For convenience reasons, `docker-compose.yml` already contains a [MailHog](https://github.com/mailhog/MailHog) service configuration. MailHog
|
||||||
|
is going to catch every email sent by OSEM and displays them on a special web service. Thus, it eliminitates the need to set up an SMTP server just to try out OSEM.
|
||||||
|
Just point your browser to http://localhost:8025 to get access to registration confirmation links etc.
|
||||||
|
|
||||||
|
Run `docker-compose up --build` to start the services. On first run, it will take a few minutes to initialize the database. Thus, wait a few minutes before you open up
|
||||||
|
http://localhost:9292 in your browser.
|
||||||
|
|
||||||
|
#### Production mode
|
||||||
|
|
||||||
|
To deploy OSEM for production, you have to make a few changes to `docker-compose.yml`. First, remove (or comment) the `mailhog` service, as it is only useful for evaluation and
|
||||||
|
cannot be used for production.
|
||||||
|
You can change the forwarded port from port `9292` to any other value if this port is already in use or you just want to use another one.
|
||||||
|
|
||||||
|
Next, you have to modify `docker-compose.env`. This file works as a Docker-like replacement for the regular Rails `.env` files described below.
|
||||||
|
You can configure any of the configuration values shown in the **Configure** section below in it. The most essential variables are already configured to standard
|
||||||
|
values in `docker-compose.env` which you most likely want to change.
|
||||||
|
|
||||||
|
First, you need to modify the email related settings. You need a working SMTP server for OSEM to send out registration confirmation mails etc.
|
||||||
|
|
||||||
|
For security reasons, the following variables have to be changed, too:
|
||||||
|
|
||||||
|
- `MYSQL_PASSWORD`
|
||||||
|
- `MYSQL_ROOT_PASSWORD`
|
||||||
|
- `SECRET_KEY_BASE`
|
||||||
|
|
||||||
|
These variables need to be set to the correct values at first, as they are used to initialize everything. Modification of these variables after installation and initialization is more
|
||||||
|
complicated and out of this document's scope.
|
||||||
|
|
||||||
|
As with any other Docker-Compose configuration, run `docker-compose up --build` (or `docker-compose up --build -d` to run in background) to start the services. During the first
|
||||||
|
start, the database has to be initialized which can take several minutes. The web service is by default exposed on localhost only as it is intended to be served by a reverse proxy (for SSL
|
||||||
|
termination, caching etc.).
|
||||||
|
You should not directly expose the web server port unless you have a good reason to do so.
|
||||||
|
|
||||||
|
|
||||||
## Configure
|
## Configure
|
||||||
There are a couple of environment variables you can set to configure OSEM. Check out the *dotenv.example* file.
|
There are a couple of environment variables you can set to configure OSEM. Check out the *dotenv.example* file.
|
||||||
|
|
||||||
|
|
|
||||||
2
Vagrantfile
vendored
2
Vagrantfile
vendored
|
|
@ -12,7 +12,7 @@ Vagrant.configure(2) do |config|
|
||||||
|
|
||||||
# Every Vagrant development environment requires a box. You can search for
|
# Every Vagrant development environment requires a box. You can search for
|
||||||
# boxes at https://atlas.hashicorp.com/search.
|
# boxes at https://atlas.hashicorp.com/search.
|
||||||
config.vm.box = "opensuse/openSUSE-42.1-x86_64"
|
config.vm.box = "opensuse/openSUSE-42.2-x86_64"
|
||||||
|
|
||||||
# Disable automatic box update checking. If you disable this, then
|
# Disable automatic box update checking. If you disable this, then
|
||||||
# boxes will only be checked for updates when the user runs
|
# boxes will only be checked for updates when the user runs
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@ $(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw_line_chart(animation, $canvas){
|
function draw_line_chart(animation, $canvas){
|
||||||
var options = get_animation({}, animation);
|
|
||||||
var chart_data = create_dataset($canvas);
|
var chart_data = create_dataset($canvas);
|
||||||
var weeks = $canvas.parent().data('weeks');
|
var weeks = $canvas.parent().data('weeks');
|
||||||
var data = {
|
var data = {
|
||||||
|
|
@ -63,10 +62,27 @@ $(function() {
|
||||||
datasets : chart_data
|
datasets : chart_data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var options = get_animation(wholeNumberAxisFix(data), animation);
|
||||||
var ctx = $canvas.get(0).getContext("2d");
|
var ctx = $canvas.get(0).getContext("2d");
|
||||||
new Chart(ctx).Line(data, options);
|
new Chart(ctx).Line(data, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wholeNumberAxisFix(data){
|
||||||
|
var maxValue = false;
|
||||||
|
for(datasetIndex = 0; datasetIndex < data.datasets.length; ++datasetIndex){
|
||||||
|
var setMax = Math.max.apply(null, data.datasets[datasetIndex].data);
|
||||||
|
if (maxValue === false || setMax > maxValue) maxValue = setMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
var steps = maxValue;
|
||||||
|
var stepWidth = 1;
|
||||||
|
if (maxValue > 10) {
|
||||||
|
stepWidth = Math.floor(maxValue / 10);
|
||||||
|
steps = Math.ceil(maxValue / stepWidth);
|
||||||
|
}
|
||||||
|
return { scaleOverride: true, scaleSteps: steps, scaleStepWidth: stepWidth, scaleStartValue: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
function create_dataset($canvas){
|
function create_dataset($canvas){
|
||||||
var selected = getSelectedConferences($canvas);
|
var selected = getSelectedConferences($canvas);
|
||||||
var chart_data = $canvas.parent().data('chart');
|
var chart_data = $canvas.parent().data('chart');
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
$(function () {
|
$(function () {
|
||||||
$(document).ready(function() {
|
|
||||||
$('.datatable').DataTable({
|
$('.datatable').DataTable({
|
||||||
// ajax: ...,
|
// ajax: ...,
|
||||||
stateSave: true,
|
stateSave: true,
|
||||||
autoWidth: false,
|
autoWidth: false,
|
||||||
pagingType: 'full_numbers',
|
pagingType: 'full_numbers',
|
||||||
"lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]]
|
"lengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]],
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#versionstable').DataTable({
|
$('#versionstable').DataTable({
|
||||||
|
|
@ -13,6 +12,3 @@ $(function () {
|
||||||
order: [[ 0, 'desc' ]]
|
order: [[ 0, 'desc' ]]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,11 +78,12 @@ var Schedule = {
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).ready( function() {
|
$(document).ready( function() {
|
||||||
// hide the remove button for unscheduled events
|
// hide the remove button for unscheduled and non schedulable events
|
||||||
$('.unscheduled-events .schedule-event-delete-button').hide();
|
$('.unscheduled-events .schedule-event-delete-button').hide();
|
||||||
|
$('.non_schedulable .schedule-event-delete-button').hide();
|
||||||
|
|
||||||
// set events as draggable
|
// set events as draggable
|
||||||
$('.schedule-event').draggable({
|
$('.schedule-event').not('.non_schedulable').draggable({
|
||||||
snap: '.schedule-room-slot',
|
snap: '.schedule-room-slot',
|
||||||
revertDuration: 200,
|
revertDuration: 200,
|
||||||
revert: function (event, ui) {
|
revert: function (event, ui) {
|
||||||
|
|
@ -99,7 +100,7 @@ $(document).ready( function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// set room cells as droppable
|
// set room cells as droppable
|
||||||
$('.schedule-room-slot').droppable({
|
$('.schedule-room-slot').not('.non_schedulable .schedule-room-slot').droppable({
|
||||||
accept: '.schedule-event',
|
accept: '.schedule-event',
|
||||||
tolerance: "pointer",
|
tolerance: "pointer",
|
||||||
drop: function(event, ui) {
|
drop: function(event, ui) {
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@ function update_price($this){
|
||||||
// Calculate price for row
|
// Calculate price for row
|
||||||
var value = $this.val();
|
var value = $this.val();
|
||||||
var price = $('#price_' + id).text();
|
var price = $('#price_' + id).text();
|
||||||
$('#total_row_' + id).text(value * price);
|
$('#total_row_' + id).text((value * price).toFixed(2));
|
||||||
|
|
||||||
// Calculate total price
|
// Calculate total price
|
||||||
var total = 0;
|
var total = 0;
|
||||||
$('.total_row').each(function( index ) {
|
$('.total_row').each(function( index ) {
|
||||||
total += parseInt($(this).text());
|
total += parseFloat($(this).text());
|
||||||
});
|
});
|
||||||
$('#total_price').text(total);
|
$('#total_price').text(total.toFixed(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
$( document ).ready(function() {
|
$( document ).ready(function() {
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,6 @@
|
||||||
color: black;
|
color: black;
|
||||||
background-color: #eeeeee;
|
background-color: #eeeeee;
|
||||||
}
|
}
|
||||||
input[type=text],
|
|
||||||
input[type=password] {
|
|
||||||
text-align: center;
|
|
||||||
padding: 5px;
|
|
||||||
display: block;
|
|
||||||
margin: auto;
|
|
||||||
width: 255px;
|
|
||||||
}
|
|
||||||
.btn-group {
|
.btn-group {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
@ -37,7 +29,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
padding: 17px 17px 0px 17px;
|
padding: 17px;
|
||||||
min-width: 225px;
|
min-width: 225px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -267,6 +267,10 @@ td.no-padding{
|
||||||
font-size: 7px;
|
font-size: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.non_schedulable{
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
/* Small devices (tablets, 768px and up) */
|
/* Small devices (tablets, 768px and up) */
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.room, .event-title{
|
.room, .event-title{
|
||||||
|
|
|
||||||
|
|
@ -90,3 +90,17 @@ p.comment-body {
|
||||||
.changeset{
|
.changeset{
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.box{
|
||||||
|
height: 230px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sidebar hamburger btn */
|
||||||
|
.side-nav-btn{
|
||||||
|
margin-left: 10px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qr-image{
|
||||||
|
margin-left: 120px;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,22 @@ module Admin
|
||||||
class BaseController < ApplicationController
|
class BaseController < ApplicationController
|
||||||
before_filter :verify_user_admin
|
before_filter :verify_user_admin
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_ability
|
||||||
|
@current_ability ||= AdminAbility.new(current_user)
|
||||||
|
end
|
||||||
|
|
||||||
def verify_user_admin
|
def verify_user_admin
|
||||||
if (current_user.nil?)
|
if (current_user.nil?)
|
||||||
redirect_to sign_in_path
|
redirect_to sign_in_path
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
unless (current_user.has_role? :organizer, :any) || (current_user.has_role? :cfp, :any) ||
|
unless (current_user.has_role? :organizer, :any) || (current_user.has_role? :cfp, :any) ||
|
||||||
(current_user.has_role? :info_desk, :any) ||
|
(current_user.has_role? :info_desk, :any) || (current_user.has_role? :organization_admin, :any) ||
|
||||||
(current_user.has_role? :volunteers_coordinator, :any) || current_user.is_admin
|
(current_user.has_role? :volunteers_coordinator, :any) ||
|
||||||
raise CanCan::AccessDenied.new('You are not authorized to access this area!')
|
(current_user.has_role? :track_organizer, :any) || current_user.is_admin
|
||||||
|
raise CanCan::AccessDenied.new('You are not authorized to access this page.')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
116
app/controllers/admin/booths_controller.rb
Normal file
116
app/controllers/admin/booths_controller.rb
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
module Admin
|
||||||
|
class BoothsController < Admin::BaseController
|
||||||
|
load_and_authorize_resource :conference, find_by: :short_title
|
||||||
|
load_and_authorize_resource through: :conference
|
||||||
|
|
||||||
|
def index; end
|
||||||
|
|
||||||
|
def show; end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@url = admin_conference_booths_path(@conference.short_title)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@url = admin_conference_booths_path(@conference.short_title)
|
||||||
|
|
||||||
|
@booth = @conference.booths.new(booth_params)
|
||||||
|
|
||||||
|
@booth.submitter = current_user
|
||||||
|
|
||||||
|
if @booth.save
|
||||||
|
redirect_to admin_conference_booths_path,
|
||||||
|
notice: 'Booth successfully created.'
|
||||||
|
else
|
||||||
|
flash.now[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}."
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@url = admin_conference_booth_path(@conference.short_title, @booth.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@url = admin_conference_booth_path(@conference.short_title, @booth.id)
|
||||||
|
|
||||||
|
@booth.update_attributes(booth_params)
|
||||||
|
|
||||||
|
if @booth.save
|
||||||
|
redirect_to admin_conference_booths_path,
|
||||||
|
notice: "Successfully updated booth for #{@booth.title}."
|
||||||
|
else
|
||||||
|
flash.now[:error] = "An error prohibited the Booth for #{@booth.title} "\
|
||||||
|
"#{@booth.errors.full_messages.join('. ')}."
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept
|
||||||
|
@booth.accept!
|
||||||
|
|
||||||
|
if @booth.save
|
||||||
|
if @conference.email_settings.send_on_booths_acceptance
|
||||||
|
Mailbot.conference_booths_acceptance_mail(@booth).deliver
|
||||||
|
end
|
||||||
|
redirect_to admin_conference_booths_path(conference_id: @conference.short_title),
|
||||||
|
notice: 'Booth successfully accepted!'
|
||||||
|
else
|
||||||
|
redirect_to admin_conference_booths_path(conference_id: @conference.short_title)
|
||||||
|
flash[:error] = "Booth could not be accepted. #{@booth.errors.full_messages.to_sentence}."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_accept
|
||||||
|
update_state(:to_accept, 'Booth to accept')
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_reject
|
||||||
|
update_state(:to_reject, 'Booth to reject')
|
||||||
|
end
|
||||||
|
|
||||||
|
def reject
|
||||||
|
@booth.reject!
|
||||||
|
|
||||||
|
if @booth.save
|
||||||
|
Mailbot.conference_booths_rejection_mail(@booth).deliver
|
||||||
|
redirect_to admin_conference_booths_path(conference_id: @conference.short_title),
|
||||||
|
notice: 'Booth successfully rejected.'
|
||||||
|
else
|
||||||
|
redirect_to admin_conference_booths_path(conference_id: @conference.short_title)
|
||||||
|
flash[:error] = "Booth could not be rejected. #{@booth.errors.full_messages.to_sentence}."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def restart
|
||||||
|
update_state(:restart, 'Booth is submitted')
|
||||||
|
end
|
||||||
|
|
||||||
|
def cancel
|
||||||
|
update_state(:cancel, 'Booth is canceled')
|
||||||
|
end
|
||||||
|
|
||||||
|
def confirm
|
||||||
|
update_state(:confirm, 'Booth successfully confirmed')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def update_state(transition, notice)
|
||||||
|
alert = @booth.update_state(transition, notice)
|
||||||
|
|
||||||
|
if alert.blank?
|
||||||
|
flash[:notice] = notice
|
||||||
|
redirect_back_or_to(admin_conference_booths_path(conference_id: @conference.short_title)) && return
|
||||||
|
else
|
||||||
|
flash[:error] = alert
|
||||||
|
return redirect_back_or_to(admin_conference_booths_path(conference_id: @conference.short_title)) && return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def booth_params
|
||||||
|
params.require(:booth).permit(:title, :description, :reasoning, :state, :picture, :conference_id,
|
||||||
|
:created_at, :updated_at, :submitter_relationship, :website_url, responsible_ids: [])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -2,23 +2,25 @@ module Admin
|
||||||
class CfpsController < Admin::BaseController
|
class CfpsController < Admin::BaseController
|
||||||
load_and_authorize_resource :conference, find_by: :short_title
|
load_and_authorize_resource :conference, find_by: :short_title
|
||||||
load_and_authorize_resource :program, through: :conference, singleton: true
|
load_and_authorize_resource :program, through: :conference, singleton: true
|
||||||
load_and_authorize_resource through: :program, singleton: true
|
load_and_authorize_resource through: :program
|
||||||
|
|
||||||
|
def index; end
|
||||||
|
|
||||||
def show; end
|
def show; end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@cfp = @program.build_cfp
|
@cfp = @program.cfps.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit; end
|
def edit; end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@cfp = @program.build_cfp(cfp_params)
|
@cfp = @program.cfps.new(cfp_params)
|
||||||
send_mail_on_cfp_dates_updates = @cfp.notify_on_cfp_date_update?
|
send_mail_on_cfp_dates_updates = @cfp.notify_on_cfp_date_update?
|
||||||
|
|
||||||
if @cfp.save
|
if @cfp.save
|
||||||
ConferenceCfpUpdateMailJob.perform_later(@conference) if send_mail_on_cfp_dates_updates
|
ConferenceCfpUpdateMailJob.perform_later(@conference) if send_mail_on_cfp_dates_updates
|
||||||
redirect_to admin_conference_program_cfp_path,
|
redirect_to admin_conference_program_cfps_path,
|
||||||
notice: 'Call for papers successfully created.'
|
notice: 'Call for papers successfully created.'
|
||||||
else
|
else
|
||||||
flash.now[:error] = "Creating the call for papers failed. #{@cfp.errors.full_messages.join('. ')}."
|
flash.now[:error] = "Creating the call for papers failed. #{@cfp.errors.full_messages.join('. ')}."
|
||||||
|
|
@ -27,14 +29,13 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@cfp = @program.cfp
|
|
||||||
@cfp.assign_attributes(cfp_params)
|
@cfp.assign_attributes(cfp_params)
|
||||||
|
|
||||||
send_mail_on_cfp_dates_updates = @cfp.notify_on_cfp_date_update?
|
send_mail_on_cfp_dates_updates = @cfp.notify_on_cfp_date_update?
|
||||||
|
|
||||||
if @cfp.update_attributes(cfp_params)
|
if @cfp.update_attributes(cfp_params)
|
||||||
ConferenceCfpUpdateMailJob.perform_later(@conference) if send_mail_on_cfp_dates_updates
|
ConferenceCfpUpdateMailJob.perform_later(@conference) if send_mail_on_cfp_dates_updates
|
||||||
redirect_to admin_conference_program_cfp_path(@conference.short_title),
|
redirect_to admin_conference_program_cfps_path(@conference.short_title),
|
||||||
notice: 'Call for papers successfully updated.'
|
notice: 'Call for papers successfully updated.'
|
||||||
else
|
else
|
||||||
flash.now[:error] = "Updating call for papers failed. #{@cfp.errors.to_a.join('. ')}."
|
flash.now[:error] = "Updating call for papers failed. #{@cfp.errors.to_a.join('. ')}."
|
||||||
|
|
@ -44,9 +45,9 @@ module Admin
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
if @cfp.destroy
|
if @cfp.destroy
|
||||||
redirect_to admin_conference_program_cfp_path, notice: 'Call for Papers was successfully deleted.'
|
redirect_to admin_conference_program_cfps_path, notice: 'Call for Papers was successfully deleted.'
|
||||||
else
|
else
|
||||||
redirect_to admin_conference_program_cfp_path, error: 'An error prohibited this Call for Papers from being destroyed: '\
|
redirect_to admin_conference_program_cfps_path, error: 'An error prohibited this Call for Papers from being destroyed: '\
|
||||||
"#{@cfp.errors.full_messages.join('. ')}."
|
"#{@cfp.errors.full_messages.join('. ')}."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -54,7 +55,7 @@ module Admin
|
||||||
private
|
private
|
||||||
|
|
||||||
def cfp_params
|
def cfp_params
|
||||||
params.require(:cfp).permit(:start_date, :end_date)
|
params.require(:cfp).permit(:start_date, :end_date, :cfp_type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,9 @@ module Admin
|
||||||
@registrations = {}
|
@registrations = {}
|
||||||
@registration_weeks = [0]
|
@registration_weeks = [0]
|
||||||
|
|
||||||
|
@tickets = {}
|
||||||
|
@ticket_weeks = [0]
|
||||||
|
|
||||||
@conferences.each do |c|
|
@conferences.each do |c|
|
||||||
# Event submissions over time chart
|
# Event submissions over time chart
|
||||||
@submissions[c.short_title] = c.get_submissions_per_week
|
@submissions[c.short_title] = c.get_submissions_per_week
|
||||||
|
|
@ -45,6 +48,10 @@ module Admin
|
||||||
# Conference registrations over time chart
|
# Conference registrations over time chart
|
||||||
@registrations[c.short_title] = c.get_registrations_per_week
|
@registrations[c.short_title] = c.get_registrations_per_week
|
||||||
@registration_weeks.push(@registrations[c.short_title].length)
|
@registration_weeks.push(@registrations[c.short_title].length)
|
||||||
|
|
||||||
|
# Tickets sold over time chart
|
||||||
|
@tickets[c.short_title] = c.get_tickets_sold_per_week
|
||||||
|
@ticket_weeks.push(@tickets[c.short_title].length)
|
||||||
end
|
end
|
||||||
|
|
||||||
@cfp_weeks = @cfp_weeks.max
|
@cfp_weeks = @cfp_weeks.max
|
||||||
|
|
@ -55,12 +62,17 @@ module Admin
|
||||||
@registrations = normalize_array_length(@registrations, @registration_weeks)
|
@registrations = normalize_array_length(@registrations, @registration_weeks)
|
||||||
@registration_weeks = @registration_weeks > 0 ? (1..@registration_weeks).to_a : 1
|
@registration_weeks = @registration_weeks > 0 ? (1..@registration_weeks).to_a : 1
|
||||||
|
|
||||||
|
@ticket_weeks = @ticket_weeks.max
|
||||||
|
@tickets = normalize_array_length(@tickets, @ticket_weeks)
|
||||||
|
@ticket_weeks = @ticket_weeks > 0 ? (1..@ticket_weeks).to_a : 1
|
||||||
|
|
||||||
@event_distribution = Conference.event_distribution
|
@event_distribution = Conference.event_distribution
|
||||||
@user_distribution = Conference.user_distribution
|
@user_distribution = Conference.user_distribution
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@conference = Conference.new
|
@conference = Conference.new
|
||||||
|
@organizations = Organization.accessible_by(current_ability, :update).pluck(:name, :id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
|
@ -133,6 +145,20 @@ module Admin
|
||||||
@submissions_data = @submissions_data.except('Weeks')
|
@submissions_data = @submissions_data.except('Weeks')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@tickets_data = {}
|
||||||
|
@tickets_data = @conference.get_tickets_data
|
||||||
|
@ticket_weeks = 0
|
||||||
|
if @tickets_data['Weeks']
|
||||||
|
@ticket_weeks = @tickets_data['Weeks']
|
||||||
|
@tickets_data = @tickets_data.except('Weeks')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Set line color using a hash function
|
||||||
|
@tickets = []
|
||||||
|
@tickets_data.keys.each do |title|
|
||||||
|
@tickets.append(short_title: title, color: "\##{Digest::MD5.hexdigest(title)[0..5]}")
|
||||||
|
end
|
||||||
|
|
||||||
# Doughnut charts
|
# Doughnut charts
|
||||||
@event_type_distribution = @conference.event_type_distribution
|
@event_type_distribution = @conference.event_type_distribution
|
||||||
@event_type_distribution_confirmed = @conference.event_type_distribution(:confirmed)
|
@event_type_distribution_confirmed = @conference.event_type_distribution(:confirmed)
|
||||||
|
|
@ -186,7 +212,7 @@ module Admin
|
||||||
:vpositions_attributes, :use_volunteers, :color,
|
:vpositions_attributes, :use_volunteers, :color,
|
||||||
:sponsorship_levels_attributes, :sponsors_attributes,
|
:sponsorship_levels_attributes, :sponsors_attributes,
|
||||||
:targets, :targets_attributes,
|
:targets, :targets_attributes,
|
||||||
:campaigns, :campaigns_attributes, :registration_limit)
|
:campaigns, :campaigns_attributes, :registration_limit, :organization_id, :ticket_layout, :booth_limit)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,9 @@ module Admin
|
||||||
:send_on_conference_registration_dates_updated, :conference_registration_dates_updated_subject, :conference_registration_dates_updated_body,
|
:send_on_conference_registration_dates_updated, :conference_registration_dates_updated_subject, :conference_registration_dates_updated_body,
|
||||||
:send_on_venue_updated, :venue_updated_subject, :venue_updated_body,
|
:send_on_venue_updated, :venue_updated_subject, :venue_updated_body,
|
||||||
:send_on_cfp_dates_updated, :cfp_dates_updated_subject, :cfp_dates_updated_body,
|
:send_on_cfp_dates_updated, :cfp_dates_updated_subject, :cfp_dates_updated_body,
|
||||||
:send_on_program_schedule_public, :program_schedule_public_subject, :program_schedule_public_body)
|
:send_on_program_schedule_public, :program_schedule_public_subject, :program_schedule_public_body,
|
||||||
|
:send_on_booths_acceptance, :booths_acceptance_subject, :booths_acceptance_body,
|
||||||
|
:send_on_booths_rejection, :booths_rejection_subject, :booths_rejection_body)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,10 @@ module Admin
|
||||||
load_and_authorize_resource :program, through: :conference, singleton: true
|
load_and_authorize_resource :program, through: :conference, singleton: true
|
||||||
load_and_authorize_resource :event, through: :program
|
load_and_authorize_resource :event, through: :program
|
||||||
load_and_authorize_resource :events_registration, only: :toggle_attendance
|
load_and_authorize_resource :events_registration, only: :toggle_attendance
|
||||||
|
# For some reason this doesn't work, so a workaround is used
|
||||||
|
# load_and_authorize_resource :track, through: :program, only: [:index, :show, :edit]
|
||||||
|
|
||||||
before_action :get_event, except: [:index, :create, :new]
|
before_action :get_tracks, only: [:index, :show, :edit]
|
||||||
|
|
||||||
# FIXME: The timezome should only be applied on output, otherwise
|
# FIXME: The timezome should only be applied on output, otherwise
|
||||||
# you get lost in timezone conversions...
|
# you get lost in timezone conversions...
|
||||||
|
|
@ -16,8 +18,6 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@events = @program.events
|
|
||||||
@tracks = @program.tracks
|
|
||||||
@difficulty_levels = @program.difficulty_levels
|
@difficulty_levels = @program.difficulty_levels
|
||||||
@event_types = @program.event_types
|
@event_types = @program.event_types
|
||||||
@tracks_distribution_confirmed = @conference.tracks_distribution(:confirmed)
|
@tracks_distribution_confirmed = @conference.tracks_distribution(:confirmed)
|
||||||
|
|
@ -43,7 +43,6 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@tracks = @program.tracks
|
|
||||||
@event_types = @program.event_types
|
@event_types = @program.event_types
|
||||||
@comments = @event.root_comments
|
@comments = @event.root_comments
|
||||||
@comment_count = @event.comment_threads.count
|
@comment_count = @event.comment_threads.count
|
||||||
|
|
@ -58,7 +57,6 @@ module Admin
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@event_types = @program.event_types
|
@event_types = @program.event_types
|
||||||
@tracks = Track.all
|
|
||||||
@comments = @event.root_comments
|
@comments = @event.root_comments
|
||||||
@comment_count = @event.comment_threads.count
|
@comment_count = @event.comment_threads.count
|
||||||
@user = @event.submitter
|
@user = @event.submitter
|
||||||
|
|
@ -104,7 +102,7 @@ module Admin
|
||||||
ahoy.track 'Event submission', title: 'New submission'
|
ahoy.track 'Event submission', title: 'New submission'
|
||||||
redirect_to admin_conference_program_events_path(@conference.short_title), notice: 'Event was successfully submitted.'
|
redirect_to admin_conference_program_events_path(@conference.short_title), notice: 'Event was successfully submitted.'
|
||||||
else
|
else
|
||||||
flash[:error] = "Could not submit proposal: #{@event.errors.full_messages.join(', ')}"
|
flash.now[:error] = "Could not submit proposal: #{@event.errors.full_messages.join(', ')}"
|
||||||
render action: 'new'
|
render action: 'new'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -187,16 +185,6 @@ module Admin
|
||||||
params.require(:comment).permit(:commentable, :body, :user_id)
|
params.require(:comment).permit(:commentable, :body, :user_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_event
|
|
||||||
@event = @conference.program.events.find(params[:id])
|
|
||||||
unless @event
|
|
||||||
redirect_to admin_conference_program_events_path(conference_id: @conference.short_title),
|
|
||||||
error: 'Error! Could not find event!'
|
|
||||||
return
|
|
||||||
end
|
|
||||||
@event
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_state(transition, notice, mail = false, subject = false, send_mail = false)
|
def update_state(transition, notice, mail = false, subject = false, send_mail = false)
|
||||||
alert = @event.update_state(transition, mail, subject, send_mail, params[:send_mail].blank?)
|
alert = @event.update_state(transition, mail, subject, send_mail, params[:send_mail].blank?)
|
||||||
|
|
||||||
|
|
@ -208,5 +196,9 @@ module Admin
|
||||||
return redirect_back_or_to(admin_conference_program_events_path(conference_id: @conference.short_title)) && return
|
return redirect_back_or_to(admin_conference_program_events_path(conference_id: @conference.short_title)) && return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_tracks
|
||||||
|
@tracks = Track.accessible_by(current_ability).where(program: @program).confirmed
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
94
app/controllers/admin/organizations_controller.rb
Normal file
94
app/controllers/admin/organizations_controller.rb
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
module Admin
|
||||||
|
class OrganizationsController < Admin::BaseController
|
||||||
|
load_and_authorize_resource :organization
|
||||||
|
before_action :verify_user, only: [:assign_org_admins, :unassign_org_admins]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@organizations = Organization.all
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@organization = Organization.new(organization_params)
|
||||||
|
if @organization.save
|
||||||
|
redirect_to admin_organizations_path,
|
||||||
|
notice: 'Organization successfully created'
|
||||||
|
else
|
||||||
|
redirect_to new_admin_organization_path,
|
||||||
|
error: @organization.errors.full_messages.join(', ')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@organization = Organization.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit; end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @organization.update_attributes(organization_params)
|
||||||
|
redirect_to admin_organizations_path,
|
||||||
|
notice: 'Organization successfully updated'
|
||||||
|
else
|
||||||
|
redirect_to edit_admin_organization_path(@organization),
|
||||||
|
error: @organization.errors.full_messages.join(', ')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @organization.destroy
|
||||||
|
redirect_to admin_organizations_path,
|
||||||
|
notice: 'Organization successfully destroyed'
|
||||||
|
else
|
||||||
|
redirect_to admin_organizations_path,
|
||||||
|
error: 'Organization cannot be destroyed'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def assign_org_admins
|
||||||
|
if @user.has_role? 'organization_admin', @organization
|
||||||
|
flash[:error] = "User #{@user.email} already has the role organization admin"
|
||||||
|
elsif @user.add_role 'organization_admin', @organization
|
||||||
|
flash[:notice] = "Successfully added role organization admin to user #{@user.email}"
|
||||||
|
else
|
||||||
|
flash[:error] = "Coud not add role organization admin to #{@user.email}"
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to admins_admin_organization_path(@organization)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unassign_org_admins
|
||||||
|
if @user.remove_role 'organization_admin', @organization
|
||||||
|
flash[:notice] = "Successfully removed role organization admin from user #{@user.email}"
|
||||||
|
else
|
||||||
|
flash[:error] = "Could not remove role organization admin from user #{@user.email}"
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to admins_admin_organization_path(@organization)
|
||||||
|
end
|
||||||
|
|
||||||
|
def admins
|
||||||
|
@role = @organization.roles.first
|
||||||
|
@users = @role.users
|
||||||
|
render 'show_org_admins'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def user_params
|
||||||
|
params.require(:user).permit(:email)
|
||||||
|
end
|
||||||
|
|
||||||
|
def verify_user
|
||||||
|
@user = User.find_by(email: user_params[:email])
|
||||||
|
unless @user
|
||||||
|
redirect_to admins_admin_organization_path(@organization),
|
||||||
|
error: 'Could not find user. Please provide a valid email!'
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def organization_params
|
||||||
|
params.require(:organization).permit(:name, :description, :picture)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
14
app/controllers/admin/physical_tickets_controller.rb
Normal file
14
app/controllers/admin/physical_tickets_controller.rb
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
module Admin
|
||||||
|
class PhysicalTicketsController < Admin::BaseController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
load_resource :conference, find_by: :short_title
|
||||||
|
load_and_authorize_resource
|
||||||
|
authorize_resource :conference_registrations, class: Registration
|
||||||
|
|
||||||
|
def index
|
||||||
|
@physical_tickets = @conference.physical_tickets
|
||||||
|
@tickets_sold_distribution = @conference.tickets_sold_distribution
|
||||||
|
@tickets_turnover_distribution = @conference.tickets_turnover_distribution
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -30,7 +30,7 @@ module Admin
|
||||||
flash.now[:error] = "Updating program failed. #{@program.errors.to_a.join('. ')}."
|
flash.now[:error] = "Updating program failed. #{@program.errors.to_a.join('. ')}."
|
||||||
render :new
|
render :new
|
||||||
end
|
end
|
||||||
format.js { render json: { errors: "The selected schedule couldn't been updated #{@program.errors.to_a.join('. ')}" }, status: 422 }
|
format.js { render json: { errors: "The selected schedule couldn't be updated #{@program.errors.to_a.join('. ')}" }, status: 422 }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
module Admin
|
module Admin
|
||||||
class RegistrationPeriodsController < ApplicationController
|
class RegistrationPeriodsController < Admin::BaseController
|
||||||
load_and_authorize_resource :conference, find_by: :short_title
|
load_and_authorize_resource :conference, find_by: :short_title
|
||||||
load_and_authorize_resource through: :conference, singleton: true
|
load_and_authorize_resource through: :conference, singleton: true
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,11 @@ module Admin
|
||||||
class ReportsController < Admin::BaseController
|
class ReportsController < Admin::BaseController
|
||||||
load_and_authorize_resource :conference, find_by: :short_title
|
load_and_authorize_resource :conference, find_by: :short_title
|
||||||
load_and_authorize_resource :program, through: :conference, singleton: true
|
load_and_authorize_resource :program, through: :conference, singleton: true
|
||||||
|
# For some reason this doesn't work, so a workaround is used
|
||||||
|
# load_and_authorize_resource :event, through: :program
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@events = @program.events
|
@events = Event.accessible_by(current_ability).where(program: @program)
|
||||||
@events_commercials = Commercial.where(commercialable_type: 'Event', commercialable_id: @events.pluck(:id))
|
@events_commercials = Commercial.where(commercialable_type: 'Event', commercialable_id: @events.pluck(:id))
|
||||||
@events_missing_commercial = @events.where.not(id: @events_commercials.pluck(:commercialable_id))
|
@events_missing_commercial = @events.where.not(id: @events_commercials.pluck(:commercialable_id))
|
||||||
@events_with_requirements = @events.where.not(description: ['', nil])
|
@events_with_requirements = @events.where.not(description: ['', nil])
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,26 @@ module Admin
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@roles = Role.where(resource: @conference)
|
@roles = Role.where(resource: @conference)
|
||||||
|
tracks = @conference.program.tracks.where.not(submitter: nil)
|
||||||
|
@roles += Role.where(resource: tracks)
|
||||||
authorize! :index, @role
|
authorize! :index, @role
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@url = if @track
|
||||||
|
toggle_user_admin_conference_program_track_role_path(@conference.short_title, @track, @role.name)
|
||||||
|
else
|
||||||
|
toggle_user_admin_conference_role_path(@conference.short_title, @role.name)
|
||||||
|
end
|
||||||
@users = @role.users
|
@users = @role.users
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
@url = if @track
|
||||||
|
admin_conference_program_track_role_path(@conference.short_title, @track, @role.name)
|
||||||
|
else
|
||||||
|
admin_conference_role_path(@conference.short_title, @role.name)
|
||||||
|
end
|
||||||
@users = @role.users
|
@users = @role.users
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -23,7 +35,13 @@ module Admin
|
||||||
role_name = @role.name
|
role_name = @role.name
|
||||||
|
|
||||||
if @role.update_attributes(role_params)
|
if @role.update_attributes(role_params)
|
||||||
redirect_to admin_conference_role_path(@conference.short_title, @role.name),
|
url = if @track
|
||||||
|
admin_conference_program_track_role_path(@conference.short_title, @track, @role.name)
|
||||||
|
else
|
||||||
|
admin_conference_role_path(@conference.short_title, @role.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to url,
|
||||||
notice: 'Successfully updated role ' + @role.name
|
notice: 'Successfully updated role ' + @role.name
|
||||||
else
|
else
|
||||||
@role.name = role_name
|
@role.name = role_name
|
||||||
|
|
@ -36,8 +54,14 @@ module Admin
|
||||||
user = User.find_by(email: user_params[:email])
|
user = User.find_by(email: user_params[:email])
|
||||||
state = user_params[:state]
|
state = user_params[:state]
|
||||||
|
|
||||||
|
url = if @track
|
||||||
|
admin_conference_program_track_role_path(@conference.short_title, @track, @role.name)
|
||||||
|
else
|
||||||
|
admin_conference_role_path(@conference.short_title, @role.name)
|
||||||
|
end
|
||||||
|
|
||||||
unless user
|
unless user
|
||||||
redirect_to admin_conference_role_path(@conference.short_title, @role.name),
|
redirect_to url,
|
||||||
error: 'Could not find user. Please provide a valid email!'
|
error: 'Could not find user. Please provide a valid email!'
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -49,17 +73,23 @@ module Admin
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if @role.resource_type == 'Conference'
|
||||||
|
role_resource = @conference
|
||||||
|
elsif @role.resource_type == 'Track'
|
||||||
|
role_resource = @track
|
||||||
|
end
|
||||||
|
|
||||||
# Remove user
|
# Remove user
|
||||||
if state == 'false'
|
if state == 'false'
|
||||||
if user.remove_role @role.name, @conference
|
if user.remove_role @role.name, role_resource
|
||||||
flash[:notice] = "Successfully removed role #{@role.name} from user #{user.email}"
|
flash[:notice] = "Successfully removed role #{@role.name} from user #{user.email}"
|
||||||
else
|
else
|
||||||
flash[:error] = "Could not remove role #{@role.name} from user #{user.email}"
|
flash[:error] = "Could not remove role #{@role.name} from user #{user.email}"
|
||||||
end
|
end
|
||||||
elsif user.has_role? @role.name, @conference
|
elsif user.has_role? @role.name, role_resource
|
||||||
flash[:error] = "User #{user.email} already has the role #{@role.name}"
|
flash[:error] = "User #{user.email} already has the role #{@role.name}"
|
||||||
# Add user
|
# Add user
|
||||||
elsif user.add_role @role.name, @conference
|
elsif user.add_role @role.name, role_resource
|
||||||
flash[:notice] = "Successfully added role #{@role.name} to user #{user.email}"
|
flash[:notice] = "Successfully added role #{@role.name} to user #{user.email}"
|
||||||
else
|
else
|
||||||
flash[:error] = "Coud not add role #{@role.name} to #{user.email}"
|
flash[:error] = "Coud not add role #{@role.name} to #{user.email}"
|
||||||
|
|
@ -67,7 +97,7 @@ module Admin
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.js
|
format.js
|
||||||
format.html { redirect_to admin_conference_role_path(@conference.short_title, @role.name) }
|
format.html { redirect_to url }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -77,8 +107,13 @@ module Admin
|
||||||
# Set 'organizer' as default role, when there is no other selection
|
# Set 'organizer' as default role, when there is no other selection
|
||||||
@selection = params[:id] ? params[:id].parameterize.underscore : 'organizer'
|
@selection = params[:id] ? params[:id].parameterize.underscore : 'organizer'
|
||||||
|
|
||||||
|
if @selection == 'track_organizer'
|
||||||
|
@track = @conference.program.tracks.find_by(short_name: params[:track_id])
|
||||||
|
@role = Role.find_by(name: @selection, resource: @track)
|
||||||
|
else
|
||||||
@role = Role.find_by(name: @selection, resource: @conference)
|
@role = Role.find_by(name: @selection, resource: @conference)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def role_params
|
def role_params
|
||||||
params.require(:role).permit(:name, :description, user_ids: [])
|
params.require(:role).permit(:name, :description, user_ids: [])
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,21 @@ module Admin
|
||||||
# the schedule of a conference, which should not be accessed in the first place
|
# the schedule of a conference, which should not be accessed in the first place
|
||||||
load_and_authorize_resource :conference, find_by: :short_title
|
load_and_authorize_resource :conference, find_by: :short_title
|
||||||
load_and_authorize_resource :program, through: :conference, singleton: true
|
load_and_authorize_resource :program, through: :conference, singleton: true
|
||||||
load_and_authorize_resource :schedule, through: :program
|
load_and_authorize_resource :schedule, through: :program, except: [:new, :create]
|
||||||
load_resource :event_schedules, through: :schedule
|
load_resource :event_schedules, through: :schedule
|
||||||
load_resource :selected_schedule, through: :program, singleton: true
|
load_resource :selected_schedule, through: :program, singleton: true
|
||||||
load_resource :venue, through: :conference, singleton: true
|
load_resource :venue, through: :conference, singleton: true
|
||||||
|
|
||||||
def index; end
|
def index; end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@schedule = @program.schedules.build(track: @program.tracks.new)
|
||||||
|
authorize! :new, @schedule
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@schedule = @program.schedules.new(schedule_params)
|
||||||
|
authorize! :create, @schedule
|
||||||
if @schedule.save
|
if @schedule.save
|
||||||
redirect_to admin_conference_schedule_path(@conference.short_title, @schedule.id),
|
redirect_to admin_conference_schedule_path(@conference.short_title, @schedule.id),
|
||||||
notice: 'Schedule was successfully created.'
|
notice: 'Schedule was successfully created.'
|
||||||
|
|
@ -23,10 +30,25 @@ module Admin
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@event_schedules = @schedule.event_schedules
|
@event_schedules = @schedule.event_schedules
|
||||||
@unscheduled_events = @program.events.confirmed - @schedule.events
|
|
||||||
|
if @schedule.track
|
||||||
|
track = @schedule.track
|
||||||
|
@unscheduled_events = track.events.confirmed - @schedule.events
|
||||||
|
@dates = track.start_date..track.end_date
|
||||||
|
@rooms = [track.room]
|
||||||
|
else
|
||||||
|
@program.tracks.self_organized.confirmed.each do |t|
|
||||||
|
@event_schedules += t.selected_schedule.event_schedules if t.selected_schedule
|
||||||
|
end
|
||||||
|
self_organized_tracks_events = @program.tracks.self_organized.confirmed.map do |t|
|
||||||
|
t.events.confirmed
|
||||||
|
end
|
||||||
|
self_organized_tracks_events.flatten.compact!
|
||||||
|
@unscheduled_events = @program.events.confirmed - @schedule.events - self_organized_tracks_events
|
||||||
@dates = @conference.start_date..@conference.end_date
|
@dates = @conference.start_date..@conference.end_date
|
||||||
@rooms = @conference.venue.rooms if @conference.venue
|
@rooms = @conference.venue.rooms if @conference.venue
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
if @schedule.destroy
|
if @schedule.destroy
|
||||||
|
|
@ -37,5 +59,11 @@ module Admin
|
||||||
error: "Schedule couldn't be deleted. #{@schedule.errors.full_messages.join('. ')}."
|
error: "Schedule couldn't be deleted. #{@schedule.errors.full_messages.join('. ')}."
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def schedule_params
|
||||||
|
params.require(:schedule).permit(:track_id) if params[:schedule]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,8 @@ module Admin
|
||||||
:include_tracks, :include_program, :include_cfp,
|
:include_tracks, :include_program, :include_cfp,
|
||||||
:include_venue, :include_registrations,
|
:include_venue, :include_registrations,
|
||||||
:include_tickets, :include_lodgings,
|
:include_tickets, :include_lodgings,
|
||||||
:include_sponsors, :include_social_media)
|
:include_sponsors, :include_social_media,
|
||||||
|
:include_booths)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
16
app/controllers/admin/ticket_scannings_controller.rb
Normal file
16
app/controllers/admin/ticket_scannings_controller.rb
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
module Admin
|
||||||
|
class TicketScanningsController < Admin::BaseController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
load_resource :physical_ticket, find_by: :token
|
||||||
|
# We authorize manually in these actions
|
||||||
|
skip_authorize_resource only: [:create]
|
||||||
|
|
||||||
|
def create
|
||||||
|
@ticket_scanning = TicketScanning.new(physical_ticket: @physical_ticket)
|
||||||
|
authorize! :create, @ticket_scanning
|
||||||
|
@ticket_scanning.save
|
||||||
|
redirect_to conferences_path,
|
||||||
|
notice: "Ticket with token #{@physical_ticket.token} successfully scanned."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -5,6 +5,8 @@ module Admin
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize! :update, Ticket.new(conference_id: @conference.id)
|
authorize! :update, Ticket.new(conference_id: @conference.id)
|
||||||
|
@tickets_sold_distribution = @conference.tickets_sold_distribution
|
||||||
|
@tickets_turnover_distribution = @conference.tickets_turnover_distribution
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
|
|
@ -48,7 +50,7 @@ module Admin
|
||||||
private
|
private
|
||||||
|
|
||||||
def ticket_params
|
def ticket_params
|
||||||
params.require(:ticket).permit(:conference, :title, :url, :description, :conference_id, :price_cents, :price_currency, :price)
|
params.require(:ticket).permit(:conference, :title, :url, :description, :conference_id, :price_cents, :price_currency, :price, :registration_ticket)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,10 @@ module Admin
|
||||||
class TracksController < Admin::BaseController
|
class TracksController < Admin::BaseController
|
||||||
load_and_authorize_resource :conference, find_by: :short_title
|
load_and_authorize_resource :conference, find_by: :short_title
|
||||||
load_and_authorize_resource :program, through: :conference, singleton: true
|
load_and_authorize_resource :program, through: :conference, singleton: true
|
||||||
load_and_authorize_resource through: :program
|
load_and_authorize_resource through: :program, find_by: :short_name
|
||||||
|
|
||||||
|
# Show flash message with ajax calls
|
||||||
|
after_action :prepare_unobtrusive_flash, only: :toggle_cfp_inclusion
|
||||||
|
|
||||||
def index; end
|
def index; end
|
||||||
|
|
||||||
|
|
@ -19,6 +22,8 @@ module Admin
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@track = @program.tracks.new(track_params)
|
@track = @program.tracks.new(track_params)
|
||||||
|
@track.state = 'confirmed'
|
||||||
|
@track.cfp_active = true
|
||||||
if @track.save
|
if @track.save
|
||||||
redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title),
|
redirect_to admin_conference_program_tracks_path(conference_id: @conference.short_title),
|
||||||
notice: 'Track successfully created.'
|
notice: 'Track successfully created.'
|
||||||
|
|
@ -50,10 +55,80 @@ module Admin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def toggle_cfp_inclusion
|
||||||
|
@track.cfp_active = !@track.cfp_active
|
||||||
|
if @track.save
|
||||||
|
flash[:notice] = "Successfully changed cfp inclusion of #{@track.name} to #{@track.cfp_active}"
|
||||||
|
else
|
||||||
|
flash[:error] = "Failed to toggle cfp inclusion of #{@track.name} to #{@track.cfp_active}"
|
||||||
|
end
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def restart
|
||||||
|
update_state(:restart, "Review for #{@track.name} started!")
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_accept
|
||||||
|
update_state(:to_accept, "Track #{@track.name} marked as a possible acceptance!")
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept
|
||||||
|
if @track.room && @track.start_date && @track.end_date
|
||||||
|
update_state(:accept, "Track #{@track.name} accepted!")
|
||||||
|
else
|
||||||
|
flash[:alert] = 'Please make sure that the track has a room and start/end dates before accepting it'
|
||||||
|
redirect_to edit_admin_conference_program_track_path(@conference.short_title, @track)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def confirm
|
||||||
|
update_state(:confirm, "Track #{@track.name} confirmed!")
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_reject
|
||||||
|
update_state(:to_reject, "Track #{@track.name} marked as a possible rejection!")
|
||||||
|
end
|
||||||
|
|
||||||
|
def reject
|
||||||
|
update_state(:reject, "Track #{@track.name} rejected!")
|
||||||
|
end
|
||||||
|
|
||||||
|
def cancel
|
||||||
|
update_state(:cancel, "Track #{@track.name} canceled!")
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_selected_schedule
|
||||||
|
if @track.update_attributes(params.require(:track).permit(:selected_schedule_id))
|
||||||
|
respond_to do |format|
|
||||||
|
format.js { render json: {} }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
respond_to do |format|
|
||||||
|
format.js { render json: { errors: "The selected schedule couldn't be updated #{@track.errors.to_a.join('. ')}" }, status: 422 }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def track_params
|
def track_params
|
||||||
params.require(:track).permit(:name, :description, :color)
|
params.require(:track).permit(:name, :description, :color, :short_name, :cfp_active, :start_date, :end_date, :room_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_state(transition, notice)
|
||||||
|
errors = @track.update_state(transition)
|
||||||
|
|
||||||
|
if errors.blank?
|
||||||
|
flash[:notice] = notice
|
||||||
|
else
|
||||||
|
flash[:error] = errors
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_back_or_to(admin_conference_program_tracks_path(conference_id: @conference.short_title))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,21 @@
|
||||||
module Admin
|
module Admin
|
||||||
class VersionsController < Admin::BaseController
|
class VersionsController < Admin::BaseController
|
||||||
skip_authorization_check
|
load_resource :conference, find_by: :short_title, only: :index
|
||||||
|
load_and_authorize_resource class: PaperTrail::Version
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize! :index, PaperTrail::Version.new(item_type: 'User')
|
@conferences_with_role = current_user.is_admin? ? Conference.pluck(:short_title) : Conference.with_role([:organizer, :cfp, :info_desk], current_user).pluck(:short_title)
|
||||||
conf_ids_for_organizer = current_user.is_admin? ? Conference.pluck(:id) : Conference.with_role(:organizer, current_user).pluck(:id)
|
|
||||||
@versions = PaperTrail::Version.where(["conference_id IN (?) OR item_type = 'User'", conf_ids_for_organizer])
|
if current_user.has_role? :organization_admin, :any
|
||||||
|
@conferences_with_role = Organization.with_role('organization_admin', current_user).map { |org| org.conferences.pluck :short_title }.flatten
|
||||||
|
end
|
||||||
|
@conferences_with_role.uniq!
|
||||||
|
|
||||||
|
return if @conference.blank?
|
||||||
|
@versions = PaperTrail::Version.where(conference_id: @conference.id).accessible_by(current_ability)
|
||||||
end
|
end
|
||||||
|
|
||||||
def revert_attribute
|
def revert_attribute
|
||||||
@version = PaperTrail::Version.find(params[:id])
|
|
||||||
authorize! :revert_attribute, @version
|
|
||||||
|
|
||||||
if params[:attribute] && @version.changeset.reject{ |_, values| values[0].blank? && values[1].blank? }.keys.include?(params[:attribute])
|
if params[:attribute] && @version.changeset.reject{ |_, values| values[0].blank? && values[1].blank? }.keys.include?(params[:attribute])
|
||||||
if @version.item[params[:attribute]] == @version.changeset[params[:attribute]][0]
|
if @version.item[params[:attribute]] == @version.changeset[params[:attribute]][0]
|
||||||
flash[:error] = 'The item is already in the state that you are trying to revert it back to'
|
flash[:error] = 'The item is already in the state that you are trying to revert it back to'
|
||||||
|
|
@ -33,9 +37,6 @@ module Admin
|
||||||
end
|
end
|
||||||
|
|
||||||
def revert_object
|
def revert_object
|
||||||
@version = PaperTrail::Version.find(params[:id])
|
|
||||||
authorize! :revert_object, @version
|
|
||||||
|
|
||||||
if @version.event != 'create'
|
if @version.event != 'create'
|
||||||
if @version.reify.save
|
if @version.reify.save
|
||||||
flash[:notice] = 'The selected change was successfully reverted'
|
flash[:notice] = 'The selected change was successfully reverted'
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,10 @@ module Admin
|
||||||
|
|
||||||
def show
|
def show
|
||||||
if can_manage_volunteers?(@conference)
|
if can_manage_volunteers?(@conference)
|
||||||
if @conference.use_vpositions
|
@volunteers = if @conference.use_vpositions
|
||||||
@volunteers = @conference.registrations.joins(:vchoices).uniq
|
@conference.registrations.joins(:vchoices).uniq
|
||||||
else
|
else
|
||||||
@volunteers = @conference.registrations.where(volunteer: true)
|
@conference.registrations.where(volunteer: true)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
authorize! :index, :volunteer
|
authorize! :index, :volunteer
|
||||||
|
|
|
||||||
97
app/controllers/booths_controller.rb
Normal file
97
app/controllers/booths_controller.rb
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
class BoothsController < ApplicationController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
load_resource :conference, find_by: :short_title
|
||||||
|
load_and_authorize_resource through: :conference
|
||||||
|
skip_authorize_resource only: [:withdraw, :confirm, :restart]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@booths = current_user.booths.where(conference_id: @conference.id).uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
def show; end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@url = conference_booths_path(@conference.short_title)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@url = conference_booths_path(@conference.short_title)
|
||||||
|
|
||||||
|
@booth.submitter = current_user
|
||||||
|
|
||||||
|
if @booth.save
|
||||||
|
redirect_to conference_booths_path,
|
||||||
|
notice: 'Booth successfully created.'
|
||||||
|
else
|
||||||
|
flash.now[:error] = "Creating booth failed. #{@booth.errors.full_messages.to_sentence}."
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@url = conference_booth_path(@conference.short_title, @booth.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@url = conference_booth_path(@conference.short_title, @booth.id)
|
||||||
|
@booth.update_attributes(booth_params)
|
||||||
|
|
||||||
|
if @booth.save
|
||||||
|
redirect_to conference_booths_path,
|
||||||
|
notice: 'Booth successfully updated!'
|
||||||
|
else
|
||||||
|
flash.now[:error] = "Booth could not be updated. #{@booth.errors.full_messages.to_sentence}."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy; end
|
||||||
|
|
||||||
|
def withdraw
|
||||||
|
authorize! :update, @booth
|
||||||
|
@url = conference_booth_path(@conference.short_title, @booth.id)
|
||||||
|
|
||||||
|
@booth.withdraw!
|
||||||
|
|
||||||
|
if @booth.save
|
||||||
|
redirect_to conference_booths_path,
|
||||||
|
notice: 'Booth successfully withdrawn'
|
||||||
|
else
|
||||||
|
flash.now[:error] = "Booth could not be withdrawn. #{@booth.errors.full_messages.to_sentence}."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def confirm
|
||||||
|
authorize! :update, @booth
|
||||||
|
@url = conference_booth_path(@conference.short_title, @booth.id)
|
||||||
|
|
||||||
|
@booth.confirm!
|
||||||
|
|
||||||
|
if @booth.save
|
||||||
|
redirect_to conference_booths_path,
|
||||||
|
notice: 'Booth successfully confirmed'
|
||||||
|
else
|
||||||
|
flash.now[:error] = "Booth could not be confirmed. #{@booth.errors.full_messages.to_sentence}."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def restart
|
||||||
|
authorize! :update, @booth
|
||||||
|
@url = conference_booth_path(@conference.short_title, @booth.id)
|
||||||
|
|
||||||
|
@booth.restart!
|
||||||
|
|
||||||
|
if @booth.save
|
||||||
|
redirect_to conference_booths_path,
|
||||||
|
notice: 'Booth successfully re-submitted'
|
||||||
|
else
|
||||||
|
flash.now[:error] = "Booth could not be re-submitted. #{@booth.errors.full_messages.to_sentence}."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def booth_params
|
||||||
|
params.require(:booth).permit(:title, :description, :reasoning, :state, :picture, :conference_id,
|
||||||
|
:created_at, :updated_at, :submitter_relationship, :website_url, responsible_ids: [])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -27,8 +27,9 @@ class ConferenceRegistrationsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@total_price = Ticket.total_price(@conference, current_user, paid: true)
|
@total_price = Ticket.total_price_user(@conference, current_user, paid: true)
|
||||||
@tickets = current_user.ticket_purchases.by_conference(@conference).paid
|
@tickets = current_user.ticket_purchases.by_conference(@conference).paid
|
||||||
|
@total_price_per_ticket = @tickets.group(:ticket_id).sum('amount_paid * quantity')
|
||||||
@ticket_payments = @tickets.group_by(&:ticket_id)
|
@ticket_payments = @tickets.group_by(&:ticket_id)
|
||||||
@total_quantity = @tickets.group(:ticket_id).sum(:quantity)
|
@total_quantity = @tickets.group(:ticket_id).sum(:quantity)
|
||||||
end
|
end
|
||||||
|
|
@ -38,11 +39,11 @@ class ConferenceRegistrationsController < ApplicationController
|
||||||
def create
|
def create
|
||||||
@registration = @conference.registrations.new(registration_params)
|
@registration = @conference.registrations.new(registration_params)
|
||||||
|
|
||||||
if current_user.nil?
|
@user = if current_user.nil?
|
||||||
# @user variable needs to be set so that _sign_up_form_embedded works properly
|
# @user variable needs to be set so that _sign_up_form_embedded works properly
|
||||||
@user = @registration.build_user(user_params)
|
@registration.build_user(user_params)
|
||||||
else
|
else
|
||||||
@user = current_user
|
current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
@registration.user = @user
|
@registration.user = @user
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,29 @@
|
||||||
class ConferencesController < ApplicationController
|
class ConferencesController < ApplicationController
|
||||||
protect_from_forgery with: :null_session
|
protect_from_forgery with: :null_session
|
||||||
before_action :respond_to_options
|
before_action :respond_to_options
|
||||||
load_and_authorize_resource find_by: :short_title
|
load_and_authorize_resource find_by: :short_title, except: :show
|
||||||
load_resource :program, through: :conference, singleton: true, except: :index
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@current = Conference.where('end_date >= ?', Date.current).reorder(start_date: :asc)
|
@current = Conference.where('end_date >= ?', Date.current).reorder(start_date: :asc)
|
||||||
@antiquated = @conferences - @current
|
@antiquated = @conferences - @current
|
||||||
end
|
end
|
||||||
|
|
||||||
def show; end
|
def show
|
||||||
|
@conference = if params[:id]
|
||||||
|
Conference.find_by_short_title(params[:id])
|
||||||
|
else
|
||||||
|
load_conference_by_domain
|
||||||
|
end
|
||||||
|
authorize! :show, @conference
|
||||||
|
@program = @conference.program
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def load_conference_by_domain
|
||||||
|
Conference.find_by(custom_domain: request.domain)
|
||||||
|
end
|
||||||
|
|
||||||
def respond_to_options
|
def respond_to_options
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { head :ok }
|
format.html { head :ok }
|
||||||
|
|
|
||||||
9
app/controllers/openids_controller.rb
Normal file
9
app/controllers/openids_controller.rb
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
class OpenidsController < ApplicationController
|
||||||
|
load_and_authorize_resource :user
|
||||||
|
load_and_authorize_resource through: :user
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@openid.destroy
|
||||||
|
redirect_to :back
|
||||||
|
end
|
||||||
|
end
|
||||||
7
app/controllers/organizations_controller.rb
Normal file
7
app/controllers/organizations_controller.rb
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
class OrganizationsController < ApplicationController
|
||||||
|
load_and_authorize_resource :organization
|
||||||
|
|
||||||
|
def index
|
||||||
|
@organizations = Organization.all
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -10,6 +10,9 @@ class PaymentsController < ApplicationController
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@total_amount_to_pay = Ticket.total_price(@conference, current_user, paid: false)
|
@total_amount_to_pay = Ticket.total_price(@conference, current_user, paid: false)
|
||||||
|
if @total_amount_to_pay.zero?
|
||||||
|
raise CanCan::AccessDenied.new('Nothing to pay for!', :new, Payment)
|
||||||
|
end
|
||||||
@unpaid_ticket_purchases = current_user.ticket_purchases.unpaid.by_conference(@conference)
|
@unpaid_ticket_purchases = current_user.ticket_purchases.unpaid.by_conference(@conference)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -18,7 +21,7 @@ class PaymentsController < ApplicationController
|
||||||
|
|
||||||
if @payment.purchase && @payment.save
|
if @payment.purchase && @payment.save
|
||||||
update_purchased_ticket_purchases
|
update_purchased_ticket_purchases
|
||||||
redirect_to conference_conference_registration_path(@conference.short_title),
|
redirect_to conference_physical_tickets_path,
|
||||||
notice: 'Thanks! Your ticket is booked successfully.'
|
notice: 'Thanks! Your ticket is booked successfully.'
|
||||||
else
|
else
|
||||||
@total_amount_to_pay = Ticket.total_price(@conference, current_user, paid: false)
|
@total_amount_to_pay = Ticket.total_price(@conference, current_user, paid: false)
|
||||||
|
|
@ -38,6 +41,8 @@ class PaymentsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_purchased_ticket_purchases
|
def update_purchased_ticket_purchases
|
||||||
current_user.ticket_purchases.by_conference(@conference).unpaid.update_all(paid: true, payment_id: @payment.id)
|
current_user.ticket_purchases.by_conference(@conference).unpaid.each do |ticket_purchase|
|
||||||
|
ticket_purchase.pay(@payment)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
28
app/controllers/physical_tickets_controller.rb
Normal file
28
app/controllers/physical_tickets_controller.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
class PhysicalTicketsController < ApplicationController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
load_resource :conference, find_by: :short_title
|
||||||
|
load_and_authorize_resource find_by: :token
|
||||||
|
authorize_resource :conference_registrations, class: Registration
|
||||||
|
|
||||||
|
def index
|
||||||
|
@physical_tickets = current_user.physical_tickets.by_conference(@conference)
|
||||||
|
@unpaid_ticket_purchases = current_user.ticket_purchases.by_conference(@conference).unpaid
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@file_name = "ticket_for_#{@conference.short_title}"
|
||||||
|
@user = @physical_ticket.user
|
||||||
|
@ticket_layout = @conference.ticket_layout.to_sym
|
||||||
|
@qrcode_image = RQRCode::QRCode.new(@physical_ticket.token).as_png(size: 180, border_modules: 0)
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
format.pdf do
|
||||||
|
pdf = TicketPdf.new(@conference, @user, @physical_ticket, @ticket_layout, @file_name)
|
||||||
|
send_data pdf.render,
|
||||||
|
filename: @file_name,
|
||||||
|
type: 'application/pdf',
|
||||||
|
disposition: 'attachment'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -49,6 +49,14 @@ class ProposalsController < ApplicationController
|
||||||
# by default.
|
# by default.
|
||||||
@event.speakers = [current_user]
|
@event.speakers = [current_user]
|
||||||
@event.submitter = current_user
|
@event.submitter = current_user
|
||||||
|
|
||||||
|
track = Track.find_by(id: params[:event][:track_id])
|
||||||
|
if track && !track.cfp_active
|
||||||
|
flash.now[:error] = 'You have selected a track that doesn\'t accept proposals'
|
||||||
|
render action: 'new'
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if @event.save
|
if @event.save
|
||||||
ahoy.track 'Event submission', title: 'New submission'
|
ahoy.track 'Event submission', title: 'New submission'
|
||||||
redirect_to conference_program_proposals_path(@conference.short_title), notice: 'Proposal was successfully submitted.'
|
redirect_to conference_program_proposals_path(@conference.short_title), notice: 'Proposal was successfully submitted.'
|
||||||
|
|
@ -61,6 +69,13 @@ class ProposalsController < ApplicationController
|
||||||
def update
|
def update
|
||||||
@url = conference_program_proposal_path(@conference.short_title, params[:id])
|
@url = conference_program_proposal_path(@conference.short_title, params[:id])
|
||||||
|
|
||||||
|
track = Track.find_by(id: params[:event][:track_id])
|
||||||
|
if track && !track.cfp_active
|
||||||
|
flash.now[:error] = 'You have selected a track that doesn\'t accept proposals'
|
||||||
|
render action: 'edit'
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if @event.update(event_params)
|
if @event.update(event_params)
|
||||||
redirect_to conference_program_proposals_path(conference_id: @conference.short_title),
|
redirect_to conference_program_proposals_path(conference_id: @conference.short_title),
|
||||||
notice: 'Proposal was successfully updated.'
|
notice: 'Proposal was successfully updated.'
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,17 @@ class SchedulesController < ApplicationController
|
||||||
# the schedule takes you to today if it is a date of the schedule
|
# the schedule takes you to today if it is a date of the schedule
|
||||||
@current_day = @conference.current_conference_day
|
@current_day = @conference.current_conference_day
|
||||||
@day = @current_day.present? ? @current_day : @dates.first
|
@day = @current_day.present? ? @current_day : @dates.first
|
||||||
return unless @current_day
|
unless @current_day
|
||||||
# the schedule takes you to the current time if it is beetween the start and the end time.
|
# the schedule takes you to the current time if it is beetween the start and the end time.
|
||||||
@hour_column = @conference.hours_from_start_time(@conf_start, @conference.end_hour)
|
@hour_column = @conference.hours_from_start_time(@conf_start, @conference.end_hour)
|
||||||
end
|
end
|
||||||
|
# Ids of the schedules of confrmed self_organized tracks along with the selected_schedule_id
|
||||||
|
@selected_schedules_ids = [@conference.program.selected_schedule_id]
|
||||||
|
@conference.program.tracks.self_organized.confirmed.each do |track|
|
||||||
|
@selected_schedules_ids << track.selected_schedule_id
|
||||||
|
end
|
||||||
|
@selected_schedules_ids.compact!
|
||||||
|
end
|
||||||
|
|
||||||
def events
|
def events
|
||||||
@dates = @conference.start_date..@conference.end_date
|
@dates = @conference.start_date..@conference.end_date
|
||||||
|
|
@ -32,11 +39,7 @@ class SchedulesController < ApplicationController
|
||||||
@events_schedules = @program.selected_event_schedules
|
@events_schedules = @program.selected_event_schedules
|
||||||
@events_schedules = [] unless @events_schedules
|
@events_schedules = [] unless @events_schedules
|
||||||
|
|
||||||
@unscheduled_events = if @program.selected_schedule
|
@unscheduled_events = @program.events.confirmed - @events_schedules.map(&:event)
|
||||||
@program.events.confirmed - @program.selected_schedule.events
|
|
||||||
else
|
|
||||||
@program.events.confirmed
|
|
||||||
end
|
|
||||||
|
|
||||||
day = @conference.current_conference_day
|
day = @conference.current_conference_day
|
||||||
@tag = day.strftime('%Y-%m-%d') if day
|
@tag = day.strftime('%Y-%m-%d') if day
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,19 @@ class SubscriptionsController < ApplicationController
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@subscription = current_user.subscriptions.build(conference_id: @conference.id)
|
@subscription = current_user.subscriptions.build(conference_id: @conference.id)
|
||||||
if @subscription.save!
|
if @subscription.save
|
||||||
redirect_to root_path, notice: "You have been subscribed to receive email notifications for #{@conference.short_title}."
|
redirect_to root_path, notice: "You have subscribed to receive email notifications for #{@conference.title}."
|
||||||
else
|
else
|
||||||
redirect_to root_path, error: subscription.errors.full_messages.to_sentence
|
redirect_to root_path, error: @subscription.errors.full_messages.to_sentence
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@subscription = current_user.subscriptions.find_by(conference_id: @conference.id)
|
@subscription = current_user.subscriptions.find_by(conference_id: @conference.id)
|
||||||
|
|
||||||
|
redirect_to(root_path, error: "You are not subscribed to #{@conference.title}.") && return unless @subscription
|
||||||
if @subscription.destroy
|
if @subscription.destroy
|
||||||
redirect_to root_path, notice: "You have been unsubscribed and now you will not be receiving email notifications for #{@conference.short_title}."
|
redirect_to root_path, notice: "You have unsubscribed and you will not be receiving email notifications for #{@conference.title}."
|
||||||
else
|
else
|
||||||
redirect_to root_path, error: @subscription.errors.full_messages.to_sentence
|
redirect_to root_path, error: @subscription.errors.full_messages.to_sentence
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ class TicketPurchasesController < ApplicationController
|
||||||
before_filter :authenticate_user!
|
before_filter :authenticate_user!
|
||||||
load_resource :conference, find_by: :short_title
|
load_resource :conference, find_by: :short_title
|
||||||
authorize_resource :conference_registrations, class: Registration
|
authorize_resource :conference_registrations, class: Registration
|
||||||
|
authorize_resource
|
||||||
|
|
||||||
def create
|
def create
|
||||||
current_user.ticket_purchases.by_conference(@conference).unpaid.destroy_all
|
current_user.ticket_purchases.by_conference(@conference).unpaid.destroy_all
|
||||||
|
|
@ -11,18 +12,22 @@ class TicketPurchasesController < ApplicationController
|
||||||
redirect_to new_conference_payment_path,
|
redirect_to new_conference_payment_path,
|
||||||
notice: 'Please pay here to get tickets.'
|
notice: 'Please pay here to get tickets.'
|
||||||
elsif current_user.ticket_purchases.by_conference(@conference).paid.any?
|
elsif current_user.ticket_purchases.by_conference(@conference).paid.any?
|
||||||
redirect_to conference_conference_registration_path(@conference.short_title),
|
redirect_to conference_physical_tickets_path,
|
||||||
notice: 'You have free tickets for the conference.'
|
notice: 'You have free tickets for the conference.'
|
||||||
else
|
else
|
||||||
redirect_to conference_tickets_path(@conference.short_title),
|
redirect_to conference_tickets_path(@conference.short_title),
|
||||||
error: 'Please get at least one ticket to continue.'
|
error: 'Please get at least one ticket to continue.'
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
redirect_to conference_conference_registration_path(@conference.short_title),
|
redirect_to conference_tickets_path(@conference.short_title),
|
||||||
error: "Oops, something went wrong with your purchase! #{message}"
|
error: "Oops, something went wrong with your purchase! #{message}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def index
|
||||||
|
@unpaid_ticket_purchases = current_user.ticket_purchases.by_conference(@conference).unpaid
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def ticket_purchase_params
|
def ticket_purchase_params
|
||||||
|
|
|
||||||
70
app/controllers/tracks_controller.rb
Normal file
70
app/controllers/tracks_controller.rb
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
class TracksController < ApplicationController
|
||||||
|
load_resource :conference, find_by: :short_title
|
||||||
|
load_resource :program, through: :conference, singleton: true
|
||||||
|
load_and_authorize_resource through: :program, find_by: :short_name
|
||||||
|
|
||||||
|
def index
|
||||||
|
@tracks = @tracks.where(submitter: current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def show; end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@track = @program.tracks.new(color: @conference.next_color_for_collection(:tracks))
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit; end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@track = @program.tracks.new(track_params)
|
||||||
|
@track.submitter = current_user
|
||||||
|
@track.cfp_active = false
|
||||||
|
if @track.save
|
||||||
|
redirect_to conference_program_tracks_path(conference_id: @conference.short_title),
|
||||||
|
notice: 'Track request successfully created.'
|
||||||
|
else
|
||||||
|
flash.now[:error] = "Creating Track request failed: #{@track.errors.full_messages.join('. ')}."
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @track.update_attributes(track_params)
|
||||||
|
redirect_to conference_program_tracks_path(conference_id: @conference.short_title),
|
||||||
|
notice: 'Track request successfully updated.'
|
||||||
|
else
|
||||||
|
flash.now[:error] = "Track request update failed: #{@track.errors.full_messages.join('. ')}."
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def restart
|
||||||
|
update_state(:restart, "Track #{@track.name} re-submitted.")
|
||||||
|
end
|
||||||
|
|
||||||
|
def confirm
|
||||||
|
update_state(:confirm, "Track #{@track.name} confirmed.")
|
||||||
|
end
|
||||||
|
|
||||||
|
def withdraw
|
||||||
|
update_state(:withdraw, "Track #{@track.name} withdrawn.")
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def track_params
|
||||||
|
params.require(:track).permit(:name, :description, :color, :short_name, :start_date, :end_date, :relevance)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_state(transition, notice)
|
||||||
|
errors = @track.update_state(transition)
|
||||||
|
|
||||||
|
if errors.blank?
|
||||||
|
flash[:notice] = notice
|
||||||
|
else
|
||||||
|
flash[:error] = errors
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_back_or_to(conference_program_tracks_path(conference_id: @conference.short_title))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -11,13 +11,13 @@ module Users
|
||||||
|
|
||||||
def handle(provider)
|
def handle(provider)
|
||||||
auth_hash = request.env['omniauth.auth']
|
auth_hash = request.env['omniauth.auth']
|
||||||
uid = auth_hash[:uid]
|
username = auth_hash.info.email.split('@')[0]
|
||||||
openid = Openid.find_for_oauth(auth_hash) # Get or create openid
|
openid = Openid.find_for_oauth(auth_hash) # Get or create openid
|
||||||
# If openid exists and is associated with a user, sign in with associated user,
|
# If openid exists and is associated with a user, sign in with associated user,
|
||||||
# even if the email of the associated user and the email of the provided openid are different
|
# even if the email of the associated user and the email of the provided openid are different
|
||||||
unless (user = openid.user)
|
unless (user = openid.user)
|
||||||
user = User.find_for_auth(auth_hash, current_user) # Get or create users
|
user = User.find_for_auth(auth_hash, current_user) # Get or create users
|
||||||
user.username = "#{uid}@#{provider}" if user.username.blank?
|
user.username = "#{username}@#{provider}" if user.username.blank?
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,11 @@ module ApplicationHelper
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns time with conference timezone
|
||||||
|
def time_with_timezone(time)
|
||||||
|
time.strftime('%F %R') + ' ' + @conference.timezone.to_s
|
||||||
|
end
|
||||||
|
|
||||||
# Set resource_name for devise so that we can call the devise help links (views/devise/shared/_links) from anywhere (eg sign_up form in proposals#new)
|
# Set resource_name for devise so that we can call the devise help links (views/devise/shared/_links) from anywhere (eg sign_up form in proposals#new)
|
||||||
def resource_name
|
def resource_name
|
||||||
:user
|
:user
|
||||||
|
|
@ -51,7 +56,7 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def tracks(conference)
|
def tracks(conference)
|
||||||
all = conference.program.tracks.map {|t| t.name}
|
all = conference.program.tracks.confirmed.cfp_active.pluck(:name)
|
||||||
first = all[0...-1]
|
first = all[0...-1]
|
||||||
last = all[-1]
|
last = all[-1]
|
||||||
ts = ''
|
ts = ''
|
||||||
|
|
@ -93,25 +98,6 @@ module ApplicationHelper
|
||||||
.reverse.sub(',', ' dna ').reverse
|
.reverse.sub(',', ' dna ').reverse
|
||||||
end
|
end
|
||||||
|
|
||||||
# Recieves a model_name and id
|
|
||||||
# Returns nil if model_name is invalid
|
|
||||||
# Returns object in its current state if its alive
|
|
||||||
# Otherwise Returns object state just before deletion
|
|
||||||
def current_or_last_object_state(model_name, id)
|
|
||||||
return nil unless id.present? && model_name.present?
|
|
||||||
begin
|
|
||||||
object = model_name.constantize.find_by(id: id)
|
|
||||||
rescue NameError
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
if object.nil?
|
|
||||||
object_last_version = PaperTrail::Version.where(item_type: model_name, item_id: id).last
|
|
||||||
object = object_last_version.reify if object_last_version
|
|
||||||
end
|
|
||||||
object
|
|
||||||
end
|
|
||||||
|
|
||||||
def normalize_array_length(hashmap, length)
|
def normalize_array_length(hashmap, length)
|
||||||
hashmap.each do |_, value|
|
hashmap.each do |_, value|
|
||||||
if value.length < length
|
if value.length < length
|
||||||
|
|
@ -131,7 +117,7 @@ module ApplicationHelper
|
||||||
|
|
||||||
def concurrent_events(event)
|
def concurrent_events(event)
|
||||||
return nil unless event.scheduled? && event.program.selected_event_schedules
|
return nil unless event.scheduled? && event.program.selected_event_schedules
|
||||||
event_schedule = event.program.selected_event_schedules.find_by(event: event)
|
event_schedule = event.program.selected_event_schedules.find { |es| es.event == event }
|
||||||
other_event_schedules = event.program.selected_event_schedules.reject { |other_event_schedule| other_event_schedule == event_schedule }
|
other_event_schedules = event.program.selected_event_schedules.reject { |other_event_schedule| other_event_schedule == event_schedule }
|
||||||
concurrent_events = []
|
concurrent_events = []
|
||||||
|
|
||||||
|
|
@ -147,7 +133,7 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def speaker_links(event)
|
def speaker_links(event)
|
||||||
event.speakers.map{ |speaker| link_to speaker.name, admin_user_path(speaker) }.join(', ').html_safe
|
safe_join(event.speakers.map{ |speaker| link_to speaker.name, admin_user_path(speaker) }, ',')
|
||||||
end
|
end
|
||||||
|
|
||||||
def speaker_selector_input(form)
|
def speaker_selector_input(form)
|
||||||
|
|
@ -157,6 +143,14 @@ module ApplicationHelper
|
||||||
include_blank: false, label: 'Speakers', input_html: { class: 'select-help-toggle', multiple: 'true' }
|
include_blank: false, label: 'Speakers', input_html: { class: 'select-help-toggle', multiple: 'true' }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def responsibles_selector_input(form)
|
||||||
|
users = User.active.pluck(:id, :name, :username, :email).map { |user| [user[0], user[1].blank? ? user[2] : user[1], user[2], user[3]] }.sort_by { |user| user[1].downcase }
|
||||||
|
form.input :responsibles, as: :select,
|
||||||
|
collection: options_for_select(users.map {|user| ["#{user[1]} (#{user[2]}) #{user[3]}", user[0]]}, @booth.responsibles.map(&:id)),
|
||||||
|
include_blank: false, label: 'Responsibles', input_html: { class: 'select-help-toggle', multiple: 'true' },
|
||||||
|
hint: 'The people responsible for the booth. You can only select existing users.'
|
||||||
|
end
|
||||||
|
|
||||||
def event_types(conference)
|
def event_types(conference)
|
||||||
conference.program.event_types.map { |et| et.title.pluralize }.to_sentence
|
conference.program.event_types.map { |et| et.title.pluralize }.to_sentence
|
||||||
end
|
end
|
||||||
|
|
@ -168,4 +162,13 @@ module ApplicationHelper
|
||||||
new_user_session_path
|
new_user_session_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# ====Gets
|
||||||
|
# a conference object
|
||||||
|
# ==== Returns
|
||||||
|
# class hidden if conference is over
|
||||||
|
def hidden_if_conference_over(conference)
|
||||||
|
'hidden' if Date.today > conference.end_date
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -39,4 +39,12 @@ module EventsHelper
|
||||||
content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes)
|
content_tag :span, 'REPLACEMENT', class: (['label', 'label-info'] + label_classes)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def track_selector_input(form)
|
||||||
|
if @program.tracks.confirmed.cfp_active.any?
|
||||||
|
form.input :track_id, as: :select,
|
||||||
|
collection: @program.tracks.confirmed.cfp_active.pluck(:name, :id),
|
||||||
|
include_blank: '(Please select)'
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,19 @@ module FormatHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def booth_status_icon(booth)
|
||||||
|
case booth.state
|
||||||
|
when 'new', 'to_reject', 'to_accept'
|
||||||
|
'fa-eye'
|
||||||
|
when 'accepted'
|
||||||
|
'fa-check text-muted'
|
||||||
|
when 'confirmed'
|
||||||
|
'fa-check text-success'
|
||||||
|
when 'rejected', 'withdrawn', 'canceled'
|
||||||
|
'fa-ban'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def event_progress_color(progress)
|
def event_progress_color(progress)
|
||||||
progress = progress.to_i
|
progress = progress.to_i
|
||||||
if progress == 100
|
if progress == 100
|
||||||
|
|
@ -102,7 +115,6 @@ module FormatHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# rubocop:disable Lint/EndAlignment
|
|
||||||
def word_pluralize(count, singular, plural = nil)
|
def word_pluralize(count, singular, plural = nil)
|
||||||
word = if (count == 1 || count =~ /^1(\.0+)?$/)
|
word = if (count == 1 || count =~ /^1(\.0+)?$/)
|
||||||
singular
|
singular
|
||||||
|
|
@ -176,7 +188,7 @@ module FormatHelper
|
||||||
(schedule == @selected_schedule) ? 'Yes' : 'No'
|
(schedule == @selected_schedule) ? 'Yes' : 'No'
|
||||||
end
|
end
|
||||||
|
|
||||||
def markdown(text)
|
def markdown(text, escape_html=true)
|
||||||
return '' if text.nil?
|
return '' if text.nil?
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
@ -184,12 +196,12 @@ module FormatHelper
|
||||||
space_after_headers: true,
|
space_after_headers: true,
|
||||||
no_intra_emphasis: true
|
no_intra_emphasis: true
|
||||||
}
|
}
|
||||||
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(escape_html: true), options)
|
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(escape_html: escape_html), options)
|
||||||
markdown.render(text).html_safe
|
markdown.render(text).html_safe
|
||||||
end
|
end
|
||||||
|
|
||||||
def markdown_hint(text='')
|
def markdown_hint(text='')
|
||||||
markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text")
|
markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text", false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def quantity_left_of(resource)
|
def quantity_left_of(resource)
|
||||||
|
|
|
||||||
|
|
@ -2,14 +2,6 @@ module PathsHelper
|
||||||
##
|
##
|
||||||
# Includes functions related to links or redirects
|
# Includes functions related to links or redirects
|
||||||
##
|
##
|
||||||
def link_to_user(user_id)
|
|
||||||
user = User.find_by(id: user_id)
|
|
||||||
if user
|
|
||||||
link_to user.name, admin_user_path(id: user_id)
|
|
||||||
else
|
|
||||||
'Someone (probably via the console)'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def active_nav_li(link)
|
def active_nav_li(link)
|
||||||
if current_page?(link)
|
if current_page?(link)
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,78 @@ module VersionsHelper
|
||||||
##
|
##
|
||||||
# Groups functions related to change description
|
# Groups functions related to change description
|
||||||
##
|
##
|
||||||
def link_if_alive(version, link_text, link_url)
|
def link_if_alive(version, link_text, link_url, conference)
|
||||||
version.item ? link_to(link_text, link_url) : link_text
|
version.item && conference ? link_to(link_text, link_url) : "#{link_text} with ID #{version.item_id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def link_to_organization(organization_id)
|
||||||
|
return 'deleted organization' unless organization_id
|
||||||
|
|
||||||
|
org = Organization.find_by(id: organization_id)
|
||||||
|
return current_or_last_object_state('Organization', organization_id).try(:name) unless org
|
||||||
|
org.name.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def link_to_conference(conference_id)
|
||||||
|
return 'deleted conference' if conference_id.nil?
|
||||||
|
|
||||||
|
conference = Conference.find_by(id: conference_id)
|
||||||
|
if conference
|
||||||
|
link_to conference.short_title,
|
||||||
|
edit_admin_conference_path(conference.short_title)
|
||||||
|
else
|
||||||
|
short_title = current_or_last_object_state('Conference', conference_id).try(:short_title) || ''
|
||||||
|
" #{short_title} with ID #{conference_id}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def link_to_user(user_id)
|
||||||
|
return 'Someone (probably via the console)' unless user_id
|
||||||
|
|
||||||
|
user = User.find_by(id: user_id)
|
||||||
|
if user
|
||||||
|
link_to user.name, admin_user_path(id: user_id)
|
||||||
|
else
|
||||||
|
name = current_or_last_object_state('User', user_id).try(:name) || PaperTrail::Version.where(item_type: 'User', item_id: user_id).last.changeset['name'].second if PaperTrail::Version.where(item_type: 'User', item_id: user_id).any?
|
||||||
|
"#{name ? name : 'Unknown user'} with ID #{user_id}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Receives a model_name and id
|
||||||
|
# Returns nil if model_name is invalid
|
||||||
|
# Returns object in its current state if its alive
|
||||||
|
# Otherwise Returns object state just before deletion
|
||||||
|
def current_or_last_object_state(model_name, id)
|
||||||
|
return nil unless id.present? && model_name.present?
|
||||||
|
begin
|
||||||
|
object = model_name.constantize.find_by(id: id)
|
||||||
|
rescue NameError
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if object.nil?
|
||||||
|
object_last_version = PaperTrail::Version.where(item_type: model_name, item_id: id).last
|
||||||
|
object = object_last_version.reify if object_last_version
|
||||||
|
end
|
||||||
|
object
|
||||||
end
|
end
|
||||||
|
|
||||||
def subscription_change_description(version)
|
def subscription_change_description(version)
|
||||||
user = current_or_last_object_state(version.item_type, version.item_id).user
|
user_id = current_or_last_object_state(version.item_type, version.item_id).user_id
|
||||||
user_name = user.name unless user.id.to_s == version.whodunnit
|
user_name = User.find_by(id: user_id).try(:name) || current_or_last_object_state('User', user_id).try(:name) || PaperTrail::Version.where(item_type: 'User', item_id: user_id).last.changeset[:name].second unless user_id.to_s == version.whodunnit
|
||||||
version.event == 'create' ? "subscribed #{user_name} to" : "unsubscribed #{user_name} from"
|
version.event == 'create' ? "subscribed #{user_name} to" : "unsubscribed #{user_name} from"
|
||||||
end
|
end
|
||||||
|
|
||||||
def registration_change_description(version)
|
def registration_change_description(version)
|
||||||
if version.item_type == 'Registration'
|
if version.item_type == 'Registration'
|
||||||
user = current_or_last_object_state(version.item_type, version.item_id).user
|
user_id = current_or_last_object_state(version.item_type, version.item_id).user_id
|
||||||
elsif version.item_type == 'EventsRegistration'
|
elsif version.item_type == 'EventsRegistration'
|
||||||
registration_id = current_or_last_object_state(version.item_type, version.item_id).registration_id
|
registration_id = current_or_last_object_state(version.item_type, version.item_id).registration_id
|
||||||
user = current_or_last_object_state('Registration', registration_id).user
|
user_id = current_or_last_object_state('Registration', registration_id).user_id
|
||||||
end
|
end
|
||||||
|
user_name = User.find_by(id: user_id).try(:name) || current_or_last_object_state('User', user_id).try(:name) || PaperTrail::Version.where(item_type: 'User', item_id: user_id).last.changeset[:name].second
|
||||||
|
|
||||||
if user.id.to_s == version.whodunnit
|
if user_id.to_s == version.whodunnit
|
||||||
case version.event
|
case version.event
|
||||||
when 'create' then 'registered to'
|
when 'create' then 'registered to'
|
||||||
when 'update' then "updated #{updated_attributes(version)} of the registration for"
|
when 'update' then "updated #{updated_attributes(version)} of the registration for"
|
||||||
|
|
@ -28,9 +81,9 @@ module VersionsHelper
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
case version.event
|
case version.event
|
||||||
when 'create' then "registered #{user.name} to"
|
when 'create' then "registered #{user_name} to"
|
||||||
when 'update' then "updated #{updated_attributes(version)} of #{user.name}'s registration for"
|
when 'update' then "updated #{updated_attributes(version)} of #{user_name}'s registration for"
|
||||||
when 'destroy' then "unregistered #{user.name} from"
|
when 'destroy' then "unregistered #{user_name} from"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,22 @@ class Mailbot < ActionMailer::Base
|
||||||
conference.email_settings.registration_body))
|
conference.email_settings.registration_body))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ticket_confirmation_mail(ticket_purchase)
|
||||||
|
@ticket_purchase = ticket_purchase
|
||||||
|
@conference = ticket_purchase.conference
|
||||||
|
@user = ticket_purchase.user
|
||||||
|
|
||||||
|
PhysicalTicket.last(ticket_purchase.quantity).each do |physical_ticket|
|
||||||
|
pdf = TicketPdf.new(@conference, @user, physical_ticket, @conference.ticket_layout.to_sym, "ticket_for_#{@conference.short_title}_#{physical_ticket.id}")
|
||||||
|
attachments["ticket_for_#{@conference.short_title}_#{physical_ticket.id}.pdf"] = pdf.render
|
||||||
|
end
|
||||||
|
|
||||||
|
mail(to: @user.email,
|
||||||
|
from: @conference.contact.email,
|
||||||
|
template_name: 'ticket_confirmation_template',
|
||||||
|
subject: "#{@conference.title} | Ticket Confirmation and PDF!")
|
||||||
|
end
|
||||||
|
|
||||||
def acceptance_mail(event)
|
def acceptance_mail(event)
|
||||||
conference = event.program.conference
|
conference = event.program.conference
|
||||||
|
|
||||||
|
|
@ -81,6 +97,24 @@ class Mailbot < ActionMailer::Base
|
||||||
conference.email_settings.cfp_dates_updated_body))
|
conference.email_settings.cfp_dates_updated_body))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def conference_booths_acceptance_mail(booth)
|
||||||
|
conference = booth.conference
|
||||||
|
|
||||||
|
mail(to: booth.submitter.email,
|
||||||
|
from: conference.contact.email,
|
||||||
|
subject: conference.email_settings.booths_acceptance_subject,
|
||||||
|
body: conference.email_settings.generate_booth_mail(booth, conference.email_settings.booths_acceptance_body))
|
||||||
|
end
|
||||||
|
|
||||||
|
def conference_booths_rejection_mail(booth)
|
||||||
|
conference = booth.conference
|
||||||
|
|
||||||
|
mail(to: booth.submitter.email,
|
||||||
|
from: conference.contact.email,
|
||||||
|
subject: conference.email_settings.booths_rejection_subject,
|
||||||
|
body: conference.email_settings.generate_booth_mail(booth, conference.email_settings.booths_rejection_body))
|
||||||
|
end
|
||||||
|
|
||||||
def event_comment_mail(comment, user)
|
def event_comment_mail(comment, user)
|
||||||
@comment = comment
|
@comment = comment
|
||||||
@event = @comment.commentable
|
@event = @comment.commentable
|
||||||
|
|
|
||||||
|
|
@ -3,32 +3,19 @@ class Ability
|
||||||
|
|
||||||
# Initializes the ability class
|
# Initializes the ability class
|
||||||
def initialize(user)
|
def initialize(user)
|
||||||
# Order Abilities
|
|
||||||
# (Check https://github.com/CanCanCommunity/cancancan/wiki/Ability-Precedence)
|
|
||||||
# Check roles of user, using rolify. Role name is *case sensitive*
|
|
||||||
# user.is_organizer? or user.has_role? :organizer
|
|
||||||
# user.is_cfp_of? Conference or user.has_role? :cfp, Conference
|
|
||||||
# user.is_info_desk_of? Conference
|
|
||||||
# user.is_volunteers_coordinator_of? Conference
|
|
||||||
# user.is_attendee_of? Conference
|
|
||||||
# The following is wrong because a user will only have 'cfp' role for a specific conference
|
|
||||||
# user.is_cfp? # This is always false
|
|
||||||
|
|
||||||
user ||= User.new
|
user ||= User.new
|
||||||
|
|
||||||
# This is what sets up the different abilities
|
|
||||||
if user.new_record?
|
if user.new_record?
|
||||||
not_signed_in
|
not_signed_in
|
||||||
# Checks if the user does not have any role and is not an admin
|
|
||||||
elsif user.roles.any? || user.is_admin
|
|
||||||
signed_in_with_roles(user)
|
|
||||||
else
|
else
|
||||||
signed_in(user)
|
signed_in(user)
|
||||||
|
common_abilities_for_admins(user) if user.roles.any? || user.is_admin?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Abilities for not signed in users (guests)
|
# Abilities for not signed in users (guests)
|
||||||
def not_signed_in
|
def not_signed_in
|
||||||
|
can [:index], Organization
|
||||||
can [:index], Conference
|
can [:index], Conference
|
||||||
can [:show], Conference do |conference|
|
can [:show], Conference do |conference|
|
||||||
conference.splashpage && conference.splashpage.public == true
|
conference.splashpage && conference.splashpage.public == true
|
||||||
|
|
@ -73,7 +60,6 @@ class Ability
|
||||||
def signed_in(user)
|
def signed_in(user)
|
||||||
# Abilities from not_signed_in user are also inherited
|
# Abilities from not_signed_in user are also inherited
|
||||||
not_signed_in
|
not_signed_in
|
||||||
|
|
||||||
can :manage, User, id: user.id
|
can :manage, User, id: user.id
|
||||||
|
|
||||||
can :manage, Registration, user_id: user.id
|
can :manage, Registration, user_id: user.id
|
||||||
|
|
@ -83,9 +69,19 @@ class Ability
|
||||||
conference.registration_open? && !conference.registration_limit_exceeded? || conference.program.speakers.confirmed.include?(user)
|
conference.registration_open? && !conference.registration_limit_exceeded? || conference.program.speakers.confirmed.include?(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
can :index, Organization
|
||||||
can :index, Ticket
|
can :index, Ticket
|
||||||
can :manage, TicketPurchase, user_id: user.id
|
can :manage, TicketPurchase, user_id: user.id
|
||||||
can [:new, :create], Payment, user_id: user.id
|
can [:new, :create], Payment, user_id: user.id
|
||||||
|
can [:index, :show], PhysicalTicket, user: user
|
||||||
|
|
||||||
|
can [:new, :create], Booth do |booth|
|
||||||
|
booth.new_record? && booth.conference.program.cfps.for_booths.try(:open?)
|
||||||
|
end
|
||||||
|
|
||||||
|
can [:edit, :update, :index, :show], Booth do |booth|
|
||||||
|
booth.users.include?(user)
|
||||||
|
end
|
||||||
|
|
||||||
can [:create, :destroy], Subscription, user_id: user.id
|
can [:create, :destroy], Subscription, user_id: user.id
|
||||||
|
|
||||||
|
|
@ -93,181 +89,58 @@ class Ability
|
||||||
event.program.cfp_open? && event.new_record?
|
event.program.cfp_open? && event.new_record?
|
||||||
end
|
end
|
||||||
|
|
||||||
can [:update, :show, :delete, :index], Event do |event|
|
can [:update, :show, :index], Event do |event|
|
||||||
event.users.include?(user)
|
event.users.include?(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
# can manage the commercials of their own events
|
# can manage the commercials of their own events
|
||||||
can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id)
|
can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id)
|
||||||
|
|
||||||
|
can [:destroy], Openid
|
||||||
|
|
||||||
|
can [:new, :create], Track do |track|
|
||||||
|
track.new_record? && track.program.cfps.for_tracks.try(:open?)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Abilities for signed in users with roles
|
can [:index, :show, :restart, :confirm, :withdraw], Track, submitter_id: user.id
|
||||||
def signed_in_with_roles(user)
|
|
||||||
# Abilities from not_signed_in and signed_in are also inherited
|
|
||||||
signed_in(user)
|
|
||||||
|
|
||||||
signed_in_with_organizer_role(user) if user.has_role? :organizer, :any
|
can [:edit, :update], Track do |track|
|
||||||
signed_in_with_cfp_role(user) if user.has_role? :cfp, :any
|
user == track.submitter && !(track.accepted? || track.confirmed?)
|
||||||
signed_in_with_info_desk_role(user) if user.has_role? :info_desk, :any
|
end
|
||||||
signed_in_with_volunteers_coordinator_role(user) if user.has_role? :volunteers_coordinator, :any
|
end
|
||||||
|
|
||||||
# for users with any role
|
# Abilities for users with roles wandering around in non-admin views.
|
||||||
|
def common_abilities_for_admins(user)
|
||||||
can :access, Admin
|
can :access, Admin
|
||||||
can [:show], Conference
|
can :manage, :all if user.is_admin?
|
||||||
can :index, Commercial, commercialable_type: 'Conference'
|
|
||||||
cannot [:edit, :update, :destroy], Question, global: true
|
|
||||||
# for admins
|
|
||||||
can :manage, :all if user.is_admin
|
|
||||||
|
|
||||||
# even admin cannot create new users with ICHAIN enabled
|
|
||||||
cannot [:new, :create], User if ENV['OSEM_ICHAIN_ENABLED'] == 'true'
|
|
||||||
|
|
||||||
cannot :revert_object, PaperTrail::Version do |version|
|
|
||||||
(version.event == 'create' && %w(Conference User Event).include?(version.item_type))
|
|
||||||
end
|
|
||||||
|
|
||||||
cannot :revert_attribute, PaperTrail::Version do |version|
|
|
||||||
version.event != 'update' || version.item.nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
cannot :destroy, Program
|
|
||||||
# Do not delete venue, when there are rooms being used
|
|
||||||
cannot :destroy, Venue do |venue|
|
|
||||||
venue.conference.program.events.where.not(room_id: nil).any?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def signed_in_with_organizer_role(user)
|
|
||||||
# ids of all the conferences for which the user has the 'organizer' role
|
|
||||||
conf_ids_for_organizer = Conference.with_role(:organizer, user).pluck(:id)
|
conf_ids_for_organizer = Conference.with_role(:organizer, user).pluck(:id)
|
||||||
|
|
||||||
can :manage, Resource, conference_id: conf_ids_for_organizer
|
|
||||||
can [:new, :create], Conference if user.has_role?(:organizer, :any)
|
|
||||||
can :manage, Conference, id: conf_ids_for_organizer
|
|
||||||
can :manage, Splashpage, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Contact, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, EmailSettings, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Campaign, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Target, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Commercial, commercialable_type: 'Conference',
|
|
||||||
commercialable_id: conf_ids_for_organizer
|
|
||||||
can :manage, Registration, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, RegistrationPeriod, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Question, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Question do |question|
|
|
||||||
!(question.conferences.pluck(:id) & conf_ids_for_organizer).empty?
|
|
||||||
end
|
|
||||||
can :manage, Vposition, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Vday, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Program, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Schedule, program: { conference_id: conf_ids_for_organizer }
|
|
||||||
can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids_for_organizer } }
|
|
||||||
can :manage, Cfp, program: { conference_id: conf_ids_for_organizer}
|
|
||||||
can :manage, Event, program: { conference_id: conf_ids_for_organizer}
|
|
||||||
can :manage, EventType, program: { conference_id: conf_ids_for_organizer}
|
|
||||||
can :manage, Track, program: { conference_id: conf_ids_for_organizer}
|
|
||||||
can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_organizer}
|
|
||||||
can :manage, Commercial, commercialable_type: 'Event',
|
|
||||||
commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id)
|
|
||||||
can :manage, Venue, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Commercial, commercialable_type: 'Venue',
|
|
||||||
commercialable_id: Venue.where(conference_id: conf_ids_for_organizer).pluck(:id)
|
|
||||||
can :manage, Lodging, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Room, venue: { conference_id: conf_ids_for_organizer}
|
|
||||||
can :manage, Sponsor, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, SponsorshipLevel, conference_id: conf_ids_for_organizer
|
|
||||||
can :manage, Ticket, conference_id: conf_ids_for_organizer
|
|
||||||
can :index, Comment, commentable_type: 'Event',
|
|
||||||
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id)
|
|
||||||
|
|
||||||
# Abilities for Role (Conference resource)
|
|
||||||
can [:index, :show], Role
|
|
||||||
can [:edit, :update, :toggle_user], Role do |role|
|
|
||||||
role.resource_type == 'Conference' && (conf_ids_for_organizer.include? role.resource_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version|
|
|
||||||
version.item_type == 'User' || (conf_ids_for_organizer.include? version.conference_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def signed_in_with_cfp_role(user)
|
|
||||||
# ids of all the conferences for which the user has the 'cfp' role
|
|
||||||
conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id)
|
conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id)
|
||||||
|
|
||||||
can [:index, :show, :update], Resource, conference_id: conf_ids_for_cfp
|
|
||||||
can :manage, Event, program: { conference_id: conf_ids_for_cfp }
|
|
||||||
can :manage, EventType, program: { conference_id: conf_ids_for_cfp }
|
|
||||||
can :manage, Track, program: { conference_id: conf_ids_for_cfp }
|
|
||||||
can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_cfp }
|
|
||||||
can :manage, EmailSettings, conference_id: conf_ids_for_cfp
|
|
||||||
can :manage, Schedule, program: { conference_id: conf_ids_for_cfp }
|
|
||||||
can :manage, Room, venue: { conference_id: conf_ids_for_cfp }
|
|
||||||
can :show, Venue, conference_id: conf_ids_for_cfp
|
|
||||||
can :show, Commercial, commercialable_type: 'Venue', commercialable_id: Venue.where(conference_id: conf_ids_for_cfp).pluck(:id)
|
|
||||||
can :manage, Cfp, program: { conference_id: conf_ids_for_cfp }
|
|
||||||
can :manage, Program, conference_id: conf_ids_for_cfp
|
|
||||||
can :manage, Commercial, commercialable_type: 'Event',
|
|
||||||
commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id)
|
|
||||||
can :index, Comment, commentable_type: 'Event',
|
|
||||||
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id)
|
|
||||||
|
|
||||||
# Abilities for Role (Conference resource)
|
|
||||||
can [:index, :show], Role
|
|
||||||
|
|
||||||
# Can add or remove users from role, when user has that same role for the conference
|
|
||||||
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
|
||||||
can :toggle_user, Role do |role|
|
|
||||||
role.resource_type == 'Conference' && role.name == 'cfp' &&
|
|
||||||
(Conference.with_role(:cfp, user).pluck(:id).include? role.resource_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Event', conference_id: conf_ids_for_cfp
|
|
||||||
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Vote', conference_id: conf_ids_for_cfp
|
|
||||||
can [:index, :revert_object, :revert_attribute], PaperTrail::Version do |version|
|
|
||||||
version.item_type == 'Commercial' && conf_ids_for_cfp.include?(version.conference_id) &&
|
|
||||||
(version.object.to_s.include?('Event') || version.object_changes.to_s.include?('Event'))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def signed_in_with_info_desk_role(user)
|
|
||||||
# ids of all the conferences for which the user has the 'info_desk' role
|
|
||||||
conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id)
|
conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id)
|
||||||
|
|
||||||
can [:index, :show, :update], Resource, conference_id: conf_ids_for_info_desk
|
if conf_ids_for_organizer
|
||||||
|
# To access splashpage of their conference if it is not public
|
||||||
|
can :show, Conference, id: conf_ids_for_organizer
|
||||||
|
# To access conference/proposals/registrations
|
||||||
|
can :manage, Registration, conference_id: conf_ids_for_organizer
|
||||||
|
# To access conference/proposals
|
||||||
|
can :manage, Event, program: { conference_id: conf_ids_for_organizer }
|
||||||
|
# To access comment link in menu bar
|
||||||
|
can :index, Comment, commentable_type: 'Event',
|
||||||
|
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_organizer).pluck(:id)).pluck(:id)
|
||||||
|
end
|
||||||
|
|
||||||
|
if conf_ids_for_cfp
|
||||||
|
# To access comment link in menu bar
|
||||||
|
can :index, Comment, commentable_type: 'Event',
|
||||||
|
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id)
|
||||||
|
# To access conference/proposals
|
||||||
|
can :manage, Event, program: { conference_id: conf_ids_for_cfp }
|
||||||
|
end
|
||||||
|
|
||||||
|
if conf_ids_for_info_desk
|
||||||
|
# To access conference/proposals/registrations
|
||||||
can :manage, Registration, conference_id: conf_ids_for_info_desk
|
can :manage, Registration, conference_id: conf_ids_for_info_desk
|
||||||
can :manage, Question, conference_id: conf_ids_for_info_desk
|
|
||||||
can :manage, Question do |question|
|
|
||||||
!(question.conferences.pluck(:id) & conf_ids_for_info_desk).empty?
|
|
||||||
end
|
|
||||||
|
|
||||||
# Abilities for Role (Conference resource)
|
|
||||||
can [:index, :show], Role
|
|
||||||
|
|
||||||
# Can add or remove users from role, when user has that same role for the conference
|
|
||||||
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
|
||||||
can :toggle_user, Role do |role|
|
|
||||||
role.resource_type == 'Conference' && role.name == 'info_desk' &&
|
|
||||||
(Conference.with_role(:info_desk, user).pluck(:id).include? role.resource_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def signed_in_with_volunteers_coordinator_role(user)
|
|
||||||
# ids of all the conferences for which the user has the 'volunteers_coordinator' role
|
|
||||||
conf_ids_for_volunteers_coordinator = Conference.with_role(:volunteers_coordinator, user).pluck(:id)
|
|
||||||
|
|
||||||
can [:index, :show, :update], Resource, conference_id: conf_ids_for_volunteers_coordinator
|
|
||||||
can :manage, Vposition, conference_id: conf_ids_for_volunteers_coordinator
|
|
||||||
can :manage, Vday, conference_id: conf_ids_for_volunteers_coordinator
|
|
||||||
|
|
||||||
# Abilities for Role (Conference resource)
|
|
||||||
can [:index, :show], Role
|
|
||||||
|
|
||||||
# Can add or remove users from role, when user has that same role for the conference
|
|
||||||
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
|
||||||
can :toggle_user, Role do |role|
|
|
||||||
role.resource_type == 'Conference' && role.name == 'volunteers_coordinator' &&
|
|
||||||
(Conference.with_role(:volunteers_coordinator, user).pluck(:id).include? role.resource_id)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
324
app/models/admin_ability.rb
Normal file
324
app/models/admin_ability.rb
Normal file
|
|
@ -0,0 +1,324 @@
|
||||||
|
class AdminAbility
|
||||||
|
include CanCan::Ability
|
||||||
|
|
||||||
|
def initialize(user)
|
||||||
|
# Order Abilities
|
||||||
|
# (Check https://github.com/CanCanCommunity/cancancan/wiki/Ability-Precedence)
|
||||||
|
# Check roles of user, using rolify. Role name is *case sensitive*
|
||||||
|
# user.is_organizer? or user.has_role? :organizer
|
||||||
|
# user.is_cfp_of? Conference or user.has_role? :cfp, Conference
|
||||||
|
# user.is_info_desk_of? Conference
|
||||||
|
# user.is_volunteers_coordinator_of? Conference
|
||||||
|
# user.is_attendee_of? Conference
|
||||||
|
# The following is wrong because a user will only have 'cfp' role for a specific conference
|
||||||
|
# user.is_cfp? # This is always false
|
||||||
|
|
||||||
|
user ||= User.new
|
||||||
|
signed_in_with_roles(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def common_abilities_for_roles(user)
|
||||||
|
can :manage, Registration, user_id: user.id
|
||||||
|
|
||||||
|
can :index, Conference
|
||||||
|
can :show, Registration, &:new_record?
|
||||||
|
|
||||||
|
can [:new, :create], Registration do |registration|
|
||||||
|
conference = registration.conference
|
||||||
|
conference.registration_open? && !conference.registration_limit_exceeded? || conference.program.speakers.confirmed.include?(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
can [:index, :admins], Organization
|
||||||
|
can :index, Ticket
|
||||||
|
can :manage, TicketPurchase, user_id: user.id
|
||||||
|
can [:new, :create], Payment, user_id: user.id
|
||||||
|
|
||||||
|
can [:create, :destroy], Subscription, user_id: user.id
|
||||||
|
|
||||||
|
can [:new, :create], Event do |event|
|
||||||
|
event.program.cfp_open? && event.new_record?
|
||||||
|
end
|
||||||
|
|
||||||
|
# can manage the commercials of their own events
|
||||||
|
can :manage, Commercial, commercialable_type: 'Event', commercialable_id: user.events.pluck(:id)
|
||||||
|
|
||||||
|
can [:destroy], Openid
|
||||||
|
can :access, Admin
|
||||||
|
can :index, Commercial, commercialable_type: 'Conference'
|
||||||
|
cannot [:edit, :update, :destroy], Question, global: true
|
||||||
|
# for admins
|
||||||
|
can :manage, :all if user.is_admin
|
||||||
|
# even admin cannot create new users with ICHAIN enabled
|
||||||
|
cannot [:new, :create], User if ENV['OSEM_ICHAIN_ENABLED'] == 'true'
|
||||||
|
cannot :revert_object, PaperTrail::Version do |version|
|
||||||
|
(version.event == 'create' && %w[Conference User Event].include?(version.item_type))
|
||||||
|
end
|
||||||
|
cannot :revert_attribute, PaperTrail::Version do |version|
|
||||||
|
version.event != 'update' || version.item.nil?
|
||||||
|
end
|
||||||
|
# Can't create cfp if there are no available cfp types
|
||||||
|
cannot [:new, :create], Cfp do |cfp|
|
||||||
|
cfp.program.remaining_cfp_types.empty?
|
||||||
|
end
|
||||||
|
cannot :destroy, Program
|
||||||
|
# Do not delete venue, when there are rooms being used
|
||||||
|
cannot :destroy, Venue do |venue|
|
||||||
|
venue.conference.program.events.where.not(room_id: nil).any?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Prevent requests for tracks from being destroyed
|
||||||
|
cannot :destroy, Track do |track|
|
||||||
|
track.self_organized?
|
||||||
|
end
|
||||||
|
# Can't accept a booth when booth_limit is reached
|
||||||
|
cannot :accept, Booth do |booth|
|
||||||
|
conference = booth.conference
|
||||||
|
conference.maximum_accepted_booths?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Abilities for signed in users with roles
|
||||||
|
def signed_in_with_roles(user)
|
||||||
|
signed_in_with_organization_admin_role(user) if user.has_role? :organization_admin, :any
|
||||||
|
signed_in_with_organizer_role(user) if user.has_role? :organizer, :any
|
||||||
|
signed_in_with_cfp_role(user) if user.has_role? :cfp, :any
|
||||||
|
signed_in_with_info_desk_role(user) if user.has_role? :info_desk, :any
|
||||||
|
signed_in_with_volunteers_coordinator_role(user) if user.has_role? :volunteers_coordinator, :any
|
||||||
|
signed_in_with_track_organizer_role(user) if user.has_role? :track_organizer, :any
|
||||||
|
common_abilities_for_roles(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def signed_in_with_organization_admin_role(user)
|
||||||
|
org_ids_for_organization_admin = Organization.with_role(:organization_admin, user).pluck(:id)
|
||||||
|
conf_ids_for_organization_admin = Conference.where(organization_id: org_ids_for_organization_admin).pluck(:id)
|
||||||
|
|
||||||
|
can [:read, :update, :destroy, :assign_org_admins, :unassign_org_admins, :admins], Organization, id: org_ids_for_organization_admin
|
||||||
|
can :new, Conference
|
||||||
|
can :manage, Conference, organization_id: org_ids_for_organization_admin
|
||||||
|
can [:index, :show], Role
|
||||||
|
|
||||||
|
signed_in_with_organizer_role(user, conf_ids_for_organization_admin)
|
||||||
|
end
|
||||||
|
|
||||||
|
def signed_in_with_organizer_role(user, conf_ids_for_organization_admin = [])
|
||||||
|
# ids of all the conferences for which the user has the 'organizer' role and
|
||||||
|
# conferences that belong to organizations for which user is 'organization_admin'
|
||||||
|
conf_ids = conf_ids_for_organization_admin.concat(Conference.with_role(:organizer, user).pluck(:id)).uniq
|
||||||
|
# ids of all the tracks that belong to the programs of the above conferences
|
||||||
|
track_ids = Track.joins(:program).where('programs.conference_id IN (?)', conf_ids).pluck(:id)
|
||||||
|
|
||||||
|
can :manage, Resource, conference_id: conf_ids
|
||||||
|
can [:read, :update, :destroy], Conference, id: conf_ids
|
||||||
|
can :manage, Splashpage, conference_id: conf_ids
|
||||||
|
can :manage, Contact, conference_id: conf_ids
|
||||||
|
can :manage, EmailSettings, conference_id: conf_ids
|
||||||
|
can :manage, Campaign, conference_id: conf_ids
|
||||||
|
can :manage, Target, conference_id: conf_ids
|
||||||
|
can :manage, Commercial, commercialable_type: 'Conference',
|
||||||
|
commercialable_id: conf_ids
|
||||||
|
can :manage, Registration, conference_id: conf_ids
|
||||||
|
can :manage, RegistrationPeriod do |registration_period|
|
||||||
|
conference = registration_period.conference
|
||||||
|
conf_ids.include?(conference.id) && conference.tickets.for_registration.any?
|
||||||
|
end
|
||||||
|
can :manage, Booth, conference_id: conf_ids
|
||||||
|
can :manage, Question, conference_id: conf_ids
|
||||||
|
can :manage, Question do |question|
|
||||||
|
!(question.conferences.pluck(:id) & conf_ids).empty?
|
||||||
|
end
|
||||||
|
can :manage, Vposition, conference_id: conf_ids
|
||||||
|
can :manage, Vday, conference_id: conf_ids
|
||||||
|
can :manage, Program, conference_id: conf_ids
|
||||||
|
can :manage, Schedule, program: { conference_id: conf_ids }
|
||||||
|
can :manage, EventSchedule, schedule: { program: { conference_id: conf_ids } }
|
||||||
|
can :manage, Cfp, program: { conference_id: conf_ids }
|
||||||
|
can :manage, Event, program: { conference_id: conf_ids }
|
||||||
|
can :manage, EventType, program: { conference_id: conf_ids }
|
||||||
|
can :manage, Track, program: { conference_id: conf_ids }
|
||||||
|
can :manage, DifficultyLevel, program: { conference_id: conf_ids }
|
||||||
|
can :manage, Commercial, commercialable_type: 'Event',
|
||||||
|
commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids).pluck(:id)).pluck(:id)
|
||||||
|
can :manage, Venue, conference_id: conf_ids
|
||||||
|
can :manage, Commercial, commercialable_type: 'Venue',
|
||||||
|
commercialable_id: Venue.where(conference_id: conf_ids).pluck(:id)
|
||||||
|
can :manage, Lodging, conference_id: conf_ids
|
||||||
|
can :manage, Room, venue: { conference_id: conf_ids }
|
||||||
|
can :manage, Sponsor, conference_id: conf_ids
|
||||||
|
can :manage, SponsorshipLevel, conference_id: conf_ids
|
||||||
|
can :manage, Ticket, conference_id: conf_ids
|
||||||
|
can :create, TicketScanning do |ticket_scanning|
|
||||||
|
conf_id = ticket_scanning.physical_ticket.ticket_purchase.conference_id
|
||||||
|
conf_ids.include? conf_id
|
||||||
|
end
|
||||||
|
can :index, Comment, commentable_type: 'Event',
|
||||||
|
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids).pluck(:id)).pluck(:id)
|
||||||
|
|
||||||
|
# Abilities for Role (Conference resource)
|
||||||
|
can [:index, :show], Role do |role|
|
||||||
|
role.resource_type == 'Conference' || role.resource_type == 'Track'
|
||||||
|
end
|
||||||
|
|
||||||
|
can [:edit, :update, :toggle_user], Role do |role|
|
||||||
|
role.resource_type == 'Conference' && (conf_ids.include? role.resource_id) ||
|
||||||
|
role.resource_type == 'Track' && (track_ids.include? role.resource_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'User'
|
||||||
|
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, conference_id: conf_ids
|
||||||
|
end
|
||||||
|
|
||||||
|
def signed_in_with_cfp_role(user)
|
||||||
|
# ids of all the conferences for which the user has the 'cfp' role
|
||||||
|
conf_ids_for_cfp = Conference.with_role(:cfp, user).pluck(:id)
|
||||||
|
|
||||||
|
can :show, Conference do |conf|
|
||||||
|
conf_ids_for_cfp.include?(conf.id)
|
||||||
|
end
|
||||||
|
can [:index, :show, :update], Resource, conference_id: conf_ids_for_cfp
|
||||||
|
can :manage, Booth, conference_id: conf_ids_for_cfp
|
||||||
|
can :manage, Event, program: { conference_id: conf_ids_for_cfp }
|
||||||
|
can :manage, EventType, program: { conference_id: conf_ids_for_cfp }
|
||||||
|
can :manage, Track, program: { conference_id: conf_ids_for_cfp }
|
||||||
|
can :manage, DifficultyLevel, program: { conference_id: conf_ids_for_cfp }
|
||||||
|
can :manage, EmailSettings, conference_id: conf_ids_for_cfp
|
||||||
|
can :manage, Schedule, program: { conference_id: conf_ids_for_cfp }
|
||||||
|
can :manage, Room, venue: { conference_id: conf_ids_for_cfp }
|
||||||
|
can :show, Venue, conference_id: conf_ids_for_cfp
|
||||||
|
can :show, Commercial, commercialable_type: 'Venue', commercialable_id: Venue.where(conference_id: conf_ids_for_cfp).pluck(:id)
|
||||||
|
can :manage, Cfp, program: { conference_id: conf_ids_for_cfp }
|
||||||
|
can :manage, Program, conference_id: conf_ids_for_cfp
|
||||||
|
can :manage, Commercial, commercialable_type: 'Event',
|
||||||
|
commercialable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id)
|
||||||
|
can :index, Comment, commentable_type: 'Event',
|
||||||
|
commentable_id: Event.where(program_id: Program.where(conference_id: conf_ids_for_cfp).pluck(:id)).pluck(:id)
|
||||||
|
|
||||||
|
# Abilities for Role (Conference resource)
|
||||||
|
can [:index, :show], Role do |role|
|
||||||
|
role.resource_type == 'Conference' || role.resource_type == 'Track'
|
||||||
|
end
|
||||||
|
# Can add or remove users from role, when user has that same role for the conference
|
||||||
|
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
||||||
|
can :toggle_user, Role do |role|
|
||||||
|
role.resource_type == 'Conference' && role.name == 'cfp' &&
|
||||||
|
(Conference.with_role(:cfp, user).pluck(:id).include? role.resource_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
can [:index, :revert_object, :revert_attribute], PaperTrail::Version,
|
||||||
|
item_type: %w[Event EventType Track DifficultyLevel EmailSettings Room Cfp Program Comment], conference_id: conf_ids_for_cfp
|
||||||
|
can [:index, :revert_object, :revert_attribute], PaperTrail::Version,
|
||||||
|
["item_type = 'Commercial' AND conference_id IN (?) AND (object LIKE '%Event%' OR object_changes LIKE '%Event%')", conf_ids_for_cfp] do |version|
|
||||||
|
version.item_type == 'Commercial' && conf_ids_for_cfp.include?(version.conference_id) &&
|
||||||
|
(version.object.to_s.include?('Event') || version.object_changes.to_s.include?('Event'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def signed_in_with_info_desk_role(user)
|
||||||
|
# ids of all the conferences for which the user has the 'info_desk' role
|
||||||
|
conf_ids_for_info_desk = Conference.with_role(:info_desk, user).pluck(:id)
|
||||||
|
|
||||||
|
can :show, Conference do |conf|
|
||||||
|
conf_ids_for_info_desk.include?(conf.id)
|
||||||
|
end
|
||||||
|
can [:index, :show, :update], Resource, conference_id: conf_ids_for_info_desk
|
||||||
|
can :manage, Registration, conference_id: conf_ids_for_info_desk
|
||||||
|
can :manage, Question, conference_id: conf_ids_for_info_desk
|
||||||
|
can :manage, Question do |question|
|
||||||
|
!(question.conferences.pluck(:id) & conf_ids_for_info_desk).empty?
|
||||||
|
end
|
||||||
|
can :create, TicketScanning do |ticket_scanning|
|
||||||
|
conf_id = ticket_scanning.physical_ticket.ticket_purchase.conference_id
|
||||||
|
conf_ids_for_info_desk.include? conf_id
|
||||||
|
end
|
||||||
|
|
||||||
|
# Abilities for Role (Conference resource)
|
||||||
|
can [:index, :show], Role do |role|
|
||||||
|
role.resource_type == 'Conference' || role.resource_type == 'Track'
|
||||||
|
end
|
||||||
|
# Can add or remove users from role, when user has that same role for the conference
|
||||||
|
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
||||||
|
can :toggle_user, Role do |role|
|
||||||
|
role.resource_type == 'Conference' && role.name == 'info_desk' &&
|
||||||
|
(Conference.with_role(:info_desk, user).pluck(:id).include? role.resource_id)
|
||||||
|
end
|
||||||
|
can [:index, :revert_object, :revert_attribute], PaperTrail::Version, item_type: 'Registration', conference_id: conf_ids_for_info_desk
|
||||||
|
end
|
||||||
|
|
||||||
|
def signed_in_with_volunteers_coordinator_role(user)
|
||||||
|
# ids of all the conferences for which the user has the 'volunteers_coordinator' role
|
||||||
|
conf_ids_for_volunteers_coordinator = Conference.with_role(:volunteers_coordinator, user).pluck(:id)
|
||||||
|
|
||||||
|
can :show, Conference do |conf|
|
||||||
|
conf_ids_for_volunteers_coordinator.include?(conf.id)
|
||||||
|
end
|
||||||
|
can [:index, :show, :update], Resource, conference_id: conf_ids_for_volunteers_coordinator
|
||||||
|
can :manage, Vposition, conference_id: conf_ids_for_volunteers_coordinator
|
||||||
|
can :manage, Vday, conference_id: conf_ids_for_volunteers_coordinator
|
||||||
|
|
||||||
|
# Abilities for Role (Conference resource)
|
||||||
|
can [:index, :show], Role do |role|
|
||||||
|
role.resource_type == 'Conference' || role.resource_type == 'Track'
|
||||||
|
end
|
||||||
|
# Can add or remove users from role, when user has that same role for the conference
|
||||||
|
# Eg. If you are member of the CfP team, you can add more CfP team members (add users to the role 'CfP')
|
||||||
|
can :toggle_user, Role do |role|
|
||||||
|
role.resource_type == 'Conference' && role.name == 'volunteers_coordinator' &&
|
||||||
|
(Conference.with_role(:volunteers_coordinator, user).pluck(:id).include? role.resource_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def signed_in_with_track_organizer_role(user)
|
||||||
|
# ids of all the conferences for which the user has the 'track organizer' role
|
||||||
|
conf_ids_for_track_organizer = Track.with_role(:track_organizer, user).joins(:program).pluck(:conference_id)
|
||||||
|
# ids of all the tracks for which the user has the 'track_organizer' role
|
||||||
|
track_ids_for_track_organizer = Track.with_role(:track_organizer, user).pluck(:id)
|
||||||
|
|
||||||
|
can :show, Conference do |conf|
|
||||||
|
conf_ids_for_track_organizer.include?(conf.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show Program in the admin sidebar
|
||||||
|
can :show, Program, conference_id: conf_ids_for_track_organizer
|
||||||
|
|
||||||
|
# Show Tracks in the admin sidebar
|
||||||
|
can :update, Track do |track|
|
||||||
|
track.new_record? && conf_ids_for_track_organizer.include?(track.program.conference_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
can :manage, Track, id: track_ids_for_track_organizer
|
||||||
|
|
||||||
|
cannot [:edit, :update], Track do |track|
|
||||||
|
track.self_organized_and_accepted_or_confirmed?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show Roles in the admin sidebar and allow authorization of the index action
|
||||||
|
can [:index, :show], Role do |role|
|
||||||
|
role.resource_type == 'Conference' || role.resource_type == 'Track'
|
||||||
|
end
|
||||||
|
|
||||||
|
can :toggle_user, Role do |role|
|
||||||
|
role.resource_type == 'Track' && track_ids_for_track_organizer.include?(role.resource_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show Events in the admin sidebar
|
||||||
|
can :update, Event do |event|
|
||||||
|
event.new_record? && conf_ids_for_track_organizer.include?(event.program.conference_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
can :manage, Event, track_id: track_ids_for_track_organizer
|
||||||
|
can :manage, Commercial, commercialable_type: 'Event',
|
||||||
|
commercialable_id: Event.where(track_id: track_ids_for_track_organizer).pluck(:id)
|
||||||
|
|
||||||
|
# Show Scheduless in the admin sidebar
|
||||||
|
can :update, Schedule do |schedule|
|
||||||
|
schedule.new_record? && conf_ids_for_track_organizer.include?(schedule.program.conference_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show new track schedule button
|
||||||
|
can :new, Schedule do |schedule|
|
||||||
|
schedule.new_record? && conf_ids_for_track_organizer.include?(schedule.program.conference_id) && schedule.track.try(:new_record?)
|
||||||
|
end
|
||||||
|
|
||||||
|
can :manage, Schedule, track_id: track_ids_for_track_organizer
|
||||||
|
can :manage, EventSchedule, schedule: { track_id: track_ids_for_track_organizer }
|
||||||
|
end
|
||||||
|
end
|
||||||
83
app/models/booth.rb
Normal file
83
app/models/booth.rb
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
class Booth < ActiveRecord::Base
|
||||||
|
include ActiveRecord::Transitions
|
||||||
|
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
|
||||||
|
|
||||||
|
belongs_to :conference
|
||||||
|
has_many :booth_requests, dependent: :destroy
|
||||||
|
has_many :users, through: :booth_requests
|
||||||
|
|
||||||
|
has_one :submitter_booth_user, -> { where(role: 'submitter') }, class_name: 'BoothRequest'
|
||||||
|
has_one :submitter, through: :submitter_booth_user, source: :user
|
||||||
|
|
||||||
|
has_many :responsibles_booth_user, -> { where(role: 'responsible') }, class_name: 'BoothRequest'
|
||||||
|
has_many :responsibles, through: :responsibles_booth_user, source: :user
|
||||||
|
|
||||||
|
validates :title,
|
||||||
|
uniqueness: { case_sensitive: false },
|
||||||
|
presence: true
|
||||||
|
|
||||||
|
validates :description,
|
||||||
|
:reasoning,
|
||||||
|
:state,
|
||||||
|
:responsibles,
|
||||||
|
:conference_id,
|
||||||
|
:website_url,
|
||||||
|
:submitter_relationship,
|
||||||
|
presence: true
|
||||||
|
|
||||||
|
scope :accepted, -> { where(state: 'accepted') }
|
||||||
|
scope :confirmed, -> { where(state: 'confirmed') }
|
||||||
|
|
||||||
|
mount_uploader :picture, PictureUploader, mount_on: :logo_link
|
||||||
|
|
||||||
|
state_machine initial: :new do
|
||||||
|
state :new
|
||||||
|
state :withdrawn
|
||||||
|
state :to_accept
|
||||||
|
state :accepted
|
||||||
|
state :to_reject
|
||||||
|
state :rejected
|
||||||
|
state :canceled
|
||||||
|
state :confirmed
|
||||||
|
|
||||||
|
event :restart do
|
||||||
|
transitions to: :new, from: [:withdrawn, :rejected, :canceled]
|
||||||
|
end
|
||||||
|
event :withdraw do
|
||||||
|
transitions to: :withdrawn, from: [:new, :to_accept, :accepted, :to_reject, :rejected, :confirmed]
|
||||||
|
end
|
||||||
|
event :confirm do
|
||||||
|
transitions to: :confirmed, from: [:accepted]
|
||||||
|
end
|
||||||
|
event :to_accept do
|
||||||
|
transitions to: :to_accept, from: [:new, :to_reject]
|
||||||
|
end
|
||||||
|
event :to_reject do
|
||||||
|
transitions to: :to_reject, from: [:new, :to_accept]
|
||||||
|
end
|
||||||
|
event :accept do
|
||||||
|
transitions to: :accepted, from: [:new, :to_accept]
|
||||||
|
end
|
||||||
|
event :reject do
|
||||||
|
transitions to: :rejected, from: [:new, :to_reject]
|
||||||
|
end
|
||||||
|
event :cancel do
|
||||||
|
transitions to: :canceled, from: [:accepted, :rejected, :to_accept, :to_reject, :confirmed]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def transition_possible?(transition)
|
||||||
|
self.class.state_machine.events_for(current_state).include?(transition)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_state(transition, _notice)
|
||||||
|
alert = ''
|
||||||
|
begin
|
||||||
|
send(transition)
|
||||||
|
save
|
||||||
|
rescue Transitions::InvalidTransition => e
|
||||||
|
alert = "Update state failed. #{e.message}"
|
||||||
|
end
|
||||||
|
alert
|
||||||
|
end
|
||||||
|
end
|
||||||
9
app/models/booth_request.rb
Normal file
9
app/models/booth_request.rb
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
class BoothRequest < ActiveRecord::Base
|
||||||
|
belongs_to :booth
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
validates :role,
|
||||||
|
presence: true
|
||||||
|
|
||||||
|
ROLES = %w[submitter responsible].freeze
|
||||||
|
end
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
# cannot delete program if there are events submitted
|
# cannot delete program if there are events submitted
|
||||||
|
|
||||||
class Cfp < ActiveRecord::Base
|
class Cfp < ActiveRecord::Base
|
||||||
|
TYPES = %w(events booths tracks).freeze
|
||||||
|
|
||||||
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
|
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
|
||||||
belongs_to :program
|
belongs_to :program
|
||||||
|
|
||||||
|
|
@ -8,6 +10,15 @@ class Cfp < ActiveRecord::Base
|
||||||
validates :start_date, :end_date, presence: true
|
validates :start_date, :end_date, presence: true
|
||||||
validate :before_end_of_conference
|
validate :before_end_of_conference
|
||||||
validate :start_after_end_date
|
validate :start_after_end_date
|
||||||
|
validates :cfp_type,
|
||||||
|
presence: true,
|
||||||
|
inclusion: {
|
||||||
|
in: TYPES
|
||||||
|
},
|
||||||
|
uniqueness: {
|
||||||
|
scope: :program,
|
||||||
|
case_sensitive: false
|
||||||
|
}
|
||||||
|
|
||||||
##
|
##
|
||||||
# Checks whether cfp date is updated
|
# Checks whether cfp date is updated
|
||||||
|
|
@ -55,15 +66,52 @@ class Cfp < ActiveRecord::Base
|
||||||
result > 0 ? result : 0
|
result > 0 ? result : 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Checks if the call for papers is currently open
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +false+ -> If the CFP is not set or today isn't in the CFP period.
|
||||||
|
# * +true+ -> If today is in the CFP period.
|
||||||
|
def open?
|
||||||
|
(start_date..end_date).cover?(Date.current)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Finds the cfp for events if it exists
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +Cfp+ -> The cfp with type 'events'
|
||||||
|
def self.for_events
|
||||||
|
find_by(cfp_type: 'events')
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Finds the cfp for tracks if it exists
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +Cfp+ -> The cfp with type 'tracks'
|
||||||
|
def self.for_tracks
|
||||||
|
find_by(cfp_type: 'tracks')
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Finds the cfp for booths if it exists
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +Cfp+ -> The cfp with type 'booths'
|
||||||
|
def self.for_booths
|
||||||
|
find_by(cfp_type: 'booths')
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def before_end_of_conference
|
def before_end_of_conference
|
||||||
if program.conference && program.conference.end_date && end_date && (end_date > program.conference.end_date)
|
if program && program.conference && program.conference.end_date && end_date && (end_date > program.conference.end_date)
|
||||||
errors
|
errors
|
||||||
.add(:end_date, "can't be after the conference end date (#{program.conference.end_date})")
|
.add(:end_date, "can't be after the conference end date (#{program.conference.end_date})")
|
||||||
end
|
end
|
||||||
|
|
||||||
if program.conference && program.conference.end_date && start_date && (start_date > program.conference.end_date)
|
if program && program.conference && program.conference.end_date && start_date && (start_date > program.conference.end_date)
|
||||||
errors
|
errors
|
||||||
.add(:start_date, "can't be after the conference end date (#{program.conference.end_date})")
|
.add(:start_date, "can't be after the conference end date (#{program.conference.end_date})")
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ class Comment < ActiveRecord::Base
|
||||||
# want user to vote on the quality of comments.
|
# want user to vote on the quality of comments.
|
||||||
#acts_as_votable
|
#acts_as_votable
|
||||||
|
|
||||||
belongs_to :commentable, polymorphic: true
|
belongs_to :commentable, counter_cache: true, polymorphic: true
|
||||||
|
|
||||||
# NOTE: Comments belong to a user
|
# NOTE: Comments belong to a user
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
|
||||||
11
app/models/concerns/revision_count.rb
Normal file
11
app/models/concerns/revision_count.rb
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
module RevisionCount
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
after_update :increment_revision
|
||||||
|
end
|
||||||
|
|
||||||
|
def increment_revision
|
||||||
|
conference.update_column(:revision, conference.revision + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
class Conference < ActiveRecord::Base
|
class Conference < ActiveRecord::Base
|
||||||
|
include RevisionCount
|
||||||
require 'uri'
|
require 'uri'
|
||||||
serialize :events_per_week, Hash
|
serialize :events_per_week, Hash
|
||||||
# Needed to call 'Conference.with_role' in /models/ability.rb
|
# Needed to call 'Conference.with_role' in /models/ability.rb
|
||||||
|
|
@ -6,6 +7,10 @@ class Conference < ActiveRecord::Base
|
||||||
resourcify :roles, dependent: :delete_all
|
resourcify :roles, dependent: :delete_all
|
||||||
|
|
||||||
default_scope { order('start_date DESC') }
|
default_scope { order('start_date DESC') }
|
||||||
|
scope :upcoming, (-> { where('end_date >= ?', Date.current) })
|
||||||
|
scope :past, (-> { where('end_date < ?', Date.current) })
|
||||||
|
|
||||||
|
belongs_to :organization
|
||||||
|
|
||||||
has_paper_trail ignore: %i(updated_at guid revision events_per_week), meta: { conference_id: :id }
|
has_paper_trail ignore: %i(updated_at guid revision events_per_week), meta: { conference_id: :id }
|
||||||
|
|
||||||
|
|
@ -17,11 +22,17 @@ class Conference < ActiveRecord::Base
|
||||||
has_one :email_settings, dependent: :destroy
|
has_one :email_settings, dependent: :destroy
|
||||||
has_one :program, dependent: :destroy
|
has_one :program, dependent: :destroy
|
||||||
has_one :venue, dependent: :destroy
|
has_one :venue, dependent: :destroy
|
||||||
|
has_many :physical_tickets, through: :ticket_purchases
|
||||||
has_many :ticket_purchases, dependent: :destroy
|
has_many :ticket_purchases, dependent: :destroy
|
||||||
has_many :payments, dependent: :destroy
|
has_many :payments, dependent: :destroy
|
||||||
has_many :supporters, through: :ticket_purchases, source: :user
|
has_many :supporters, through: :ticket_purchases, source: :user
|
||||||
has_many :tickets, dependent: :destroy
|
has_many :tickets, dependent: :destroy do
|
||||||
|
def for_registration
|
||||||
|
where(registration_ticket: true)
|
||||||
|
end
|
||||||
|
end
|
||||||
has_many :resources, dependent: :destroy
|
has_many :resources, dependent: :destroy
|
||||||
|
has_many :booths, dependent: :destroy
|
||||||
|
|
||||||
has_many :lodgings, dependent: :destroy
|
has_many :lodgings, dependent: :destroy
|
||||||
has_many :registrations, dependent: :destroy
|
has_many :registrations, dependent: :destroy
|
||||||
|
|
@ -53,7 +64,9 @@ class Conference < ActiveRecord::Base
|
||||||
:start_date,
|
:start_date,
|
||||||
:end_date,
|
:end_date,
|
||||||
:start_hour,
|
:start_hour,
|
||||||
:end_hour, presence: true
|
:end_hour,
|
||||||
|
:ticket_layout,
|
||||||
|
:organization, presence: true
|
||||||
|
|
||||||
validates :short_title, uniqueness: true
|
validates :short_title, uniqueness: true
|
||||||
validates :short_title, format: { with: /\A[a-zA-Z0-9_-]*\z/ }
|
validates :short_title, format: { with: /\A[a-zA-Z0-9_-]*\z/ }
|
||||||
|
|
@ -69,6 +82,8 @@ class Conference < ActiveRecord::Base
|
||||||
after_create :create_free_ticket
|
after_create :create_free_ticket
|
||||||
after_update :delete_event_schedules
|
after_update :delete_event_schedules
|
||||||
|
|
||||||
|
enum ticket_layout: [:portrait, :landscape]
|
||||||
|
|
||||||
##
|
##
|
||||||
# Checks if the user is registered to the conference
|
# Checks if the user is registered to the conference
|
||||||
#
|
#
|
||||||
|
|
@ -128,7 +143,7 @@ class Conference < ActiveRecord::Base
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
if program && program.cfp && program.events
|
if program && program.cfp && program.events
|
||||||
submissions = program.events.group(:week).count
|
submissions = program.events.select(:week).group(:week).order(:week).count
|
||||||
start_week = program.cfp.start_week
|
start_week = program.cfp.start_week
|
||||||
weeks = program.cfp.weeks
|
weeks = program.cfp.weeks
|
||||||
result = calculate_items_per_week(start_week, weeks, submissions)
|
result = calculate_items_per_week(start_week, weeks, submissions)
|
||||||
|
|
@ -176,7 +191,7 @@ class Conference < ActiveRecord::Base
|
||||||
registration_period.start_date &&
|
registration_period.start_date &&
|
||||||
registration_period.end_date
|
registration_period.end_date
|
||||||
|
|
||||||
reg = registrations.group(:week).count
|
reg = registrations.group(:week).order(:week).count
|
||||||
start_week = get_registration_start_week
|
start_week = get_registration_start_week
|
||||||
weeks = registration_weeks
|
weeks = registration_weeks
|
||||||
result = calculate_items_per_week(start_week, weeks, reg)
|
result = calculate_items_per_week(start_week, weeks, reg)
|
||||||
|
|
@ -184,6 +199,59 @@ class Conference < ActiveRecord::Base
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Returns an array with the summarized ticket sales per week.
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 tickets sold
|
||||||
|
def get_tickets_sold_per_week
|
||||||
|
result = []
|
||||||
|
|
||||||
|
if tickets && ticket_purchases && registration_period
|
||||||
|
tickets_sold = ticket_purchases.paid.group(:week).sum(:quantity)
|
||||||
|
start_week = get_registration_start_week
|
||||||
|
weeks = registration_weeks
|
||||||
|
result = calculate_items_per_week(start_week, weeks, tickets_sold)
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Returns an hash with ticket sales by ticket title
|
||||||
|
# per week.
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +Array+ -> e.g. 'Free Access' => [0, 3, 3, 5] -> first week 0 tickets sold, second week 3 tickets sold.
|
||||||
|
def get_tickets_data
|
||||||
|
result = {}
|
||||||
|
if tickets && ticket_purchases && registration_period
|
||||||
|
tickets_per_ticket_id_and_week = ticket_purchases.paid.group(:ticket_id, :week).sum(:quantity)
|
||||||
|
|
||||||
|
start_week = get_registration_start_week
|
||||||
|
weeks = registration_weeks
|
||||||
|
|
||||||
|
tickets_by_id_per_week = {}
|
||||||
|
|
||||||
|
tickets.each do |ticket|
|
||||||
|
tickets_by_id_per_week[ticket.id] = {}
|
||||||
|
(start_week...(start_week + weeks)).each do |week|
|
||||||
|
tickets_by_id_per_week[ticket.id][week] = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
tickets_per_ticket_id_and_week.each do |ticket_week, value|
|
||||||
|
tickets_by_id_per_week[ticket_week[0]][ticket_week[1]] = value
|
||||||
|
end
|
||||||
|
|
||||||
|
tickets_by_id_per_week.each do |ticket, values|
|
||||||
|
result[Ticket.find(ticket).title] = pad_array_left_not_kumulative(start_week, values)
|
||||||
|
end
|
||||||
|
|
||||||
|
result['Weeks'] = weeks > 0 ? (1..weeks).to_a : 0
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Calculates how many weeks the registration is.
|
# Calculates how many weeks the registration is.
|
||||||
#
|
#
|
||||||
|
|
@ -281,8 +349,8 @@ class Conference < ActiveRecord::Base
|
||||||
# ====Returns
|
# ====Returns
|
||||||
# * +hash+ -> user: submissions
|
# * +hash+ -> user: submissions
|
||||||
def self.get_top_submitter(limit = 5)
|
def self.get_top_submitter(limit = 5)
|
||||||
submitter = EventUser.where('event_role = ?', 'submitter').limit(limit).group(:user_id)
|
submitter = EventUser.select(:user_id).where('event_role = ?', 'submitter').limit(limit).group(:user_id)
|
||||||
counter = submitter.order('count_all desc').count
|
counter = submitter.order('count_all desc').count(:all)
|
||||||
calculate_user_submission_hash(submitter, counter)
|
calculate_user_submission_hash(submitter, counter)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -292,10 +360,10 @@ class Conference < ActiveRecord::Base
|
||||||
# ====Returns
|
# ====Returns
|
||||||
# * +hash+ -> user: submissions
|
# * +hash+ -> user: submissions
|
||||||
def get_top_submitter(limit = 5)
|
def get_top_submitter(limit = 5)
|
||||||
submitter = EventUser.joins(:event)
|
submitter = EventUser.joins(:event).select(:user_id)
|
||||||
.where('event_role = ? and program_id = ?', 'submitter', Conference.find(id).program.id)
|
.where('event_role = ? and program_id = ?', 'submitter', Conference.find(id).program.id)
|
||||||
.limit(limit).group(:user_id)
|
.limit(limit).group(:user_id)
|
||||||
counter = submitter.order('count_all desc').count
|
counter = submitter.order('count_all desc').count(:all)
|
||||||
Conference.calculate_user_submission_hash(submitter, counter)
|
Conference.calculate_user_submission_hash(submitter, counter)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -396,6 +464,46 @@ class Conference < ActiveRecord::Base
|
||||||
calculate_user_distribution_hash(active_user, unconfirmed_user, dead_user)
|
calculate_user_distribution_hash(active_user, unconfirmed_user, dead_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Returns a hash with per ticket sales => { "Title" => { value: number of tickets sold,
|
||||||
|
# color: generated from the title using a hash function }, ...}
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +hash+ -> hash
|
||||||
|
def tickets_sold_distribution
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
if tickets && ticket_purchases
|
||||||
|
tickets.each do |ticket|
|
||||||
|
result[ticket.title] = {
|
||||||
|
'value' => ApplicationController.helpers.humanized_money(ticket.tickets_sold).delete(',').to_i,
|
||||||
|
'color' => "\##{Digest::MD5.hexdigest(ticket.title)[0..5]}"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Returns a hash with per ticket turnover => { "Title" => { value: ticket turnover,
|
||||||
|
# color: generated from the title using a hash function }, ...}
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +hash+ -> hash
|
||||||
|
def tickets_turnover_distribution
|
||||||
|
result = {}
|
||||||
|
|
||||||
|
if tickets && ticket_purchases
|
||||||
|
tickets.each do |ticket|
|
||||||
|
result[ticket.title] = {
|
||||||
|
'value' => ApplicationController.helpers.humanized_money(ticket.tickets_turnover_total(ticket.id)).delete(',').to_i,
|
||||||
|
'color' => "\##{Digest::MD5.hexdigest(ticket.title)[0..5]}"
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Calculates the overall program minutes
|
# Calculates the overall program minutes
|
||||||
#
|
#
|
||||||
|
|
@ -460,10 +568,10 @@ class Conference < ActiveRecord::Base
|
||||||
# ====Returns
|
# ====Returns
|
||||||
# * +hash+ -> track => {color, value}
|
# * +hash+ -> track => {color, value}
|
||||||
def tracks_distribution(state = nil)
|
def tracks_distribution(state = nil)
|
||||||
if state
|
tracks_grouped = if state
|
||||||
tracks_grouped = program.events.select(:track_id).where('state = ?', state).group(:track_id)
|
program.events.select(:track_id).where('state = ?', state).group(:track_id)
|
||||||
else
|
else
|
||||||
tracks_grouped = program.events.select(:track_id).group(:track_id)
|
program.events.select(:track_id).group(:track_id)
|
||||||
end
|
end
|
||||||
tracks_counted = tracks_grouped.count
|
tracks_counted = tracks_grouped.count
|
||||||
|
|
||||||
|
|
@ -547,7 +655,7 @@ class Conference < ActiveRecord::Base
|
||||||
def self.write_event_distribution_to_db
|
def self.write_event_distribution_to_db
|
||||||
week = DateTime.now.end_of_week
|
week = DateTime.now.end_of_week
|
||||||
|
|
||||||
Conference.where('end_date > ?', Date.today).each do |conference|
|
Conference.where('end_date > ?', Date.today).find_each do |conference|
|
||||||
result = {}
|
result = {}
|
||||||
Event.state_machine.states.each do |state|
|
Event.state_machine.states.each do |state|
|
||||||
count = conference.program.events.where('state = ?', state.name).count
|
count = conference.program.events.where('state = ?', state.name).count
|
||||||
|
|
@ -634,6 +742,28 @@ class Conference < ActiveRecord::Base
|
||||||
(start_hour..(end_hour - 1)).cover?(current_hour) ? current_hour - start_hour : 0
|
(start_hour..(end_hour - 1)).cover?(current_hour) ? current_hour - start_hour : 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +True+ -> if accepted booths are equal to the booth limit
|
||||||
|
# * +False+ -> Accepted booths have not reached the booth limit
|
||||||
|
def maximum_accepted_booths?
|
||||||
|
booth_limit > 0 && booths.accepted.count + booths.confirmed.count >= booth_limit
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return the current conference object to be used in RevisionCount
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +ActiveRecord+
|
||||||
|
def conference
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_param
|
||||||
|
short_title
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Returns a different html colour for every i and consecutive colors are
|
# Returns a different html colour for every i and consecutive colors are
|
||||||
|
|
@ -889,10 +1019,10 @@ class Conference < ActiveRecord::Base
|
||||||
# ====Returns
|
# ====Returns
|
||||||
# * +hash+ -> object_type => {color, value}
|
# * +hash+ -> object_type => {color, value}
|
||||||
def calculate_event_distribution(group_by_id, association_symbol, state = nil)
|
def calculate_event_distribution(group_by_id, association_symbol, state = nil)
|
||||||
if state
|
grouped = if state
|
||||||
grouped = program.events.select(group_by_id).where('state = ?', 'confirmed').group(group_by_id)
|
program.events.select(group_by_id).where('state = ?', 'confirmed').group(group_by_id)
|
||||||
else
|
else
|
||||||
grouped = program.events.select(group_by_id).group(group_by_id)
|
program.events.select(group_by_id).group(group_by_id)
|
||||||
end
|
end
|
||||||
counted = grouped.count
|
counted = grouped.count
|
||||||
|
|
||||||
|
|
@ -1004,7 +1134,8 @@ class Conference < ActiveRecord::Base
|
||||||
def self.calculate_user_submission_hash(submitters, counter)
|
def self.calculate_user_submission_hash(submitters, counter)
|
||||||
result = ActiveSupport::OrderedHash.new
|
result = ActiveSupport::OrderedHash.new
|
||||||
counter.each do |key, value|
|
counter.each do |key, value|
|
||||||
submitter = submitters.where(user_id: key).first
|
# make PG happy by including the user_id in ORDER
|
||||||
|
submitter = submitters.where(user_id: key).order(:user_id).first
|
||||||
if submitter
|
if submitter
|
||||||
result[submitter.user] = value
|
result[submitter.user] = value
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ class EmailSettings < ActiveRecord::Base
|
||||||
|
|
||||||
has_paper_trail on: [:update], ignore: [:updated_at], meta: { conference_id: :conference_id }
|
has_paper_trail on: [:update], ignore: [:updated_at], meta: { conference_id: :conference_id }
|
||||||
|
|
||||||
def get_values(conference, user, event = nil)
|
def get_values(conference, user, event = nil, booth = nil)
|
||||||
h = {
|
h = {
|
||||||
'email' => user.email,
|
'email' => user.email,
|
||||||
'name' => user.name,
|
'name' => user.name,
|
||||||
|
|
@ -45,6 +45,10 @@ class EmailSettings < ActiveRecord::Base
|
||||||
h['proposalslink'] = Rails.application.routes.url_helpers.conference_program_proposals_url(
|
h['proposalslink'] = Rails.application.routes.url_helpers.conference_program_proposals_url(
|
||||||
conference.short_title, host: (ENV['OSEM_HOSTNAME'] || 'localhost:3000'))
|
conference.short_title, host: (ENV['OSEM_HOSTNAME'] || 'localhost:3000'))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if booth
|
||||||
|
h['booth_title'] = booth.title
|
||||||
|
end
|
||||||
h
|
h
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -58,6 +62,11 @@ class EmailSettings < ActiveRecord::Base
|
||||||
parse_template(conf_update_template, values)
|
parse_template(conf_update_template, values)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate_booth_mail(booth, booth_template)
|
||||||
|
values = get_values(booth.conference, booth.submitter, nil, booth)
|
||||||
|
parse_template(booth_template, values)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def parse_template(text, values)
|
def parse_template(text, values)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
class Event < ActiveRecord::Base
|
class Event < ActiveRecord::Base
|
||||||
include ActiveRecord::Transitions
|
include ActiveRecord::Transitions
|
||||||
|
include RevisionCount
|
||||||
has_paper_trail on: [:create, :update], ignore: [:updated_at, :guid, :week], meta: { conference_id: :conference_id }
|
has_paper_trail on: [:create, :update], ignore: [:updated_at, :guid, :week], meta: { conference_id: :conference_id }
|
||||||
|
|
||||||
acts_as_commentable
|
acts_as_commentable
|
||||||
|
|
@ -44,6 +45,7 @@ class Event < ActiveRecord::Base
|
||||||
validates :max_attendees, numericality: { only_integer: true, greater_than_or_equal_to: 1, allow_nil: true }
|
validates :max_attendees, numericality: { only_integer: true, greater_than_or_equal_to: 1, allow_nil: true }
|
||||||
|
|
||||||
validate :max_attendees_no_more_than_room_size
|
validate :max_attendees_no_more_than_room_size
|
||||||
|
validate :valid_track
|
||||||
|
|
||||||
scope :confirmed, -> { where(state: 'confirmed') }
|
scope :confirmed, -> { where(state: 'confirmed') }
|
||||||
scope :canceled, -> { where(state: 'canceled') }
|
scope :canceled, -> { where(state: 'canceled') }
|
||||||
|
|
@ -83,7 +85,7 @@ class Event < ActiveRecord::Base
|
||||||
# ====Returns
|
# ====Returns
|
||||||
# * +true+ or +false+
|
# * +true+ or +false+
|
||||||
def scheduled?
|
def scheduled?
|
||||||
event_schedules.find_by(schedule_id: program.selected_schedule_id).present?
|
event_schedules.find_by(schedule_id: selected_schedule_id).present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def registration_possible?
|
def registration_possible?
|
||||||
|
|
@ -115,7 +117,7 @@ class Event < ActiveRecord::Base
|
||||||
def average_rating
|
def average_rating
|
||||||
@total_rating = 0
|
@total_rating = 0
|
||||||
votes.each do |vote|
|
votes.each do |vote|
|
||||||
@total_rating = @total_rating + vote.rating
|
@total_rating += vote.rating
|
||||||
end
|
end
|
||||||
@total = votes.size
|
@total = votes.size
|
||||||
@total_rating > 0 ? number_with_precision(@total_rating / @total.to_f, precision: 2, strip_insignificant_zeros: true) : 0
|
@total_rating > 0 ? number_with_precision(@total_rating / @total.to_f, precision: 2, strip_insignificant_zeros: true) : 0
|
||||||
|
|
@ -241,14 +243,22 @@ class Event < ActiveRecord::Base
|
||||||
def room
|
def room
|
||||||
# We use try(:selected_schedule_id) because this function is used for
|
# We use try(:selected_schedule_id) because this function is used for
|
||||||
# validations so program could not be present there
|
# validations so program could not be present there
|
||||||
|
if track.try(:self_organized?)
|
||||||
|
track.room
|
||||||
|
else
|
||||||
event_schedules.find_by(schedule_id: program.try(:selected_schedule_id)).try(:room)
|
event_schedules.find_by(schedule_id: program.try(:selected_schedule_id)).try(:room)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Returns the start time at which this event is scheduled
|
# Returns the start time at which this event is scheduled
|
||||||
#
|
#
|
||||||
def time
|
def time
|
||||||
event_schedules.find_by(schedule_id: program.selected_schedule_id).try(:start_time)
|
event_schedules.find_by(schedule_id: selected_schedule_id).try(:start_time)
|
||||||
|
end
|
||||||
|
|
||||||
|
def conference
|
||||||
|
program.conference
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
@ -298,4 +308,25 @@ class Event < ActiveRecord::Base
|
||||||
def conference_id
|
def conference_id
|
||||||
program.conference_id
|
program.conference_id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Allow only confirmed tracks that belong to the same program as the event
|
||||||
|
#
|
||||||
|
def valid_track
|
||||||
|
return unless track && track.program && program
|
||||||
|
errors.add(:track, 'is invalid') unless track.confirmed? && track.program == program
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return the id of the selected schedule
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +Integer+ -> selected_schedule_id of self-organized track or program
|
||||||
|
def selected_schedule_id
|
||||||
|
if track.try(:self_organized?)
|
||||||
|
track.selected_schedule_id
|
||||||
|
else
|
||||||
|
program.selected_schedule_id
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ class EventSchedule < ActiveRecord::Base
|
||||||
validates :event, uniqueness: { scope: :schedule }
|
validates :event, uniqueness: { scope: :schedule }
|
||||||
validate :start_after_end_hour
|
validate :start_after_end_hour
|
||||||
validate :start_before_start_hour
|
validate :start_before_start_hour
|
||||||
|
validate :same_room_as_track
|
||||||
|
validate :during_track
|
||||||
|
validate :valid_schedule
|
||||||
|
|
||||||
scope :confirmed, -> { joins(:event).where('state = ?', 'confirmed') }
|
scope :confirmed, -> { joins(:event).where('state = ?', 'confirmed') }
|
||||||
scope :canceled, -> { joins(:event).where('state = ?', 'canceled') }
|
scope :canceled, -> { joins(:event).where('state = ?', 'canceled') }
|
||||||
|
|
@ -52,4 +55,35 @@ class EventSchedule < ActiveRecord::Base
|
||||||
def conference_id
|
def conference_id
|
||||||
schedule.program.conference_id
|
schedule.program.conference_id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Validates that the event is scheduled in the same room as its track
|
||||||
|
#
|
||||||
|
def same_room_as_track
|
||||||
|
return unless event.try(:track).try(:room)
|
||||||
|
errors.add(:room, "must be the same as the track's room (#{event.track.room.name})") unless event.track.room == room
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Validates that the event is scheduled within its track's time slot
|
||||||
|
#
|
||||||
|
def during_track
|
||||||
|
return unless event.try(:track) && start_time
|
||||||
|
|
||||||
|
if event.track.try(:start_date) && event.track.start_date > start_time
|
||||||
|
errors.add(:start_time, "can't be before the track's start date (#{event.track.start_date})")
|
||||||
|
end
|
||||||
|
|
||||||
|
if event.track.try(:end_date) && event.track.end_date + 1.day < end_time
|
||||||
|
errors.add(:end_time, "can't be after the track's end date (#{event.track.end_date})")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Validates that the event is scheduled in its self-organized tracks's schedules
|
||||||
|
#
|
||||||
|
def valid_schedule
|
||||||
|
return unless event.try(:track).try(:self_organized?) && schedule
|
||||||
|
errors.add(:schedule, "must be one of #{event.track.name} track's schedules") unless event.track.schedules.include?(schedule)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
class EventUser < ActiveRecord::Base
|
class EventUser < ActiveRecord::Base
|
||||||
# TODO Do we need these roles?
|
# TODO: Do we need these roles?
|
||||||
ROLES = [['Speaker', 'speaker'], ['Submitter', 'submitter'], ['Moderator', 'moderator']]
|
ROLES = [%w[Speaker speaker], %w[Submitter submitter], %w[Moderator moderator]]
|
||||||
|
|
||||||
belongs_to :event
|
belongs_to :event
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
|
||||||
19
app/models/organization.rb
Normal file
19
app/models/organization.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
class Organization < ActiveRecord::Base
|
||||||
|
resourcify :roles, dependent: :delete_all
|
||||||
|
|
||||||
|
has_paper_trail
|
||||||
|
|
||||||
|
has_many :conferences, dependent: :destroy
|
||||||
|
|
||||||
|
after_create :create_roles
|
||||||
|
|
||||||
|
validates :name, presence: true
|
||||||
|
|
||||||
|
mount_uploader :picture, PictureUploader, mount_on: :picture
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_roles
|
||||||
|
roles.where(name: 'organization_admin').first_or_create(description: 'For the administrators of an organization and its conferences')
|
||||||
|
end
|
||||||
|
end
|
||||||
22
app/models/physical_ticket.rb
Normal file
22
app/models/physical_ticket.rb
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
class PhysicalTicket < ActiveRecord::Base
|
||||||
|
belongs_to :ticket_purchase
|
||||||
|
has_one :ticket, through: :ticket_purchase
|
||||||
|
has_one :conference, through: :ticket_purchase
|
||||||
|
has_one :user, through: :ticket_purchase
|
||||||
|
has_many :ticket_scannings
|
||||||
|
|
||||||
|
before_create :set_token
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_token
|
||||||
|
self.token = generate_token
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_token
|
||||||
|
loop do
|
||||||
|
token = SecureRandom.hex(10)
|
||||||
|
break token unless PhysicalTicket.exists?(token: token)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -5,7 +5,7 @@ class Program < ActiveRecord::Base
|
||||||
|
|
||||||
belongs_to :conference
|
belongs_to :conference
|
||||||
|
|
||||||
has_one :cfp, dependent: :destroy
|
has_many :cfps, dependent: :destroy
|
||||||
has_many :event_types, dependent: :destroy
|
has_many :event_types, dependent: :destroy
|
||||||
has_many :tracks, dependent: :destroy
|
has_many :tracks, dependent: :destroy
|
||||||
has_many :difficulty_levels, dependent: :destroy
|
has_many :difficulty_levels, dependent: :destroy
|
||||||
|
|
@ -71,7 +71,11 @@ class Program < ActiveRecord::Base
|
||||||
|
|
||||||
# Returns all event_schedules for the selected schedule ordered by start_time
|
# Returns all event_schedules for the selected schedule ordered by start_time
|
||||||
def selected_event_schedules
|
def selected_event_schedules
|
||||||
selected_schedule.event_schedules.order(start_time: :asc) if selected_schedule
|
event_schedules = selected_schedule.event_schedules.order(start_time: :asc) if selected_schedule
|
||||||
|
tracks.self_organized.confirmed.order(start_date: :asc).each do |track|
|
||||||
|
event_schedules += track.selected_schedule.event_schedules.order(start_time: :asc) if track.selected_schedule
|
||||||
|
end
|
||||||
|
event_schedules.sort_by(&:start_time) if event_schedules
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
@ -163,6 +167,23 @@ class Program < ActiveRecord::Base
|
||||||
EventSchedule.where(schedule: selected_schedule).where(start_time: parsed_date..(parsed_date + 1)).any?
|
EventSchedule.where(schedule: selected_schedule).where(start_time: parsed_date..(parsed_date + 1)).any?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Provides backwards compatibility for when the program had one cfp
|
||||||
|
#
|
||||||
|
# ====Returns
|
||||||
|
# * +ActiveRecord+ -> The program's cfp with cfp_type == 'events'
|
||||||
|
def cfp
|
||||||
|
return nil if cfps.for_events.blank?
|
||||||
|
cfps.for_events
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# ====Returns
|
||||||
|
# * +Array+ -> The types of cfps for which a cfp doesn't exist yet
|
||||||
|
def remaining_cfp_types
|
||||||
|
Cfp::TYPES - cfps.pluck(:cfp_type)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ class Registration < ActiveRecord::Base
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :conference
|
belongs_to :conference
|
||||||
|
|
||||||
has_and_belongs_to_many :events
|
|
||||||
has_and_belongs_to_many :qanswers
|
has_and_belongs_to_many :qanswers
|
||||||
has_and_belongs_to_many :vchoices
|
has_and_belongs_to_many :vchoices
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
#
|
|
||||||
# suseconferenceclient relies on a 'revision' attribute for caching and
|
|
||||||
# doing some calculations.
|
|
||||||
#
|
|
||||||
# It should be incremented after any change in the conference or in any
|
|
||||||
# associated models
|
|
||||||
#
|
|
||||||
# This observer updates the revision column in a non-intrusive way,
|
|
||||||
# preventing validations, callbacks or exceptions to be triggered
|
|
||||||
#
|
|
||||||
# Relying on paper_trail could also be an option, but a 'revision' column
|
|
||||||
# in table 'conferences' looks like a more simple and straightforward solution
|
|
||||||
#
|
|
||||||
class RevisionObserver < ActiveRecord::Observer
|
|
||||||
observe :conference, :event, :room, :track
|
|
||||||
|
|
||||||
def after_save(model)
|
|
||||||
begin
|
|
||||||
conference = model.kind_of?(Conference) ? model : model.conference
|
|
||||||
conference.reload.increment(:revision)
|
|
||||||
conference.update_column(:revision, conference.revision)
|
|
||||||
rescue
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
class Room < ActiveRecord::Base
|
class Room < ActiveRecord::Base
|
||||||
|
include RevisionCount
|
||||||
belongs_to :venue
|
belongs_to :venue
|
||||||
has_many :event_schedules, dependent: :destroy
|
has_many :event_schedules, dependent: :destroy
|
||||||
|
has_many :tracks
|
||||||
|
|
||||||
has_paper_trail ignore: [:guid], meta: { conference_id: :conference_id }
|
has_paper_trail ignore: [:guid], meta: { conference_id: :conference_id }
|
||||||
|
|
||||||
|
|
@ -10,6 +12,10 @@ class Room < ActiveRecord::Base
|
||||||
|
|
||||||
validates :size, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
|
validates :size, numericality: { only_integer: true, greater_than: 0 }, allow_nil: true
|
||||||
|
|
||||||
|
def conference
|
||||||
|
venue.conference
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def generate_guid
|
def generate_guid
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
class Schedule < ActiveRecord::Base
|
class Schedule < ActiveRecord::Base
|
||||||
belongs_to :program
|
belongs_to :program
|
||||||
|
belongs_to :track
|
||||||
has_many :event_schedules, dependent: :destroy
|
has_many :event_schedules, dependent: :destroy
|
||||||
has_many :events, through: :event_schedules
|
has_many :events, through: :event_schedules
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
class Subscription < ActiveRecord::Base
|
class Subscription < ActiveRecord::Base
|
||||||
validates :user_id, uniqueness: { scope: [:conference_id] }
|
|
||||||
belongs_to :conference
|
belongs_to :conference
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,18 @@ class Ticket < ActiveRecord::Base
|
||||||
result ? result : Money.new(0, 'USD')
|
result ? result : Money.new(0, 'USD')
|
||||||
end
|
end
|
||||||
|
|
||||||
def tickets_sold
|
def self.total_price_user(conference, user, paid: false)
|
||||||
ticket_purchases.sum(:quantity)
|
tickets = TicketPurchase.where(conference: conference, user: user, paid: paid)
|
||||||
|
tickets.inject(0){ |sum, ticket| sum + (ticket.amount_paid * ticket.quantity) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def tickets_turnover
|
def tickets_turnover_total(id)
|
||||||
tickets_sold * price
|
tickets = TicketPurchase.where(ticket_id: id)
|
||||||
|
tickets.inject(0){ |sum, ticket| sum + (ticket.amount_paid * ticket.quantity) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def tickets_sold
|
||||||
|
ticket_purchases.paid.sum(:quantity)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,11 @@ class TicketPurchase < ActiveRecord::Base
|
||||||
belongs_to :ticket
|
belongs_to :ticket
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :conference
|
belongs_to :conference
|
||||||
|
belongs_to :payment
|
||||||
|
|
||||||
validates :ticket_id, :user_id, :conference_id, :quantity, presence: true
|
validates :ticket_id, :user_id, :conference_id, :quantity, presence: true
|
||||||
|
validate :one_registration_ticket_per_user
|
||||||
|
validate :registration_ticket_already_purchased, on: :create
|
||||||
validates :quantity, numericality: { greater_than: 0 }
|
validates :quantity, numericality: { greater_than: 0 }
|
||||||
|
|
||||||
delegate :title, to: :ticket
|
delegate :title, to: :ticket
|
||||||
|
|
@ -13,28 +15,35 @@ class TicketPurchase < ActiveRecord::Base
|
||||||
delegate :price_cents, to: :ticket
|
delegate :price_cents, to: :ticket
|
||||||
delegate :price_currency, to: :ticket
|
delegate :price_currency, to: :ticket
|
||||||
|
|
||||||
|
has_many :physical_tickets
|
||||||
|
|
||||||
scope :paid, -> { where(paid: true) }
|
scope :paid, -> { where(paid: true) }
|
||||||
scope :unpaid, -> { where(paid: false) }
|
scope :unpaid, -> { where(paid: false) }
|
||||||
scope :by_conference, ->(conference) { where(conference_id: conference.id) }
|
scope :by_conference, ->(conference) { where(conference_id: conference.id) }
|
||||||
scope :by_user, ->(user) { where(user_id: user.id) }
|
scope :by_user, ->(user) { where(user_id: user.id) }
|
||||||
|
|
||||||
|
after_create :set_week
|
||||||
|
|
||||||
def self.purchase(conference, user, purchases)
|
def self.purchase(conference, user, purchases)
|
||||||
errors = []
|
errors = []
|
||||||
|
if count_purchased_registration_tickets(conference, purchases) > 1
|
||||||
|
errors.push('You cannot buy more than one registration tickets.')
|
||||||
|
else
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
conference.tickets.each do |ticket|
|
conference.tickets.each do |ticket|
|
||||||
quantity = purchases[ticket.id.to_s].to_i
|
quantity = purchases[ticket.id.to_s].to_i
|
||||||
# if the user bought the ticket and is still unpaid, just update the quantity
|
# if the user bought the ticket and is still unpaid, just update the quantity
|
||||||
if ticket.bought?(user) && ticket.unpaid?(user)
|
purchase = if ticket.bought?(user) && ticket.unpaid?(user)
|
||||||
purchase = update_quantity(conference, quantity, ticket, user)
|
update_quantity(conference, quantity, ticket, user)
|
||||||
else
|
else
|
||||||
purchase = purchase_ticket(conference, quantity, ticket, user)
|
purchase_ticket(conference, quantity, ticket, user)
|
||||||
end
|
end
|
||||||
|
|
||||||
if purchase && !purchase.save
|
if purchase && !purchase.save
|
||||||
errors.push(purchase.errors.full_messages)
|
errors.push(purchase.errors.full_messages)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
errors.join('. ')
|
errors.join('. ')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -44,7 +53,8 @@ class TicketPurchase < ActiveRecord::Base
|
||||||
conference_id: conference.id,
|
conference_id: conference.id,
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
quantity: quantity,
|
quantity: quantity,
|
||||||
paid: ticket.price_cents.zero?)
|
amount_paid: ticket.price)
|
||||||
|
purchase.pay(nil) if ticket.price_cents.zero?
|
||||||
end
|
end
|
||||||
purchase
|
purchase
|
||||||
end
|
end
|
||||||
|
|
@ -58,4 +68,37 @@ class TicketPurchase < ActiveRecord::Base
|
||||||
purchase.quantity = quantity if quantity > 0
|
purchase.quantity = quantity if quantity > 0
|
||||||
purchase
|
purchase
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def pay(payment)
|
||||||
|
update_attributes(paid: true, payment: payment)
|
||||||
|
PhysicalTicket.transaction do
|
||||||
|
quantity.times { physical_tickets.create }
|
||||||
|
end
|
||||||
|
Mailbot.ticket_confirmation_mail(self).deliver_later
|
||||||
|
end
|
||||||
|
|
||||||
|
def one_registration_ticket_per_user
|
||||||
|
if ticket.try(:registration_ticket?) && quantity != 1
|
||||||
|
errors.add(:quantity, 'cannot be greater than one for registration tickets.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def registration_ticket_already_purchased
|
||||||
|
if ticket.try(:registration_ticket?) && user.tickets.for_registration(conference).present?
|
||||||
|
errors.add(:quantity, 'cannot be greater than one for registration tickets.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_week
|
||||||
|
self.week = created_at.strftime('%W')
|
||||||
|
save!
|
||||||
|
end
|
||||||
|
|
||||||
|
def count_purchased_registration_tickets(conference, purchases)
|
||||||
|
conference.tickets.for_registration.inject(0) do |sum, registration_ticket|
|
||||||
|
sum + purchases[registration_ticket.id.to_s].to_i
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
13
app/models/ticket_scanning.rb
Normal file
13
app/models/ticket_scanning.rb
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
class TicketScanning < ActiveRecord::Base
|
||||||
|
belongs_to :physical_ticket
|
||||||
|
|
||||||
|
before_create :mark_user_present
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def mark_user_present
|
||||||
|
if physical_ticket.ticket.registration_ticket?
|
||||||
|
physical_ticket.user.mark_attendance_for_conference(physical_ticket.conference)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,15 +1,176 @@
|
||||||
class Track < ActiveRecord::Base
|
class Track < ActiveRecord::Base
|
||||||
belongs_to :program
|
include ActiveRecord::Transitions
|
||||||
has_many :events, dependent: :nullify
|
include RevisionCount
|
||||||
|
|
||||||
has_paper_trail only: [:name, :description, :color], meta: { conference_id: :conference_id }
|
resourcify :roles, dependent: :delete_all
|
||||||
|
|
||||||
|
belongs_to :program
|
||||||
|
belongs_to :submitter, class_name: 'User'
|
||||||
|
belongs_to :room
|
||||||
|
belongs_to :selected_schedule, class_name: 'Schedule'
|
||||||
|
has_many :events, dependent: :nullify
|
||||||
|
has_many :schedules
|
||||||
|
|
||||||
|
has_paper_trail ignore: [:updated_at], meta: { conference_id: :conference_id }
|
||||||
|
|
||||||
before_create :generate_guid
|
before_create :generate_guid
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :color, format: /\A#[0-9A-F]{6}\z/
|
validates :color, format: /\A#[0-9A-F]{6}\z/
|
||||||
|
validates :short_name,
|
||||||
|
presence: true,
|
||||||
|
format: /\A[a-zA-Z0-9_-]*\z/,
|
||||||
|
uniqueness: {
|
||||||
|
scope: :program
|
||||||
|
}
|
||||||
|
validates :state,
|
||||||
|
presence: true,
|
||||||
|
inclusion: { in: %w(new to_accept accepted confirmed to_reject rejected canceled withdrawn) }
|
||||||
|
validates :cfp_active, inclusion: { in: [true, false] }
|
||||||
|
validates :start_date, presence: true, if: :self_organized_and_accepted_or_confirmed?
|
||||||
|
validates :end_date, presence: true, if: :self_organized_and_accepted_or_confirmed?
|
||||||
|
validates :room, presence: true, if: :self_organized_and_accepted_or_confirmed?
|
||||||
|
validates :relevance, presence: true, if: :self_organized?
|
||||||
|
validates :description, presence: true, if: :self_organized?
|
||||||
|
validate :dates_within_conference_dates
|
||||||
|
validate :start_date_before_end_date
|
||||||
|
validate :valid_room
|
||||||
|
validate :overlapping
|
||||||
|
|
||||||
before_validation :capitalize_color
|
before_validation :capitalize_color
|
||||||
|
|
||||||
|
scope :accepted, -> { where(state: 'accepted') }
|
||||||
|
scope :confirmed, -> { where(state: 'confirmed') }
|
||||||
|
scope :cfp_active, -> { where(cfp_active: true) }
|
||||||
|
scope :self_organized, -> { where.not(submitter: nil) }
|
||||||
|
|
||||||
|
state_machine initial: :pending do
|
||||||
|
state :new
|
||||||
|
state :to_accept
|
||||||
|
state :accepted
|
||||||
|
state :confirmed
|
||||||
|
state :to_reject
|
||||||
|
state :rejected
|
||||||
|
state :canceled
|
||||||
|
state :withdrawn
|
||||||
|
|
||||||
|
event :restart do
|
||||||
|
transitions to: :new, from: [:rejected, :withdrawn, :canceled]
|
||||||
|
end
|
||||||
|
event :to_accept do
|
||||||
|
transitions to: :to_accept, from: [:new, :to_reject]
|
||||||
|
end
|
||||||
|
event :accept do
|
||||||
|
transitions to: :accepted, from: [:new, :to_accept], on_transition: :create_organizer_role
|
||||||
|
end
|
||||||
|
event :confirm do
|
||||||
|
transitions to: :confirmed, from: [:accepted], on_transition: :assign_role_to_submitter
|
||||||
|
end
|
||||||
|
event :to_reject do
|
||||||
|
transitions to: :to_reject, from: [:new, :to_accept]
|
||||||
|
end
|
||||||
|
event :reject do
|
||||||
|
transitions to: :rejected, from: [:new, :to_reject]
|
||||||
|
end
|
||||||
|
event :cancel do
|
||||||
|
transitions to: :canceled, from: [:to_accept, :to_reject, :accepted, :confirmed], on_transition: :revoke_role_and_cleanup
|
||||||
|
end
|
||||||
|
event :withdraw do
|
||||||
|
transitions to: :withdrawn, from: [:new, :to_accept, :to_reject, :accepted, :confirmed], on_transition: :revoke_role_and_cleanup
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def conference
|
||||||
|
program.conference
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Checks if the track is self-organized
|
||||||
|
# ====Returns
|
||||||
|
# * +true+ -> If the track has a submitter
|
||||||
|
# * +false+ -> if the track doesn't have a submitter
|
||||||
|
def self_organized?
|
||||||
|
return true if submitter
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_param
|
||||||
|
short_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def transition_possible?(transition)
|
||||||
|
self.class.state_machine.events_for(current_state).include?(transition)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Gives the role of the track_organizer to the submitter
|
||||||
|
def assign_role_to_submitter
|
||||||
|
submitter.add_role 'track_organizer', self
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Revokes the track organizer role, destroys the track's schedule, removes the
|
||||||
|
# track from events that have it set and reverts their state to new
|
||||||
|
#
|
||||||
|
def revoke_role_and_cleanup
|
||||||
|
role = Role.find_by(name: 'track_organizer', resource: self)
|
||||||
|
|
||||||
|
if role
|
||||||
|
role.users.each do |user|
|
||||||
|
user.remove_role 'track_organizer', self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.selected_schedule_id = nil
|
||||||
|
save!
|
||||||
|
|
||||||
|
schedules.each(&:destroy!)
|
||||||
|
|
||||||
|
events.each do |event|
|
||||||
|
event.track = nil
|
||||||
|
event.state = 'new'
|
||||||
|
event.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Checks if the track is accepted
|
||||||
|
# ====Returns
|
||||||
|
# * +true+ -> If the track's state is 'accepted'
|
||||||
|
# * +false+ -> If the track's state isn't 'accepted'
|
||||||
|
def accepted?
|
||||||
|
state == 'accepted'
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Checks if the track is confirmed
|
||||||
|
# ====Returns
|
||||||
|
# * +true+ -> If the track's state is 'confirmed'
|
||||||
|
# * +false+ -> If the track's state isn't 'confirmed'
|
||||||
|
def confirmed?
|
||||||
|
state == 'confirmed'
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Checks if a self-organized track is accepted or confirmed
|
||||||
|
# ====Returns
|
||||||
|
# * +true+ -> If the track's state is 'accepted' or 'confirmed'
|
||||||
|
# * +false+ -> If the track's state is neither 'accepted' nor 'confirmed'
|
||||||
|
def self_organized_and_accepted_or_confirmed?
|
||||||
|
self_organized? && (accepted? || confirmed?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_state(transition)
|
||||||
|
error = ''
|
||||||
|
|
||||||
|
begin
|
||||||
|
send(transition)
|
||||||
|
rescue Transitions::InvalidTransition => e
|
||||||
|
error += "State update failed. #{e.message} "
|
||||||
|
end
|
||||||
|
|
||||||
|
error += errors.full_messages.join(', ') unless save
|
||||||
|
error
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def generate_guid
|
def generate_guid
|
||||||
|
|
@ -27,4 +188,51 @@ class Track < ActiveRecord::Base
|
||||||
def conference_id
|
def conference_id
|
||||||
program.conference_id
|
program.conference_id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Creates the role of the track organizer
|
||||||
|
def create_organizer_role
|
||||||
|
Role.where(name: 'track_organizer', resource: self).first_or_create(description: 'For the organizers of the Track')
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Verify that the track's dates are between the conference's dates
|
||||||
|
#
|
||||||
|
def dates_within_conference_dates
|
||||||
|
return unless start_date && end_date && program.try(:conference).try(:start_date) && program.try(:conference).try(:end_date)
|
||||||
|
errors.add(:start_date, "can't be outside of the conference's dates (#{program.conference.start_date}-#{program.conference.end_date})") unless (program.conference.start_date..program.conference.end_date).cover?(start_date)
|
||||||
|
errors.add(:end_date, "can't be outside of the conference's dates (#{program.conference.start_date}-#{program.conference.end_date})") unless (program.conference.start_date..program.conference.end_date).cover?(end_date)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Verify that the start date isn't after the end date
|
||||||
|
#
|
||||||
|
def start_date_before_end_date
|
||||||
|
return unless start_date && end_date
|
||||||
|
errors.add(:start_date, 'can\'t be after the end date') if start_date > end_date
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Verify that the room is a room of the conference
|
||||||
|
#
|
||||||
|
def valid_room
|
||||||
|
return unless room.try(:venue).try(:conference) && program.try(:conference)
|
||||||
|
errors.add(:room, "must be a room of #{program.conference.venue.name}") unless room.venue.conference == program.conference
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Check that there is no other track in the same room with overlapping dates
|
||||||
|
#
|
||||||
|
def overlapping
|
||||||
|
return unless start_date && end_date && room && program.try(:tracks)
|
||||||
|
(program.tracks.accepted + program.tracks.confirmed - [self]).each do |existing_track|
|
||||||
|
next unless existing_track.room == room && existing_track.start_date && existing_track.end_date
|
||||||
|
if start_date >= existing_track.start_date && start_date <= existing_track.end_date ||
|
||||||
|
end_date >= existing_track.start_date && end_date <= existing_track.end_date ||
|
||||||
|
start_date <= existing_track.start_date && end_date >= existing_track.end_date
|
||||||
|
errors.add(:track, 'has overlapping dates with a confirmed or accepted track in the same room')
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,11 @@ end
|
||||||
|
|
||||||
class User < ActiveRecord::Base
|
class User < ActiveRecord::Base
|
||||||
rolify
|
rolify
|
||||||
|
has_many :physical_tickets, through: :ticket_purchases do
|
||||||
|
def by_conference(conference)
|
||||||
|
where('ticket_purchases.conference_id = ?', conference)
|
||||||
|
end
|
||||||
|
end
|
||||||
has_many :users_roles
|
has_many :users_roles
|
||||||
has_many :roles, through: :users_roles, dependent: :destroy
|
has_many :roles, through: :users_roles, dependent: :destroy
|
||||||
|
|
||||||
|
|
@ -25,10 +30,10 @@ class User < ActiveRecord::Base
|
||||||
# :lockable, :timeoutable and :omniauthable
|
# :lockable, :timeoutable and :omniauthable
|
||||||
devise_modules = []
|
devise_modules = []
|
||||||
|
|
||||||
if ENV['OSEM_ICHAIN_ENABLED'] == 'true'
|
devise_modules += if ENV['OSEM_ICHAIN_ENABLED'] == 'true'
|
||||||
devise_modules += [ :ichain_authenticatable, :ichain_registerable, :omniauthable, omniauth_providers: [] ]
|
[:ichain_authenticatable, :ichain_registerable, :omniauthable, omniauth_providers: []]
|
||||||
else
|
else
|
||||||
devise_modules += [:database_authenticatable, :registerable,
|
[:database_authenticatable, :registerable,
|
||||||
:recoverable, :rememberable, :trackable, :validatable, :confirmable,
|
:recoverable, :rememberable, :trackable, :validatable, :confirmable,
|
||||||
:omniauthable, omniauth_providers: [:suse, :google, :facebook, :github]]
|
:omniauthable, omniauth_providers: [:suse, :google, :facebook, :github]]
|
||||||
end
|
end
|
||||||
|
|
@ -42,14 +47,26 @@ class User < ActiveRecord::Base
|
||||||
has_many :event_users, dependent: :destroy
|
has_many :event_users, dependent: :destroy
|
||||||
has_many :events, -> { uniq }, through: :event_users
|
has_many :events, -> { uniq }, through: :event_users
|
||||||
has_many :presented_events, -> { joins(:event_users).where(event_users: {event_role: 'speaker'}).uniq }, through: :event_users, source: :event
|
has_many :presented_events, -> { joins(:event_users).where(event_users: {event_role: 'speaker'}).uniq }, through: :event_users, source: :event
|
||||||
has_many :registrations, dependent: :destroy
|
has_many :registrations, dependent: :destroy do
|
||||||
|
def for_conference conference
|
||||||
|
where(conference: conference).first
|
||||||
|
end
|
||||||
|
end
|
||||||
has_many :events_registrations, through: :registrations
|
has_many :events_registrations, through: :registrations
|
||||||
has_many :ticket_purchases, dependent: :destroy
|
has_many :ticket_purchases, dependent: :destroy
|
||||||
has_many :payments, dependent: :destroy
|
has_many :payments, dependent: :destroy
|
||||||
has_many :tickets, through: :ticket_purchases, source: :ticket
|
has_many :tickets, through: :ticket_purchases, source: :ticket do
|
||||||
|
def for_registration conference
|
||||||
|
where(conference: conference, registration_ticket: true).first
|
||||||
|
end
|
||||||
|
end
|
||||||
has_many :votes, dependent: :destroy
|
has_many :votes, dependent: :destroy
|
||||||
has_many :voted_events, through: :votes, source: :events
|
has_many :voted_events, through: :votes, source: :events
|
||||||
has_many :subscriptions, dependent: :destroy
|
has_many :subscriptions, dependent: :destroy
|
||||||
|
has_many :tracks, foreign_key: 'submitter_id'
|
||||||
|
has_many :booth_requests
|
||||||
|
has_many :booth_requests, dependent: :destroy
|
||||||
|
has_many :booths, through: :booth_requests
|
||||||
accepts_nested_attributes_for :roles
|
accepts_nested_attributes_for :roles
|
||||||
|
|
||||||
scope :admin, -> { where(is_admin: true) }
|
scope :admin, -> { where(is_admin: true) }
|
||||||
|
|
@ -80,6 +97,12 @@ class User < ActiveRecord::Base
|
||||||
event_registration.attended
|
event_registration.attended
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def mark_attendance_for_conference conference
|
||||||
|
registration = registrations.for_conference(conference)
|
||||||
|
registration.attended = true
|
||||||
|
registration.save
|
||||||
|
end
|
||||||
|
|
||||||
def name
|
def name
|
||||||
self[:name].blank? ? username : self[:name]
|
self[:name].blank? ? username : self[:name]
|
||||||
end
|
end
|
||||||
|
|
@ -156,7 +179,11 @@ class User < ActiveRecord::Base
|
||||||
def get_roles
|
def get_roles
|
||||||
result = {}
|
result = {}
|
||||||
roles.each do |role|
|
roles.each do |role|
|
||||||
resource = Conference.find(role.resource_id).short_title
|
resource = if role.resource_type == 'Conference'
|
||||||
|
Conference.find(role.resource_id).short_title
|
||||||
|
elsif role.resource_type == 'Track'
|
||||||
|
Track.find(role.resource_id).name
|
||||||
|
end
|
||||||
if result[role.name].nil?
|
if result[role.name].nil?
|
||||||
result[role.name] = [resource]
|
result[role.name] = [resource]
|
||||||
else
|
else
|
||||||
|
|
|
||||||
92
app/pdfs/ticket_pdf.rb
Normal file
92
app/pdfs/ticket_pdf.rb
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
class TicketPdf < Prawn::Document
|
||||||
|
def initialize(conference, user, physical_ticket, ticket_layout, file_name)
|
||||||
|
super(page_layout: ticket_layout, page_size: 'A4', filename: file_name)
|
||||||
|
@user = user
|
||||||
|
@physical_ticket = physical_ticket
|
||||||
|
@conference = conference
|
||||||
|
|
||||||
|
@left = bounds.left
|
||||||
|
@right = bounds.right
|
||||||
|
@mid_vertical = (bounds.top - bounds.bottom) / 2
|
||||||
|
@mid_horizontal = (bounds.right - bounds.left) / 2
|
||||||
|
@x = 0
|
||||||
|
|
||||||
|
draw_first_square
|
||||||
|
draw_second_square
|
||||||
|
draw_third_square
|
||||||
|
draw_fourth_square
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_first_square
|
||||||
|
move_down @mid_vertical
|
||||||
|
dash(2, space: 1)
|
||||||
|
stroke_horizontal_rule
|
||||||
|
stroke_vertical_line bounds.top, bounds.bottom, at: @mid_horizontal
|
||||||
|
move_up @mid_vertical
|
||||||
|
draw_text 'TICKET HOLDER', at: [@x, cursor - 30], size: 17
|
||||||
|
dash(2, space: 0)
|
||||||
|
bounding_box [@x, cursor - 50], width: 230, height: 150 do
|
||||||
|
pad(15) do
|
||||||
|
text_box 'NAME', at: [@x + 10, cursor], size: 13
|
||||||
|
fill_color '808080'
|
||||||
|
text_box @user.name.to_s, at: [@x + 10, cursor - 20], size: 18
|
||||||
|
fill_color '000000'
|
||||||
|
text_box 'EMAIL', at: [@x + 10, cursor - 60], size: 13
|
||||||
|
fill_color '808080'
|
||||||
|
text_box @user.email.to_s, at: [@x + 10, cursor - 80], size: 18, overflow: :shrink_to_fit
|
||||||
|
fill_color '000000'
|
||||||
|
end
|
||||||
|
stroke_bounds
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_second_square
|
||||||
|
move_up 150
|
||||||
|
if @conference.picture?
|
||||||
|
if 7 * @conference.picture.image[:width] > 12 * @conference.picture.image[:height]
|
||||||
|
image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], width: 120
|
||||||
|
else
|
||||||
|
image "#{Rails.root}/public#{@conference.picture_url}", at: [@mid_horizontal + 30, cursor], height: 70
|
||||||
|
end
|
||||||
|
else
|
||||||
|
image "#{Rails.root}/public/img/osem-logo.png", at: [@mid_horizontal + 30, cursor], height: 70
|
||||||
|
end
|
||||||
|
move_down 70
|
||||||
|
draw_text @conference.title.to_s, at: [@mid_horizontal + 30, cursor - 30], size: 12
|
||||||
|
draw_text @conference.organization.name.to_s, at: [@mid_horizontal + 30, cursor - 50], size: 12
|
||||||
|
if @conference.venue
|
||||||
|
draw_text @conference.venue.name, at: [@mid_horizontal + 30, cursor - 70]
|
||||||
|
draw_text @conference.venue.street, at: [@mid_horizontal + 30, cursor - 90]
|
||||||
|
draw_text @conference.venue.city, at: [@mid_horizontal + 30, cursor - 110]
|
||||||
|
end
|
||||||
|
move_up 130
|
||||||
|
move_down @mid_vertical
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_third_square
|
||||||
|
draw_text 'EVENT', at: [@x, cursor - 40], size: 15
|
||||||
|
fill_color '808080'
|
||||||
|
draw_text @conference.title.to_s, at: [@x, cursor - 60], size: 12
|
||||||
|
draw_text @conference.start_date.strftime('%B %d, %Y').to_s, at: [@x, cursor - 80], size: 12
|
||||||
|
move_down 80
|
||||||
|
fill_color '000000'
|
||||||
|
draw_text 'TICKET', at: [@x, cursor - 30], size: 15
|
||||||
|
fill_color '808080'
|
||||||
|
draw_text @physical_ticket.ticket.title.to_s, at: [@x, cursor - 50], size: 12
|
||||||
|
move_down 50
|
||||||
|
fill_color '000000'
|
||||||
|
draw_text 'TICKET REF.', at: [@x, cursor - 30], size: 15
|
||||||
|
fill_color '808080'
|
||||||
|
draw_text @physical_ticket.ticket_purchase.id.to_s, at: [@x, cursor - 50], size: 12
|
||||||
|
move_down 50
|
||||||
|
fill_color '000000'
|
||||||
|
draw_text 'Powered By OSEM', at: [(@mid_horizontal - @left - 100) / 2, cursor - 100], size: 11
|
||||||
|
move_up 180
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_fourth_square
|
||||||
|
x = @mid_horizontal + (@right - @mid_horizontal - 180) / 2
|
||||||
|
y = cursor - (bounds.top - @mid_vertical - 180) / 2
|
||||||
|
print_qr_code(@physical_ticket.token, pos: [x, y], extent: 180, stroke: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -52,6 +52,10 @@ class PictureUploader < CarrierWave::Uploader::Base
|
||||||
"system/#{object_class_name}/#{mounted_as}/#{model.id}"
|
"system/#{object_class_name}/#{mounted_as}/#{model.id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def image
|
||||||
|
@image ||= MiniMagick::Image.open(file.file)
|
||||||
|
end
|
||||||
|
|
||||||
# Create different versions of your uploaded files:
|
# Create different versions of your uploaded files:
|
||||||
version :large do
|
version :large do
|
||||||
process resize_to_fit: [300, 300]
|
process resize_to_fit: [300, 300]
|
||||||
|
|
|
||||||
49
app/views/admin/booths/_change_state_dropdown.html.haml
Normal file
49
app/views/admin/booths/_change_state_dropdown.html.haml
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
- if booth.transition_possible? :accept
|
||||||
|
- if can? :accept, booth
|
||||||
|
- if @conference.booth_limit > 0
|
||||||
|
- confirm_message = ' You are able to accept '+ pluralize(@conference.booth_limit - (@conference.booths.accepted.count + @conference.booths.confirmed.count), 'more booth') + " (booth limit set to #{@conference.booth_limit}). Are you sure you want to accept this one?"
|
||||||
|
- if @conference.email_settings.send_on_booths_acceptance
|
||||||
|
- link = 'Accept with email'
|
||||||
|
- confirm_message = "By accepting this booth, an email will be sent informing the submitter for the acceptance. You may change the state to \'To accept\' until you are completely sure." + confirm_message
|
||||||
|
- else
|
||||||
|
- link = 'Accept booth'
|
||||||
|
%li= link_to link,
|
||||||
|
accept_admin_conference_booth_path(@conference.short_title, booth),
|
||||||
|
method: :patch ,id: "accept_booth_#{booth.id}",
|
||||||
|
data: (confirm_message ? { confirm: confirm_message } : nil)
|
||||||
|
|
||||||
|
- if booth.transition_possible? :reject
|
||||||
|
- if @conference.email_settings.send_on_booths_rejection
|
||||||
|
- link = 'Reject with email'
|
||||||
|
- else
|
||||||
|
- link = 'Reject'
|
||||||
|
%li= link_to link,
|
||||||
|
reject_admin_conference_booth_path(@conference.short_title, booth),
|
||||||
|
method: :patch, id: "reject_booth_#{booth.id}",
|
||||||
|
data: (@conference.email_settings.send_on_booths_rejection ? { confirm: 'By rejecting this booth, an email will be sent informing the submitter about the rejection. You may change the state to \'To reject\' until you are completely sure.'} : nil)
|
||||||
|
|
||||||
|
- if booth.transition_possible? :to_reject
|
||||||
|
%li= link_to 'To reject booth',
|
||||||
|
to_reject_admin_conference_booth_path(@conference.short_title, booth),
|
||||||
|
method: :patch, id: "to_reject_booth_#{booth.id}"
|
||||||
|
|
||||||
|
- if booth.transition_possible? :restart
|
||||||
|
%li= link_to 'Start review',
|
||||||
|
restart_admin_conference_booth_path(@conference.short_title, booth),
|
||||||
|
method: :patch, id: "restart_booth_#{booth.id}"
|
||||||
|
|
||||||
|
- if booth.transition_possible? :to_accept
|
||||||
|
%li= link_to 'To accept booth',
|
||||||
|
to_accept_admin_conference_booth_path(@conference.short_title, booth),
|
||||||
|
method: :patch, id: "to_accept_booth_#{booth.id}"
|
||||||
|
|
||||||
|
- if booth.transition_possible? :cancel
|
||||||
|
%li= link_to 'Cancel booth',
|
||||||
|
cancel_admin_conference_booth_path(@conference.short_title, booth),
|
||||||
|
method: :patch, id: "cancel_booth_#{booth.id}"
|
||||||
|
|
||||||
|
- if booth.transition_possible? :confirm
|
||||||
|
%li= link_to 'Confirm booth',
|
||||||
|
confirm_admin_conference_booth_path(@conference.short_title, booth),
|
||||||
|
method: :patch, id: "confirm_booth_#{booth.id}"
|
||||||
5
app/views/admin/booths/edit.html.haml
Normal file
5
app/views/admin/booths/edit.html.haml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
%h1
|
||||||
|
Editing
|
||||||
|
= @booth.title
|
||||||
|
|
||||||
|
= render 'booths/form'
|
||||||
78
app/views/admin/booths/index.html.haml
Normal file
78
app/views/admin/booths/index.html.haml
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
.row
|
||||||
|
.col-md-12
|
||||||
|
.page-header
|
||||||
|
%h1
|
||||||
|
Booths
|
||||||
|
= "(#{@booths.length})" if @booths.any?
|
||||||
|
%p.text-muted
|
||||||
|
All the booth requests
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-md-12
|
||||||
|
%h4
|
||||||
|
- if @conference.booth_limit == 0
|
||||||
|
%p
|
||||||
|
Set the
|
||||||
|
= link_to 'Booth limit', edit_admin_conference_path(@conference.short_title)
|
||||||
|
to make sure you are not accepting more booths than you can accommodate.
|
||||||
|
- elsif !@conference.maximum_accepted_booths?
|
||||||
|
%p
|
||||||
|
You cannot accept more than
|
||||||
|
%b
|
||||||
|
= pluralize(@conference.booth_limit, 'booth')
|
||||||
|
(
|
||||||
|
= pluralize(@conference.booths.accepted.count + @conference.booths.confirmed.count, 'accepted booth')
|
||||||
|
so far)
|
||||||
|
- else
|
||||||
|
%p
|
||||||
|
You have reached the maximum number of accepted booths.
|
||||||
|
(
|
||||||
|
= link_to "#{@conference.booth_limit} booths", edit_admin_conference_path(@conference.short_title)
|
||||||
|
)
|
||||||
|
- if @booths.any?
|
||||||
|
%table.table.table-striped.table-bordered.table-hover.datatable
|
||||||
|
%thead
|
||||||
|
%th
|
||||||
|
%b ID
|
||||||
|
%th
|
||||||
|
%b Logo
|
||||||
|
%th
|
||||||
|
%b Title
|
||||||
|
%th
|
||||||
|
%b Submitter
|
||||||
|
%th
|
||||||
|
%b Responsibles
|
||||||
|
%th
|
||||||
|
%b State
|
||||||
|
%th
|
||||||
|
%b Actions
|
||||||
|
- @booths.each do |booth|
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
= booth.id
|
||||||
|
%td
|
||||||
|
- if booth.logo_link
|
||||||
|
= image_tag(booth.picture.thumb.url, width: '20%')
|
||||||
|
%td
|
||||||
|
= link_to booth.title, admin_conference_booth_path(@conference.short_title, booth)
|
||||||
|
%td
|
||||||
|
= link_to booth.submitter.name, admin_user_path(booth.submitter) if booth.submitter
|
||||||
|
%td
|
||||||
|
.responsibles
|
||||||
|
- booth.responsibles.each_with_index do |responsible, i|
|
||||||
|
= link_to responsible.name, admin_user_path(responsible)
|
||||||
|
= ", " unless i == booth.responsibles.length - 1
|
||||||
|
%td
|
||||||
|
.btn-group
|
||||||
|
%button{ type: 'button', class: 'btn btn-link dropdown-toggle', 'data-toggle' => 'dropdown' }
|
||||||
|
= booth.state.humanize
|
||||||
|
%span.caret
|
||||||
|
%ul.dropdown-menu{ role: 'menu' }
|
||||||
|
= render 'change_state_dropdown', booth: booth
|
||||||
|
%td
|
||||||
|
= link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, booth.id),
|
||||||
|
class: 'btn btn-primary'
|
||||||
|
.row
|
||||||
|
.col-md-12.text-right
|
||||||
|
- if can? :create, Booth
|
||||||
|
= link_to 'New Booth', new_admin_conference_booth_path(@conference.short_title), class: 'button btn btn-primary'
|
||||||
3
app/views/admin/booths/new.html.haml
Normal file
3
app/views/admin/booths/new.html.haml
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
%h1 New booth
|
||||||
|
|
||||||
|
= render 'booths/form'
|
||||||
58
app/views/admin/booths/show.html.haml
Normal file
58
app/views/admin/booths/show.html.haml
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
.row
|
||||||
|
.col-md-12
|
||||||
|
%h3
|
||||||
|
= image_tag(@booth.picture.thumb.url, size: '20%', alt: '')
|
||||||
|
= @booth.title
|
||||||
|
.btn-group.pull-right
|
||||||
|
= link_to 'Edit', edit_admin_conference_booth_path(@conference.short_title, @booth), class: 'btn btn-mini btn-primary'
|
||||||
|
|
||||||
|
.row
|
||||||
|
.col-md-12
|
||||||
|
%table.table
|
||||||
|
%tr
|
||||||
|
%td.col-md-2
|
||||||
|
%b Description
|
||||||
|
%td
|
||||||
|
= markdown(@booth.description)
|
||||||
|
%tr
|
||||||
|
%td.col-md-2
|
||||||
|
%b Reasoning
|
||||||
|
%td
|
||||||
|
= markdown(@booth.reasoning)
|
||||||
|
%tr
|
||||||
|
%td.col-md-2
|
||||||
|
%b Website
|
||||||
|
%td
|
||||||
|
- if @booth.website_url.present?
|
||||||
|
= link_to @booth.website_url, @booth.website_url
|
||||||
|
%tr
|
||||||
|
%td.col-md-2
|
||||||
|
%b Submitter
|
||||||
|
%td
|
||||||
|
= link_to @booth.submitter.name, admin_user_path(@booth.submitter)
|
||||||
|
%tr
|
||||||
|
%td.col-md-2
|
||||||
|
%b Submitter's relationship
|
||||||
|
%td
|
||||||
|
= @booth.submitter_relationship
|
||||||
|
%tr
|
||||||
|
%td.col-md-2
|
||||||
|
%b Responsibles
|
||||||
|
%td
|
||||||
|
- @booth.responsibles.each_with_index do |responsibles, i|
|
||||||
|
.responsibles
|
||||||
|
= link_to responsibles.name, admin_user_path(responsibles)
|
||||||
|
(
|
||||||
|
= responsibles.email
|
||||||
|
)
|
||||||
|
= " , " unless i == @booth.responsibles.length - 1
|
||||||
|
%tr
|
||||||
|
%td.col-md-2
|
||||||
|
%b Submitted on
|
||||||
|
%td
|
||||||
|
= @booth.created_at
|
||||||
|
%tr
|
||||||
|
%td.col-md-2
|
||||||
|
%b Last updated on
|
||||||
|
%td
|
||||||
|
= @booth.updated_at
|
||||||
16
app/views/admin/cfps/_booths_cfp.html.haml
Normal file
16
app/views/admin/cfps/_booths_cfp.html.haml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
%dt
|
||||||
|
Type:
|
||||||
|
%dd
|
||||||
|
= @cfp.cfp_type.capitalize
|
||||||
|
%dt
|
||||||
|
Start Date:
|
||||||
|
%dd
|
||||||
|
= @cfp.start_date.strftime('%A, %B %e. %Y')
|
||||||
|
%dt
|
||||||
|
End Date:
|
||||||
|
%dd
|
||||||
|
= @cfp.end_date.strftime('%A, %B %e. %Y')
|
||||||
|
%dt
|
||||||
|
Days Left:
|
||||||
|
%dd
|
||||||
|
= pluralize(@cfp.remaining_days, 'day')
|
||||||
42
app/views/admin/cfps/_events_cfp.html.haml
Normal file
42
app/views/admin/cfps/_events_cfp.html.haml
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
%dt
|
||||||
|
Type:
|
||||||
|
%dd
|
||||||
|
= @cfp.cfp_type.capitalize
|
||||||
|
%dt
|
||||||
|
Start Date:
|
||||||
|
%dd#start_date
|
||||||
|
= @cfp.start_date.strftime('%A, %B %-d. %Y')
|
||||||
|
%dt
|
||||||
|
End Date:
|
||||||
|
%dd#end_date
|
||||||
|
= @cfp.end_date.strftime('%A, %B %-d. %Y')
|
||||||
|
%dt
|
||||||
|
Days Left:
|
||||||
|
%dd
|
||||||
|
= pluralize(@cfp.remaining_days, 'day')
|
||||||
|
%dt
|
||||||
|
Event types:
|
||||||
|
%dd
|
||||||
|
= event_types(@conference)
|
||||||
|
%dt
|
||||||
|
Tracks:
|
||||||
|
%dd
|
||||||
|
= tracks(@conference)
|
||||||
|
%dt
|
||||||
|
Public Schedule:
|
||||||
|
%dd#schedule_public
|
||||||
|
- if @program.schedule_public
|
||||||
|
Yes
|
||||||
|
- else
|
||||||
|
No
|
||||||
|
%dt
|
||||||
|
Schedule changeable?
|
||||||
|
%dd#schedule_changes
|
||||||
|
- if @program.schedule_fluid
|
||||||
|
Yes
|
||||||
|
- else
|
||||||
|
No
|
||||||
|
%dt
|
||||||
|
Rating Levels:
|
||||||
|
%dd#rating
|
||||||
|
= @program.rating
|
||||||
|
|
@ -4,8 +4,9 @@
|
||||||
%h1 Call for Papers
|
%h1 Call for Papers
|
||||||
.row
|
.row
|
||||||
.col-md-8
|
.col-md-8
|
||||||
= semantic_form_for(@cfp, url: admin_conference_program_cfp_path(@conference.short_title), html: {multipart: true}) do |f|
|
= semantic_form_for(@cfp, url: (@cfp.new_record? ? admin_conference_program_cfps_path : admin_conference_program_cfp_path(@conference.short_title, @cfp)), html: {multipart: true}) do |f|
|
||||||
= f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, readonly: 'readonly' }
|
= f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', start_date: @conference.start_date, end_date: @conference.end_date, readonly: 'readonly' }
|
||||||
= f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly' }
|
= f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly' }
|
||||||
|
= f.input :cfp_type, as: :select, collection: (@cfp.new_record? ? @program.remaining_cfp_types : [@cfp.cfp_type] + @program.remaining_cfp_types).map {|type| ["#{type.capitalize}", type]}, include_blank: false, label: 'Type', input_html: { class: 'select-help-toggle' }
|
||||||
%p.text-right
|
%p.text-right
|
||||||
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }
|
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }
|
||||||
|
|
|
||||||
16
app/views/admin/cfps/_tracks_cfp.html.haml
Normal file
16
app/views/admin/cfps/_tracks_cfp.html.haml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
%dt
|
||||||
|
Type:
|
||||||
|
%dd
|
||||||
|
= @cfp.cfp_type.capitalize
|
||||||
|
%dt
|
||||||
|
Start Date:
|
||||||
|
%dd#start_date
|
||||||
|
= @cfp.start_date.strftime('%A, %B %-d. %Y')
|
||||||
|
%dt
|
||||||
|
End Date:
|
||||||
|
%dd#end_date
|
||||||
|
= @cfp.end_date.strftime('%A, %B %-d. %Y')
|
||||||
|
%dt
|
||||||
|
Days Left:
|
||||||
|
%dd
|
||||||
|
= pluralize(@cfp.remaining_days, 'day')
|
||||||
36
app/views/admin/cfps/index.html.haml
Normal file
36
app/views/admin/cfps/index.html.haml
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
.row
|
||||||
|
.col-md-12
|
||||||
|
.page-header
|
||||||
|
%h1 Call for Papers
|
||||||
|
%p.text-muted
|
||||||
|
Call for people to submit events to your conference
|
||||||
|
- if @program.cfps
|
||||||
|
.row
|
||||||
|
.col-md-12
|
||||||
|
%table.table.table-hover.datatable#tickets
|
||||||
|
%thead
|
||||||
|
%th Type
|
||||||
|
%th Start Date
|
||||||
|
%th End Date
|
||||||
|
%th Days Left
|
||||||
|
%th Actions
|
||||||
|
%tbody
|
||||||
|
- @program.cfps.each do |cfp|
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
= link_to(admin_conference_program_cfp_path(@conference.short_title, cfp.id)) do
|
||||||
|
= cfp.cfp_type.capitalize
|
||||||
|
%td
|
||||||
|
= cfp.start_date.strftime('%A, %B %-d. %Y')
|
||||||
|
%td
|
||||||
|
= cfp.end_date.strftime('%A, %B %-d. %Y')
|
||||||
|
%td
|
||||||
|
= pluralize(cfp.remaining_days, 'day')
|
||||||
|
%td
|
||||||
|
.btn-group
|
||||||
|
= link_to 'Edit', edit_admin_conference_program_cfp_path(@conference.short_title, cfp.id), method: :get, class: 'btn btn-primary'
|
||||||
|
= link_to 'Delete', admin_conference_program_cfp_path(@conference.short_title, cfp.id), method: 'delete', class: 'btn btn-danger', data: { confirm: 'Are you sure you want to delete the CfP?' }
|
||||||
|
- if can? :new, @program.cfps.new
|
||||||
|
.row
|
||||||
|
.col-md-12.text-right
|
||||||
|
= link_to 'Create Call for Papers', new_admin_conference_program_cfp_path(@conference.short_title), class: 'btn btn-primary'
|
||||||
|
|
@ -4,55 +4,13 @@
|
||||||
%h1 Call for Papers
|
%h1 Call for Papers
|
||||||
%p.text-muted
|
%p.text-muted
|
||||||
Call for people to submit events to your conference
|
Call for people to submit events to your conference
|
||||||
- if @cfp
|
|
||||||
.row
|
.row
|
||||||
.col-md-8
|
.col-md-8
|
||||||
%dl.dl-horizontal
|
%dl.dl-horizontal
|
||||||
%dt
|
= render "#{@cfp.cfp_type}_cfp"
|
||||||
Start Date:
|
|
||||||
%dd#start_date
|
|
||||||
= @cfp.start_date.strftime('%A, %B %-d. %Y')
|
|
||||||
%dt
|
|
||||||
End Date:
|
|
||||||
%dd#end_date
|
|
||||||
= @cfp.end_date.strftime('%A, %B %-d. %Y')
|
|
||||||
%dt
|
|
||||||
Days Left:
|
|
||||||
%dd
|
|
||||||
= pluralize(@cfp.remaining_days, 'day')
|
|
||||||
%dt
|
|
||||||
Event types:
|
|
||||||
%dd
|
|
||||||
= event_types(@conference)
|
|
||||||
%dt
|
|
||||||
Tracks:
|
|
||||||
%dd
|
|
||||||
= tracks(@conference)
|
|
||||||
%dt
|
|
||||||
Public Schedule
|
|
||||||
%dd#schedule_public
|
|
||||||
- if @program.schedule_public
|
|
||||||
Yes
|
|
||||||
- else
|
|
||||||
No
|
|
||||||
%dt
|
|
||||||
Schedule changeable?
|
|
||||||
%dd#schedule_changes
|
|
||||||
- if @program.schedule_fluid
|
|
||||||
Yes
|
|
||||||
- else
|
|
||||||
No
|
|
||||||
%dt
|
|
||||||
Rating Levels
|
|
||||||
%dd#rating
|
|
||||||
= @program.rating
|
|
||||||
.row
|
.row
|
||||||
.col-md-12.text-right
|
.col-md-12.text-right
|
||||||
= link_to(edit_admin_conference_program_cfp_path(@conference.short_title), class: 'btn btn-primary') do
|
= link_to(edit_admin_conference_program_cfp_path(@conference.short_title, @cfp.id), class: 'btn btn-primary') do
|
||||||
Edit
|
Edit
|
||||||
= link_to(admin_conference_program_cfp_path(@conference.short_title), method: 'delete', class: 'btn btn-danger', data: { confirm: 'Are you sure you want to delete the CfP?' }) do
|
= link_to(admin_conference_program_cfp_path(@conference.short_title, @cfp.id), method: 'delete', class: 'btn btn-danger', data: { confirm: 'Are you sure you want to delete the CfP?' }) do
|
||||||
Delete
|
Delete
|
||||||
- else
|
|
||||||
.row
|
|
||||||
.col-md-12.text-right
|
|
||||||
= link_to 'Create Call for Papers', new_admin_conference_program_cfp_path(@conference.short_title), class: 'btn btn-primary'
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,23 @@
|
||||||
.text-center
|
.text-center
|
||||||
%h4 #{title}
|
%h4 #{title}
|
||||||
%canvas.doughnut_chart{ 'data-chart' => data.to_json }
|
%canvas.doughnut_chart{ id: "dough_#{title}", 'data-chart' => data.to_json }
|
||||||
- if data
|
- if data
|
||||||
- data.each do |key, value|
|
- data.each do |key, value|
|
||||||
%span{ 'style' => "border-bottom: 3px solid #{value['color']}" } #{key}: #{value['value']}
|
%span{ 'style' => "border-bottom: 3px solid #{value['color']}" } #{key}: #{value['value']}
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
$(document).ready( function(){
|
||||||
|
|
||||||
|
var d = $("#dough_#{title}");
|
||||||
|
var dt = d.get(0).getContext('2d');
|
||||||
|
|
||||||
|
$(window).resize( respondCanvas );
|
||||||
|
|
||||||
|
function respondCanvas(){
|
||||||
|
dt.canvas.width = 150;
|
||||||
|
dt.canvas.height = 150;
|
||||||
|
}
|
||||||
|
|
||||||
|
respondCanvas();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -27,3 +27,21 @@
|
||||||
%span{ 'style' => "border-bottom: 3px solid #{conference[:color]};", 'data-chart' => "#{name}" }
|
%span{ 'style' => "border-bottom: 3px solid #{conference[:color]};", 'data-chart' => "#{name}" }
|
||||||
%input{ 'type' => 'checkbox', 'name' => "#{conference[:short_title]}" }
|
%input{ 'type' => 'checkbox', 'name' => "#{conference[:short_title]}" }
|
||||||
#{conference[:short_title]}
|
#{conference[:short_title]}
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
$(document).ready( function(){
|
||||||
|
|
||||||
|
var c = $("#line_chart_#{name}");
|
||||||
|
var ct = c.get(0).getContext('2d');
|
||||||
|
var container = $(c).parent();
|
||||||
|
|
||||||
|
$(window).resize( respondCanvas );
|
||||||
|
|
||||||
|
function respondCanvas(){
|
||||||
|
c.attr('width', $(container).width() );
|
||||||
|
c.attr('height', $(container).height() );
|
||||||
|
}
|
||||||
|
|
||||||
|
respondCanvas();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
.list-group
|
.list-group
|
||||||
%li.list-group-item
|
%li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)}" }
|
||||||
%h4
|
%h4
|
||||||
Conference progress
|
Conference progress
|
||||||
.progress
|
.progress
|
||||||
.progress-bar{ 'role' => 'progressbar', 'aria-valuenow' => "#{conference_progress['process']}", 'aria-valuemin' => '0',
|
.progress-bar{ 'role' => 'progressbar', 'aria-valuenow' => "#{conference_progress['process']}", 'aria-valuemin' => '0',
|
||||||
'aria-valuemax' => '100', 'style' => "width: #{conference_progress['process']}%;" }
|
'aria-valuemax' => '100', 'style' => "width: #{conference_progress['process']}%;" }
|
||||||
= conference_progress['process'] + '%'
|
= conference_progress['process'] + '%'
|
||||||
%li{ 'class' => "list-group-item #{class_for_todo(conference_progress['registration'])}" }
|
%li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['registration'])}" }
|
||||||
%span{ 'class' => icon_for_todo(conference_progress['registration']) }
|
%span{ 'class' => icon_for_todo(conference_progress['registration']) }
|
||||||
- if can? :update, @conference
|
- if can? :update, @conference
|
||||||
- if conference.registration_period
|
- if conference.registration_period
|
||||||
|
|
@ -15,13 +15,13 @@
|
||||||
= link_to 'Set up registration period', new_admin_conference_registration_period_path(conference_progress['short_title'])
|
= link_to 'Set up registration period', new_admin_conference_registration_period_path(conference_progress['short_title'])
|
||||||
- else
|
- else
|
||||||
Set up registration period
|
Set up registration period
|
||||||
%li{ 'class' => "list-group-item #{class_for_todo(conference_progress['cfp'])}" }
|
%li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['cfp'])}" }
|
||||||
%span{ 'class' => icon_for_todo(conference_progress['cfp']) }
|
%span{ 'class' => icon_for_todo(conference_progress['cfp']) }
|
||||||
- if can? :update, Cfp.new(program_id: @program.id)
|
- if can? :update, Cfp.new(program_id: @program.id)
|
||||||
= link_to 'Set up call for papers', admin_conference_program_cfp_path(conference_progress['short_title'])
|
= link_to 'Set up call for papers', admin_conference_program_cfps_path(conference_progress['short_title'])
|
||||||
- else
|
- else
|
||||||
Set up call for papers
|
Set up call for papers
|
||||||
%li{'class'=>"list-group-item #{class_for_todo(conference_progress['venue'])}"}
|
%li{'class'=>"list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['venue'])}"}
|
||||||
%span{'class'=>icon_for_todo(conference_progress['venue'])}
|
%span{'class'=>icon_for_todo(conference_progress['venue'])}
|
||||||
- if can? :update, Venue.new(conference: @conference)
|
- if can? :update, Venue.new(conference: @conference)
|
||||||
- @conference.reload
|
- @conference.reload
|
||||||
|
|
@ -32,31 +32,31 @@
|
||||||
- else
|
- else
|
||||||
- @conference.reload
|
- @conference.reload
|
||||||
Add venue
|
Add venue
|
||||||
%li{ 'class' => "list-group-item #{class_for_todo(conference_progress['rooms'])}" }
|
%li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['rooms'])}" }
|
||||||
%span{ 'class' => icon_for_todo(conference_progress['rooms']) }
|
%span{ 'class' => icon_for_todo(conference_progress['rooms']) }
|
||||||
- if @conference.venue && (can? :update, @conference.venue.rooms.build)
|
- if @conference.venue && (can? :update, @conference.venue.rooms.build)
|
||||||
= link_to 'Add rooms', admin_conference_venue_rooms_path(conference_progress['short_title'])
|
= link_to 'Add rooms', admin_conference_venue_rooms_path(conference_progress['short_title'])
|
||||||
- else
|
- else
|
||||||
Add rooms
|
Add rooms
|
||||||
%li{ 'class' => "list-group-item #{class_for_todo(conference_progress['tracks'])}" }
|
%li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['tracks'])}" }
|
||||||
%span{ 'class' => icon_for_todo(conference_progress['tracks']) }
|
%span{ 'class' => icon_for_todo(conference_progress['tracks']) }
|
||||||
- if can? :update, @conference.program.tracks.build
|
- if can? :update, @conference.program.tracks.build
|
||||||
= link_to 'Add tracks', admin_conference_program_tracks_path(conference_progress['short_title'])
|
= link_to 'Add tracks', admin_conference_program_tracks_path(conference_progress['short_title'])
|
||||||
- else
|
- else
|
||||||
Add tracks
|
Add tracks
|
||||||
%li{ 'class' => "list-group-item #{class_for_todo(conference_progress['event_types'])}" }
|
%li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['event_types'])}" }
|
||||||
%span{ 'class' => icon_for_todo(conference_progress['event_types']) }
|
%span{ 'class' => icon_for_todo(conference_progress['event_types']) }
|
||||||
- if can? :update, @conference.program.event_types.build
|
- if can? :update, @conference.program.event_types.build
|
||||||
= link_to 'Add event types', admin_conference_program_event_types_path(conference_progress['short_title'])
|
= link_to 'Add event types', admin_conference_program_event_types_path(conference_progress['short_title'])
|
||||||
- else
|
- else
|
||||||
Add event types
|
Add event types
|
||||||
%li{ 'class' => "list-group-item #{class_for_todo(conference_progress['difficulty_levels'])}" }
|
%li{ 'class' => "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['difficulty_levels'])}" }
|
||||||
%span{ 'class' => icon_for_todo(conference_progress['difficulty_levels']) }
|
%span{ 'class' => icon_for_todo(conference_progress['difficulty_levels']) }
|
||||||
- if can? :update, @conference.program.difficulty_levels.build
|
- if can? :update, @conference.program.difficulty_levels.build
|
||||||
= link_to 'Add difficulty levels', admin_conference_program_difficulty_levels_path(conference_progress['short_title'])
|
= link_to 'Add difficulty levels', admin_conference_program_difficulty_levels_path(conference_progress['short_title'])
|
||||||
- else
|
- else
|
||||||
Add difficulty levels
|
Add difficulty levels
|
||||||
%li{ class: "list-group-item #{class_for_todo(conference_progress['splashpage'])}" }
|
%li{ class: "list-group-item #{hidden_if_conference_over(conference)} #{class_for_todo(conference_progress['splashpage'])}" }
|
||||||
%span{ 'class' => icon_for_todo(conference_progress['splashpage']) }
|
%span{ 'class' => icon_for_todo(conference_progress['splashpage']) }
|
||||||
- if can? :update, @conference
|
- if can? :update, @conference
|
||||||
= link_to 'Set up a Splashpage', admin_conference_splashpage_path(conference_progress['short_title'])
|
= link_to 'Set up a Splashpage', admin_conference_splashpage_path(conference_progress['short_title'])
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
= image_tag @conference.picture.thumb.url
|
= image_tag @conference.picture.thumb.url
|
||||||
= f.input :picture, label: false, hint: 'This will be displayed on the front page.'
|
= f.input :picture, label: false, hint: 'This will be displayed on the front page.'
|
||||||
= f.hidden_field :picture_cache
|
= f.hidden_field :picture_cache
|
||||||
|
= f.input :ticket_layout, as: :select, collection: Conference.ticket_layouts.keys, hint: "Layout type for tickets of the conference."
|
||||||
= f.inputs name: 'Scheduling' do
|
= f.inputs name: 'Scheduling' do
|
||||||
= f.input :timezone, as: :time_zone, hint: 'The conference time zone'
|
= f.input :timezone, as: :time_zone, hint: 'The conference time zone'
|
||||||
= f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', readonly: 'readonly' }
|
= f.input :start_date, as: :string, input_html: { id: 'conference-start-datepicker', readonly: 'readonly' }
|
||||||
|
|
@ -25,4 +26,7 @@
|
||||||
= f.input :end_hour, input_html: {size: 2, type: 'number', min: 1, max: 24}
|
= f.input :end_hour, input_html: {size: 2, type: 'number', min: 1, max: 24}
|
||||||
= f.inputs name: 'Registrations' do
|
= f.inputs name: 'Registrations' do
|
||||||
= f.input :registration_limit, as: :number, in: 0..9999, hint: 'Limit the number of registrations to the conference (0 no limit). Please note that the registration limit doesn\'t apply to speakers of confirmed events (they will still be able to register even if it has been reached). You currently have ' + pluralize(@conference.registrations.count, 'registration')
|
= f.input :registration_limit, as: :number, in: 0..9999, hint: 'Limit the number of registrations to the conference (0 no limit). Please note that the registration limit doesn\'t apply to speakers of confirmed events (they will still be able to register even if it has been reached). You currently have ' + pluralize(@conference.registrations.count, 'registration')
|
||||||
|
= f.inputs name: 'Booths' do
|
||||||
|
= f.input :booth_limit, as: :number, in: 0..9999,
|
||||||
|
hint: 'Booth limit is the maximum number of booths that you can accept for this conference. By setting this number (0 no limit) you can be sure that you are not going to accept more booths than the conference can accommodate. You currently have ' + pluralize(@conference.booths.accepted.count, 'accepted booth') +'.'
|
||||||
= f.action :submit, as: :button, button_html: {class: 'btn btn-primary'}
|
= f.action :submit, as: :button, button_html: {class: 'btn btn-primary'}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue