effective_cpd 1.0.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -6
  3. data/app/controllers/admin/cpd_audit_levels_controller.rb +2 -2
  4. data/app/controllers/admin/cpd_audit_reviews_controller.rb +2 -2
  5. data/app/controllers/admin/cpd_audits_controller.rb +15 -1
  6. data/app/controllers/admin/cpd_statements_controller.rb +1 -1
  7. data/app/controllers/effective/cpd_audit_reviews_controller.rb +5 -39
  8. data/app/controllers/effective/cpd_audits_controller.rb +5 -41
  9. data/app/datatables/admin/effective_cpd_audit_reviews_datatable.rb +3 -1
  10. data/app/datatables/admin/effective_cpd_audits_datatable.rb +11 -9
  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 +257 -66
  18. data/app/models/concerns/effective_cpd_audit_level.rb +7 -4
  19. data/app/models/concerns/effective_cpd_audit_review.rb +121 -65
  20. data/app/models/concerns/effective_cpd_statement.rb +1 -0
  21. data/app/models/concerns/effective_cpd_user.rb +10 -5
  22. data/app/models/effective/cpd_audit_level_question.rb +1 -1
  23. data/app/models/effective/cpd_audit_level_section.rb +4 -3
  24. data/app/models/effective/cpd_audit_response.rb +3 -2
  25. data/app/models/effective/cpd_audit_review_item.rb +1 -1
  26. data/app/views/admin/cpd_audit_levels/_form_content_audit.html.haml +1 -1
  27. data/app/views/admin/cpd_audit_levels/_form_content_audit_review.html.haml +1 -1
  28. data/app/views/admin/cpd_audit_levels/_form_cpd_audit_level.html.haml +7 -1
  29. data/app/views/admin/cpd_audit_levels/_form_cpd_audit_level_section.html.haml +2 -0
  30. data/app/views/admin/cpd_audit_reviews/_form.html.haml +4 -1
  31. data/app/views/admin/cpd_audits/_form.html.haml +1 -49
  32. data/app/views/admin/cpd_audits/_form_chat.html.haml +4 -0
  33. data/app/views/admin/cpd_audits/{_form_determination.html.haml → _form_close.html.haml} +1 -1
  34. data/app/views/admin/cpd_audits/_form_complete.html.haml +17 -0
  35. data/app/views/admin/cpd_audits/_form_cpd_audit.html.haml +60 -0
  36. data/app/views/admin/cpd_audits/_form_deadlines.html.haml +8 -9
  37. data/app/views/admin/cpd_audits/_form_exemption.html.haml +1 -1
  38. data/app/views/admin/cpd_audits/_form_extension.html.haml +1 -1
  39. data/app/views/admin/cpd_audits/_form_files.html.haml +6 -0
  40. data/app/views/admin/cpd_audits/_form_missing_info.html.haml +11 -0
  41. data/app/views/admin/cpd_audits/_form_new.html.haml +3 -1
  42. data/app/views/admin/cpd_audits/_form_process.html.haml +18 -0
  43. data/app/views/admin/cpd_audits/_status.html.haml +48 -6
  44. data/app/views/admin/users/_form_cpd.html.haml +7 -0
  45. data/app/views/admin/users/_form_cpd_audits.html.haml +8 -0
  46. data/app/views/effective/cpd/_dashboard.html.haml +15 -12
  47. data/app/views/effective/cpd_audit_level_questions/_cpd_audit_level_question.html.haml +2 -1
  48. data/app/views/effective/cpd_audit_reviews/_conflict.html.haml +1 -1
  49. data/app/views/effective/cpd_audit_reviews/_cpd_audit_level_section.html.haml +3 -3
  50. data/app/views/effective/cpd_audit_reviews/_cpd_audit_review.html.haml +3 -1
  51. data/app/views/effective/cpd_audit_reviews/_cpd_statement.html.haml +3 -3
  52. data/app/views/effective/cpd_audit_reviews/_feedback.html.haml +9 -0
  53. data/app/views/effective/cpd_audit_reviews/_files.html.haml +12 -0
  54. data/app/views/effective/cpd_audit_reviews/_layout.html.haml +11 -1
  55. data/app/views/effective/cpd_audit_reviews/_recommendation.html.haml +6 -2
  56. data/app/views/effective/cpd_audit_reviews/_summary.html.haml +41 -14
  57. data/app/views/effective/cpd_audit_reviews/chat.html.haml +4 -0
  58. data/app/views/effective/cpd_audit_reviews/conflict.html.haml +5 -1
  59. data/app/views/effective/cpd_audit_reviews/cpd_audit_level_section.html.haml +2 -2
  60. data/app/views/effective/cpd_audit_reviews/feedback.html.haml +16 -0
  61. data/app/views/effective/cpd_audit_reviews/files.html.haml +17 -0
  62. data/app/views/effective/cpd_audit_reviews/recommendation.html.haml +5 -3
  63. data/app/views/effective/cpd_audit_reviews/start.html.haml +10 -3
  64. data/app/views/effective/cpd_audit_reviews/statements.html.haml +4 -5
  65. data/app/views/effective/cpd_audit_reviews/submit.html.haml +1 -1
  66. data/app/views/effective/cpd_audit_reviews/submitted.html.haml +20 -0
  67. data/app/views/effective/cpd_audit_reviews/waiting.html.haml +1 -1
  68. data/app/views/effective/cpd_audits/_conflict.html.haml +1 -1
  69. data/app/views/effective/cpd_audits/_cpd.html.haml +1 -1
  70. data/app/views/effective/cpd_audits/_cpd_audit.html.haml +3 -1
  71. data/app/views/effective/cpd_audits/_cpd_audit_level_section.html.haml +1 -1
  72. data/app/views/effective/cpd_audits/_exemption.html.haml +1 -1
  73. data/app/views/effective/cpd_audits/_extension.html.haml +2 -2
  74. data/app/views/effective/cpd_audits/_files.html.haml +1 -1
  75. data/app/views/effective/cpd_audits/_layout.html.haml +18 -6
  76. data/app/views/effective/cpd_audits/_missing_info.html.haml +19 -0
  77. data/app/views/effective/cpd_audits/_summary.html.haml +30 -12
  78. data/app/views/effective/cpd_audits/_waiting.html.haml +1 -1
  79. data/app/views/effective/cpd_audits/chat.html.haml +4 -0
  80. data/app/views/effective/cpd_audits/conflict.html.haml +5 -1
  81. data/app/views/effective/cpd_audits/cpd_audit_level_section.html.haml +1 -0
  82. data/app/views/effective/cpd_audits/start.html.haml +10 -4
  83. data/app/views/effective/cpd_audits/submit.html.haml +5 -2
  84. data/app/views/effective/cpd_audits/{complete.html.haml → submitted.haml} +13 -8
  85. data/app/views/effective/cpd_audits/waiting.html.haml +1 -1
  86. data/app/views/effective/cpd_mailer/cpd_audit_missing_info.liquid +15 -0
  87. data/app/views/effective/cpd_mailer/cpd_audit_review_ready.liquid +1 -1
  88. data/app/views/effective/cpd_mailer/cpd_audit_submitted.liquid +3 -1
  89. data/config/effective_cpd.rb +6 -2
  90. data/config/routes.rb +2 -0
  91. data/db/migrate/01_create_effective_cpd.rb.erb +25 -7
  92. data/lib/effective_cpd/version.rb +1 -1
  93. data/lib/effective_cpd.rb +5 -0
  94. metadata +34 -5
  95. data/app/views/effective/cpd_audit_reviews/complete.html.haml +0 -20
