effective_cpd 1.1.0 → 1.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce8f5f1c83904eecbd1cc49e84720ec7ed6d51aa39773354666b0e07e9bda56a
4
- data.tar.gz: 3a69c509409f5d33427f19c223a4803d8b1a8a49aa1d8e9addc03ee4f16cefce
3
+ metadata.gz: d431d1c016484d56c812b1e62e51203d8d6dcc9a626452e3e0275a194126f045
4
+ data.tar.gz: af7ef23916669b65010a86afe274c65cc123662a95b30d69c96cd6767eae41f6
5
5
  SHA512:
6
- metadata.gz: 0dfbe56c0a27a8743663d3ae374a62c1f0c674d46b189a2636b144d8f3bfe12c1ccc19fd8163e63d0b92010aeedc8b62856a5f87558ce231842093279b2404d3
7
- data.tar.gz: '0864c315be7007b31a19dc76b934618ffd6bf678f547a063d9e6bdd0c62b491b13fccf62b264a69dadb7652cd527bdc27e3a1832bc0aa6fd798a2105feef7bbf'
6
+ metadata.gz: 64768ebc20002cc568e939d0ed694edc7d293899a3470529a42a88100a3a94dfd27dbc379ed250cbf3a3439a4abef84b9cefa95f4d00edfba8fea9d9ecfbb9bc
7
+ data.tar.gz: 91b7b3f4853dfd810c98039949f3ac1d00fc4d0a6ba95aa51745809d683b142ff21fc74ab397659b473d8620b3de1097be27e2b93065720ba09ec3f28a18aa67
data/README.md CHANGED
@@ -186,8 +186,8 @@ if user.persisted?
186
186
  end
187
187
 
188
188
  if user.reviewer?
189
- can [:index], Effective::CpdAudit
190
- can [:index, :show, :update], Effective::CpdAuditReview, user_id: user.id
189
+ can [:index], EffectiveCpd.CpdAudit
190
+ can [:index, :show, :update], EffectiveCpd.CpdAuditReview, user_id: user.id
191
191
  end
192
192
 
193
193
  if user.admin?
@@ -197,15 +197,21 @@ if user.admin?
197
197
  can :manage, Effective::CpdCycle
198
198
  can :manage, Effective::CpdRule
199
199
 
200
- can([:index, :show], Effective::CpdStatement)
201
- can(:unsubmit, Effective::CpdStatement) { |statement| statement.completed? }
200
+ can([:index, :show], EffectiveCpd.CpdStatement)
201
+ can(:unsubmit, EffectiveCpd.CpdStatement) { |statement| statement.completed? }
202
202
 
203
203
  can :manage, Effective::CpdAuditLevel
204
204
  can :manage, Effective::CpdAuditLevelSection
205
205
  can :manage, Effective::CpdAuditLevelQuestion
206
206
 
207
- can :manage, Effective::CpdAudit
208
- can :manage, Effective::CpdAuditReview
207
+ can(crud - [:destroy], EffectiveCpd.CpdAudit)
208
+ can(:destroy, EffectiveCpd.CpdAudit) { |audit| audit.draft? }
209
+
210
+ can(:missing, EffectiveCpd.CpdAudit) { |audit| audit.was_submitted? && !audit.missing_info? }
211
+ can(:complete, EffectiveCpd.CpdAudit) { |audit| audit.was_submitted? && !audit.was_completed? }
212
+ can(:close, EffectiveCpd.CpdAudit) { |audit| audit.was_submitted? && !audit.closed? }
213
+
214
+ can(crud - [:edit, :update], EffectiveCpd.CpdAuditReview)
209
215
  end
