effective_cpd 0.6.9 → 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.
@@ -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
@@ -25,6 +25,7 @@ module Effective
25
25
  end
26
26
 
27
27
  scope :submitted, -> { where(cpd_audit: Effective::CpdAudit.where.not(submitted_at: nil)) }
28
+ scope :sorted, -> { order(:id) }
28
29
  scope :deep, -> { includes(:cpd_audit, :cpd_audit_level_question) }
29
30
 
30
31
  before_validation(if: -> { cpd_audit_level_question.present? }) do
@@ -1,228 +1,5 @@
1
1
  module Effective
2
2
  class CpdAuditReview < ActiveRecord::Base
3
- attr_accessor :current_user
4
- attr_accessor :current_step
5
-
6
- belongs_to :cpd_audit
7
- belongs_to :cpd_audit_level
8
- belongs_to :user, polymorphic: true # Auditor
9
-
10
- has_many :cpd_audit_review_items, -> { CpdAuditReviewItem.sorted }, inverse_of: :cpd_audit_review, dependent: :destroy
11
- accepts_nested_attributes_for :cpd_audit_review_items, reject_if: :all_blank, allow_destroy: true
12
-
13
- if respond_to?(:log_changes)
14
- log_changes(to: :cpd_audit, except: :wizard_steps)
15
- end
16
-
17
- acts_as_email_form
18
- acts_as_tokened
19
- acts_as_reportable if respond_to?(:acts_as_reportable)
20
-
21
- acts_as_wizard(
22
- start: 'Start',
23
- information: 'Information',
24
- instructions: 'Instructions',
25
-
26
- # Optional based on cpd_audit_level options
27
- conflict: 'Conflict of Interest',
28
-
29
- waiting: 'Waiting on Auditee Submission',
30
-
31
- statements: 'Review CPD Statements',
32
- # ... There will be one step per cpd_statement here. "statement1"
33
-
34
- questionnaire: 'Review Questionnaire Responses',
35
- # ... There will be one step per cpd_audit_level_sections here
36
-
37
- recommendation: 'Recommendation',
38
- submit: 'Confirm & Submit',
39
- complete: 'Complete'
40
- )
41
-
42
- effective_resource do
43
- token :string
44
- due_date :date
45
-
46
- # Auditor response
47
- conflict_of_interest :boolean
48
- conflict_of_interest_reason :text
49
-
50
- # Rolling comments
51
- comments :text
52
-
53
- # Recommendation Step
54
- recommendation :string
55
-
56
- # Status Dates
57
- submitted_at :datetime
58
-
59
- # acts_as_statused
60
- # I'm not using acts_as_statused yet, but I probably will later
61
- status :string
62
- status_steps :text
63
-
64
- # Wizard Progress
65
- wizard_steps :text
66
-
67
- timestamps
68
- end
69
-
70
- scope :deep, -> { includes(:cpd_audit, :cpd_audit_level, :user) }
71
- scope :sorted, -> { order(:id) }
72
-
73
- scope :available, -> { where(submitted_at: nil) }
74
- scope :completed, -> { where.not(submitted_at: nil) }
75
-
76
- # effective_reports
77
- def reportable_scopes
78
- { available: nil, completed: nil }
79
- end
80
-
81
- before_validation(if: -> { new_record? }) do
82
- self.cpd_audit_level ||= cpd_audit&.cpd_audit_level
83
- self.due_date ||= deadline_to_review()
84
- end
85
-
86
- validate(if: -> { recommendation.present? }) do
87
- unless cpd_audit_level.recommendations.include?(recommendation)
88
- self.errors.add(:recommendation, 'must exist in this audit level')
89
- end
90
- end
91
-
92
- after_commit(on: :create) { send_email(:cpd_audit_review_opened) }
93
- after_commit(on: :destroy) { cpd_audit.review! }
94
-
95
- def to_s
96
- 'audit review'
97
- end
98
-
99
- def to_s
100
- persisted? ? "#{cpd_audit_level} Audit Review by #{user}" : 'audit review'
101
- end
102
-
103
- # Find or build
104
- def cpd_audit_review_item(item)
105
- unless item.kind_of?(CpdAuditResponse) || item.kind_of?(CpdStatementActivity)
106
- raise("expected a cpd_audit_response or cpd_statement_activity")
107
- end
108
-
109
- cpd_audit_review_item = cpd_audit_review_items.find { |cari| cari.item == item }
110
- cpd_audit_review_item ||= cpd_audit_review_items.build(item: item)
111
- end
112
-
113
- # The dynamic CPD Statement review steps
114
- def auditee_cpd_statements
115
- cpd_audit.user.cpd_statements.select do |cpd_statement|
116
- cpd_statement.completed? && (submitted_at.blank? || cpd_statement.submitted_at < submitted_at)
117
- end
118
- end
119
-
120
- def cpd_statement(wizard_step)
121
- cpd_cycle_id = (wizard_step.to_s.split('statement').last.to_i rescue false)
122
- auditee_cpd_statements.find { |cpd_statement| cpd_statement.cpd_cycle_id == cpd_cycle_id }
123
- end
124
-
125
- def dynamic_wizard_statement_steps
126
- @statement_steps ||= auditee_cpd_statements.each_with_object({}) do |cpd_statement, h|
127
- h["statement#{cpd_statement.cpd_cycle_id}".to_sym] = "#{cpd_statement.cpd_cycle.to_s} Activities"
128
- end
129
- end
130
-
131
- # The dynamic CPD Audit Level Sections steps
132
- def cpd_audit_level_section(wizard_step)
133
- position = (wizard_step.to_s.split('section').last.to_i rescue false)
134
- cpd_audit_level.cpd_audit_level_sections.find { |section| (section.position + 1) == position }
135
- end
136
-
137
- def dynamic_wizard_questionnaire_steps
138
- @questionnaire_steps ||= cpd_audit_level.cpd_audit_level_sections.each_with_object({}) do |section, h|
139
- h["section#{section.position+1}".to_sym] = section.title
140
- end
141
- end
142
-
143
- def dynamic_wizard_steps
144
- dynamic_wizard_statement_steps.merge(dynamic_wizard_questionnaire_steps)
145
- end
146
-
147
- def can_visit_step?(step)
148
- return (step == :complete) if completed? # Can only view complete step once submitted
149
- can_revisit_completed_steps(step)
150
- end
151
-
152
- def required_steps
153
- steps = [:start, :information, :instructions]
154
-
155
- steps << :conflict if cpd_audit_level.conflict_of_interest?
156
-
157
- if conflict_of_interest?
158
- return steps + [:submit, :complete]
159
- end
160
-
161
- steps += [:waiting] unless ready?
162
-
163
- steps += [:statements] + dynamic_wizard_statement_steps.keys
164
- steps += [:questionnaire] + dynamic_wizard_questionnaire_steps.keys
165
- steps += [:recommendation, :submit, :complete]
166
-
167
- steps
168
- end
169
-
170
- def wizard_step_title(step)
171
- WIZARD_STEPS[step] || dynamic_wizard_steps.fetch(step)
172
- end
173
-
174
- # Called by CpdAudit.extension_granted
175
- def extension_granted!
176
- self.due_date = deadline_to_review()
177
- end
178
-
179
- # Called by CpdAudit.submit!
180
- def ready!
181
- send_email(:cpd_audit_review_ready)
182
- end
183
-
184
- # Called by review wizard submit step
185
- def submit!
186
- update!(submitted_at: Time.zone.now)
187
- cpd_audit.review! # maybe go from submitted->removed
188
-
189
- send_email(:cpd_audit_review_submitted)
190
- end
191
-
192
- # When ready, the applicant review wizard hides the waiting step
193
- def ready?
194
- cpd_audit&.was_submitted?
195
- end
196
-
197
- def in_progress?
198
- submitted_at.blank?
199
- end
200
-
201
- def completed?
202
- submitted_at.present?
203
- end
204
-
205
- def email_form_defaults(action)
206
- { from: EffectiveCpd.mailer_sender }
207
- end
208
-
209
- def send_email(email)
210
- EffectiveCpd.send_email(email, self, email_form_params) unless email_form_skip?
211
- true
212
- end
213
-
214
- def deadline_to_conflict_of_interest
215
- cpd_audit.deadline_to_conflict_of_interest
216
- end
217
-
218
- def deadline_to_review
219
- return nil unless cpd_audit_level&.days_to_review.present?
220
-
221
- date = cpd_audit.deadline_to_submit
222
- return nil unless date.present?
223
-
224
- EffectiveResources.advance_date(date, business_days: cpd_audit_level.days_to_review)
225
- end
226
-
3
+ effective_cpd_audit_review
227
4
  end