@@ -32,6 +32,8 @@ module EffectiveCpdAuditReview
32
32
 
33
33
  waiting: 'Waiting on Auditee Submission',
34
34
 
35
+ files: 'Review Files',
36
+
35
37
  statements: 'Review CPD Statements',
36
38
  # ... There will be one step per cpd_statement here. "statement1"
37
39
 
@@ -39,8 +41,8 @@ module EffectiveCpdAuditReview
39
41
  # ... There will be one step per cpd_audit_level_sections here
40
42
 
41
43
  recommendation: 'Recommendation',
42
- submit: 'Confirm & Submit',
43
- complete: 'Complete'
44
+ submit: 'Submit',
45
+ submitted: 'Submitted'
44
46
  )
45
47
 
46
48
  attr_accessor :current_user
@@ -57,29 +59,38 @@ module EffectiveCpdAuditReview
57
59
  accepts_nested_attributes_for :cpd_audit_review_items, reject_if: :all_blank, allow_destroy: true
58
60
 
59
61
  effective_resource do
60
- token :string
61
- due_date :date
62
+ due_date :date, permitted: false
63
+
64
+ # Anonymous Name Mode
65
+ anonymous_name :string, permitted: false # Required when cpd_audit_level.anonymous?
66
+ anonymous_number :integer, permitted: false # A unique value
62
67
 
63
68
  # Auditor response
64
69
  conflict_of_interest :boolean
65
70
  conflict_of_interest_reason :text
66
71
 
67
- # Rolling comments
72
+ # Rolling comments - internal, reviewer/admin only
68
73
  comments :text
