fe 0.0.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +16 -36
- data/app/assets/javascripts/fe/admin.js +0 -1
- data/app/assets/javascripts/fe/fe.admin.js +40 -16
- data/app/assets/javascripts/fe/fe.common.js +48 -14
- data/app/assets/javascripts/fe/fe.public.js +1 -414
- data/app/assets/javascripts/fe/fe.public.nojquery.js +450 -0
- data/app/assets/javascripts/fe/jquery.validate.pack.js +3 -15
- data/app/assets/stylesheets/360front.css +0 -0
- data/app/assets/stylesheets/fe/fe.screen.css.scss.erb +69 -10
- data/app/controllers/fe/admin/elements_controller.rb +64 -48
- data/app/controllers/fe/admin/email_templates_controller.rb +2 -2
- data/app/controllers/fe/admin/question_pages_controller.rb +1 -1
- data/app/controllers/fe/admin/question_sheets_controller.rb +2 -103
- data/app/controllers/fe/concerns/admin/question_sheets_controller_concern.rb +112 -0
- data/app/controllers/fe/concerns/answer_pages_controller_concern.rb +2 -1
- data/app/controllers/fe/concerns/answer_sheets_controller_concern.rb +1 -1
- data/app/controllers/fe/concerns/application_controller_concern.rb +13 -0
- data/app/controllers/fe/reference_sheets_controller.rb +2 -0
- data/app/controllers/fe/references_controller.rb +1 -0
- data/app/helpers/fe/application_helper.rb +5 -0
- data/app/mailers/fe/notifier.rb +11 -4
- data/app/models/answer_sheet.rb +2 -0
- data/app/models/fe/application.rb +2 -1
- data/app/models/fe/concerns/answer_pages_presenter_concern.rb +10 -1
- data/app/models/fe/concerns/answer_sheet_concern.rb +38 -8
- data/app/models/fe/concerns/choice_field_concern.rb +17 -10
- data/app/models/fe/date_field.rb +1 -1
- data/app/models/fe/element.rb +105 -31
- data/app/models/fe/page.rb +52 -20
- data/app/models/fe/page_element.rb +6 -1
- data/app/models/fe/page_link.rb +6 -3
- data/app/models/fe/person.rb +11 -8
- data/app/models/fe/question.rb +2 -6
- data/app/models/fe/question_grid.rb +1 -1
- data/app/models/fe/question_grid_with_total.rb +15 -0
- data/app/models/fe/question_set.rb +1 -1
- data/app/models/fe/question_sheet.rb +15 -13
- data/app/models/fe/reference_question.rb +0 -10
- data/app/models/fe/reference_sheet.rb +17 -13
- data/app/models/staff.rb +2 -0
- data/app/validators/email_validator.rb +11 -0
- data/app/views/fe/admin/elements/create.js.erb +1 -0
- data/app/views/fe/admin/elements/drop.js.erb +1 -0
- data/app/views/fe/admin/elements/duplicate.js.erb +1 -0
- data/app/views/fe/admin/panels/_advanced_options.html.erb +9 -3
- data/app/views/fe/admin/panels/_common_fields.html.erb +19 -5
- data/app/views/fe/admin/panels/_page.html.erb +1 -1
- data/app/views/fe/admin/panels/_prop_choice_field.html.erb +20 -11
- data/app/views/fe/admin/panels/_prop_element.html.erb +2 -9
- data/app/views/fe/admin/panels/_prop_page.html.erb +8 -3
- data/app/views/fe/admin/panels/_prop_paragraph.html.erb +38 -24
- data/app/views/fe/admin/panels/_prop_section.html.erb +8 -2
- data/app/views/fe/admin/panels/_prop_sheet.html.erb +4 -1
- data/app/views/fe/admin/question_pages/_element.html.erb +11 -1
- data/app/views/fe/answer_pages/_answer_page.html.erb +9 -8
- data/app/views/fe/answer_pages/_element.html.erb +6 -7
- data/app/views/fe/answer_pages/_page_name.html.erb +1 -0
- data/app/views/fe/answer_pages/update.js.erb +3 -3
- data/app/views/fe/answer_sheets/_answer_sheet.html.erb +3 -3
- data/app/views/fe/answer_sheets/_element.html.erb +52 -34
- data/app/views/fe/answer_sheets/_incomplete.html.erb +1 -1
- data/app/views/fe/answer_sheets/_page_link.html.erb +2 -2
- data/app/views/fe/answer_sheets/_pages_list.html.erb +3 -3
- data/app/views/fe/answer_sheets/_submit_to.html.erb +1 -0
- data/app/views/fe/answer_sheets/edit.html.erb +14 -14
- data/app/views/fe/answer_sheets/incomplete.js.erb +3 -0
- data/app/views/fe/answer_sheets/index.html.erb +3 -3
- data/app/views/fe/answer_sheets/show.html.erb +1 -1
- data/app/views/fe/applications/_logout.html.erb +1 -0
- data/app/views/fe/applications/show.html.erb +1 -0
- data/app/views/fe/questions/fe/_acceptance.html.erb +3 -3
- data/app/views/fe/questions/fe/_attachment_field.html.erb +7 -3
- data/app/views/fe/questions/fe/_checkbox_field.html.erb +26 -24
- data/app/views/fe/questions/fe/_date_field.html.erb +1 -2
- data/app/views/fe/questions/fe/_date_field_mmyy.html.erb +2 -2
- data/app/views/fe/questions/fe/_drop_down_field.html.erb +3 -2
- data/app/views/fe/questions/fe/_paragraph.html.erb +1 -1
- data/app/views/fe/questions/fe/_question_grid.html.erb +14 -9
- data/app/views/fe/questions/fe/_question_grid_with_total.html.erb +21 -14
- data/app/views/fe/questions/fe/_questions.html.erb +2 -2
- data/app/views/fe/questions/fe/_radio_button_field.html.erb +12 -11
- data/app/views/fe/questions/fe/_rating.html.erb +9 -8
- data/app/views/fe/questions/fe/_reference_discipler.html.erb +1 -1
- data/app/views/fe/questions/fe/_reference_friend.html.erb +1 -1
- data/app/views/fe/questions/fe/_reference_parent.html.erb +1 -1
- data/app/views/fe/questions/fe/_reference_peer.html.erb +1 -1
- data/app/views/fe/questions/fe/_reference_question.html.erb +22 -15
- data/app/views/fe/questions/fe/_reference_roommate.html.erb +1 -1
- data/app/views/fe/questions/fe/_reference_spiritual.html.erb +1 -1
- data/app/views/fe/questions/fe/_reference_staff.html.erb +1 -1
- data/app/views/fe/questions/fe/_section.html.erb +1 -1
- data/app/views/fe/questions/fe/_text_area_field.html.erb +10 -3
- data/app/views/fe/questions/fe/_text_field.html.erb +1 -1
- data/app/views/fe/questions/fe/_yes_no_field.erb +3 -3
- data/app/views/fe/reference_pages/_reference.html.erb +11 -11
- data/app/views/fe/reference_pages/edit.html.erb +7 -7
- data/app/views/fe/reference_sheets/done.html.erb +2 -2
- data/app/views/fe/reference_sheets/not_found.html.erb +4 -4
- data/app/views/fe/references/edit.html.erb +6 -6
- data/app/views/fe/references/show.html.erb +7 -7
- data/app/views/fe/references/submit.js.erb +1 -1
- data/app/views/fe/submit_pages/_thankyou.html.erb +1 -1
- data/app/views/fe/submit_pages/edit.html.erb +9 -9
- data/app/views/layouts/fe/_error_messages_for.html.erb +7 -0
- data/app/views/layouts/fe/application.html.erb +1 -1
- data/config/routes.rb +0 -36
- data/db/migrate/20131003044250_create_reference_sheets.rb +1 -0
- data/db/migrate/20140623153424_create_fe_people.rb +1 -1
- data/db/migrate/20140624180246_create_fe_addresses.rb +1 -1
- data/db/migrate/20140624182216_create_fe_phone_numbers.rb +16 -0
- data/db/migrate/20140625160545_create_fe_users.rb +1 -1
- data/db/migrate/20150504221439_add_all_element_ids_to_pages.rb +5 -0
- data/db/migrate/20150713022326_add_locale_columns.rb +9 -0
- data/db/migrate/20150714220730_add_locale_to_answer_sheet.rb +5 -0
- data/db/migrate/20150928085325_change_pages_all_element_ids_to_text.rb +5 -0
- data/db/migrate/20150930191538_add_locale_to_reference_sheets.rb +5 -0
- data/lib/access_key_generator.rb +12 -0
- data/lib/distinct_distinct_patch.rb +20 -0
- data/lib/fe.rb +4 -0
- data/lib/fe/engine.rb +16 -4
- data/lib/fe/version.rb +1 -1
- data/spec/controllers/fe/admin/elements_controller_spec.rb +201 -1
- data/spec/controllers/fe/admin/email_templates_controller_spec.rb +26 -1
- data/spec/controllers/fe/admin/question_pages_controller_spec.rb +8 -1
- data/spec/controllers/fe/admin/question_sheets_controller_spec.rb +48 -1
- data/spec/controllers/fe/answer_pages_controller_spec.rb +73 -1
- data/spec/controllers/fe/answer_sheets_controller_spec.rb +80 -1
- data/spec/controllers/fe/reference_pages_controller.rb +4 -0
- data/spec/controllers/fe/references_controller_spec.rb +4 -0
- data/spec/controllers/fe/submit_pages_controller_spec.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +9 -0
- data/spec/dummy/app/models/application.rb +3 -0
- data/spec/dummy/app/models/person.rb +11 -0
- data/spec/dummy/app/models/user.rb +3 -0
- data/spec/dummy/config/application.rb +2 -1
- data/spec/dummy/config/database.yml +20 -17
- data/spec/dummy/config/environments/production.rb +1 -5
- data/spec/dummy/config/environments/test.rb +3 -1
- data/spec/dummy/config/initializers/fast_gettext.rb +5 -0
- data/spec/dummy/config/secrets.yml +2 -2
- data/spec/dummy/db/migrate/20141203214017_core.fe_engine.rb +92 -0
- data/spec/dummy/db/migrate/20141203214018_create_reference_sheets.fe_engine.rb +25 -0
- data/spec/dummy/db/migrate/20141203214019_add_element_and_answer_fields.fe_engine.rb +11 -0
- data/spec/dummy/db/migrate/20141203214020_create_email_templates.fe_engine.rb +18 -0
- data/spec/dummy/db/migrate/20141203214021_add_max_lengths.fe_engine.rb +9 -0
- data/spec/dummy/db/migrate/20141203214022_create_join_table.fe_engine.rb +12 -0
- data/spec/dummy/db/migrate/20141203214023_remove_question_id_from_element.fe_engine.rb +10 -0
- data/spec/dummy/db/migrate/20141203214024_create_fe_people.fe_engine.rb +13 -0
- data/spec/dummy/db/migrate/20141203214025_create_fe_addresses.fe_engine.rb +21 -0
- data/{db/migrate/20140624182216_create_create_fe_phone_numbers.rb → spec/dummy/db/migrate/20141203214026_create_create_fe_phone_numbers.fe_engine.rb} +1 -0
- data/spec/dummy/db/migrate/20141203214027_create_fe_users.fe_engine.rb +13 -0
- data/spec/dummy/db/migrate/20141203214028_add_conditional_type_to_elements.fe_engine.rb +6 -0
- data/spec/dummy/db/migrate/20141203214029_add_conditional_answer_to_elements.fe_engine.rb +6 -0
- data/spec/dummy/db/migrate/20141203214030_remove_short_value_column.fe_engine.rb +6 -0
- data/spec/dummy/db/migrate/20141203214031_move_conditional_ids_used_for_choice_field_to_their_own_column.fe_engine.rb +8 -0
- data/spec/dummy/db/migrate/20150123215803_create_users.rb +9 -0
- data/spec/dummy/db/migrate/20150504222619_add_all_element_ids_to_pages.fe_engine.rb +6 -0
- data/spec/dummy/db/migrate/20150930190001_create_fe_phone_numbers.fe_engine.rb +20 -0
- data/spec/dummy/db/migrate/20150930190002_add_locale_columns.fe_engine.rb +10 -0
- data/spec/dummy/db/migrate/20150930190003_add_locale_to_answer_sheet.fe_engine.rb +6 -0
- data/spec/dummy/db/migrate/20150930190004_change_pages_all_element_ids_to_text.fe_engine.rb +6 -0
- data/spec/dummy/db/migrate/20150930191756_add_locale_to_reference_sheets.fe_engine.rb +6 -0
- data/spec/dummy/db/schema.rb +50 -20
- data/spec/dummy/log/development.log +5 -0
- data/spec/factories/applications.rb +0 -1
- data/spec/factories/dummy_applications.rb +6 -0
- data/spec/factories/dummy_people.rb +6 -0
- data/spec/factories/dummy_users.rb +6 -0
- data/spec/factories/elements.rb +28 -3
- data/spec/factories/email_templates.rb +5 -0
- data/spec/factories/fe_email_templates.rb +9 -0
- data/spec/factories/fe_people.rb +0 -2
- data/spec/factories/fe_user.rb +6 -0
- data/spec/factories/question_sheet.rb +1 -1
- data/spec/factories/reference_sheets.rb +9 -0
- data/spec/mailers/fe/notifier_spec.rb +39 -0
- data/spec/models/fe/choice_field_spec.rb +20 -0
- data/spec/models/fe/element_spec.rb +185 -0
- data/spec/models/fe/page_spec.rb +112 -0
- data/spec/models/fe/question_sheet_spec.rb +106 -0
- data/spec/models/fe/reference_sheet_spec.rb +20 -0
- data/spec/rails_helper.rb +41 -13
- data/spec/support/choices.xml +6 -0
- metadata +136 -48
- data/app/assets/javascripts/fe/rails.extra.js +0 -6
- data/app/controllers/fe/applications_controller.rb +0 -183
- data/app/controllers/fe/payments_controller.rb +0 -184
- data/app/models/fe/payment.rb +0 -77
- data/app/models/fe/payment_question.rb +0 -22
- data/app/views/fe/admin/panels/_prop_payment_question.html.erb +0 -1
- data/app/views/fe/application/_logout.html.erb +0 -1
- data/app/views/fe/payment_pages/_credit.html.erb +0 -47
- data/app/views/fe/payment_pages/_mail.html.erb +0 -27
- data/app/views/fe/payment_pages/_payment.html.erb +0 -6
- data/app/views/fe/payment_pages/_staff.html.erb +0 -25
- data/app/views/fe/payment_pages/_staff_results.html.erb +0 -17
- data/app/views/fe/payment_pages/edit.html.erb +0 -75
- data/app/views/fe/payment_pages/staff_search.js.erb +0 -2
- data/app/views/fe/payments/_credit.html.erb +0 -47
- data/app/views/fe/payments/_errors.html.erb +0 -1
- data/app/views/fe/payments/_payment.html.erb +0 -13
- data/app/views/fe/payments/_staff.html.erb +0 -21
- data/app/views/fe/payments/_staff_results.html.erb +0 -18
- data/app/views/fe/payments/approve.js.erb +0 -3
- data/app/views/fe/payments/create.js.erb +0 -19
- data/app/views/fe/payments/destroy.js.erb +0 -7
- data/app/views/fe/payments/edit.html.erb +0 -56
- data/app/views/fe/payments/error.js.erb +0 -3
- data/app/views/fe/payments/no_access.html.erb +0 -7
- data/app/views/fe/payments/staff_search.js.erb +0 -1
- data/app/views/fe/payments/update.html.erb +0 -24
- data/app/views/fe/questions/fe/_payment_question.html.erb +0 -70
- data/db/migrate/20140828045339_create_payments.rb +0 -13
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/factories/payments.rb +0 -7
- data/spec/models/fe/payment_question_spec.rb +0 -65
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
module Fe::Admin::QuestionSheetsControllerConcern
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
included do
|
|
6
|
+
before_filter :check_valid_user
|
|
7
|
+
before_filter :get_question_sheet, :only => [:show, :archive, :unarchive, :destroy, :edit, :update, :duplicate]
|
|
8
|
+
layout 'fe/fe.admin'
|
|
9
|
+
end
|
|
10
|
+
rescue ActiveSupport::Concern::MultipleIncludedBlocks
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# list of all questionnaires/forms to edit
|
|
14
|
+
# GET /question_sheets
|
|
15
|
+
def index
|
|
16
|
+
@active_question_sheets = Fe::QuestionSheet.active.order('label')
|
|
17
|
+
@archived_question_sheets = Fe::QuestionSheet.archived.order('label')
|
|
18
|
+
|
|
19
|
+
respond_to do |format|
|
|
20
|
+
format.html # index.rhtml
|
|
21
|
+
format.xml { render :xml => @question_sheets.to_xml }
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def archive
|
|
26
|
+
@question_sheet.update_attribute(:archived, true)
|
|
27
|
+
redirect_to :back
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def unarchive
|
|
31
|
+
@question_sheet.update_attribute(:archived, false)
|
|
32
|
+
redirect_to :back
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def duplicate
|
|
36
|
+
@question_sheet.duplicate
|
|
37
|
+
redirect_to :back
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# entry point: display form designer with page 1 and panels loaded
|
|
41
|
+
# GET /question_sheets/1
|
|
42
|
+
def show
|
|
43
|
+
@all_pages = @question_sheet.pages
|
|
44
|
+
@page = @all_pages[0]
|
|
45
|
+
|
|
46
|
+
respond_to do |format|
|
|
47
|
+
format.html # show.rhtml
|
|
48
|
+
format.xml { render :xml => @question_sheet.to_xml }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# create sheet with inital page, redirect to show
|
|
53
|
+
# POST /question_sheets
|
|
54
|
+
def create
|
|
55
|
+
@question_sheet = Fe::QuestionSheet.new_with_page
|
|
56
|
+
|
|
57
|
+
respond_to do |format|
|
|
58
|
+
if @question_sheet.save
|
|
59
|
+
format.html { redirect_to fe_admin_question_sheet_path(@question_sheet) }
|
|
60
|
+
format.xml { head :created, :location => admin_question_sheet_path(@question_sheet) }
|
|
61
|
+
else
|
|
62
|
+
format.html { render :action => "new" }
|
|
63
|
+
format.xml { render :xml => @question_sheet.errors.to_xml }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
# display sheet properties panel
|
|
70
|
+
# GET /question_sheets/1/edit
|
|
71
|
+
def edit
|
|
72
|
+
|
|
73
|
+
respond_to do |format|
|
|
74
|
+
format.js
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# save changes to properties panel (label, language)
|
|
79
|
+
# PUT /question_sheets/1
|
|
80
|
+
def update
|
|
81
|
+
params.require(:fe_question_sheet).permit!
|
|
82
|
+
|
|
83
|
+
respond_to do |format|
|
|
84
|
+
if @question_sheet.update_attributes(params[:fe_question_sheet])
|
|
85
|
+
format.html { redirect_to fe_admin_question_sheet_path(@question_sheet) }
|
|
86
|
+
format.js
|
|
87
|
+
format.xml { head :ok }
|
|
88
|
+
else
|
|
89
|
+
format.html { render :action => "edit" }
|
|
90
|
+
format.js { render :action => "error.rjs"}
|
|
91
|
+
format.xml { render :xml => @question_sheet.errors.to_xml }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# mark sheet as destroyed
|
|
97
|
+
# DELETE /question_sheets/1
|
|
98
|
+
def destroy
|
|
99
|
+
@question_sheet.destroy
|
|
100
|
+
|
|
101
|
+
respond_to do |format|
|
|
102
|
+
format.html { redirect_to fe_admin_question_sheets_path }
|
|
103
|
+
format.xml { head :ok }
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
protected
|
|
108
|
+
def get_question_sheet
|
|
109
|
+
@question_sheet = Fe::QuestionSheet.find(params[:id])
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
@@ -39,7 +39,8 @@ module Fe::AnswerPagesControllerConcern
|
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
@presenter.active_page = nil
|
|
42
|
-
@answer_sheet.
|
|
42
|
+
@answer_sheet.update(locale: session[:locale])
|
|
43
|
+
@saved_at_timestamp = [@answer_sheet.updated_at, @answer_sheet.answers.maximum(:updated_at)].compact.max
|
|
43
44
|
respond_to do |format|
|
|
44
45
|
format.js
|
|
45
46
|
#format.html
|
|
@@ -22,7 +22,7 @@ module Fe::AnswerSheetsControllerConcern
|
|
|
22
22
|
@question_sheet = Fe::QuestionSheet.find(params[:question_sheet_id])
|
|
23
23
|
@answer_sheet = @question_sheet.answer_sheets.create
|
|
24
24
|
|
|
25
|
-
redirect_to
|
|
25
|
+
redirect_to edit_fe_answer_sheet_path(@answer_sheet)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
# display answer sheet for data capture (page 1)
|
|
@@ -4,6 +4,7 @@ module Fe::ApplicationControllerConcern
|
|
|
4
4
|
begin
|
|
5
5
|
included do
|
|
6
6
|
helper_method :fe_user
|
|
7
|
+
before_filter :set_locale
|
|
7
8
|
end
|
|
8
9
|
rescue ActiveSupport::Concern::MultipleIncludedBlocks
|
|
9
10
|
end
|
|
@@ -18,6 +19,18 @@ module Fe::ApplicationControllerConcern
|
|
|
18
19
|
@fe_user
|
|
19
20
|
end
|
|
20
21
|
|
|
22
|
+
def extract_locale_from_accept_language_header
|
|
23
|
+
request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first if request.env['HTTP_ACCEPT_LANGUAGE'].present?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def set_locale
|
|
27
|
+
session[:locale] = params[:locale] if params[:locale]
|
|
28
|
+
session[:locale] ||= extract_locale_from_accept_language_header || I18n.default_locale
|
|
29
|
+
if @answer_sheet
|
|
30
|
+
session[:locale] = I18n.default_locale unless @answer_sheet.languages.include?(session[:locale])
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
21
34
|
def current_person
|
|
22
35
|
#raise "no user" unless current_user
|
|
23
36
|
return nil unless current_user
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
# TODO determine how this relates to Fe::ReferencesController and if we can delete one of the two
|
|
1
2
|
class Fe::ReferenceSheetsController < Fe::AnswerSheetsController
|
|
2
3
|
skip_before_filter :ssm_login_required, :login
|
|
3
4
|
before_filter :edit_only, :except => [:edit]
|
|
5
|
+
|
|
4
6
|
def edit
|
|
5
7
|
@reference_sheet = @answer_sheet
|
|
6
8
|
unless @answer_sheet
|
|
@@ -54,5 +54,10 @@ module Fe
|
|
|
54
54
|
|
|
55
55
|
content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
|
|
56
56
|
end
|
|
57
|
+
|
|
58
|
+
def error_messages_for(model)
|
|
59
|
+
record = instance_variable_get(:"@#{(model.is_a?(ActiveRecord::Base) ? model.class : model).to_s.underscore}")
|
|
60
|
+
render "layouts/fe/error_messages_for", record: record
|
|
61
|
+
end
|
|
57
62
|
end
|
|
58
63
|
end
|
data/app/mailers/fe/notifier.rb
CHANGED
|
@@ -6,12 +6,19 @@ module Fe
|
|
|
6
6
|
email_template = EmailTemplate.find_by_name(template_name)
|
|
7
7
|
|
|
8
8
|
if email_template.nil?
|
|
9
|
-
raise "Email Template #{template_name} could not be found"
|
|
9
|
+
raise "Email Template '#{template_name}' could not be found"
|
|
10
10
|
else
|
|
11
|
-
|
|
11
|
+
set_format = options.delete(:format)
|
|
12
|
+
mail({:to => p_recipients,
|
|
12
13
|
:from => p_from,
|
|
13
|
-
:subject => Liquid::Template.parse(email_template.subject).render(template_params)
|
|
14
|
-
|
|
14
|
+
:subject => Liquid::Template.parse(email_template.subject).render(template_params)}.merge(options)) do |format|
|
|
15
|
+
case set_format.to_s
|
|
16
|
+
when 'html'
|
|
17
|
+
format.html { render html: Liquid::Template.parse(email_template.content).render(template_params) }
|
|
18
|
+
else
|
|
19
|
+
format.text { render text: Liquid::Template.parse(email_template.content).render(template_params) }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
15
22
|
@recipients = p_recipients
|
|
16
23
|
@from = p_from
|
|
17
24
|
@subject = Liquid::Template.parse(email_template.subject).render(template_params)
|
|
@@ -2,9 +2,10 @@ require 'aasm'
|
|
|
2
2
|
|
|
3
3
|
# a visitor applies to a sleeve (application)
|
|
4
4
|
class Fe::Application < Fe::AnswerSheet
|
|
5
|
+
|
|
5
6
|
self.table_name = "#{Fe.table_name_prefix}applications"
|
|
6
7
|
|
|
7
|
-
belongs_to :applicant, :
|
|
8
|
+
belongs_to :applicant, foreign_key: 'person_id', class_name: "Person"
|
|
8
9
|
has_many :references, :class_name => 'ReferenceSheet', :foreign_key => :applicant_answer_sheet_id, :dependent => :destroy
|
|
9
10
|
has_one :answer_sheet_question_sheet, :foreign_key => "answer_sheet_id"
|
|
10
11
|
has_many :answer_sheet_question_sheets, :foreign_key => 'answer_sheet_id'
|
|
@@ -48,6 +48,15 @@ module Fe
|
|
|
48
48
|
link
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
+
def prev_page
|
|
52
|
+
active_page_dom_id = active_page_link.dom_id
|
|
53
|
+
|
|
54
|
+
this_page = @page_links.find {|p| p.dom_id == active_page_dom_id}
|
|
55
|
+
index = @page_links.index(this_page)
|
|
56
|
+
return nil if index == 0
|
|
57
|
+
@page_links.at( index - 1 ) unless this_page.nil?
|
|
58
|
+
end
|
|
59
|
+
|
|
51
60
|
def next_page
|
|
52
61
|
active_page_dom_id = active_page_link.dom_id
|
|
53
62
|
|
|
@@ -81,7 +90,7 @@ module Fe
|
|
|
81
90
|
end
|
|
82
91
|
|
|
83
92
|
def new_page_link(answer_sheet, page, a = nil)
|
|
84
|
-
Fe::PageLink.new(
|
|
93
|
+
Fe::PageLink.new(edit_fe_answer_sheet_page_path(answer_sheet, page, :a => a), dom_page(answer_sheet, page), page) if page
|
|
85
94
|
end
|
|
86
95
|
|
|
87
96
|
protected
|
|
@@ -4,15 +4,41 @@ module Fe
|
|
|
4
4
|
|
|
5
5
|
begin
|
|
6
6
|
included do
|
|
7
|
-
has_many :answer_sheet_question_sheets, :
|
|
8
|
-
has_many :question_sheets, :
|
|
9
|
-
has_many :answers,
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
has_many :answer_sheet_question_sheets, foreign_key: 'answer_sheet_id', class_name: '::Fe::AnswerSheetQuestionSheet'
|
|
8
|
+
has_many :question_sheets, through: :answer_sheet_question_sheets, class_name: 'Fe::QuestionSheet'
|
|
9
|
+
has_many :answers, ->(answer_sheet) {
|
|
10
|
+
question_sheet_ids = answer_sheet.question_sheet_ids
|
|
11
|
+
|
|
12
|
+
if question_sheet_ids.any?
|
|
13
|
+
element_ids = Fe::Page.joins(:question_sheet).where(question_sheet_id: question_sheet_ids).pluck(:all_element_ids).compact
|
|
14
|
+
element_ids = element_ids.collect{ |e| e.split(',') }.flatten
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
unless question_sheet_ids.any? && element_ids.any?
|
|
18
|
+
# an answer sheet not assigned to a question sheet, or assigned to
|
|
19
|
+
# a question sheet with no elements should not return any answers
|
|
20
|
+
return where('false')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
where('question_id' => element_ids)
|
|
24
|
+
|
|
25
|
+
}, foreign_key: 'answer_sheet_id', class_name: '::Fe::Answer'
|
|
26
|
+
has_many :reference_sheets, :foreign_key => 'applicant_answer_sheet_id', class_name: 'Fe::ReferenceSheet'
|
|
27
|
+
has_many :payments, :foreign_key => 'application_id', class_name: 'Fe::Payment'
|
|
12
28
|
end
|
|
13
29
|
rescue ActiveSupport::Concern::MultipleIncludedBlocks
|
|
14
30
|
end
|
|
15
31
|
|
|
32
|
+
def languages
|
|
33
|
+
return [] unless question_sheets.first
|
|
34
|
+
|
|
35
|
+
unless @languages
|
|
36
|
+
@languages = question_sheets.first.languages
|
|
37
|
+
question_sheets[1..-1].each { |qs| @languages &= qs.languages.select(&:present?) }
|
|
38
|
+
end
|
|
39
|
+
@languages
|
|
40
|
+
end
|
|
41
|
+
|
|
16
42
|
def complete?
|
|
17
43
|
!completed_at.nil?
|
|
18
44
|
end
|
|
@@ -28,7 +54,7 @@ module Fe
|
|
|
28
54
|
end
|
|
29
55
|
|
|
30
56
|
def pages
|
|
31
|
-
Page.where(:question_sheet_id => question_sheets.collect(&:id))
|
|
57
|
+
Page.where(:question_sheet_id => question_sheets.collect(&:id)).order('number')
|
|
32
58
|
end
|
|
33
59
|
|
|
34
60
|
def completely_filled_out?
|
|
@@ -44,12 +70,16 @@ module Fe
|
|
|
44
70
|
end
|
|
45
71
|
|
|
46
72
|
def percent_complete
|
|
47
|
-
num_questions = question_sheets.inject(0.0) { |sum, qs| qs.nil? ? sum : qs.
|
|
73
|
+
num_questions = question_sheets.inject(0.0) { |sum, qs| qs.nil? ? sum : qs.questions_count + sum }
|
|
48
74
|
return 0 if num_questions == 0
|
|
49
|
-
num_answers = answers.where("value IS NOT NULL
|
|
75
|
+
num_answers = answers.where("(value IS NOT NULL) AND (value != '')").select("DISTINCT question_id").count
|
|
50
76
|
[ [ (num_answers.to_f / num_questions.to_f * 100.0).to_i, 100 ].min, 0 ].max
|
|
51
77
|
end
|
|
52
78
|
|
|
53
79
|
def collat_title() "" end
|
|
80
|
+
|
|
81
|
+
def question_sheet_ids
|
|
82
|
+
question_sheets.collect(&:id)
|
|
83
|
+
end
|
|
54
84
|
end
|
|
55
85
|
end
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
require 'net/http'
|
|
2
|
+
# :nocov:
|
|
2
3
|
begin
|
|
3
4
|
require 'xml/libxml'
|
|
4
5
|
rescue LoadError
|
|
5
6
|
require 'rexml/document'
|
|
6
7
|
end
|
|
8
|
+
# :nocov:
|
|
7
9
|
|
|
8
10
|
module Fe
|
|
9
11
|
module ChoiceFieldConcern
|
|
@@ -17,22 +19,23 @@ module Fe
|
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
# Returns choices stored one per line in content field
|
|
20
|
-
def choices
|
|
22
|
+
def choices(locale = nil)
|
|
21
23
|
retVal = Array.new
|
|
22
24
|
if ['yes-no', 'acceptance'].include?(self.style)
|
|
23
|
-
return [[
|
|
24
|
-
elsif
|
|
25
|
+
return [[_('Yes'),1],[_('No'),0]]
|
|
26
|
+
elsif source.present?
|
|
25
27
|
begin
|
|
26
28
|
doc = XML::Document.file(source)
|
|
27
29
|
options = doc.find(text_xpath).collect { |n| n.content }
|
|
28
30
|
values = doc.find(value_xpath).collect { |n| n.content }
|
|
29
31
|
retVal = [options, values].transpose
|
|
30
|
-
rescue NameError
|
|
32
|
+
rescue NameError, LibXML::XML::Error
|
|
31
33
|
doc = REXML::Document.new Net::HTTP.get_response(URI.parse(source)).body
|
|
32
|
-
retVal = [ doc.elements.collect(text_xpath){|c|c.text}, doc.elements.collect(value_xpath){|c|c.text} ].transpose
|
|
34
|
+
retVal = [ doc.elements.collect(text_xpath){|c|c.text}, doc.elements.collect(value_xpath){|c|c.text} ].transpose
|
|
33
35
|
end
|
|
34
|
-
elsif
|
|
35
|
-
|
|
36
|
+
elsif content.present?
|
|
37
|
+
choices = content_translations[locale] || content
|
|
38
|
+
choices.split("\n").each do |opt|
|
|
36
39
|
pair = opt.strip.split(";").reverse!
|
|
37
40
|
pair[1] ||= pair[0]
|
|
38
41
|
retVal << pair
|
|
@@ -124,18 +127,22 @@ module Fe
|
|
|
124
127
|
def conditional_match(answer_sheet)
|
|
125
128
|
displayed_response = display_response(answer_sheet)
|
|
126
129
|
(is_true(displayed_response) && is_true(conditional_answer)) ||
|
|
127
|
-
(
|
|
130
|
+
(is_response_false(answer_sheet) && is_false(conditional_answer)) ||
|
|
128
131
|
(displayed_response == conditional_answer)
|
|
129
132
|
end
|
|
130
133
|
|
|
134
|
+
def is_response_false(answer_sheet)
|
|
135
|
+
is_false(display_response(answer_sheet))
|
|
136
|
+
end
|
|
137
|
+
|
|
131
138
|
protected
|
|
132
139
|
def is_true(val)
|
|
133
|
-
[
|
|
140
|
+
['1','true','yes'].include?(val.to_s.downcase)
|
|
134
141
|
end
|
|
135
142
|
|
|
136
143
|
def is_false(val)
|
|
137
144
|
# returns false if false (a bit odd)
|
|
138
|
-
[
|
|
145
|
+
['0','false','no'].include?(val.to_s.downcase)
|
|
139
146
|
end
|
|
140
147
|
|
|
141
148
|
end
|
data/app/models/fe/date_field.rb
CHANGED
data/app/models/fe/element.rb
CHANGED
|
@@ -4,23 +4,29 @@ module Fe
|
|
|
4
4
|
self.table_name = self.table_name.sub('fe_', Fe.table_name_prefix)
|
|
5
5
|
|
|
6
6
|
belongs_to :question_grid,
|
|
7
|
-
:
|
|
8
|
-
|
|
7
|
+
class_name: "Fe::QuestionGrid"
|
|
8
|
+
|
|
9
|
+
belongs_to :question_grid_with_total,
|
|
10
|
+
class_name: "Fe::QuestionGridWithTotal",
|
|
11
|
+
foreign_key: "question_grid_id"
|
|
9
12
|
|
|
10
13
|
belongs_to :choice_field,
|
|
11
|
-
:
|
|
12
|
-
|
|
14
|
+
class_name: "Fe::ChoiceField"
|
|
15
|
+
|
|
16
|
+
has_many :choice_field_children, foreign_key: 'choice_field_id',
|
|
17
|
+
class_name: 'Fe::Element'
|
|
13
18
|
|
|
14
19
|
belongs_to :question_sheet, :foreign_key => "related_question_sheet_id"
|
|
15
20
|
|
|
16
|
-
belongs_to :conditional, :
|
|
21
|
+
belongs_to :conditional, polymorphic: true
|
|
17
22
|
|
|
18
23
|
self.inheritance_column = :kind
|
|
19
24
|
|
|
20
|
-
has_many :page_elements, :
|
|
21
|
-
has_many :pages, :
|
|
25
|
+
has_many :page_elements, dependent: :destroy
|
|
26
|
+
has_many :pages, through: :page_elements
|
|
22
27
|
|
|
23
28
|
scope :active, -> { select("distinct(#{Fe::Element.table_name}.id), #{Fe::Element.table_name}.*").where(Fe::QuestionSheet.table_name + '.archived' => false).joins({:pages => :question_sheet}) }
|
|
29
|
+
scope :questions, -> { where("kind NOT IN('Fe::Paragraph', 'Fe::Section', 'Fe::QuestionGrid', 'Fe::QuestionGridWithTotal')") }
|
|
24
30
|
|
|
25
31
|
validates_presence_of :kind
|
|
26
32
|
validates_presence_of :style
|
|
@@ -32,8 +38,13 @@ module Fe
|
|
|
32
38
|
|
|
33
39
|
before_validation :set_defaults, :on => :create
|
|
34
40
|
before_save :set_conditional_element
|
|
41
|
+
after_save :update_page_all_element_ids
|
|
35
42
|
after_save :update_any_previous_conditional_elements
|
|
36
43
|
|
|
44
|
+
serialize :label_translations, Hash
|
|
45
|
+
serialize :tip_translations, Hash
|
|
46
|
+
serialize :content_translations, Hash
|
|
47
|
+
|
|
37
48
|
# HUMANIZED_ATTRIBUTES = {
|
|
38
49
|
# :slug => "Variable"
|
|
39
50
|
# }changed.include?('address1')
|
|
@@ -41,6 +52,23 @@ module Fe
|
|
|
41
52
|
# def self.human_attrib_name(attr)
|
|
42
53
|
# HUMANIZED_ATTRIBUTES[attr.to_sym] || super
|
|
43
54
|
# end
|
|
55
|
+
def label(locale = nil)
|
|
56
|
+
label_translations[locale] || self[:label]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def content(locale = nil)
|
|
60
|
+
content_translations[locale] || self[:content]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def tooltip(locale = nil)
|
|
64
|
+
tip_translations[locale] || self[:tooltip]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# returns all pages this element is on, whether that be directly, through a grid, or as a choice field conditional option
|
|
68
|
+
def pages_on
|
|
69
|
+
all_pages = pages.reload + [question_grid, question_grid_with_total, choice_field].compact.collect(&:pages_on)
|
|
70
|
+
all_pages.flatten.uniq
|
|
71
|
+
end
|
|
44
72
|
|
|
45
73
|
def has_response?(answer_sheet = nil)
|
|
46
74
|
false
|
|
@@ -52,7 +80,7 @@ module Fe
|
|
|
52
80
|
unless eval("answer_sheet." + self.object_name + ".nil?")
|
|
53
81
|
klass = eval("answer_sheet." + self.object_name + ".class")
|
|
54
82
|
column = klass.columns_hash[self.attribute_name]
|
|
55
|
-
column.limit
|
|
83
|
+
return column.limit
|
|
56
84
|
end
|
|
57
85
|
rescue
|
|
58
86
|
nil
|
|
@@ -61,24 +89,54 @@ module Fe
|
|
|
61
89
|
end
|
|
62
90
|
|
|
63
91
|
# assume each element is on a question sheet only once to make things simpler. if not, just take the first one
|
|
64
|
-
def previous_element(question_sheet)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
92
|
+
def previous_element(question_sheet, page = nil)
|
|
93
|
+
unless page
|
|
94
|
+
page_element = page_elements.joins(page: :question_sheet).where("#{Fe::QuestionSheet.table_name}.id" => question_sheet.id).first
|
|
95
|
+
return unless page_element
|
|
96
|
+
page = page_element.page
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
index = page.all_element_ids_arr.index(self.id)
|
|
100
|
+
unless index
|
|
101
|
+
# this can happen for yesno options, since they're rendered as elements but aren't on the page or in a grid
|
|
102
|
+
# but just in case self is an element on the page and the element_ids got out of sync, rebuild the all_element_ids
|
|
103
|
+
# and try again
|
|
104
|
+
page.rebuild_all_element_ids
|
|
105
|
+
index = page.all_element_ids_arr.index(self.id)
|
|
106
|
+
end
|
|
107
|
+
if index && index > 0 && prev_el_id = page.all_element_ids_arr[index-1]
|
|
108
|
+
return Fe::Element.find(prev_el_id)
|
|
71
109
|
end
|
|
72
110
|
end
|
|
73
111
|
|
|
74
|
-
def
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
prev_el.
|
|
79
|
-
|
|
80
|
-
|
|
112
|
+
def hidden_by_conditional?(answer_sheet, page, prev_el)
|
|
113
|
+
(prev_el ||= previous_element(answer_sheet.question_sheet, page)) &&
|
|
114
|
+
prev_el.is_a?(Fe::Question) &&
|
|
115
|
+
prev_el.conditional == self &&
|
|
116
|
+
!prev_el.conditional_match(answer_sheet)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def hidden_by_choice_field?(answer_sheet)
|
|
120
|
+
choice_field.present? &&
|
|
121
|
+
choice_field.is_a?(Fe::ChoiceField) &&
|
|
122
|
+
choice_field.is_response_false(answer_sheet)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# use prev_el directly if it's passed in; otherwise, pass page to previous_element to find the prev_el faster
|
|
126
|
+
def visible?(answer_sheet = nil, page = nil, prev_el = nil)
|
|
127
|
+
!hidden?(answer_sheet, page, prev_el)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# use prev_el directly if it's passed in; otherwise, pass page to previous_element to find the prev_el faster
|
|
131
|
+
def hidden?(answer_sheet = nil, page = nil, prev_el = nil)
|
|
132
|
+
@hidden ||= answer_sheet &&
|
|
133
|
+
(hidden_by_choice_field?(answer_sheet) ||
|
|
134
|
+
hidden_by_conditional?(answer_sheet, page, prev_el))
|
|
135
|
+
end
|
|
81
136
|
|
|
137
|
+
# use prev_el directly if it's passed in; otherwise, pass page to previous_element to find the prev_el faster
|
|
138
|
+
def required?(answer_sheet = nil, page = nil, prev_el = nil)
|
|
139
|
+
if hidden?(answer_sheet, page, prev_el)
|
|
82
140
|
return false
|
|
83
141
|
else
|
|
84
142
|
required == true
|
|
@@ -130,7 +188,8 @@ module Fe
|
|
|
130
188
|
when "Fe::ChoiceField"
|
|
131
189
|
new_element.choice_field_id = parent.id
|
|
132
190
|
end
|
|
133
|
-
new_element.
|
|
191
|
+
new_element.position = parent.elements.maximum(:position).to_i + 1 if parent
|
|
192
|
+
new_element.save!(:validate => false)
|
|
134
193
|
Fe::PageElement.create(:element => new_element, :page => page) unless parent
|
|
135
194
|
|
|
136
195
|
# duplicate children
|
|
@@ -144,6 +203,7 @@ module Fe
|
|
|
144
203
|
# include nested elements
|
|
145
204
|
def all_elements
|
|
146
205
|
if respond_to?(:elements)
|
|
206
|
+
elements.reload
|
|
147
207
|
(elements + elements.collect(&:all_elements)).flatten
|
|
148
208
|
else
|
|
149
209
|
[]
|
|
@@ -151,6 +211,7 @@ module Fe
|
|
|
151
211
|
end
|
|
152
212
|
|
|
153
213
|
def reuseable?
|
|
214
|
+
return false if Fe.never_reuse_elements
|
|
154
215
|
(self.is_a?(Fe::Question) || self.is_a?(Fe::QuestionGrid) || self.is_a?(Fe::QuestionGridWithTotal))
|
|
155
216
|
end
|
|
156
217
|
|
|
@@ -167,27 +228,40 @@ module Fe
|
|
|
167
228
|
def set_conditional_element
|
|
168
229
|
case conditional_type
|
|
169
230
|
when "Fe::Element"
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if index
|
|
173
|
-
self.conditional_id = page.
|
|
231
|
+
pages_on.each do |page|
|
|
232
|
+
|
|
233
|
+
if index = page.all_element_ids_arr.index(self.id)
|
|
234
|
+
self.conditional_id = page.all_element_ids_arr[index+1]
|
|
235
|
+
else
|
|
236
|
+
self.conditional_id = nil
|
|
174
237
|
end
|
|
175
238
|
end
|
|
239
|
+
when ""
|
|
240
|
+
# keep conditional_type nil instead of empty to be consistent
|
|
241
|
+
self.conditional_type = nil
|
|
176
242
|
end
|
|
177
243
|
end
|
|
178
244
|
|
|
179
245
|
def update_any_previous_conditional_elements
|
|
180
|
-
|
|
181
|
-
index = page.
|
|
246
|
+
pages_on.each do |page|
|
|
247
|
+
index = page.all_element_ids_arr.index(self.id)
|
|
182
248
|
if index && index > 0
|
|
183
|
-
prev_el = page.
|
|
249
|
+
prev_el = Fe::Element.find(page.all_element_ids_arr[index-1])
|
|
184
250
|
if prev_el.conditional_type == "Fe::Element"
|
|
185
|
-
prev_el.
|
|
251
|
+
prev_el.update_column(:conditional_id, id)
|
|
186
252
|
end
|
|
187
253
|
end
|
|
188
254
|
end
|
|
189
255
|
end
|
|
190
256
|
|
|
257
|
+
def update_page_all_element_ids
|
|
258
|
+
[question_grid, question_grid_with_total].compact.each do |field|
|
|
259
|
+
field.update_page_all_element_ids
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
pages.reload.each do |p| p.rebuild_all_element_ids end
|
|
263
|
+
end
|
|
264
|
+
|
|
191
265
|
protected
|
|
192
266
|
|
|
193
267
|
def set_defaults
|