effective_cpd 1.3.6 → 1.4.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.
- checksums.yaml +4 -4
- data/app/controllers/admin/cpd_targets_controller.rb +15 -0
- 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_audits_datatable.rb +1 -1
- 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_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/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: 10907aa7ee22755cd4b27d3e0fba90d6297dce95948e18c43b6e7a24f60d5f03
|
4
|
+
data.tar.gz: f2f2c72a7d1ea65c420583d7e2749dec93793b0395f4a2a4253f440c6f862f05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1114387c7ae09280a38b2f446456c1ae76d51647fd50b945dcf0d830f8e27b6aee44a6187f3f113b484939f5d89b59d78e1482416f9c9ba37b92e8be35b907da
|
7
|
+
data.tar.gz: 93c2ce6aa6b583bc33517291b44145a80542ac8545f6012a38ff5ed92a85fb7876a3f110d507034965b55942065113fb47fe0aa1c0994c44daf63613badd2e45
|
@@ -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
|
@@ -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|
|
@@ -18,7 +18,7 @@ class EffectiveCpdCompletedAuditsDatatable < Effective::Datatable
|
|
18
18
|
|
19
19
|
collection do
|
20
20
|
raise('expected a current_user') unless current_user.present?
|
21
|
-
EffectiveCpd.CpdAudit.
|
21
|
+
EffectiveCpd.CpdAudit.done.where(user: current_user)
|
22
22
|
end
|
23
23
|
|
24
24
|
end
|
@@ -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)
|
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.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-02
|
11
|
+
date: 2023-03-02 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
|