228
5
  end
@@ -32,6 +32,9 @@ EffectiveCpd.setup do |config|
32
32
  # CPD Class Settings
33
33
  # Configure the class responsible for the cpd statements.
34
34
  # config.cpd_statement_class_name = 'Effective::CpdStatement'
35
+ # config.cpd_audit_class_name = 'Effective::CpdAudit'
36
+ # config.cpd_audit_level_class_name = 'Effective::CpdAuditLevel'
37
+ # config.cpd_audit_review_class_name = 'Effective::CpdAuditReview'
35
38
 
36
39
  # Program label settings
37
40
  config.program_label = 'CPD' # CPD or MCE
@@ -120,6 +120,8 @@ class CreateEffectiveCpd < ActiveRecord::Migration[6.0]
120
120
 
121
121
  create_table <%= @cpd_audit_levels_table_name %> do |t|
122
122
  t.string :title
123
+ t.boolean :anonymous, default: false
124
+
123
125
  t.text :determinations
124
126
  t.text :recommendations
125
127
 
@@ -172,13 +174,19 @@ class CreateEffectiveCpd < ActiveRecord::Migration[6.0]
172
174
  end
173
175
 
174
176
  create_table <%= @cpd_audits_table_name %> do |t|
175
- t.references :cpd_audit_level
177
+ t.intger :cpd_audit_level_id
178
+ t.string :cpd_audit_level_type
176
179
 