69
74
 
75
+ # Comments for the auditee to see
76
+ feedback :text
77
+
70
78
  # Recommendation Step
71
79
  recommendation :string
72
80
 
73
81
  # Status Dates
74
- submitted_at :datetime
82
+ submitted_at :datetime, permitted: false
75
83
 
76
84
  # acts_as_statused
77
85
  # I'm not using acts_as_statused yet, but I probably will later
78
- status :string
79
- status_steps :text
86
+ status :string, permitted: false
87
+ status_steps :text, permitted: false
88
+
89
+ # Acts as tokyyened
90
+ token :string, permitted: false
80
91
 
81
92
  # Wizard Progress
82
- wizard_steps :text
93
+ wizard_steps :text, permitted: false
83
94
 
84
95
  timestamps
85
96
  end
@@ -89,10 +100,11 @@ module EffectiveCpdAuditReview
89
100
 
90
101
  scope :available, -> { where(submitted_at: nil) }
91
102
  scope :completed, -> { where.not(submitted_at: nil) }
103
+ scope :done, -> { where.not(submitted_at: nil) }
92
104
 
93
105
  # effective_reports
94
106
  def reportable_scopes
95
- { available: nil, completed: nil }
107
+ { available: nil, done: nil }
96
108
  end
97
109
 
98
110
  before_validation(if: -> { new_record? }) do
@@ -106,40 +118,72 @@ module EffectiveCpdAuditReview
106
118
  end
107
119
  end
108
120
 
121
+ with_options(if: -> { cpd_audit_level&.anonymous? }) do
122
+ before_validation { assign_anonymous_name_and_number }
123
+
124
+ validates :anonymous_name, presence: true
125
+ validates :anonymous_number, presence: true
126
+ end
127
+
109
128
  after_commit(on: :create) { send_email(:cpd_audit_review_opened) }
110
- after_commit(on: :destroy) { cpd_audit.review! }
111
- end
129
+ after_commit(on: :destroy) { cpd_audit.try_review! }
112
130
 
113
- def to_s
114
- persisted? ? "#{cpd_audit_level} Audit Review by #{user}" : 'audit review'
115
- end
131
+ def dynamic_wizard_statement_steps
132
+ @statement_steps ||= auditee_cpd_statements.each_with_object({}) do |cpd_statement, h|
133
+ h["statement#{cpd_statement.cpd_cycle_id}".to_sym] = "#{cpd_statement.cpd_cycle.to_s} Activities"
134
+ end
135
+ end
116
136
 
117
- # Find or build
118
- def cpd_audit_review_item(item)
119
- unless item.kind_of?(CpdAuditResponse) || item.kind_of?(CpdStatementActivity)
120
- raise("expected a cpd_audit_response or cpd_statement_activity")
137
+ def dynamic_wizard_questionnaire_steps
138
+ @questionnaire_steps ||= cpd_audit_level.cpd_audit_level_sections.reject(&:skip_review?).each_with_object({}) do |section, h|
139
+ h["section#{section.position+1}".to_sym] = section.title
140
+ end
121
141
  end
122
142
 
123
- cpd_audit_review_item = cpd_audit_review_items.find { |cari| cari.item == item }
124
- cpd_audit_review_item ||= cpd_audit_review_items.build(item: item)
125
- end
143
+ def dynamic_wizard_steps
144
+ dynamic_wizard_statement_steps.merge(dynamic_wizard_questionnaire_steps)
145
+ end
126
146
 
127
- # The dynamic CPD Statement review steps
128
- def auditee_cpd_statements
129
- cpd_audit.user.cpd_statements.select do |cpd_statement|
130
- cpd_statement.completed? && (submitted_at.blank? || cpd_statement.submitted_at < submitted_at)
147
+ def wizard_step_title(step)
148
+ self.class::WIZARD_STEPS[step] || dynamic_wizard_steps.fetch(step)
149
+ end
150
+
151
+ def required_steps
152
+ steps = [:start, :information, :instructions]
153
+
154
+ steps << :conflict if cpd_audit_level.conflict_of_interest?
155
+
156
+ if conflict_of_interest?
157
+ return steps + [:submit, :submitted]
158
+ end
159
+
160
+ steps += [:waiting] unless ready?
161
+
162
+ steps += [:files]
163
+ steps += [:statements] + dynamic_wizard_statement_steps.keys
164
+ steps += [:questionnaire] + dynamic_wizard_questionnaire_steps.keys
165
+ steps += [:recommendation, :submit, :submitted]
166
+
167
+ steps
131
168
  end
