effective_cpd 1.3.7 → 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/admin/cpd_targets_controller.rb +15 -0
- data/app/controllers/effective/cpd_statement_activities_controller.rb +6 -1
- data/app/datatables/admin/effective_cpd_cycles_datatable.rb +1 -1
- data/app/datatables/admin/effective_cpd_special_rules_datatable.rb +2 -3
- data/app/datatables/admin/effective_cpd_statements_datatable.rb +2 -4
- data/app/datatables/admin/effective_cpd_targets_datatable.rb +23 -0
- data/app/datatables/effective_cpd_available_cycles_datatable.rb +3 -4
- data/app/datatables/effective_cpd_completed_statements_datatable.rb +6 -5
- data/app/helpers/effective_cpd_helper.rb +13 -2
- data/app/models/concerns/effective_cpd_audit_review.rb +4 -0
- data/app/models/concerns/effective_cpd_statement.rb +8 -14
- data/app/models/concerns/effective_cpd_user.rb +38 -7
- data/app/models/effective/cpd_cycle.rb +1 -7
- data/app/models/effective/cpd_target.rb +31 -0
- data/app/views/admin/cpd_cycles/_form.html.haml +4 -1
- data/app/views/admin/cpd_cycles/_form_cpd_cycle.html.haml +0 -3
- data/app/views/admin/cpd_cycles/_form_cpd_special_rules.html.haml +1 -1
- data/app/views/admin/cpd_cycles/_form_cpd_targets.html.haml +18 -0
- data/app/views/admin/cpd_targets/_form.html.haml +18 -0
- data/app/views/admin/users/_form_cpd.html.haml +5 -1
- data/app/views/admin/users/_form_cpd_targets.html.haml +34 -0
- data/app/views/effective/cpd_statement_activities/_form.html.haml +2 -1
- data/app/views/effective/cpd_statements/_activities_table.html.haml +3 -0
- data/app/views/effective/cpd_statements/_layout.html.haml +6 -4
- data/app/views/effective/cpd_statements/_summary.html.haml +5 -4
- data/app/views/effective/cpd_statements/activities.html.haml +4 -2
- data/config/effective_cpd.rb +1 -0
- data/config/locales/effective_cpd.en.yml +1 -0
- data/config/routes.rb +1 -0
- data/db/migrate/01_create_effective_cpd.rb.erb +13 -1
- data/db/seeds.rb +0 -1
- data/lib/effective_cpd/version.rb +1 -1
- data/lib/effective_cpd.rb +2 -0
- data/lib/generators/effective_cpd/install_generator.rb +1 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15a9526456ab27ed3cc2dca6c6c368afe97e478282d66083cfb45e10250071c8
|
4
|
+
data.tar.gz: 4394265758150e1a979fa5cb000f22f5153c7c7a5be772e4b90d2795376697f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bffcf39a42c4481b6e51425e0ff373b9a6670c2e9c01027099d4f3abe299fdf428ba601123e38f17f136abdd5f95cec8a35560839524dcd29c69bf3cdb653d9b
|
7
|
+
data.tar.gz: e427677d3c6ec195b01b0b22c9022ce4eac3c40fa04eeeb873da3a7573e2b8a68e076cc8151f684f9a0b0c11fe1804cc63ce77c9554d50823dfb54b9ed9e1614
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Admin
|
2
|
+
class CpdTargetsController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_cpd) }
|
5
|
+
|
6
|
+
include Effective::CrudController
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def permitted_params
|
11
|
+
params.require(:effective_cpd_target).permit!
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -14,7 +14,12 @@ module Effective
|
|
14
14
|
# Redirect the remote form back to the activities page
|
15
15
|
on :save, redirect: -> {
|
16
16
|
statement = resource.cpd_statement
|
17
|
-
|
17
|
+
|
18
|
+
if params[:commit] == 'Save and Add Another'
|
19
|
+
effective_cpd.cpd_cycle_cpd_statement_build_path(statement.cpd_cycle, statement, :activities, activities: :new)
|
20
|
+
else
|
21
|
+
effective_cpd.cpd_cycle_cpd_statement_build_path(statement.cpd_cycle, statement, :activities)
|
22
|
+
end
|
18
23
|
}
|
19
24
|
|
20
25
|
def permitted_params
|
@@ -5,9 +5,8 @@ module Admin
|
|
5
5
|
col :created_at, visible: false
|
6
6
|
col :updated_at, visible: false
|
7
7
|
|
8
|
-
col :cpd_cycle
|
9
|
-
|
10
|
-
col :cpd_rules
|
8
|
+
col :cpd_cycle, label: cpd_cycle_label
|
9
|
+
col :cpd_rules, label: 'Rules'
|
11
10
|
|
12
11
|
col :category
|
13
12
|
col :max_credits_per_cycle, label: 'Max ' + cpd_credits_label
|
@@ -22,10 +22,8 @@ module Admin
|
|
22
22
|
cpd_score(cpd_statement.score)
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
cpd_score(cpd_statement.required_score || cpd_statement.targeted_score)
|
28
|
-
end
|
25
|
+
col :target_score, label: "Required " + cpd_credits_label.capitalize, as: :decimal do |cpd_statement|
|
26
|
+
cpd_score(cpd_statement.target_score)
|
29
27
|
end
|
30
28
|
|
31
29
|
col :carry_forward do |cpd_statement|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Admin
|
2
|
+
class EffectiveCpdTargetsDatatable < Effective::Datatable
|
3
|
+
datatable do
|
4
|
+
order :updated_at
|
5
|
+
|
6
|
+
col :updated_at, visible: false
|
7
|
+
col :created_at, visible: false
|
8
|
+
col :id, visible: false
|
9
|
+
|
10
|
+
col :user
|
11
|
+
col :cpd_cycle, search: Effective::CpdCycle.sorted, label: cpd_cycle_label
|
12
|
+
|
13
|
+
col :score, label: "Target or Required " + cpd_credits_label
|
14
|
+
col :required_to_submit
|
15
|
+
|
16
|
+
actions_col
|
17
|
+
end
|
18
|
+
|
19
|
+
collection do
|
20
|
+
Effective::CpdTarget.deep.all
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -7,11 +7,10 @@ class EffectiveCpdAvailableCyclesDatatable < Effective::Datatable
|
|
7
7
|
col :start_at, visible: false
|
8
8
|
|
9
9
|
col(:title, label: cpd_cycle_label)
|
10
|
-
col :available_date
|
10
|
+
col :available_date
|
11
11
|
|
12
|
-
col :
|
13
|
-
|
14
|
-
cpd_score(cpd_statement.required_score || cpd_statement.targeted_score)
|
12
|
+
col :target_score, label: "Required #{cpd_credits_label}" do |cpd_cycle|
|
13
|
+
cpd_score(current_user.cpd_target_score(cpd_cycle: cpd_cycle))
|
15
14
|
end
|
16
15
|
|
17
16
|
actions_col(actions: []) do |cpd_cycle|
|
@@ -8,14 +8,15 @@ class EffectiveCpdCompletedStatementsDatatable < Effective::Datatable
|
|
8
8
|
statement.cpd_cycle.to_s
|
9
9
|
end
|
10
10
|
|
11
|
-
col :submitted_at
|
12
|
-
col :score, label: cpd_credits_label
|
11
|
+
col :submitted_at, as: :date, label: 'Submitted'
|
13
12
|
|
14
|
-
col :
|
15
|
-
cpd_score(cpd_statement.
|
13
|
+
col :score, label: cpd_credits_label do |cpd_statement|
|
14
|
+
cpd_score(cpd_statement.score, cpd_statement.target_score)
|
16
15
|
end
|
17
16
|
|
18
|
-
col :carry_forward
|
17
|
+
col :carry_forward do |cpd_statement|
|
18
|
+
cpd_score(cpd_statement.carry_forward)
|
19
|
+
end
|
19
20
|
|
20
21
|
unless attributes[:actions] == false
|
21
22
|
actions_col(actions: []) do |cpd_statement|
|
@@ -68,6 +68,14 @@ module EffectiveCpdHelper
|
|
68
68
|
ets(EffectiveCpd.CpdAuditLevel)
|
69
69
|
end
|
70
70
|
|
71
|
+
def cpd_target_label
|
72
|
+
et(Effective::CpdTarget)
|
73
|
+
end
|
74
|
+
|
75
|
+
def cpd_targets_label
|
76
|
+
ets(Effective::CpdTarget)
|
77
|
+
end
|
78
|
+
|
71
79
|
def cpd_rule_formula_hint(cpd_activity)
|
72
80
|
raise('expected a CPDActivity') unless cpd_activity.kind_of?(Effective::CpdActivity)
|
73
81
|
|
@@ -96,8 +104,11 @@ module EffectiveCpdHelper
|
|
96
104
|
@effective_cpd_categories ||= Effective::CpdCategory.deep.sorted
|
97
105
|
end
|
98
106
|
|
99
|
-
def cpd_score(value)
|
100
|
-
("%.#{2}f" % value.to_d)
|
107
|
+
def cpd_score(value, value2 = nil)
|
108
|
+
score1 = ("%.#{2}f" % value.to_d)
|
109
|
+
score2 = ("%.#{2}f" % value2.to_d)
|
110
|
+
|
111
|
+
(value.present? && value2.present?) ? "#{score1} / #{score2}" : score1
|
101
112
|
end
|
102
113
|
|
103
114
|
end
|
@@ -118,6 +118,10 @@ module EffectiveCpdAuditReview
|
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
|
+
with_options(if: -> { current_step == :recommendation }) do
|
122
|
+
validates :recommendation, presence: true
|
123
|
+
end
|
124
|
+
|
121
125
|
with_options(if: -> { cpd_audit_level&.anonymous? }) do
|
122
126
|
before_validation { assign_anonymous_name_and_number }
|
123
127
|
|
@@ -46,7 +46,7 @@ module EffectiveCpdStatement
|
|
46
46
|
accepts_nested_attributes_for :cpd_statement_activities
|
47
47
|
|
48
48
|
effective_resource do
|
49
|
-
score :
|
49
|
+
score :decimal
|
50
50
|
|
51
51
|
confirm_read :boolean
|
52
52
|
confirm_factual :boolean
|
@@ -63,7 +63,7 @@ module EffectiveCpdStatement
|
|
63
63
|
timestamps
|
64
64
|
end
|
65
65
|
|
66
|
-
scope :deep, -> { includes(:cpd_cycle, :
|
66
|
+
scope :deep, -> { includes(:cpd_cycle, user: [:cpd_targets], cpd_statement_activities: [:files_attachments, :cpd_category, :original, cpd_activity: [:rich_text_body]]) }
|
67
67
|
scope :sorted, -> { order(:cpd_cycle_id) }
|
68
68
|
|
69
69
|
scope :draft, -> { where(submitted_at: nil) }
|
@@ -80,8 +80,8 @@ module EffectiveCpdStatement
|
|
80
80
|
self.score ||= 0
|
81
81
|
end
|
82
82
|
|
83
|
-
validate(if: -> { completed? }) do
|
84
|
-
min =
|
83
|
+
validate(if: -> { completed? && target_score_required_to_submit? }) do
|
84
|
+
min = target_score() || 0.0
|
85
85
|
self.errors.add(:score, "must be #{min} or greater to submit a statement") if score < min
|
86
86
|
end
|
87
87
|
|
@@ -130,18 +130,12 @@ module EffectiveCpdStatement
|
|
130
130
|
end
|
131
131
|
alias_method :submitted?, :completed?
|
132
132
|
|
133
|
-
def
|
134
|
-
|
135
|
-
required_by_user = user.cpd_statement_required_score(self) if user.respond_to?(:cpd_statement_required_score)
|
136
|
-
|
137
|
-
[required_by_cycle, required_by_user].compact.max
|
133
|
+
def target_score
|
134
|
+
user.cpd_target_score(cpd_cycle: cpd_cycle)
|
138
135
|
end
|
139
136
|
|
140
|
-
def
|
141
|
-
|
142
|
-
targeted_by_user = user.cpd_statement_targeted_score(self) if user.respond_to?(:cpd_statement_targeted_score)
|
143
|
-
|
144
|
-
[targeted_by_cycle, targeted_by_user].compact.max
|
137
|
+
def target_score_required_to_submit?
|
138
|
+
user.cpd_target_score_required_to_submit?(cpd_cycle: cpd_cycle)
|
145
139
|
end
|
146
140
|
|
147
141
|
def carry_forward
|
@@ -24,6 +24,10 @@ module EffectiveCpdUser
|
|
24
24
|
has_many :cpd_audits, -> { order(:id) }, inverse_of: :user
|
25
25
|
has_many :cpd_audit_reviews, -> { order(:id) }, inverse_of: :user
|
26
26
|
|
27
|
+
# Effective scoped
|
28
|
+
has_many :cpd_targets, -> { order(:cpd_cycle_id) }, inverse_of: :user, class_name: 'Effective::CpdTarget', dependent: :delete_all
|
29
|
+
accepts_nested_attributes_for :cpd_targets
|
30
|
+
|
27
31
|
# These two should not be sorted
|
28
32
|
scope :cpd_audit_auditees, -> { without_role(:cpd_audit_reviewer).without_role(:admin) }
|
29
33
|
scope :cpd_audit_reviewers, -> { with_role(:cpd_audit_reviewer) }
|
@@ -39,15 +43,25 @@ module EffectiveCpdUser
|
|
39
43
|
}
|
40
44
|
end
|
41
45
|
|
42
|
-
|
43
|
-
|
44
|
-
|
46
|
+
def cpd_target_score(cpd_cycle:)
|
47
|
+
target = cpd_target(cpd_cycle: cpd_cycle)
|
48
|
+
return target.score if target&.score.present?
|
49
|
+
|
50
|
+
# Otherwise calculate default by membership category
|
51
|
+
if self.class.try(:effective_memberships_user?)
|
52
|
+
category = membership_categories_on(cpd_cycle.start_at)&.first if cpd_cycle.start_at.present?
|
53
|
+
category ||= membership_categories_on(cpd_cycle.end_at)&.first if cpd_cycle.end_at.present?
|
54
|
+
category ||= membership&.categories&.first
|
55
|
+
|
56
|
+
category&.cpd_target_score(cpd_cycle: cpd_cycle)
|
57
|
+
end
|
45
58
|
end
|
46
59
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
60
|
+
def cpd_target_score_required_to_submit?(cpd_cycle:)
|
61
|
+
target = cpd_target(cpd_cycle: cpd_cycle)
|
62
|
+
return target.required_to_submit? unless target&.required_to_submit.nil?
|
63
|
+
|
64
|
+
cpd_cycle.required_to_submit?
|
51
65
|
end
|
52
66
|
|
53
67
|
def cpd_audit_cpd_required?
|
@@ -69,4 +83,21 @@ module EffectiveCpdUser
|
|
69
83
|
cpd_statement(cpd_cycle: cpd_cycle) || cpd_statements.build(cpd_cycle: cpd_cycle)
|
70
84
|
end
|
71
85
|
|
86
|
+
def cpd_target(cpd_cycle:)
|
87
|
+
raise('expected an CpdCycle') unless cpd_cycle.class.respond_to?(:effective_cpd_cpd_cycle?)
|
88
|
+
cpd_targets.find { |cpd_target| cpd_target.cpd_cycle_id == cpd_cycle.id }
|
89
|
+
end
|
90
|
+
|
91
|
+
# Find or build
|
92
|
+
def build_cpd_target(cpd_cycle:)
|
93
|
+
raise('expected an CpdCycle') unless cpd_cycle.class.respond_to?(:effective_cpd_cpd_cycle?)
|
94
|
+
cpd_target(cpd_cycle: cpd_cycle) || cpd_targets.build(cpd_cycle: cpd_cycle)
|
95
|
+
end
|
96
|
+
|
97
|
+
# For the form
|
98
|
+
def build_cpd_targets
|
99
|
+
Effective::CpdCycle.sorted.all.each { |cpd_cycle| build_cpd_target(cpd_cycle: cpd_cycle) }
|
100
|
+
cpd_targets.sort_by(&:cpd_cycle_id).reverse
|
101
|
+
end
|
102
|
+
|
72
103
|
end
|
@@ -26,7 +26,7 @@ module Effective
|
|
26
26
|
start_at :datetime
|
27
27
|
end_at :datetime
|
28
28
|
|
29
|
-
|
29
|
+
required_to_submit :boolean
|
30
30
|
|
31
31
|
timestamps
|
32
32
|
end
|
@@ -54,7 +54,6 @@ module Effective
|
|
54
54
|
|
55
55
|
validates :title, presence: true
|
56
56
|
validates :start_at, presence: true
|
57
|
-
validates :required_score, numericality: { greater_than: 0, allow_nil: true }
|
58
57
|
|
59
58
|
validate(if: -> { start_at.present? && end_at.present? }) do
|
60
59
|
self.errors.add(:end_at, 'must be after the start date') unless end_at > start_at
|
@@ -78,11 +77,6 @@ module Effective
|
|
78
77
|
title.presence || model_name.human
|
79
78
|
end
|
80
79
|
|
81
|
-
# Todo, implement a cpd cycle targeted score entirely
|
82
|
-
def targeted_score
|
83
|
-
nil
|
84
|
-
end
|
85
|
-
|
86
80
|
def build_from_cycle(cycle:)
|
87
81
|
raise('expected a CpdCycle') unless cycle.kind_of?(CpdCycle)
|
88
82
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Effective
|
2
|
+
class CpdTarget < ActiveRecord::Base
|
3
|
+
# App scoped
|
4
|
+
belongs_to :user, polymorphic: true
|
5
|
+
|
6
|
+
# Effective Namespace
|
7
|
+
belongs_to :cpd_cycle, class_name: 'Effective::CpdCycle'
|
8
|
+
|
9
|
+
log_changes(to: :user) if respond_to?(:log_changes)
|
10
|
+
|
11
|
+
REQUIRED_TO_SUBMIT = [["A minimum score is required to submit", true], ["Can submit with any score", false]]
|
12
|
+
|
13
|
+
effective_resource do
|
14
|
+
score :decimal
|
15
|
+
required_to_submit :boolean
|
16
|
+
|
17
|
+
timestamps
|
18
|
+
end
|
19
|
+
|
20
|
+
scope :deep, -> { includes(:user, :cpd_cycle) }
|
21
|
+
scope :sorted, -> { order(:cpd_cycle_id) }
|
22
|
+
|
23
|
+
validates :score, numericality: { greater_than_or_equal_to: 0, allow_nil: true }
|
24
|
+
validates :score, presence: true, if: -> { required_to_submit? }
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
score&.to_s || model_name.human
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
= tabs do
|
2
|
-
= tab
|
2
|
+
= tab(Effective::CpdCycle) do
|
3
3
|
= render 'admin/cpd_cycles/form_cpd_cycle', cpd_cycle: cpd_cycle
|
4
4
|
|
5
5
|
- if cpd_cycle.persisted?
|
6
|
+
= tab(ets(Effective::CpdTarget)) do
|
7
|
+
= render 'admin/cpd_cycles/form_cpd_targets', cpd_cycle: cpd_cycle
|
8
|
+
|
6
9
|
= tab 'Special Rules' do
|
7
10
|
= render 'admin/cpd_cycles/form_cpd_special_rules', cpd_cycle: cpd_cycle
|
8
11
|
|
@@ -8,9 +8,6 @@
|
|
8
8
|
= f.date_field :end_at, date_linked: false,
|
9
9
|
hint: "The last date a #{cpd_statement_label} may be created for this #{cpd_cycle_label}. leave blank for no end date."
|
10
10
|
|
11
|
-
= f.number_field :required_score,
|
12
|
-
hint: "The minimum required #{cpd_credits_label} to submit a #{cpd_statement_label} for this #{cpd_cycle_label}. leave blank to submit any amount."
|
13
|
-
|
14
11
|
- if f.object.new_record?
|
15
12
|
- latest_cycle = Effective::CpdCycle.latest_cycle
|
16
13
|
|
@@ -1,4 +1,4 @@
|
|
1
1
|
%p Special rules operate on more than one category at a time.
|
2
2
|
|
3
|
-
- datatable = Admin::EffectiveCpdSpecialRulesDatatable.new(
|
3
|
+
- datatable = Admin::EffectiveCpdSpecialRulesDatatable.new(cpd_cycle: cpd_cycle)
|
4
4
|
= render_datatable(datatable, inline: true)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
= effective_form_with(model: [:admin, cpd_cycle], engine: true) do |f|
|
2
|
+
%p The minimum number of #{cpd_credits_label} to submit a #{cpd_statement_label} in this #{cpd_cycle_label} is configured per user.
|
3
|
+
%p Visit a user page to better view their specific #{cpd_credits_label} requirements.
|
4
|
+
|
5
|
+
%p By default, the following behaviour will be applied to #{cpd_statements_label}:
|
6
|
+
|
7
|
+
.row
|
8
|
+
.col-lg-6
|
9
|
+
= f.select :required_to_submit, Effective::CpdTarget::REQUIRED_TO_SUBMIT
|
10
|
+
|
11
|
+
= f.save
|
12
|
+
|
13
|
+
%hr
|
14
|
+
|
15
|
+
.mt-4
|
16
|
+
%p The ability to submit a #{cpd_statement_label} in this #{cpd_cycle_label} has been individualized for the following:
|
17
|
+
- datatable = Admin::EffectiveCpdTargetsDatatable.new(cpd_cycle: cpd_cycle)
|
18
|
+
= render_datatable(datatable, inline: true)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
= effective_form_with(model: [:admin, cpd_target], engine: true) do |f|
|
2
|
+
= f.hidden_field :user_type, value: current_user.class.name
|
3
|
+
|
4
|
+
- if inline_datatable? && inline_datatable.attributes[:user_id].present?
|
5
|
+
= f.hidden_field :user_id
|
6
|
+
- else
|
7
|
+
- ajax_url = (@select2_ajax_path || effective_resources.users_admin_select2_ajax_index_path) unless Rails.env.test?
|
8
|
+
= f.select :user_id, current_user.class.all, ajax_url: ajax_url
|
9
|
+
|
10
|
+
- if inline_datatable? && inline_datatable.attributes[:cpd_cycle_id].present?
|
11
|
+
= f.hidden_field :cpd_cycle_id
|
12
|
+
- else
|
13
|
+
= f.select :cpd_cycle_id, Effective::CpdCycle.sorted.all, label: cpd_cycle_label
|
14
|
+
|
15
|
+
= f.number_field :score
|
16
|
+
= f.check_box :required_to_submit, label: 'A minimum score is required to submit'
|
17
|
+
|
18
|
+
= effective_submit(f)
|
@@ -1,9 +1,13 @@
|
|
1
|
-
%h2
|
1
|
+
%h2 #{cpd_statements_label}
|
2
2
|
- datatable = Admin::EffectiveCpdStatementsDatatable.new(user: user)
|
3
3
|
= render_datatable(datatable, inline: true)
|
4
4
|
|
5
5
|
%hr
|
6
6
|
|
7
|
+
%h2 #{cpd_targets_label}
|
8
|
+
= render 'admin/users/form_cpd_targets', user: user
|
9
|
+
%hr
|
10
|
+
|
7
11
|
%h2 Activities
|
8
12
|
- datatable = Admin::EffectiveCpdStatementActivitiesDatatable.new(user: user)
|
9
13
|
= render_datatable(datatable, inline: true)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
= effective_form_with model: [:admin, user] do |f|
|
2
|
+
= f.hidden_field :id
|
3
|
+
|
4
|
+
%p The default values are displayed as placeholders.
|
5
|
+
|
6
|
+
%table.table
|
7
|
+
%thead
|
8
|
+
%th= cpd_cycle_label
|
9
|
+
%th Target or Required #{cpd_credits_label}
|
10
|
+
|
11
|
+
%tbody
|
12
|
+
= f.fields_for :cpd_targets, f.object.build_cpd_targets do |ctf|
|
13
|
+
= ctf.hidden_field :id
|
14
|
+
= ctf.hidden_field :cpd_cycle_id
|
15
|
+
= ctf.hidden_field :user_type
|
16
|
+
= ctf.hidden_field :user_id
|
17
|
+
|
18
|
+
- collection = Effective::CpdTarget::REQUIRED_TO_SUBMIT
|
19
|
+
- cpd_cycle = ctf.object.cpd_cycle
|
20
|
+
- target = f.object.cpd_target_score(cpd_cycle: cpd_cycle)
|
21
|
+
- required_to_submit = f.object.cpd_target_score_required_to_submit?(cpd_cycle: cpd_cycle)
|
22
|
+
- required_to_submit_placeholder = collection.find { |label, value| value == required_to_submit }.first
|
23
|
+
|
24
|
+
%tr
|
25
|
+
%td= link_to(cpd_cycle, effective_cpd.edit_admin_cpd_cycle_path(cpd_cycle), target: '_blank')
|
26
|
+
|
27
|
+
%td
|
28
|
+
.row
|
29
|
+
.col
|
30
|
+
= ctf.number_field :score, label: false, required: false, placeholder: target.to_s
|
31
|
+
.col
|
32
|
+
= ctf.select :required_to_submit, Effective::CpdTarget::REQUIRED_TO_SUBMIT, label: false, placeholder: required_to_submit_placeholder.to_s
|
33
|
+
|
34
|
+
= f.save "Save #{cpd_targets_label}", 'data-confirm': "Really Save #{cpd_targets_label} for #{user}?"
|
@@ -35,6 +35,9 @@
|
|
35
35
|
= link_to('#', 'data-cpd-edit-activity': true) do
|
36
36
|
= icon('plus-circle', class: 'small-1')
|
37
37
|
= statement_activity.cpd_activity
|
38
|
+
= '-'
|
39
|
+
= statement_activity.description
|
40
|
+
|
38
41
|
- if statement_activity.is_carry_over?
|
39
42
|
%br
|
40
43
|
%small carried forward from #{statement_activity.original_cycle}
|
@@ -19,18 +19,20 @@
|
|
19
19
|
|
20
20
|
%tr
|
21
21
|
%td
|
22
|
-
%h4= cpd_score(resource.score
|
22
|
+
%h4= cpd_score(resource.score)
|
23
23
|
|
24
24
|
%td
|
25
|
-
#{cpd_credits_label} out of #{(resource.
|
25
|
+
#{cpd_credits_label} out of #{cpd_score(resource.target_score)}
|
26
|
+
- if resource.target_score_required_to_submit?
|
27
|
+
required
|
26
28
|
|
27
29
|
%tr
|
28
30
|
%td
|
29
|
-
%h4= cpd_score(last_3_scores
|
31
|
+
%h4= cpd_score(last_3_scores)
|
30
32
|
|
31
33
|
%td #{cpd_credits_label} in last 3 #{cpd_cycles_label} (including this #{cpd_cycle_label})
|
32
34
|
|
33
35
|
= cpd_cycle.sidebar_content.to_s
|
34
36
|
|
35
37
|
.col-9
|
36
|
-
= yield
|
38
|
+
.mb-3= yield
|
@@ -26,8 +26,9 @@
|
|
26
26
|
|
27
27
|
%tr
|
28
28
|
%th Total #{cpd_credits_label}
|
29
|
-
%td= cpd_score(cpd_statement.score)
|
29
|
+
%td= cpd_score(cpd_statement.score, cpd_statement.target_score)
|
30
30
|
|
31
|
-
|
32
|
-
%
|
33
|
-
|
31
|
+
- if cpd_statement.carry_forward.to_d > 0.0
|
32
|
+
%tr.carry-forward
|
33
|
+
%th Carry Forward
|
34
|
+
%td= cpd_score(cpd_statement.carry_forward)
|
@@ -4,7 +4,9 @@
|
|
4
4
|
.col-9
|
5
5
|
%h1= resource.cpd_cycle
|
6
6
|
|
7
|
-
|
7
|
+
- activities = (params[:activities] == 'new' ? :new : :index)
|
8
|
+
|
9
|
+
.activities-index{style: ('display: none;' unless activities == :index)}
|
8
10
|
= render('layout') do
|
9
11
|
- if resource.cpd_cycle.all_steps_content.present?
|
10
12
|
.mb-2= resource.cpd_cycle.all_steps_content.to_s
|
@@ -22,5 +24,5 @@
|
|
22
24
|
= f.hidden_field :current_step
|
23
25
|
= f.submit 'Save and Continue', center: true
|
24
26
|
|
25
|
-
.activities-new{style: 'display: none;'}
|
27
|
+
.activities-new{style: ('display: none;' unless activities == :new)}
|
26
28
|
= render('activities_new', cpd_statement: resource)
|
data/config/effective_cpd.rb
CHANGED
@@ -23,6 +23,7 @@ EffectiveCpd.setup do |config|
|
|
23
23
|
config.cpd_audit_review_items_table_name = :cpd_audit_review_items
|
24
24
|
|
25
25
|
config.cpd_bulk_audits_table_name = :cpd_bulk_audits
|
26
|
+
config.cpd_targets_table_name = :cpd_targets
|
26
27
|
|
27
28
|
# Layout Settings
|
28
29
|
# Configure the Layout per controller, or all at once
|
data/config/routes.rb
CHANGED
@@ -36,6 +36,7 @@ EffectiveCpd::Engine.routes.draw do
|
|
36
36
|
resources :cpd_cycles, except: [:show]
|
37
37
|
resources :cpd_rules, only: [:index]
|
38
38
|
resources :cpd_special_rules, except: [:show]
|
39
|
+
resources :cpd_targets, except: [:show]
|
39
40
|
|
40
41
|
resources :cpd_statements, only: [:index, :show] do
|
41
42
|
post :unsubmit, on: :member
|
@@ -6,7 +6,7 @@ class CreateEffectiveCpd < ActiveRecord::Migration[6.0]
|
|
6
6
|
t.datetime :start_at
|
7
7
|
t.datetime :end_at
|
8
8
|
|
9
|
-
t.
|
9
|
+
t.boolean :required_to_submit, default: false
|
10
10
|
|
11
11
|
t.datetime :updated_at
|
12
12
|
t.datetime :created_at
|
@@ -324,5 +324,17 @@ class CreateEffectiveCpd < ActiveRecord::Migration[6.0]
|
|
324
324
|
t.timestamps
|
325
325
|
end
|
326
326
|
|
327
|
+
create_table <%= @cpd_targets_table_name %> do |t|
|
328
|
+
t.integer :user_id
|
329
|
+
t.string :user_type
|
330
|
+
|
331
|
+
t.integer :cpd_cycle_id
|
332
|
+
|
333
|
+
t.decimal :score
|
334
|
+
t.boolean :required_to_submit
|
335
|
+
|
336
|
+
t.timestamps
|
337
|
+
end
|
338
|
+
|
327
339
|
end
|
328
340
|
end
|
data/db/seeds.rb
CHANGED
@@ -18,7 +18,6 @@ cycle = Effective::CpdCycle.create!(
|
|
18
18
|
title: "#{now.year} Continuing Professional Development",
|
19
19
|
start_at: now.beginning_of_year,
|
20
20
|
end_at: now.end_of_year,
|
21
|
-
required_score: 100,
|
22
21
|
all_steps_content: "All Steps Content",
|
23
22
|
start_content: "Start Content",
|
24
23
|
activities_content: "Activities Content",
|
data/lib/effective_cpd.rb
CHANGED
@@ -14,6 +14,8 @@ module EffectiveCpd
|
|
14
14
|
:cpd_audit_level_questions_table_name, :cpd_audit_level_question_options_table_name,
|
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, :cpd_bulk_audits_table_name,
|
17
|
+
:cpd_targets_table_name,
|
18
|
+
|
17
19
|
:layout, :auditee_user_scope, :audit_reviewer_user_scope,
|
18
20
|
:use_effective_messaging,
|
19
21
|
:mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject, :use_effective_email_templates,
|
@@ -48,6 +48,7 @@ module EffectiveCpd
|
|
48
48
|
@cpd_audit_review_items_table_name = ':' + EffectiveCpd.cpd_audit_review_items_table_name.to_s
|
49
49
|
|
50
50
|
@cpd_bulk_audits_table_name = ':' + EffectiveCpd.cpd_bulk_audits_table_name.to_s
|
51
|
+
@cpd_targets_table_name = ':' + EffectiveCpd.cpd_targets_table_name.to_s
|
51
52
|
|
52
53
|
migration_template ('../' * 3) + 'db/migrate/01_create_effective_cpd.rb.erb', 'db/migrate/create_effective_cpd.rb'
|
53
54
|
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.
|
4
|
+
version: 1.4.1
|
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-
|
11
|
+
date: 2023-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -234,6 +234,7 @@ files:
|
|
234
234
|
- app/controllers/admin/cpd_special_rules_controller.rb
|
235
235
|
- app/controllers/admin/cpd_statement_activities_controller.rb
|
236
236
|
- app/controllers/admin/cpd_statements_controller.rb
|
237
|
+
- app/controllers/admin/cpd_targets_controller.rb
|
237
238
|
- app/controllers/effective/cpd_audit_reviews_controller.rb
|
238
239
|
- app/controllers/effective/cpd_audits_controller.rb
|
239
240
|
- app/controllers/effective/cpd_cycles_controller.rb
|
@@ -253,6 +254,7 @@ files:
|
|
253
254
|
- app/datatables/admin/effective_cpd_special_rules_datatable.rb
|
254
255
|
- app/datatables/admin/effective_cpd_statement_activities_datatable.rb
|
255
256
|
- app/datatables/admin/effective_cpd_statements_datatable.rb
|
257
|
+
- app/datatables/admin/effective_cpd_targets_datatable.rb
|
256
258
|
- app/datatables/effective_cpd_available_audit_reviews_datatable.rb
|
257
259
|
- app/datatables/effective_cpd_available_audits_datatable.rb
|
258
260
|
- app/datatables/effective_cpd_available_cycles_datatable.rb
|
@@ -288,6 +290,7 @@ files:
|
|
288
290
|
- app/models/effective/cpd_special_rule_mate.rb
|
289
291
|
- app/models/effective/cpd_statement.rb
|
290
292
|
- app/models/effective/cpd_statement_activity.rb
|
293
|
+
- app/models/effective/cpd_target.rb
|
291
294
|
- app/views/admin/cpd_activities/_form.html.haml
|
292
295
|
- app/views/admin/cpd_audit_level_questions/_form.html.haml
|
293
296
|
- app/views/admin/cpd_audit_levels/_form.html.haml
|
@@ -324,10 +327,13 @@ files:
|
|
324
327
|
- app/views/admin/cpd_cycles/_form_cpd_cycle.html.haml
|
325
328
|
- app/views/admin/cpd_cycles/_form_cpd_rules.html.haml
|
326
329
|
- app/views/admin/cpd_cycles/_form_cpd_special_rules.html.haml
|
330
|
+
- app/views/admin/cpd_cycles/_form_cpd_targets.html.haml
|
327
331
|
- app/views/admin/cpd_special_rules/_form.html.haml
|
328
332
|
- app/views/admin/cpd_statements/_cpd_statement.html.haml
|
333
|
+
- app/views/admin/cpd_targets/_form.html.haml
|
329
334
|
- app/views/admin/users/_form_cpd.html.haml
|
330
335
|
- app/views/admin/users/_form_cpd_audits.html.haml
|
336
|
+
- app/views/admin/users/_form_cpd_targets.html.haml
|
331
337
|
- app/views/effective/cpd/_dashboard.html.haml
|
332
338
|
- app/views/effective/cpd_audit_level_questions/_cpd_audit_level_question.html.haml
|
333
339
|
- app/views/effective/cpd_audit_responses/_cpd_audit_response.html.haml
|