177
180
  t.integer :user_id
178
181
  t.string :user_type
179
182
 
180
183
  t.date :due_date
181
184
 
185
+ t.string :anonymous_name
186
+ t.string :selection
187
+ t.string :region
188
+ t.text :notes
189
+
182
190
  t.date :notification_date
183
191
  t.date :extension_date
184
192
 
@@ -213,8 +221,11 @@ class CreateEffectiveCpd < ActiveRecord::Migration[6.0]
213
221
  end
214
222
 
215
223
  create_table <%= @cpd_audit_reviews_table_name %> do |t|
216
- t.references :cpd_audit_level
217
- t.references :cpd_audit
224
+ t.integer :cpd_audit_level_id
225
+ t.string :cpd_audit_level_type
226
+
227
+ t.integer :cpd_audit_id
228
+ t.string :cpd_audit_type
218
229
 
219
230
  t.integer :user_id
220
231
  t.string :user_type
@@ -11,7 +11,11 @@ module EffectiveCpd
11
11
  initializer 'effective_cpd.active_record' do |app|
12
12
  ActiveSupport.on_load :active_record do
13
13
  ActiveRecord::Base.extend(EffectiveCpdUser::Base)
14
+ #ActiveRecord::Base.extend(EffectiveCpdCycle::Base)
14
15
  ActiveRecord::Base.extend(EffectiveCpdStatement::Base)
16
+ ActiveRecord::Base.extend(EffectiveCpdAudit::Base)
17
+ ActiveRecord::Base.extend(EffectiveCpdAuditLevel::Base)
18
+ ActiveRecord::Base.extend(EffectiveCpdAuditReview::Base)
15
19
  end
16
20
  end
17
21
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveCpd
2
- VERSION = '0.6.9'
2
+ VERSION = '1.0.0'
3
3
  end
data/lib/effective_cpd.rb CHANGED
@@ -16,7 +16,7 @@ module EffectiveCpd
16
16
  :cpd_audit_reviews_table_name, :cpd_audit_review_items_table_name,
17
17
  :program_label, :cycle_label, :credit_label, :layout, :auditee_user_scope, :audit_reviewer_user_scope,
18
18
  :mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject, :use_effective_email_templates,
19
- :cpd_statement_class_name
19
+ :cpd_statement_class_name, :cpd_audit_class_name, :cpd_audit_level_class_name, :cpd_audit_review_class_name
20
20
  ]
21
21
  end
22
22
 
@@ -30,4 +30,16 @@ module EffectiveCpd
30
30
  cpd_statement_class_name&.constantize || Effective::CpdStatement
31
31
  end
32
32
 
33
+ def self.CpdAudit
34
+ cpd_audit_class_name&.constantize || Effective::CpdAudit
35
+ end
36
+
37
+ def self.CpdAuditLevel
38
+ cpd_audit_level_class_name&.constantize || Effective::CpdAuditLevel
39
+ end
40
+
41
+ def self.CpdAuditReview
42
+ cpd_audit_review_class_name&.constantize || Effective::CpdAuditReview
43
+ end
44
+
33
45
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_cpd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.9
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-03 00:00:00.000000000 Z
11
+ date: 2023-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -216,6 +216,9 @@ files:
216
216
  - app/helpers/effective_cpd_audits_helper.rb
217
217
  - app/helpers/effective_cpd_helper.rb
218
218
  - app/mailers/effective/cpd_mailer.rb
219
+ - app/models/concerns/effective_cpd_audit.rb
220
+ - app/models/concerns/effective_cpd_audit_level.rb
221
+ - app/models/concerns/effective_cpd_audit_review.rb
219
222
  - app/models/concerns/effective_cpd_statement.rb
220
223
  - app/models/concerns/effective_cpd_user.rb
221
224
  - app/models/effective/cpd_activity.rb