effective_cpd 0.6.8 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/admin/cpd_audit_levels_controller.rb +7 -1
  3. data/app/controllers/admin/cpd_audit_reviews_controller.rb +7 -1
  4. data/app/controllers/admin/cpd_audits_controller.rb +21 -1
  5. data/app/controllers/admin/cpd_statements_controller.rb +1 -1
  6. data/app/controllers/effective/cpd_audit_reviews_controller.rb +3 -39
  7. data/app/controllers/effective/cpd_audits_controller.rb +3 -41
  8. data/app/datatables/admin/effective_cpd_audit_levels_datatable.rb +1 -1
  9. data/app/datatables/admin/effective_cpd_audit_reviews_datatable.rb +4 -2
  10. data/app/datatables/admin/effective_cpd_audits_datatable.rb +12 -10
  11. data/app/datatables/effective_cpd_available_audit_reviews_datatable.rb +4 -4
  12. data/app/datatables/effective_cpd_available_audits_datatable.rb +1 -1
  13. data/app/datatables/effective_cpd_completed_audit_reviews_datatable.rb +3 -3
  14. data/app/datatables/effective_cpd_completed_audits_datatable.rb +2 -2
  15. data/app/helpers/effective_cpd_audits_helper.rb +0 -32
  16. data/app/mailers/effective/cpd_mailer.rb +37 -24
  17. data/app/models/concerns/effective_cpd_audit.rb +594 -0
  18. data/app/models/concerns/effective_cpd_audit_level.rb +111 -0
  19. data/app/models/concerns/effective_cpd_audit_review.rb +297 -0
  20. data/app/models/concerns/effective_cpd_user.rb +16 -11
  21. data/app/models/effective/cpd_audit.rb +1 -397
  22. data/app/models/effective/cpd_audit_level.rb +1 -83
  23. data/app/models/effective/cpd_audit_level_question.rb +1 -1
  24. data/app/models/effective/cpd_audit_level_section.rb +4 -3
  25. data/app/models/effective/cpd_audit_response.rb +4 -2
  26. data/app/models/effective/cpd_audit_review.rb +1 -224
  27. data/app/models/effective/cpd_audit_review_item.rb +1 -1
  28. data/app/views/admin/cpd_audit_levels/_form_content_audit.html.haml +1 -1
  29. data/app/views/admin/cpd_audit_levels/_form_content_audit_review.html.haml +1 -1
  30. data/app/views/admin/cpd_audit_levels/_form_cpd_audit_level.html.haml +7 -1
  31. data/app/views/admin/cpd_audit_levels/_form_cpd_audit_level_section.html.haml +2 -0
  32. data/app/views/admin/cpd_audit_reviews/_form.html.haml +4 -1
  33. data/app/views/admin/cpd_audits/_form.html.haml +1 -49
  34. data/app/views/admin/cpd_audits/{_form_determination.html.haml → _form_close.html.haml} +1 -1
  35. data/app/views/admin/cpd_audits/_form_complete.html.haml +17 -0
  36. data/app/views/admin/cpd_audits/_form_cpd_audit.html.haml +56 -0
  37. data/app/views/admin/cpd_audits/_form_deadlines.html.haml +8 -9
  38. data/app/views/admin/cpd_audits/_form_exemption.html.haml +1 -1
  39. data/app/views/admin/cpd_audits/_form_extension.html.haml +1 -1
  40. data/app/views/admin/cpd_audits/_form_files.html.haml +6 -0
  41. data/app/views/admin/cpd_audits/_form_missing_info.html.haml +11 -0
  42. data/app/views/admin/cpd_audits/_form_new.html.haml +3 -1
  43. data/app/views/admin/cpd_audits/_form_process.html.haml +18 -0
  44. data/app/views/admin/cpd_audits/_status.html.haml +48 -6
  45. data/app/views/effective/cpd/_dashboard.html.haml +15 -12
  46. data/app/views/effective/cpd_audit_level_questions/_cpd_audit_level_question.html.haml +2 -1
  47. data/app/views/effective/cpd_audit_reviews/_conflict.html.haml +1 -1
  48. data/app/views/effective/cpd_audit_reviews/_cpd_audit_level_section.html.haml +3 -3
  49. data/app/views/effective/cpd_audit_reviews/_cpd_audit_review.html.haml +3 -1
  50. data/app/views/effective/cpd_audit_reviews/_cpd_statement.html.haml +3 -3
  51. data/app/views/effective/cpd_audit_reviews/_feedback.html.haml +9 -0
  52. data/app/views/effective/cpd_audit_reviews/_files.html.haml +12 -0
  53. data/app/views/effective/cpd_audit_reviews/_layout.html.haml +3 -0
  54. data/app/views/effective/cpd_audit_reviews/_recommendation.html.haml +6 -2
  55. data/app/views/effective/cpd_audit_reviews/_summary.html.haml +41 -14
  56. data/app/views/effective/cpd_audit_reviews/conflict.html.haml +5 -1
  57. data/app/views/effective/cpd_audit_reviews/cpd_audit_level_section.html.haml +2 -2
  58. data/app/views/effective/cpd_audit_reviews/feedback.html.haml +16 -0
  59. data/app/views/effective/cpd_audit_reviews/files.html.haml +17 -0
  60. data/app/views/effective/cpd_audit_reviews/recommendation.html.haml +5 -3
  61. data/app/views/effective/cpd_audit_reviews/start.html.haml +10 -3
  62. data/app/views/effective/cpd_audit_reviews/statements.html.haml +4 -5
  63. data/app/views/effective/cpd_audit_reviews/submit.html.haml +1 -1
  64. data/app/views/effective/cpd_audit_reviews/submitted.html.haml +20 -0
  65. data/app/views/effective/cpd_audit_reviews/waiting.html.haml +1 -1
  66. data/app/views/effective/cpd_audits/_conflict.html.haml +1 -1
  67. data/app/views/effective/cpd_audits/_cpd.html.haml +1 -1
  68. data/app/views/effective/cpd_audits/_cpd_audit.html.haml +3 -1
  69. data/app/views/effective/cpd_audits/_cpd_audit_level_section.html.haml +1 -1
  70. data/app/views/effective/cpd_audits/_exemption.html.haml +1 -1
  71. data/app/views/effective/cpd_audits/_extension.html.haml +1 -1
  72. data/app/views/effective/cpd_audits/_files.html.haml +1 -1
  73. data/app/views/effective/cpd_audits/_missing_info.html.haml +19 -0
  74. data/app/views/effective/cpd_audits/_summary.html.haml +30 -12
  75. data/app/views/effective/cpd_audits/_waiting.html.haml +1 -1
  76. data/app/views/effective/cpd_audits/conflict.html.haml +5 -1
  77. data/app/views/effective/cpd_audits/cpd_audit_level_section.html.haml +1 -0
  78. data/app/views/effective/cpd_audits/start.html.haml +10 -4
  79. data/app/views/effective/cpd_audits/submit.html.haml +5 -2
  80. data/app/views/effective/cpd_audits/{complete.html.haml → submitted.haml} +13 -8
  81. data/app/views/effective/cpd_audits/waiting.html.haml +1 -1
  82. data/app/views/effective/cpd_mailer/cpd_audit_missing_info.liquid +15 -0
  83. data/app/views/effective/cpd_mailer/cpd_audit_review_ready.liquid +1 -1
  84. data/app/views/effective/cpd_mailer/cpd_audit_submitted.liquid +3 -1
  85. data/config/effective_cpd.rb +5 -2
  86. data/db/migrate/01_create_effective_cpd.rb.erb +36 -7
  87. data/lib/effective_cpd/engine.rb +4 -0
  88. data/lib/effective_cpd/version.rb +1 -1
  89. data/lib/effective_cpd.rb +13 -1
  90. metadata +19 -5
  91. data/app/views/effective/cpd_audit_reviews/complete.html.haml +0 -20