169
+
170
+ def can_visit_step?(step)
171
+ return (step == :submitted) if completed? # Can only view complete step once submitted
172
+ can_revisit_completed_steps(step)
173
+ end
174
+
132
175
  end
133
176
 
134
- def cpd_statement(wizard_step)
135
- cpd_cycle_id = (wizard_step.to_s.split('statement').last.to_i rescue false)
136
- auditee_cpd_statements.find { |cpd_statement| cpd_statement.cpd_cycle_id == cpd_cycle_id }
177
+ def to_s
178
+ persisted? ? "#{cpd_audit_level} Audit Review by #{name}" : 'audit review'
137
179
  end
138
180
 
139
- def dynamic_wizard_statement_steps
140
- @statement_steps ||= auditee_cpd_statements.each_with_object({}) do |cpd_statement, h|
141
- h["statement#{cpd_statement.cpd_cycle_id}".to_sym] = "#{cpd_statement.cpd_cycle.to_s} Activities"
142
- end
181
+ def name
182
+ anonymous_name.presence || user.to_s
183
+ end
184
+
185
+ def anonymous?
186
+ cpd_audit_level&.anonymous?
143
187
  end
144
188
 
145
189
  # The dynamic CPD Audit Level Sections steps
@@ -148,41 +192,26 @@ module EffectiveCpdAuditReview
148
192
  cpd_audit_level.cpd_audit_level_sections.find { |section| (section.position + 1) == position }
149
193
  end
150
194
 
151
- def dynamic_wizard_questionnaire_steps
152
- @questionnaire_steps ||= cpd_audit_level.cpd_audit_level_sections.each_with_object({}) do |section, h|
153
- h["section#{section.position+1}".to_sym] = section.title
195
+ # Find or build
196
+ def cpd_audit_review_item(item)
197
+ unless item.kind_of?(Effective::CpdAuditResponse) || item.kind_of?(Effective::CpdStatementActivity)
198
+ raise("expected a cpd_audit_response or cpd_statement_activity")
154
199
  end
155
- end
156
200
 
157
- def dynamic_wizard_steps
158
- dynamic_wizard_statement_steps.merge(dynamic_wizard_questionnaire_steps)
159
- end
160
-
161
- def can_visit_step?(step)
162
- return (step == :complete) if completed? # Can only view complete step once submitted
163
- can_revisit_completed_steps(step)
201
+ cpd_audit_review_item = cpd_audit_review_items.find { |cari| cari.item == item }
202
+ cpd_audit_review_item ||= cpd_audit_review_items.build(item: item)
164
203
  end
165
204
 
166
- def required_steps
167
- steps = [:start, :information, :instructions]
168
-
169
- steps << :conflict if cpd_audit_level.conflict_of_interest?
170
-
171
- if conflict_of_interest?
172
- return steps + [:submit, :complete]
205
+ # The dynamic CPD Statement review steps
206
+ def auditee_cpd_statements
207
+ cpd_audit.user.cpd_statements.select do |cpd_statement|
208
+ cpd_statement.completed? && (submitted_at.blank? || cpd_statement.submitted_at < submitted_at)
173
209
  end
174
-
175
- steps += [:waiting] unless ready?
176
-
177
- steps += [:statements] + dynamic_wizard_statement_steps.keys
178
- steps += [:questionnaire] + dynamic_wizard_questionnaire_steps.keys
179
- steps += [:recommendation, :submit, :complete]
180
-
181
- steps
182
210
  end
183
211
 
184
- def wizard_step_title(step)
185
- WIZARD_STEPS[step] || dynamic_wizard_steps.fetch(step)
212
+ def cpd_statement(wizard_step)
213
+ cpd_cycle_id = (wizard_step.to_s.split('statement').last.to_i rescue false)
214
+ auditee_cpd_statements.find { |cpd_statement| cpd_statement.cpd_cycle_id == cpd_cycle_id }
186
215
  end
187
216
 
188
217
  # Called by CpdAudit.extension_granted
@@ -198,14 +227,18 @@ module EffectiveCpdAuditReview
198
227
  # Called by review wizard submit step
199
228
  def submit!
200
229
  update!(submitted_at: Time.zone.now)
201
- cpd_audit.review! # maybe go from submitted->removed
230
+ cpd_audit.try_review! # audit might go from completed->reviewed
202
231
 
203
232
  send_email(:cpd_audit_review_submitted)
204
233
  end
205
234
 
206
235
  # When ready, the applicant review wizard hides the waiting step
207
236
  def ready?
208
- cpd_audit&.was_submitted?
237
+ cpd_audit&.ready_to_review?
238
+ end
239
+
240
+ def draft?
241
+ submitted_at.blank?
209
242
  end
