effective_cpd 1.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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