@@ -1,401 +1,5 @@
1
1
  module Effective
2
2
  class CpdAudit < ActiveRecord::Base
3
- attr_accessor :current_user
4
- attr_accessor :current_step
5
-
6
- attr_accessor :admin_process_request
7
- ADMIN_PROCESS_REQUEST_OPTIONS = ['Granted', 'Denied']
8
-
9
- belongs_to :cpd_audit_level
10
- belongs_to :user, polymorphic: true # The user being audited
11
-
12
- has_many :cpd_audit_reviews, -> { order(:id) }, inverse_of: :cpd_audit, dependent: :destroy
13
- accepts_nested_attributes_for :cpd_audit_reviews, allow_destroy: true
14
-
15
- has_many :cpd_audit_responses, -> { order(:id) }, inverse_of: :cpd_audit, dependent: :destroy
16
- accepts_nested_attributes_for :cpd_audit_responses
17
-
18
- has_many_attached :files
19
-
20
- if respond_to?(:log_changes)
21
- log_changes(except: [:wizard_steps, :cpd_audit_reviews])
22
- end
23
-
24
- acts_as_email_form
25
- acts_as_tokened
26
- acts_as_reportable if respond_to?(:acts_as_reportable)
27
-
28
- COMPLETED_STATES = [:exemption_granted, :closed]
29
-
30
- WAITING_ON_ADMIN_STATES = [:conflicted, :exemption_requested, :extension_requested, :reviewed]
31
- WAITING_ON_REVIEWERS_STATES = [:submitted]
32
- WAITING_ON_AUDITEE_STATES = [:opened, :started, :conflicted_resolved, :exemption_denied, :extension_granted, :extension_denied]
33
-
34
- acts_as_statused(
35
- :opened, # Just Opened
36
- :started, # First screen clicked
37
- :conflicted, # Auditee has declared a conflict of interest
38
- :conflicted_resolved, # The conflict of interest has been resolved
39
- :exemption_requested, # Auditee has requested an exemption
40
- :exemption_granted, # Exemption granted -> Audit is cancelled. Exit state.
41
- :exemption_denied, # Exemption denied
42
- :extension_requested, # Audittee has requested an extension
43
- :extension_granted, # Extension granted
44
- :extension_denied, # Extension denied
45
- :submitted, # Audittee has completed questionnaire submitted. Audittee is done.
46
- :reviewed, # All audit reviews completed. Ready for a determination.
47
- :closed # Determination made by admin and/or audit committee. Exit state. All done.
48
- )
49
-
50
- acts_as_wizard(
51
- start: 'Start',
52
- information: 'Information',
53
- instructions: 'Instructions',
54
-
55
- # These 4 steps are determined by audit_level settings
56
- conflict: 'Conflict of Interest',
57
- exemption: 'Request Exemption',
58
- extension: 'Request Extension',
59
- waiting: 'Waiting',
60
- cpd: 'CPD',
61
-
62
- questionnaire: 'Questionnaire',
63
- # ... There will be one step per cpd_audit_level_sections here
64
- files: 'Upload Resume',
65
-
66
- submit: 'Confirm & Submit',
67
- complete: 'Complete'
68
- )
69
-
70
- effective_resource do
71
- due_date :date # Computed due date based on notification and extension date
72
-
73
- # Important dates
74
- notification_date :date # Can be set on CpdAudits#new, but basically created_at
75
- extension_date :date # set by admin if extension if granted
76
-
77
- # Final determination
78
- determination :string
79
-
80
- # Override Deadlines
81
- ignore_deadlines :boolean
82
-
83
- # Auditee response
84
- conflict_of_interest :boolean
85
- conflict_of_interest_reason :text
86
-
87
- exemption_request :boolean
88
- exemption_request_reason :text
89
-
90
- extension_request :boolean
91
- extension_request_date :date
92
- extension_request_reason :text
93
-
94
- # acts_as_statused
95
- status :string
96
- status_steps :text
97
-
98
- # Status dates
99
- started_at :datetime
100
- submitted_at :datetime
101
- reviewed_at :datetime
102
- closed_at :datetime
103
-
104
- # Acts as tokened
105
- token :string
106
-
107
- # Acts as Wizard
108
- wizard_steps :text
109
-
110
- timestamps
111
- end
112
-
113
- scope :deep, -> { includes(:cpd_audit_level, user: [:cpd_statements], cpd_audit_reviews: [:cpd_audit_level, :user, :cpd_audit_review_items]) }
114
- scope :sorted, -> { order(:id) }
115
-
116
- scope :draft, -> { where(submitted_at: nil) }
117
- scope :available, -> { where.not(status: COMPLETED_STATES) }
118
- scope :completed, -> { where(status: COMPLETED_STATES) }
119
-
120
- scope :waiting_on_admin, -> { where(status: WAITING_ON_ADMIN_STATES) }
121
- scope :waiting_on_auditee, -> { where(status: WAITING_ON_AUDITEE_STATES) }
122
- scope :waiting_on_reviewers, -> { where(status: WAITING_ON_REVIEWERS_STATES) }
123
-
124
- # effective_reports
125
- def reportable_scopes
126
- { draft: nil, available: nil, completed: nil, waiting_on_admin: nil, waiting_on_auditee: nil, waiting_on_reviewers: nil }
127
- end
128
-
129
- before_validation(if: -> { new_record? }) do
130
- self.notification_date ||= Time.zone.now
131
- self.due_date ||= deadline_to_submit()
132
- end
133
-
134
- validates :notification_date, presence: true
135
- validates :determination, presence: true, if: -> { closed? }
136
-
137
- validates :conflict_of_interest_reason, presence: true, if: -> { conflict_of_interest? }
138
- validates :exemption_request_reason, presence: true, if: -> { exemption_request? }
139
- validates :extension_request_date, presence: true, if: -> { extension_request? }
140
- validates :extension_request_reason, presence: true, if: -> { extension_request? }
141
-
142
- validate(if: -> { current_step == :conflict && conflict_of_interest? && !ignore_deadlines? }) do
143
- deadline = deadline_to_conflict_of_interest()
144
- self.errors.add(:base, 'deadline to declare conflict of interest has already passed') if deadline && deadline < Time.zone.now
145
- end
146
-
147
- validate(if: -> { current_step == :exemption && exemption_request? && !ignore_deadlines? }) do
148
- deadline = deadline_to_exemption()
149
- self.errors.add(:base, 'deadline to request exemption has already passed') if deadline && deadline < Time.zone.now
150
- end
151
-
152
- validate(if: -> { current_step == :extension && extension_request? && !ignore_deadlines? }) do
153
- deadline = deadline_to_extension()
154
- self.errors.add(:base, 'deadline to request extension has already passed') if deadline && deadline < Time.zone.now
155
- end
156
-
157
- validate(if: -> { determination.present? }) do
158
- unless cpd_audit_level.determinations.include?(determination)
159
- self.errors.add(:determination, 'must exist in this audit level')
160
- end
161
- end
162
-
163
- # If we're submitted. Check if we can go into reviewed?
164
- before_save(if: -> { submitted? }) { review! }
165
-
166
- after_commit(on: :create) do
167
- send_email(:cpd_audit_opened)
168
- end
169
-
170
- def to_s
171
- persisted? ? "#{cpd_audit_level} Audit of #{user}" : 'audit'
172
- end
173
-
174
- def dynamic_wizard_steps
175
- cpd_audit_level.cpd_audit_level_sections.each_with_object({}) do |section, h|
176
- h["section#{section.position+1}".to_sym] = section.title
177
- end
178
- end
179
-
180
- def can_visit_step?(step)
181
- return (step == :complete) if was_submitted? # Can only view complete step once submitted
182
- can_revisit_completed_steps(step)
183
- end
184
-
185
- def required_steps
186
- steps = [:start, :information, :instructions]
187
-
188
- steps << :conflict if cpd_audit_level.conflict_of_interest?
189
-
190
- steps << :exemption if cpd_audit_level.can_request_exemption?
191
-
192
- unless exemption_requested?
193
- steps << :extension if cpd_audit_level.can_request_extension?
194
- end
195
-
196
- if exemption_requested? || extension_requested?
197
- steps += [:waiting]
198
- end
199
-
200
- steps += [:cpd, :questionnaire] + dynamic_wizard_steps.keys + [:files, :submit, :complete]
201
-
202
- steps
203
- end
204
-
205
- def wizard_step_title(step)
206
- WIZARD_STEPS[step] || dynamic_wizard_steps.fetch(step)
207
- end
208
-
209
- def deadline_date
210
- (extension_date || notification_date)
211
- end
212
-
213
- def completed?
214
- COMPLETED_STATES.include?(status.to_sym)
215
- end
216
-
217
- def in_progress?
218
- COMPLETED_STATES.include?(status.to_sym) == false
219
- end
220
-
221
- def cpd_audit_level_section(wizard_step)
222
- position = (wizard_step.to_s.split('section').last.to_i rescue false)
223
- cpd_audit_level.cpd_audit_level_sections.find { |section| (section.position + 1) == position }
224
- end
225
-
226
- # Find or build
227
- def cpd_audit_response(cpd_audit_level_question)
228
- cpd_audit_response = cpd_audit_responses.find { |r| r.cpd_audit_level_question_id == cpd_audit_level_question.id }
229
- cpd_audit_response ||= cpd_audit_responses.build(cpd_audit: self, cpd_audit_level_question: cpd_audit_level_question)
230
- end
231
-
232
- # Auditee wizard action
233
- def start!
234
- started!
235
- end
236
-
237
- # Admin action
238
- def resolve_conflict!
239
- wizard_steps[:conflict] = nil # Have them complete the conflict step again.
240
-
241
- assign_attributes(conflict_of_interest: false, conflict_of_interest_reason: nil)
242
- conflicted_resolved!
243
- submitted!
244
-
245
- send_email(:cpd_audit_conflict_resolved)
246
- true
247
- end
248
-
249
- # Auditee wizard action
250
- def exemption!
251
- return started! unless exemption_request?
252
-
253
- update!(status: :exemption_requested)
254
- send_email(:cpd_audit_exemption_request)
255
- end
256
-
257
- # Admin action
258
- def process_exemption!
259
- case admin_process_request
260
- when 'Granted' then grant_exemption!
261
- when 'Denied' then deny_exemption!
262
- else
263
- self.errors.add(:admin_process_request, "can't be blank"); save!
264
- end
265
- end
266
-
267
- def grant_exemption!
268
- wizard_steps[:submit] ||= Time.zone.now
269
- submitted! && exemption_granted!
270
- send_email(:cpd_audit_exemption_granted)
271
- end
272
-
273
- def deny_exemption!
274
- assign_attributes(exemption_request: false)
275
- exemption_denied!
276
- send_email(:cpd_audit_exemption_denied)
277
- end
278
-
279
- # Auditee wizard action
280
- def extension!
281
- return started! unless extension_request?
282
-
283
- update!(status: :extension_requested)
284
- send_email(:cpd_audit_extension_request)
285
- end
286
-
287
- # Admin action
288
- def process_extension!
289
- case admin_process_request
290
- when 'Granted' then grant_extension!
291
- when 'Denied' then deny_extension!
292
- else
293
- self.errors.add(:admin_process_request, "can't be blank"); save!
294
- end
295
- end
296
-
297
- def grant_extension!
298
- self.extension_date = extension_request_date
299
- self.due_date = deadline_to_submit()
300
-
301
- cpd_audit_reviews.each { |cpd_audit_review| cpd_audit_review.extension_granted! }
302
- extension_granted!
303
- send_email(:cpd_audit_extension_granted)
304
- end
305
-
306
- def deny_extension!
307
- assign_attributes(extension_request: false)
308
- extension_denied!
309
- send_email(:cpd_audit_extension_denied)
310
- end
311
-
312
- # Require CPD step
313
- def user_cpd_required?
314
- return false unless user.cpd_audit_cpd_required?
315
- required_cpd_cycle.present?
316
- end
317
-
318
- def user_cpd_completed?
319
- return true if required_cpd_cycle.blank?
320
- user.cpd_statements.any? { |s| s.completed? && s.cpd_cycle_id == required_cpd_cycle.id }
321
- end
322
-
323
- def required_cpd_cycle
324
- @required_cpd_cycle ||= begin
325
- last_year = ((notification_date || created_at || Time.zone.now) - 1.year).all_year
326
- Effective::CpdCycle.available.where(start_at: last_year).first
327
- end
328
- end
329
-
330
- # Auditee wizard action
331
- def submit!
332
- if conflict_of_interest?
333
- conflicted!
334
- send_email(:cpd_audit_conflicted)
335
- else
336
- submitted!
337
-
338
- cpd_audit_reviews.each { |cpd_audit_review| cpd_audit_review.ready! }
339
- send_email(:cpd_audit_submitted)
340
- end
341
-
342
- true
343
- end
344
-
345
- # Called in a before_save. Intended for applicant_review to call in its submit! method
346
- def review!
347
- return false unless submitted?
348
- return false unless cpd_audit_reviews.present? && cpd_audit_reviews.all?(&:completed?)
349
-
350
- reviewed!
351
- send_email(:cpd_audit_reviewed)
352
- end
353
-
354
- # Admin action
355
- def close!
356
- closed!
357
- send_email(:cpd_audit_closed)
358
- end
359
-
360
- def email_form_defaults(action)
361
- { from: EffectiveCpd.mailer_sender }
362
- end
363
-
364
- def send_email(email)
365
- EffectiveCpd.send_email(email, self, email_form_params) unless email_form_skip?
366
- true
367
- end
368
-
369
- def deadline_to_conflict_of_interest
370
- return nil unless cpd_audit_level&.conflict_of_interest?
371
- return nil unless cpd_audit_level.days_to_declare_conflict.present?
372
-
373
- date = (notification_date || created_at || Time.zone.now)
374
- EffectiveResources.advance_date(date, business_days: cpd_audit_level.days_to_declare_conflict)
375
- end
376
-
377
- def deadline_to_exemption
378
- return nil unless cpd_audit_level&.can_request_exemption?
379
- return nil unless cpd_audit_level.days_to_request_exemption.present?
380
-
381
- date = (notification_date || created_at || Time.zone.now)
382
- EffectiveResources.advance_date(date, business_days: cpd_audit_level.days_to_request_exemption)
383
- end
384
-
385
- def deadline_to_extension
386
- return nil unless cpd_audit_level&.can_request_extension?
387
- return nil unless cpd_audit_level.days_to_request_extension.present?
388
-
389
- date = (notification_date || created_at || Time.zone.now)
390
- EffectiveResources.advance_date(date, business_days: cpd_audit_level.days_to_request_extension)
391
- end
392
-
393
- def deadline_to_submit
394
- return nil unless cpd_audit_level&.days_to_submit.present?
395
-
396
- date = (extension_date || notification_date || created_at || Time.zone.now)
397
- EffectiveResources.advance_date(date, business_days: cpd_audit_level.days_to_submit)
398
- end
399
-
3
+ effective_cpd_audit
400
4
  end