210
243
 
211
244
  def in_progress?
@@ -216,6 +249,10 @@ module EffectiveCpdAuditReview
216
249
  submitted_at.present?
217
250
  end
218
251
 
252
+ def done?
253
+ submitted_at.present?
254
+ end
255
+
219
256
  def email_form_defaults(action)
220
257
  { from: EffectiveCpd.mailer_sender }
221
258
  end
@@ -226,16 +263,35 @@ module EffectiveCpdAuditReview
226
263
  end
227
264
 
228
265
  def deadline_to_conflict_of_interest
229
- cpd_audit.deadline_to_conflict_of_interest
266
+ cpd_audit&.deadline_to_conflict_of_interest
230
267
  end
231
268
 
232
269
  def deadline_to_review
233
270
  return nil unless cpd_audit_level&.days_to_review.present?
234
271
 
235
- date = cpd_audit.deadline_to_submit
272
+ date = cpd_audit&.deadline_to_submit
236
273
  return nil unless date.present?
237
274
 
238
275
  EffectiveResources.advance_date(date, business_days: cpd_audit_level.days_to_review)
239
276
  end
240
277
 
278
+ # The name pattern is A23XXX where XXX is an autoincrement
279
+ def assign_anonymous_name_and_number
280
+ return if anonymous_name.present? || anonymous_number.present?
281
+ return if cpd_audit_level.blank?
282
+
283
+ prefix = cpd_audit_level.anonymous_audit_reviews_prefix
284
+ raise('expected cpd audit level to have an anonymous audit review prefix') unless prefix.present?
285
+
286
+ # Where starts with prefix
287
+ number = cpd_audit.cpd_audit_reviews.map { |ar| ar.anonymous_number }.compact.max if cpd_audit.new_record?
288
+ number ||= (self.class.all.where('anonymous_name LIKE ?', "#{prefix}%").maximum('anonymous_number') || 0)
289
+ number = number + 1 # The next number
290
+
291
+ # Apply prefix and pad number to 3 digits
292
+ name = prefix + number.to_s.rjust(3, '0')
293
+
294
+ assign_attributes(anonymous_number: number, anonymous_name: name)
295
+ end
296
+
241
297
  end
@@ -68,6 +68,7 @@ module EffectiveCpdStatement
68
68
 
69
69
  scope :draft, -> { where(submitted_at: nil) }
70
70
  scope :completed, -> { where.not(submitted_at: nil) }
71
+ scope :submitted, -> { where.not(submitted_at: nil) }
71
72
 
72
73
  # effective_reports
73
74
  def reportable_scopes
@@ -18,13 +18,14 @@ module EffectiveCpdUser
18
18
 
19
19
  included do
20
20
  # App Scoped
21
- has_many :cpd_statements, -> { order(:cpd_cycle_id) }, inverse_of: :user
21
+ has_many :cpd_statements, -> { order(:cpd_cycle_id) }, inverse_of: :user, dependent: :destroy
22
+ accepts_nested_attributes_for :cpd_statements, allow_destroy: true
22
23
 
23
- # Effective
24
- has_many :cpd_audits, -> { Effective::CpdAudit.sorted }, inverse_of: :user, class_name: 'Effective::CpdAudit'
25
- has_many :cpd_audit_reviews, -> { Effective::CpdAuditReview.sorted }, inverse_of: :user, class_name: 'Effective::CpdAuditReview'
24
+ has_many :cpd_audits, -> { order(:id) }, inverse_of: :user
25
+ has_many :cpd_audit_reviews, -> { order(:id) }, inverse_of: :user
26
26
 
27
- accepts_nested_attributes_for :cpd_statements
27
+ scope :cpd_audit_auditees, -> { without_role(:cpd_audit_reviewer) }
28
+ scope :cpd_audit_reviewers, -> { with_role(:cpd_audit_reviewer) }
28
29
  end
29
30
 
30
31
  # This one will actually be enforced or displayed first
@@ -42,6 +43,10 @@ module EffectiveCpdUser
42
43
  true
43
44
  end
44
45
 
46
+ def cpd_audit_reviewer?
47
+ roles.include?(:cpd_audit_reviewer)
48
+ end
49
+
45
50
  def cpd_statement(cpd_cycle:)
46
51
  raise('expected an CpdCycle') unless cpd_cycle.class.respond_to?(:effective_cpd_cycle?)
47
52
  cpd_statements.find { |cpd_statement| cpd_statement.cpd_cycle_id == cpd_cycle.id }
@@ -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,7 @@ 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)) }
28
29
  scope :sorted, -> { order(:id) }