210
216
  ```
211
217
 
@@ -8,6 +8,8 @@ module Effective
8
8
  EffectiveCpd.CpdAuditReview.deep.where(user: current_user)
9
9
  end
10
10
 
11
+ page_title 'Chat', only: [:chat]
12
+
11
13
  # Reuse the same view for all cpd_audit_level_section steps
12
14
  # https://github.com/zombocom/wicked/blob/v1.3.4/lib/wicked/controller/concerns/render_redirect.rb#L32
13
15
  def render_step(the_step, options = {}, params = {})
@@ -8,6 +8,8 @@ module Effective
8
8
 
9
9
  submit :resubmit, 'Resubmit Audit'
10
10
 
11
+ page_title 'Chat', only: [:chat]
12
+
11
13
  # Reuse the same view for all cpd_audit_level_section steps
12
14
  # https://github.com/zombocom/wicked/blob/v1.3.4/lib/wicked/controller/concerns/render_redirect.rb#L32
13
15
  def render_step(the_step, options = {}, params = {})
@@ -42,6 +42,8 @@ module EffectiveCpdAudit
42
42
  acts_as_email_form
43
43
  acts_as_tokened
44
44
  acts_as_reportable if respond_to?(:acts_as_reportable)
45
+ effective_messaging_parent if respond_to?(:effective_messaging_parent)
46
+
45
47
  log_changes(except: [:wizard_steps, :cpd_audit_reviews]) if respond_to?(:log_changes)
46
48
 
47
49
  acts_as_statused(
@@ -66,6 +68,7 @@ module EffectiveCpdAudit
66
68
  start: 'Start',
67
69
  information: 'Information',
68
70
  instructions: 'Instructions',
71
+ demographics: 'Demographics', # Individual only. Users fields.
69
72
 
70
73
  # These 4 steps are determined by audit_level settings
71
74
  conflict: 'Conflict of Interest',
@@ -88,7 +91,9 @@ module EffectiveCpdAudit
88
91
 
89
92
  # App scoped
90
93
  belongs_to :cpd_audit_level, polymorphic: true
94
+
91
95
  belongs_to :user, polymorphic: true # The user being audited
96
+ accepts_nested_attributes_for :user
92
97
 
93
98
  has_many :cpd_audit_reviews, -> { order(:id) }, inverse_of: :cpd_audit, dependent: :destroy
94
99
  accepts_nested_attributes_for :cpd_audit_reviews, allow_destroy: true
@@ -236,7 +241,7 @@ module EffectiveCpdAudit
236
241
  end
237
242
 
238
243
  def required_steps
239
- steps = [:start, :information, :instructions]
244
+ steps = [:start, :information, :instructions, :demographics]
240
245
 
241
246
  steps << :conflict if cpd_audit_level.conflict_of_interest?
242
247
 
@@ -265,10 +270,29 @@ module EffectiveCpdAudit
265
270
 
266
271
  can_revisit_completed_steps(step)
267
272
  end
273
+
274
+ # Effective Messaging. Find or build chat.
275
+ def build_chat
276
+ chat = chats.first || chats.build
277
+
278
+ # Assign title and anonymous
279
+ chat.assign_attributes(title: to_s, anonymous: anonymous?)
280
+
281
+ # Create a chat user for auditee
282
+ chat.build_chat_user(user: user, anonymous_name: anonymous_name)
283
+
284
+ # Create a chat user for each audit reviewer
285
+ cpd_audit_reviews.each do |cpd_audit_review|
286
+ chat.build_chat_user(user: cpd_audit_review.user, anonymous_name: cpd_audit_review.anonymous_name)
287
+ end
288
+
289
+ chat
290
+ end
291
+
268
292
  end
269
293
 
270
294
  def to_s
271
- persisted? ? "#{cpd_audit_level} Audit of #{name}" : 'audit'
295
+ (cpd_audit_level.present? && name.present?) ? "#{cpd_audit_level} Audit of #{name}" : 'audit'
272
296
  end
273
297
 
274
298
  def name
@@ -477,6 +501,7 @@ module EffectiveCpdAudit
477
501
 
478
502
  # called by a before_save when submitted
479
503
  def try_complete!
504
+ # complete! if submitted? # Automatically go from submitted->complete
480
505
  false # Nothing to do. Admin completes audits.
481
506
  end
482
507
 
@@ -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
@@ -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
@@ -51,6 +51,10 @@
51
51
  - datatable = EffectiveResources.best('Admin::EffectiveCpdAuditReviewsDatatable').new(cpd_audit: cpd_audit)
52
52
  = render_datatable(datatable, inline: true, simple: true)
53
53
 
54
+ - if EffectiveCpd.use_effective_messaging?
55
+ = tab 'Chat' do
56
+ = render 'admin/cpd_audits/form_chat', cpd_audit: cpd_audit
57
+
54
58
  - if cpd_audit.respond_to?(:log_changes_datatable)
55
59
  = tab 'Logs' do
56
60
  = render_inline_datatable(cpd_audit.log_changes_datatable)
@@ -13,3 +13,10 @@
13
13
  %h2 Audits
14
14
  - datatable = Admin::EffectiveCpdAuditsDatatable.new(user: user)
15
15
  = render_datatable(datatable)
16
+
17
+ - if user.try(:cpd_audit_reviewer?)
18
+ %hr
19
+
20
+ %h2 Audit Reviews
21
+ - datatable = Admin::EffectiveCpdAuditReviewsDatatable.new(user: user)
22
+ = render_datatable(datatable)
@@ -0,0 +1,8 @@
1
+ - if user.try(:cpd_audit_reviewer?)
2
+ %h2 Audit Reviews
3
+ - datatable = Admin::EffectiveCpdAuditReviewsDatatable.new(user: user)
4
+ = render_datatable(datatable)
5
+ - else
6
+ %h2 Audits
7
+ - datatable = Admin::EffectiveCpdAuditsDatatable.new(user: user)
8
+ = render_datatable(datatable)
@@ -1,6 +1,6 @@
1
1
  .row
2
2
  .col-3
3
- = render_wizard_sidebar(resource)
3
+ = render_wizard_sidebar(resource, path: effective_cpd.cpd_audit_review_build_path(resource))
4
4
 
5
5
  %table.table.mt-4
6
6
  %tbody
@@ -15,6 +15,13 @@
15
15
  %td
16
16
  %td
17
17
 
18
+ - if EffectiveCpd.use_effective_messaging?
19
+ .list-group
20
+ - if (controller.action_name == 'chat')
21
+ %a.active.list-group-item.list-group-item-action Chat
22
+ - else
23
+ %a.list-group-item.list-group-item-action{href: effective_cpd.chat_cpd_audit_review_path(resource)} Chat
24
+
18
25
  .col-9
19
26
  %h1= @page_title
20
27
 
@@ -0,0 +1,4 @@
1
+ - # This isn't a wizard screen. It's a show view.
2
+
3
+ = render('layout') do
4
+ = render(resource.cpd_audit.create_chat)
@@ -3,6 +3,7 @@
3
3
 
4
4
  - steps = cpd_audit.required_steps.select { |step| cpd_audit.has_completed_step?(step) }
5
5
  - blacklist = [:start, :information, :instructions, :waiting, :questionnaire, :submit, :submitted]
6
+ - blacklist += [:demographics] if cpd_audit.anonymous?
6
7
 
7
8
  - (steps - blacklist).each do |step|
8
9
  - cpd_audit.render_step = step
@@ -0,0 +1,3 @@
1
+ = wizard_card(cpd_audit) do
2
+ - raise('demographics should not be displayed on anonymous audit') if cpd_audit.anonymous?
3
+ = render 'users/demographics', parent: cpd_audit, user: cpd_audit.user
@@ -16,7 +16,7 @@
16
16
 
17
17
  %tr
18
18
  %th Reason
19
- %td= cpd_audit.exemption_request_reason
19
+ %td= cpd_audit.extension_request_reason
20
20
 
21
21
  %tr
22
22
  %th Status
@@ -1,9 +1,6 @@
1
1
  .row
2
2
  .col-3
3
- = render_wizard_sidebar(resource)
4
-
5
- - last_3_cycles = Effective::CpdCycle.sorted.where('start_at <= ?', Time.zone.now).last(3)
6
- - last_3_scores = Effective::CpdStatement.where(cpd_cycle: last_3_cycles, user: resource.user).sum(&:score)
3
+ = render_wizard_sidebar(resource, path: effective_cpd.cpd_audit_build_path(resource))
7
4
 
8
5
  %table.table.mt-4
9
6
  %tbody
@@ -15,11 +12,26 @@
15
12
  %td
16
13
  = (Time.zone.now > resource.due_date) ? 'days overdue' : 'days left to submit'
17
14
 
15
+ - if resource.user_cpd_required?
16
+ - last_3_cycles = Effective::CpdCycle.sorted.where('start_at <= ?', Time.zone.now).last(3)
17
+ - last_3_statements = Effective::CpdStatement.where(cpd_cycle: last_3_cycles, user: resource.user)
18
+
19
+ %tr
20
+ %td
21
+ %h4= cpd_score(last_3_statements.sum(&:score).to_d)
22
+
23
+ %td #{cpd_credits_label} in last 3 #{cpd_cycles_label} (including this #{cpd_cycle_label})
24
+
18
25
  %tr
19
26
  %td
20
- %h4= cpd_score(last_3_scores.to_d)
27
+ %td
21
28
 
22
- %td #{cpd_credits_label} in last 3 #{cpd_cycles_label} (including this #{cpd_cycle_label})
29
+ - if EffectiveCpd.use_effective_messaging?
30
+ .list-group
31
+ - if (controller.action_name == 'chat')
32
+ %a.active.list-group-item.list-group-item-action Chat
33
+ - else
34
+ %a.list-group-item.list-group-item-action{href: effective_cpd.chat_cpd_audit_path(resource)} Chat
23
35
 
24
36
  .col-9
25
37
  %h1= @page_title
@@ -0,0 +1,4 @@
1
+ - # This isn't a wizard screen. It's a show view.
2
+
3
+ = render('layout') do
4
+ = render(resource.create_chat)
@@ -0,0 +1,9 @@
1
+ = render('layout') do
2
+
3
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
4
+ = f.hidden_field :current_step
5
+
6
+ = f.fields_for(:user, f.object.user) do |fu|
7
+ = render 'users/fields_demographics', f: fu, user: f.object.user, parent: resource
8
+
9
+ = f.save 'Save and Continue'
@@ -0,0 +1,61 @@
1
+ -# This is a placeholder file that should be overriden by the main application
2
+
3
+ %p Placeholder
4
+
5
+ %table.table.table-sm
6
+ %tbody
7
+ %tr
8
+ %th Name
9
+ %td= user.to_s
10
+
11
+ %tr
12
+ %th Email
13
+ %td= mail_to user.email
14
+
15
+ - if user.respond_to?(:job_title)
16
+ %tr
17
+ %th Job Title:
18
+ %td= user.job_title.presence || '-'
19
+
20
+ - if user.respond_to?(:date_of_birth)
21
+ %tr
22
+ %th Date of Birth
23
+ %td= user.date_of_birth&.strftime('%F').presence || '-'
24
+
25
+ - if user.respond_to?(:phone)
26
+ %tr
27
+ %th Phone:
28
+ %td= user.phone.presence || '-'
29
+
30
+ - if user.respond_to?(:home_phone)
31
+ %tr
32
+ %th Home Phone:
33
+ %td= user.home_phone.presence || '-'
34
+
35
+ - if user.respond_to?(:cell_phone)
36
+ %tr
37
+ %th Cell Phone:
38
+ %td= user.cell_phone.presence || '-'
39
+
40
+ - if user.respond_to?(:fax)
41
+ %tr
42
+ %th Fax:
43
+ %td= user.fax.presence || '-'
44
+
45
+ - if user.respond_to?(:residential_address)
46
+ %tr
47
+ %th Residential Address:
48
+ %td
49
+ - if user.residential_address.present?
50
+ = user.residential_address.to_html
51
+ - else
52
+ = '-'
53
+
54
+ - if user.respond_to?(:billing_address)
55
+ %tr
56
+ %th Billing Address:
57
+ %td
58
+ - if user.billing_address.present?
59
+ = user.billing_address.to_html
60
+ - else
61
+ = '-'
@@ -0,0 +1,31 @@
1
+ -# This is a placeholder file that should be overriden by the main application
2
+
3
+ %p Placeholder
4
+
5
+ - if f.object.respond_to?(:first_name)
6
+ = f.text_field :first_name
7
+
8
+ - if f.object.respond_to?(:last_name)
9
+ = f.text_field :last_name
10
+
11
+ - if f.object.respond_to?(:job_title)
12
+ = f.text_field :job_title
13
+
14
+ - if f.object.respond_to?(:date_of_birth)
15
+ = f.date_field :date_of_birth
16
+
17
+ - if f.object.respond_to?(:phone)
18
+ = f.tel_field :phone
19
+
20
+ - if f.object.respond_to?(:home_phone)
21
+ = f.tel_field :home_phone
22
+
23
+ - if f.object.respond_to?(:cell_phone)
24
+ = f.tel_field :cell_phone
25
+
26
+ - if f.object.respond_to?(:fax)
27
+ = f.tel_field :fax
28
+
29
+ - if f.object.respond_to?(:billing_address)
30
+ %h2 Billing Address
31
+ = effective_address_fields(f, :billing_address)
@@ -50,6 +50,10 @@ EffectiveCpd.setup do |config|
50
50
  # Audit Reviewer Scope Collection
51
51
  config.audit_reviewer_user_scope = :cpd_audit_reviewers
52
52
 
53
+ # Effective Messaging
54
+ # Show a chat for Cpd Audit and Cpd Audit Reviewers
55
+ config.use_effective_messaging = true
56
+
53
57
  # Mailer Settings
54
58
  # Please see config/initializers/effective_resources.rb for default effective_* gem mailer settings
55
59
  #
data/config/routes.rb CHANGED
@@ -18,11 +18,13 @@ EffectiveCpd::Engine.routes.draw do
18
18
 
19
19
  # Audits Auditee wizard
20
20
  resources :cpd_audits, only: [:new, :show] do
21
+ get :chat, on: :member
21
22
  resources :build, controller: :cpd_audits, only: [:show, :update]
22
23
  end
23
24
 
24
25
  # Audits Auditor / Audit Reviewer wizard
25
26
  resources :cpd_audit_reviews, only: [:new, :show] do
27
+ get :chat, on: :member
26
28
  resources :build, controller: :cpd_audit_reviews, only: [:show, :update]
27
29
  end
28
30
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveCpd
2
- VERSION = '1.1.0'
2
+ VERSION = '1.1.2'
3
3
  end
data/lib/effective_cpd.rb CHANGED
@@ -15,6 +15,7 @@ module EffectiveCpd
15
15
  :cpd_audits_table_name, :cpd_audit_responses_table_name, :cpd_audit_response_options_table_name,
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
+ :use_effective_messaging,
18
19
  :mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject, :use_effective_email_templates,
19
20
  :cpd_statement_class_name, :cpd_audit_class_name, :cpd_audit_level_class_name, :cpd_audit_review_class_name
20
21
  ]
@@ -42,4 +43,8 @@ module EffectiveCpd
42
43
  cpd_audit_review_class_name&.constantize || Effective::CpdAuditReview
43
44
  end
44
45
 
46
+ def self.use_effective_messaging?
47
+ defined?(EffectiveMessaging) && !!use_effective_messaging
48
+ end
49
+
45
50
  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: 1.1.0
4
+ version: 1.1.2
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-01-19 00:00:00.000000000 Z
11
+ date: 2023-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: effective_messaging
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  description: Continuing professional development and audits rails engine
168
182
  email:
169
183
  - info@codeandeffect.com
@@ -251,6 +265,7 @@ files:
251
265
  - app/views/admin/cpd_audits/_audit_reviewer_fields.html.haml
252
266
  - app/views/admin/cpd_audits/_auditee_fields.html.haml
253
267
  - app/views/admin/cpd_audits/_form.html.haml
268
+ - app/views/admin/cpd_audits/_form_chat.html.haml
254
269
  - app/views/admin/cpd_audits/_form_close.html.haml
255
270
  - app/views/admin/cpd_audits/_form_complete.html.haml
256
271
  - app/views/admin/cpd_audits/_form_conflict.html.haml
@@ -273,6 +288,7 @@ files:
273
288
  - app/views/admin/cpd_special_rules/_form.html.haml
274
289
  - app/views/admin/cpd_statements/_cpd_statement.html.haml
275
290
  - app/views/admin/users/_form_cpd.html.haml
291
+ - app/views/admin/users/_form_cpd_audits.html.haml
276
292
  - app/views/effective/cpd/_dashboard.html.haml
277
293
  - app/views/effective/cpd_audit_level_questions/_cpd_audit_level_question.html.haml
278
294
  - app/views/effective/cpd_audit_responses/_cpd_audit_response.html.haml
@@ -314,6 +330,7 @@ files:
314
330
  - app/views/effective/cpd_audit_reviews/_layout.html.haml
315
331
  - app/views/effective/cpd_audit_reviews/_recommendation.html.haml
316
332
  - app/views/effective/cpd_audit_reviews/_summary.html.haml
333
+ - app/views/effective/cpd_audit_reviews/chat.html.haml
317
334
  - app/views/effective/cpd_audit_reviews/conflict.html.haml
318
335
  - app/views/effective/cpd_audit_reviews/cpd_audit_level_section.html.haml
319
336
  - app/views/effective/cpd_audit_reviews/cpd_statement.html.haml
@@ -332,6 +349,7 @@ files:
332
349
  - app/views/effective/cpd_audits/_cpd.html.haml
333
350
  - app/views/effective/cpd_audits/_cpd_audit.html.haml
334
351
  - app/views/effective/cpd_audits/_cpd_audit_level_section.html.haml
352
+ - app/views/effective/cpd_audits/_demographics.html.haml
335
353
  - app/views/effective/cpd_audits/_exemption.html.haml
336
354
  - app/views/effective/cpd_audits/_extension.html.haml
337
355
  - app/views/effective/cpd_audits/_files.html.haml
@@ -339,9 +357,11 @@ files:
339
357
  - app/views/effective/cpd_audits/_missing_info.html.haml
340
358
  - app/views/effective/cpd_audits/_summary.html.haml
341
359
  - app/views/effective/cpd_audits/_waiting.html.haml
360
+ - app/views/effective/cpd_audits/chat.html.haml
342
361
  - app/views/effective/cpd_audits/conflict.html.haml
343
362
  - app/views/effective/cpd_audits/cpd.html.haml
344
363
  - app/views/effective/cpd_audits/cpd_audit_level_section.html.haml
364
+ - app/views/effective/cpd_audits/demographics.html.haml
345
365
  - app/views/effective/cpd_audits/exemption.html.haml
346
366
  - app/views/effective/cpd_audits/extension.html.haml
347
367
  - app/views/effective/cpd_audits/files.html.haml
@@ -384,6 +404,8 @@ files:
384
404
  - app/views/effective/cpd_statements/complete.html.haml
385
405
  - app/views/effective/cpd_statements/start.html.haml
386
406
  - app/views/effective/cpd_statements/submit.html.haml
407
+ - app/views/users/_demographics.html.haml
408
+ - app/views/users/_fields_demographics.html.haml
387
409
  - config/effective_cpd.rb
388
410
  - config/routes.rb
389
411
  - db/migrate/01_create_effective_cpd.rb.erb