401
5
  end
@@ -1,87 +1,5 @@
1
1
  module Effective
2
2
  class CpdAuditLevel < ActiveRecord::Base
3
- has_many_rich_texts
4
-
5
- # For each cpd audit and cpd audit review wizard step
6
- # rich_text_all_steps_audit_content
7
- # rich_text_step_audit_content
8
-
9
- # rich_text_all_steps_audit_review_content
10
- # rich_text_step_audit_review_content
11
-
12
- has_many :cpd_audit_level_sections, -> { CpdAuditLevelSection.sorted }, inverse_of: :cpd_audit_level, dependent: :destroy
13
- accepts_nested_attributes_for :cpd_audit_level_sections, allow_destroy: true
14
-
15
- has_many :cpd_audit_level_questions, -> { CpdAuditLevelQuestion.sorted }, through: :cpd_audit_level_sections
16
-
17
- has_many :cpd_audit_reviews, -> { CpdAuditReview.sorted }, inverse_of: :cpd_audit_level, dependent: :destroy
18
- accepts_nested_attributes_for :cpd_audit_reviews, allow_destroy: true
19
-
20
- has_many :cpd_audits
21
-
22
- if respond_to?(:log_changes)
23
- log_changes(except: [:cpd_audits, :cpd_audit_reviews, :cpd_audit_level_sections, :cpd_audit_level_questions])
24
- end
25
-
26
- effective_resource do
27
- title :string
28
-
29
- determinations :text # Final determination by auditor
30
- recommendations :text # Recommendations by audit reviewers
31
-
32
- days_to_submit :integer # For auditee to submit statement
33
- days_to_review :integer # For auditor/audit_review to be completed
34
-
35
- conflict_of_interest :boolean # Feature flags
36
- can_request_exemption :boolean
37
- can_request_extension :boolean
38
-
39
- days_to_declare_conflict :integer
40
- days_to_request_exemption :integer
41
- days_to_request_extension :integer
42
-
43
- timestamps
44
- end
45
-
46
- serialize :determinations, Array
47
- serialize :recommendations, Array
48
-
49
- scope :deep, -> { all }
50
- scope :sorted, -> { order(:title) }
51
-
52
- validates :title, presence: true
53
- validates :determinations, presence: true
54
- validates :recommendations, presence: true
55
-
56
- validates :days_to_submit, numericality: { greater_than: 0, allow_nil: true }
57
- validates :days_to_review, numericality: { greater_than: 0, allow_nil: true }
58
-
59
- validates :days_to_declare_conflict, presence: true, if: -> { conflict_of_interest? }
60
- validates :days_to_declare_conflict, numericality: { greater_than: 0, allow_nil: true }
61
-
62
- validates :days_to_request_exemption, presence: true, if: -> { can_request_exemption? }
63
- validates :days_to_request_exemption, numericality: { greater_than: 0, allow_nil: true }
64
-
65
- validates :days_to_request_extension, presence: true, if: -> { can_request_extension? }
66
- validates :days_to_request_extension, numericality: { greater_than: 0, allow_nil: true }
67
-
68
- before_destroy do
69
- if (count = cpd_audits.length) > 0
70
- raise("#{count} audits belong to this audit level")
71
- end
72
- end
73
-
74
- def to_s
75
- title.presence || 'audit level'
76
- end
77
-
78
- def determinations
79
- Array(self[:determinations]) - [nil, '']
80
- end
81
-
82
- def recommendations
83
- Array(self[:recommendations]) - [nil, '']
84
- end
85
-
3
+ effective_cpd_audit_level
86
4
  end