29
30
  scope :deep, -> { includes(:cpd_audit, :cpd_audit_level_question) }
30
31
 
@@ -1,6 +1,6 @@
1
1
  module Effective
2
2
  class CpdAuditReviewItem < ActiveRecord::Base
3
- belongs_to :cpd_audit_review
3
+ belongs_to :cpd_audit_review, polymorphic: true
4
4
  belongs_to :item, polymorphic: true # CpdAuditResponse or CpdStatementActivity
5
5
 
6
6
  if respond_to?(:log_changes)
@@ -9,7 +9,7 @@
9
9
 
10
10
  %hr
11
11
 
12
- - Effective::CpdAudit::WIZARD_STEPS.each do |step, title|
12
+ - EffectiveCpd.CpdAudit::WIZARD_STEPS.each do |step, title|
13
13
  = card("#{title} Content") do
14
14
  - if defined?(EffectiveArticleEditor)
15
15
  = f.article_editor "rich_text_#{step}_audit_content", label: false, hint: "displayed on the auditee wizard #{step} wizard step only"
@@ -9,7 +9,7 @@
9
9
 
10
10
  %hr
11
11
 
12
- - Effective::CpdAuditReview::WIZARD_STEPS.each do |step, title|
12
+ - EffectiveCpd.CpdAuditReview::WIZARD_STEPS.each do |step, title|
13
13
  = card("#{title} Content") do
14
14
  - if defined?(EffectiveArticleEditor)
15
15
  = f.article_editor "rich_text_#{step}_audit_review_content", label: false, hint: "displayed on the audit reviewer #{step} wizard step only"
@@ -1,11 +1,17 @@
1
1
  = effective_form_with(model: [:admin, cpd_audit_level], engine: true) do |f|
2
2
  = f.text_field :title, hint: 'A title for this kind of audit'
3
3
 
4
+ = f.check_box :anonymous, label: 'Yes, this is an anonymous audit'
5
+
6
+ = f.show_if(:anonymous, true) do
7
+ .row
8
+ .col= f.text_field :anonymous_audits_prefix, hint: 'Used to prefix audits. Something like A23'
9
+ .col= f.text_field :anonymous_audit_reviews_prefix, hint: 'Used to prefix audit reviewers. Something like R23'
10
+
4
11
  = f.select :recommendations, f.object.recommendations,
5
12
  label: 'Audit Review recommendation choices', tags: true, placeholder: 'Type to add item...',
6
13
  hint: 'The recommendation made by an audit reviewer when reviewing an audit. Begin typing and then press enter to add a choice'
7
14
 
8
-
9
15
  = f.select :determinations, f.object.determinations,
10
16
  label: 'Audit determination choices', tags: true, placeholder: 'Type to add item...',
11
17
  hint: 'The final determination made by the auditor when closing an audit. Begin typing and then press enter to add a choice.'
@@ -7,6 +7,8 @@
7
7
  = fas.rich_text_area :top_content
8
8
  = fas.rich_text_area :bottom_content
9
9
 
10
+ = fas.check_box :skip_review, label: 'Do not display this section to audit reviewers'
11
+
10
12
  = f.submit
11
13
 
12
14
  %h2 Questions
@@ -1,9 +1,12 @@
1
1
  = effective_form_with(model: [:admin, cpd_audit_review], engine: true) do |f|
2
2
  - if inline_datatable?
3
3
  = f.hidden_field :cpd_audit_id
4
+ = f.hidden_field :cpd_audit_type
5
+
4
6
  = f.static_field :cpd_audit, label: 'CPD Audit'
5
7
  - else
6
- = f.select :cpd_audit_id, Effective::CpdAudit.available.sorted.all
8
+ = f.hidden_field :cpd_audit_type, value: EffectiveCpd.CpdAudit.class.name
9
+ = f.select :cpd_audit_id, EffectiveCpd.CpdAudit.available.sorted.all
7
10
 
8
11
  = render('admin/cpd_audits/audit_reviewer_fields', f: f)
9
12
 
@@ -1,49 +1 @@
1
- = tabs do
2
- - if cpd_audit.new_record?
3
- = tab 'New Audit' do
4
- = render 'admin/cpd_audits/form_new', cpd_audit: cpd_audit
5
-
6
- - if cpd_audit.persisted?
7
- - if cpd_audit.completed?
8
- = tab 'Audit' do
9
- = render 'effective/cpd_audits/cpd_audit', cpd_audit: cpd_audit
10
-
11
- = tab 'Status' do
12
- = render 'admin/cpd_audits/status', cpd_audit: cpd_audit
13
- - else
14
- = tab 'Status' do
15
- = render 'admin/cpd_audits/status', cpd_audit: cpd_audit
16
-
17
- = tab 'Audit' do
18
- = render 'effective/cpd_audits/cpd_audit', cpd_audit: cpd_audit
19
-
20
- = tab 'Deadlines' do
21
- = render 'admin/cpd_audits/form_deadlines', cpd_audit: cpd_audit
22
-
23
- = tab 'Statements' do
24
- - datatable = Admin::EffectiveCpdStatementsDatatable.new(user_id: cpd_audit.user.id, user_type: cpd_audit.user.class.name)
25
- = render_datatable(datatable, inline: true, simple: true)
26
-
27
- = tab 'Audit Reviews' do
28
- - datatable = Admin::EffectiveCpdAuditReviewsDatatable.new(cpd_audit_id: cpd_audit.id)
29
- = render_datatable(datatable, inline: true, simple: true)
30
-
31
- - unless cpd_audit.closed?
32
- = tab 'Determination' do
33
- = render 'admin/cpd_audits/form_determination', cpd_audit: cpd_audit
34
-
35
- - if cpd_audit.conflicted?
36
- = tab 'Process Conflict of Interest' do
37
- = render 'admin/cpd_audits/form_conflict', cpd_audit: cpd_audit
38
-
39
- - if cpd_audit.exemption_requested?
40
- = tab 'Process Exemption Request' do
41
- = render 'admin/cpd_audits/form_exemption', cpd_audit: cpd_audit
42
-
43
- - if cpd_audit.extension_requested?
44
- = tab 'Process Extension Request' do
45
- = render 'admin/cpd_audits/form_extension', cpd_audit: cpd_audit
46
-
47
- - if cpd_audit.respond_to?(:log_changes_datatable)
48
- = tab 'Logs' do
49
- = render_inline_datatable(cpd_audit.log_changes_datatable)
1
+ = render('admin/cpd_audits/form_cpd_audit', cpd_audit: cpd_audit)
@@ -0,0 +1,4 @@
1
+ - if cpd_audit.chat.present?
2
+ = render('effective/chats/chat', chat: cpd_audit.chat)
3
+ - else
4
+ %p No chat messages
@@ -1,6 +1,6 @@
1
1
  = card('Determination') do
2
2
  = effective_form_with(model: [:admin, cpd_audit], engine: true) do |f|
3
- %p This action will complete this audit and mark it as closed.
3
+ %p This action will close this audit with the following determination:
4
4
 
5
5
  = f.select :determination, cpd_audit.cpd_audit_level.determinations
6
6
 