87
5
  end
@@ -1,6 +1,6 @@
1
1
  module Effective
2
2
  class CpdAuditLevelQuestion < ActiveRecord::Base
3
- belongs_to :cpd_audit_level
3
+ belongs_to :cpd_audit_level, polymorphic: true
4
4
  belongs_to :cpd_audit_level_section
5
5
 
6
6
  has_many :cpd_audit_level_question_options, -> { CpdAuditLevelQuestionOption.sorted }, inverse_of: :cpd_audit_level_question, dependent: :delete_all
@@ -1,6 +1,6 @@
1
1
  module Effective
2
2
  class CpdAuditLevelSection < ActiveRecord::Base
3
- belongs_to :cpd_audit_level
3
+ belongs_to :cpd_audit_level, polymorphic: true
4
4
 
5
5
  has_rich_text :top_content
6
6
  has_rich_text :bottom_content
@@ -15,8 +15,9 @@ module Effective
15
15
  end
16
16
 
17
17
  effective_resource do
18
- title :string
19
- position :integer
18
+ title :string
19
+ position :integer
20
+ skip_review :boolean # Do not display this section to reviewer
20
21
 
21
22
  timestamps
22
23
  end
@@ -1,6 +1,7 @@
1
1
  module Effective
2
2
  class CpdAuditResponse < ActiveRecord::Base
3
- belongs_to :cpd_audit
3
+ belongs_to :cpd_audit, polymorphic: true
4
+
4
5
  belongs_to :cpd_audit_level_section
5
6
  belongs_to :cpd_audit_level_question
6
7
 
@@ -24,7 +25,8 @@ module Effective
24
25
  timestamps
25
26
  end
26
27
 
27
- scope :submitted, -> { where(cpd_audit: Effective::CpdAudit.where.not(submitted_at: nil)) }
28
+ scope :submitted, -> { where(cpd_audit: EffectiveCpd.CpdAudit.where.not(submitted_at: nil)) }
29
+ scope :sorted, -> { order(:id) }
28
30
  scope :deep, -> { includes(:cpd_audit, :cpd_audit_level_question) }
29
31
 
30
32
  before_validation(if: -> { cpd_audit_level_question.present? }) do