@@ -0,0 +1,17 @@
1
+ = effective_form_with(model: [:admin, cpd_audit], engine: true) do |f|
2
+ = f.hidden_field :id
3
+
4
+ %p The #{cpd_audit} will be marked <strong>completed</strong>. All deliverables have been received and all requirements completed.
5
+
6
+ %p The audit reviewer(s) will be notified that this audit is ready to review.
7
+
8
+ %h3 Email to send
9
+ %p
10
+
11
+ An
12
+ - email = Effective::EmailTemplate.where(template_name: :cpd_audit_review_ready).first!
13
+ = link_to('cpd_audit_review_ready email', effective_email_templates.edit_admin_email_template_path(email))
14
+
15
+ email will be sent to each reviewer.
16
+
17
+ = f.submit 'Complete Audit', border: false, center: true, 'data-confirm': "Complete #{f.object}?"
@@ -0,0 +1,60 @@
1
+ = tabs do
2
+ - if cpd_audit.new_record?
3
+ = tab 'New Audit' do
4
+ = render 'admin/cpd_audits/form_new', cpd_audit: cpd_audit
5
+
6
+ - if cpd_audit.persisted?
7
+ - if cpd_audit.completed?
8
+ = tab 'Audit' do
9
+ = render 'effective/cpd_audits/cpd_audit', cpd_audit: cpd_audit
10
+
11
+ = tab 'Status' do
12
+ = render 'admin/cpd_audits/status', cpd_audit: cpd_audit
13
+ - else
14
+ = tab 'Status' do
15
+ = render 'admin/cpd_audits/status', cpd_audit: cpd_audit
16
+
17
+ = tab 'Audit' do
18
+ = render 'effective/cpd_audits/cpd_audit', cpd_audit: cpd_audit
19
+
20
+ - if cpd_audit.conflicted?
21
+ = tab 'Process Conflict of Interest' do
22
+ = render 'admin/cpd_audits/form_conflict', cpd_audit: cpd_audit
23
+
24
+ - if cpd_audit.exemption_requested?
25
+ = tab 'Process Exemption Request' do
26
+ = render 'admin/cpd_audits/form_exemption', cpd_audit: cpd_audit
27
+
28
+ - if cpd_audit.extension_requested?
29
+ = tab 'Process Extension Request' do
30
+ = render 'admin/cpd_audits/form_extension', cpd_audit: cpd_audit
31
+
32
+ - if cpd_audit.was_submitted? == false
33
+ = tab 'Deadlines' do
34
+ = render 'admin/cpd_audits/form_deadlines', cpd_audit: cpd_audit
35
+
36
+ - if cpd_audit.was_submitted? && !cpd_audit.closed?
37
+ = tab 'Process' do
38
+ = render 'admin/cpd_audits/form_process', cpd_audit: cpd_audit
39
+
40
+ = yield
41
+
42
+ = tab 'Files' do
43
+ = render 'admin/cpd_audits/form_files', cpd_audit: cpd_audit
44
+
45
+ - if cpd_audit.user_cpd_required?
46
+ = tab 'Statements' do
47
+ - datatable = Admin::EffectiveCpdStatementsDatatable.new(user: cpd_audit.user)
48
+ = render_datatable(datatable, inline: true, simple: true)
49
+
50
+ = tab 'Audit Reviews' do
51
+ - datatable = EffectiveResources.best('Admin::EffectiveCpdAuditReviewsDatatable').new(cpd_audit: cpd_audit)
52
+ = render_datatable(datatable, inline: true, simple: true)
53
+
54
+ - if EffectiveCpd.use_effective_messaging?
55
+ = tab 'Chat' do
56
+ = render 'admin/cpd_audits/form_chat', cpd_audit: cpd_audit
57
+
58
+ - if cpd_audit.respond_to?(:log_changes_datatable)
59
+ = tab 'Logs' do
60
+ = render_inline_datatable(cpd_audit.log_changes_datatable)
@@ -1,12 +1,11 @@
1
- = card('Deadlines') do
2
- = effective_form_with(model: [:admin, cpd_audit], engine: true) do |f|
3
- %p The audittee has the following deadlines:
1
+ = effective_form_with(model: [:admin, cpd_audit], engine: true) do |f|
2
+ %p The audittee has the following deadlines:
4
3
 
5
- %ul
6
- %li To declare conflict of interest: #{f.object.deadline_to_conflict_of_interest}
7
- %li To request exemption: #{f.object.deadline_to_exemption}
8
- %li To request extension: #{f.object.deadline_to_extension}
4
+ %ul
5
+ %li To declare conflict of interest: #{f.object.deadline_to_conflict_of_interest}
6
+ %li To request exemption: #{f.object.deadline_to_exemption}
7
+ %li To request extension: #{f.object.deadline_to_extension}
9
8
 
10
- = f.check_box :ignore_deadlines, label: 'Yes, ignore audittee deadlines and allow these actions to be performed'
9
+ = f.check_box :ignore_deadlines, label: 'Yes, ignore audittee deadlines and allow these actions to be performed'
11
10
 
12
- = f.submit 'Save', center: true
11
+ = f.submit 'Save', center: true
@@ -11,7 +11,7 @@
11
11
  %p The exemption request shall be
12
12
 
13
13
  = effective_form_with(model: [:admin, cpd_audit], engine: true) do |f|
14
- = f.radios :admin_process_request, Effective::CpdAudit::ADMIN_PROCESS_REQUEST_OPTIONS, label: false, buttons: true, required: true
14
+ = f.radios :admin_process_request, EffectiveCpd.CpdAudit.admin_process_request_options, label: false, buttons: true, required: true
15
15
 
16
16
  = f.show_if :admin_process_request, 'Granted' do
17
17
  %p Send email
@@ -11,7 +11,7 @@
11
11
  %p The extension request shall be
12
12
 
13
13
  = effective_form_with(model: [:admin, cpd_audit], engine: true) do |f|
14
- = f.radios :admin_process_request, Effective::CpdAudit::ADMIN_PROCESS_REQUEST_OPTIONS, label: false, buttons: true, required: true
14
+ = f.radios :admin_process_request, EffectiveCpd.CpdAudit.admin_process_request_options, label: false, buttons: true, required: true
15
15
 
16
16
  = f.show_if :admin_process_request, 'Granted' do
17
17
  %p Send email
@@ -0,0 +1,6 @@
1
+ = effective_form_with(model: [:admin, cpd_audit], engine: true) do |f|
2
+ %p The auditee has attached the following:
3
+
4
+ = f.file_field :files
5
+
6
+ = f.submit 'Save', center: true