effective_cpd 0.1.3 → 0.1.4
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/assets/javascripts/effective_cpd/activities.js +6 -0
- data/app/controllers/admin/cpd_special_rules_controller.rb +13 -0
- data/app/datatables/admin/effective_cpd_special_rules_datatable.rb +23 -0
- data/app/models/effective/cpd_cycle.rb +3 -0
- data/app/models/effective/cpd_rule.rb +11 -1
- data/app/models/effective/cpd_scorer.rb +23 -1
- data/app/models/effective/cpd_special_rule.rb +54 -0
- data/app/models/effective/cpd_special_rule_mate.rb +6 -0
- data/app/views/admin/cpd_cycles/_form.html.haml +3 -0
- data/app/views/admin/cpd_cycles/_form_cpd_rules.html.haml +8 -3
- data/app/views/admin/cpd_cycles/_form_cpd_special_rules.html.haml +4 -0
- data/app/views/admin/cpd_special_rules/_form.html.haml +18 -0
- data/app/views/effective/cpd_statement_activities/_form.html.haml +1 -0
- data/app/views/effective/cpd_statements/_activities_new.html.haml +2 -0
- data/app/views/effective/cpd_statements/_activities_table.html.haml +1 -1
- data/config/effective_cpd.rb +2 -0
- data/config/routes.rb +1 -0
- data/db/migrate/01_create_effective_cpd.rb.erb +18 -0
- data/db/seeds.rb +2 -0
- data/lib/effective_cpd.rb +1 -1
- data/lib/effective_cpd/version.rb +1 -1
- data/lib/generators/effective_cpd/install_generator.rb +2 -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: 3f74220d92f6cb570ae692fae9610f7aa3c16435f025381cda0f1d76d37eb462
|
4
|
+
data.tar.gz: 5370d91a541e895acccdfe6249e7fab92083bd2e7a39138a5f1c37fe0f6141f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62863f2ebce7908df8170c7e981c026e2e16eff493376a2c21c00bfdeaeee1a2dd394713bfa5be6d1986452cd519ac6d94000f15c38ec8d5c3e561c4dd8eb297
|
7
|
+
data.tar.gz: f039df8345571dc4812372211026330d2fb69bc20eb398110cb8e0a5831273c4940132770dfdcb85212867e8b1beb5c7761b81ea52ae6b803f4579d65c48e4f3
|
@@ -44,6 +44,12 @@ $(document).on('click', '[data-cpd-edit-activity]', function(event) {
|
|
44
44
|
$activity.children('.statement-activity-form').show()
|
45
45
|
});
|
46
46
|
|
47
|
+
// When we click any x button
|
48
|
+
$(document).on('click', '[data-cpd-collapse]', function(event) {
|
49
|
+
event.preventDefault()
|
50
|
+
collapse_effective_cpd_activities()
|
51
|
+
});
|
52
|
+
|
47
53
|
// Initializers
|
48
54
|
$(document).ready(function() { initialize_effective_cpd_activities() });
|
49
55
|
$(document).on('turbolinks:load', function() { initialize_effective_cpd_activities() });
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Admin
|
2
|
+
class CpdSpecialRulesController < 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
|
+
def permitted_params
|
9
|
+
params.require(:effective_cpd_special_rule).permit!
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Admin
|
2
|
+
class EffectiveCpdSpecialRulesDatatable < Effective::Datatable
|
3
|
+
datatable do
|
4
|
+
col :id, visible: false
|
5
|
+
col :created_at, visible: false
|
6
|
+
col :updated_at, visible: false
|
7
|
+
|
8
|
+
col :cpd_cycle, label: cpd_cycle_label.titleize
|
9
|
+
|
10
|
+
col :cpd_rules
|
11
|
+
|
12
|
+
col :category
|
13
|
+
col :max_credits_per_cycle, label: 'Max ' + cpd_credits_label.titleize
|
14
|
+
|
15
|
+
actions_col
|
16
|
+
end
|
17
|
+
|
18
|
+
collection do
|
19
|
+
cpd_cycle = Effective::CpdCycle.find(attributes[:cpd_cycle_id])
|
20
|
+
Effective::CpdSpecialRule.all.deep.where(cpd_cycle: cpd_cycle)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -11,6 +11,9 @@ module Effective
|
|
11
11
|
has_many :cpd_rules, dependent: :delete_all
|
12
12
|
accepts_nested_attributes_for :cpd_rules, allow_destroy: true
|
13
13
|
|
14
|
+
has_many :cpd_special_rules, dependent: :delete_all
|
15
|
+
accepts_nested_attributes_for :cpd_special_rules, allow_destroy: true
|
16
|
+
|
14
17
|
has_many :cpd_statements
|
15
18
|
|
16
19
|
if respond_to?(:log_changes)
|
@@ -6,6 +6,9 @@ module Effective
|
|
6
6
|
# For a Category: A maximum of 35 PDHs/year may be claimed in the Contributions to Knowledge category
|
7
7
|
has_rich_text :category_credit_description
|
8
8
|
|
9
|
+
has_many :cpd_special_rule_mates, dependent: :destroy, inverse_of: :cpd_rule
|
10
|
+
has_many :cpd_special_rules, -> { CpdSpecialRule.sorted }, through: :cpd_special_rule_mates
|
11
|
+
|
9
12
|
if respond_to?(:log_changes)
|
10
13
|
log_changes(to: :cpd_cycle)
|
11
14
|
end
|
@@ -34,6 +37,7 @@ module Effective
|
|
34
37
|
timestamps
|
35
38
|
end
|
36
39
|
|
40
|
+
scope :sorted, -> { order(:id) }
|
37
41
|
scope :deep, -> { with_rich_text_category_credit_description.includes(:cpd_cycle, :ruleable) }
|
38
42
|
scope :categories, -> { where(ruleable_type: 'Effective::CpdCategory') }
|
39
43
|
scope :activities, -> { where(ruleable_type: 'Effective::CpdActivity') }
|
@@ -84,7 +88,13 @@ module Effective
|
|
84
88
|
end
|
85
89
|
|
86
90
|
def to_s
|
87
|
-
|
91
|
+
if activity?
|
92
|
+
formula.presence || ruleable.to_s.presence || 'activity rule'
|
93
|
+
elsif category?
|
94
|
+
ruleable.to_s.presence || 'category rule'
|
95
|
+
else
|
96
|
+
'new rule'
|
97
|
+
end
|
88
98
|
end
|
89
99
|
|
90
100
|
def activity?
|
@@ -78,7 +78,7 @@ module Effective
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
# This
|
81
|
+
# This enforces CycleCategory.max_credits_per_cycle
|
82
82
|
statement.cpd_statement_activities.group_by(&:cpd_category).each do |cpd_category, activities|
|
83
83
|
rule = cycle.rule_for(cpd_category)
|
84
84
|
max_credits_per_cycle = rule.max_credits_per_cycle
|
@@ -98,6 +98,28 @@ module Effective
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
+
# This enforces cumulative max credits CpdSpecialRule.max_credits_per_cycle special rules
|
102
|
+
cycle.cpd_special_rules.select(&:cumulative_max_credits?).each do |special_rule|
|
103
|
+
cpd_categories = special_rule.ruleables.select { |obj| obj.kind_of?(Effective::CpdCategory) }
|
104
|
+
|
105
|
+
max_credits_per_cycle = special_rule.max_credits_per_cycle
|
106
|
+
raise('expected max credits per cycle to be present') unless max_credits_per_cycle.to_i > 0
|
107
|
+
|
108
|
+
activities = statement.cpd_statement_activities.select { |sa| cpd_categories.include?(sa.cpd_category) }
|
109
|
+
|
110
|
+
activities.each do |activity|
|
111
|
+
next if activity.marked_for_destruction?
|
112
|
+
|
113
|
+
max_credits_per_cycle -= activity.score # We're already scored. Counting down...
|
114
|
+
|
115
|
+
if max_credits_per_cycle < 0
|
116
|
+
activity.score = [activity.score + max_credits_per_cycle, 0].max
|
117
|
+
activity.carry_forward = activity.max_score - activity.score
|
118
|
+
activity.reduced_messages["category_#{activity.cpd_category_id}"] = "You have reached the cumulative maximum of #{special_rule.max_credits_per_cycle}/#{cpd_cycle_label} for activities in the #{cpd_categories.map(&:to_s).to_sentence} categories"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
101
123
|
# This enforces the max_cycles_can_carry_forward logic
|
102
124
|
# If an Activity cannot be carried forward another cycle, its carry_forward should be 0
|
103
125
|
next_cycle = @cycles[@cycles.index(cycle) + 1]
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Effective
|
2
|
+
class CpdSpecialRule < ActiveRecord::Base
|
3
|
+
belongs_to :cpd_cycle
|
4
|
+
|
5
|
+
has_many :cpd_special_rule_mates, dependent: :destroy, inverse_of: :cpd_special_rule
|
6
|
+
has_many :cpd_rules, -> { CpdRule.sorted }, through: :cpd_special_rule_mates
|
7
|
+
|
8
|
+
if respond_to?(:log_changes)
|
9
|
+
log_changes
|
10
|
+
end
|
11
|
+
|
12
|
+
CATEGORIES = ['cumulative max credits']
|
13
|
+
|
14
|
+
effective_resource do
|
15
|
+
category :string # Special rule tyoes
|
16
|
+
|
17
|
+
# For cumulative max credits
|
18
|
+
max_credits_per_cycle :integer
|
19
|
+
|
20
|
+
timestamps
|
21
|
+
end
|
22
|
+
|
23
|
+
scope :deep, -> { includes(:cpd_special_rule_mates, cpd_rules: [:ruleable]) }
|
24
|
+
scope :sorted, -> { order(:id) }
|
25
|
+
|
26
|
+
before_validation do
|
27
|
+
self.category ||= CATEGORIES.first
|
28
|
+
end
|
29
|
+
|
30
|
+
validates :category, presence: true, inclusion: { in: CATEGORIES }
|
31
|
+
|
32
|
+
with_options(if: -> { cumulative_max_credits? }) do
|
33
|
+
validates :max_credits_per_cycle, presence: true, numericality: { greater_than: 0 }
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
if cumulative_max_credits?
|
38
|
+
"Cumulative max #{max_credits_per_cycle} credits"
|
39
|
+
else
|
40
|
+
'cpd special rule'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def cumulative_max_credits?
|
45
|
+
category == 'cumulative max credits'
|
46
|
+
end
|
47
|
+
|
48
|
+
# Right now this is going to be just Effective::CpdCategory objects
|
49
|
+
def ruleables
|
50
|
+
cpd_rules.map(&:ruleable)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -3,6 +3,9 @@
|
|
3
3
|
= render 'admin/cpd_cycles/form_cpd_cycle', cpd_cycle: cpd_cycle
|
4
4
|
|
5
5
|
- if cpd_cycle.persisted?
|
6
|
+
= tab 'Special Rules' do
|
7
|
+
= render 'admin/cpd_cycles/form_cpd_special_rules', cpd_cycle: cpd_cycle
|
8
|
+
|
6
9
|
= tab 'Category and Activity Rules' do
|
7
10
|
= tabs do
|
8
11
|
- Effective::CpdCategory.deep.sorted.each do |cpd_category|
|
@@ -6,9 +6,14 @@
|
|
6
6
|
%p= link_to 'Edit Category', edit_path, target: '_blank'
|
7
7
|
|
8
8
|
= f.fields_for :cpd_rules, cpd_cycle.rule_for(cpd_category) do |fc|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
.row
|
10
|
+
.col
|
11
|
+
= fc.number_field :max_credits_per_cycle,
|
12
|
+
label: "Max #{cpd_credits_label} per #{cpd_cycle_label}",
|
13
|
+
hint: "The maximum number of #{cpd_credits_label} that may be earned in this category for this #{cpd_cycle_label}. Leave blank for no limit."
|
14
|
+
.col
|
15
|
+
= f.select :cpd_special_rule_ids, cpd_cycle.cpd_special_rules,
|
16
|
+
label: 'Special Rules', hint: "Special rules operate on more than one category at a time"
|
12
17
|
|
13
18
|
= fc.rich_text_area :category_credit_description,
|
14
19
|
hint: "A description of the maximum #{cpd_credits_label} and carry forward policy of activities for this category"
|
@@ -0,0 +1,18 @@
|
|
1
|
+
= effective_form_with(model: [:admin, cpd_special_rule], engine: true) do |f|
|
2
|
+
- if inline_datatable?
|
3
|
+
= f.hidden_field :cpd_cycle_id
|
4
|
+
- else
|
5
|
+
= f.select :cpd_cycle_id, Effective::CpdCycle.sorted.all, label: cpd_cycle_label.titleize
|
6
|
+
|
7
|
+
= f.select :category, Effective::CpdSpecialRule::CATEGORIES
|
8
|
+
|
9
|
+
= f.show_if :category, 'cumulative max credits' do
|
10
|
+
= f.number_field :max_credits_per_cycle, label: "Cumulative max credits per #{cpd_cycle_label}",
|
11
|
+
hint: "The cumulative max #{cpd_credits_label} per #{cpd_cycle_label} that can be earned between the following categories."
|
12
|
+
|
13
|
+
- cpd_category_rules = cpd_special_rule.cpd_cycle.cpd_rules.select(&:category?)
|
14
|
+
|
15
|
+
= f.select :cpd_rule_ids, cpd_category_rules, label: 'Cumulative max included categories',
|
16
|
+
hint: "These categories will shared a maximum cumulative #{cpd_credits_label} per #{cpd_cycle_label}."
|
17
|
+
|
18
|
+
= effective_submit(f)
|
data/config/effective_cpd.rb
CHANGED
@@ -4,6 +4,8 @@ EffectiveCpd.setup do |config|
|
|
4
4
|
|
5
5
|
config.cpd_cycles_table_name = :cpd_cycles
|
6
6
|
config.cpd_rules_table_name = :cpd_rules
|
7
|
+
config.cpd_special_rules_table_name = :cpd_special_rules
|
8
|
+
config.cpd_special_rule_mates_table_name = :cpd_special_rule_mates
|
7
9
|
|
8
10
|
config.cpd_statements_table_name = :cpd_statements
|
9
11
|
config.cpd_statement_activities_table_name = :cpd_statement_activities
|
data/config/routes.rb
CHANGED
@@ -32,6 +32,7 @@ EffectiveCpd::Engine.routes.draw do
|
|
32
32
|
resources :cpd_activities, except: [:show]
|
33
33
|
resources :cpd_cycles, except: [:show]
|
34
34
|
resources :cpd_rules, only: [:index]
|
35
|
+
resources :cpd_special_rules, except: [:show]
|
35
36
|
|
36
37
|
resources :cpd_statements, only: [:index, :show]
|
37
38
|
|
@@ -51,6 +51,24 @@ class CreateEffectiveCpd < ActiveRecord::Migration[6.0]
|
|
51
51
|
t.datetime :created_at
|
52
52
|
end
|
53
53
|
|
54
|
+
create_table <%= @cpd_special_rules_table_name %> do |t|
|
55
|
+
t.references :cpd_cycle
|
56
|
+
|
57
|
+
t.integer :max_credits_per_cycle
|
58
|
+
t.string :category
|
59
|
+
|
60
|
+
t.datetime :updated_at
|
61
|
+
t.datetime :created_at
|
62
|
+
end
|
63
|
+
|
64
|
+
create_table <%= @cpd_special_rule_mates_table_name %> do |t|
|
65
|
+
t.references :cpd_rule
|
66
|
+
t.references :cpd_special_rule
|
67
|
+
|
68
|
+
t.datetime :updated_at
|
69
|
+
t.datetime :created_at
|
70
|
+
end
|
71
|
+
|
54
72
|
create_table <%= @cpd_statement_activities_table_name %> do |t|
|
55
73
|
t.references :cpd_statement
|
56
74
|
t.references :cpd_activity
|
data/db/seeds.rb
CHANGED
@@ -7,6 +7,8 @@ if Rails.env.test?
|
|
7
7
|
Effective::CpdCategory.delete_all
|
8
8
|
Effective::CpdActivity.delete_all
|
9
9
|
Effective::CpdRule.delete_all
|
10
|
+
Effective::CpdSpecialRule.delete_all
|
11
|
+
Effective::CpdSpecialRuleMate.delete_all
|
10
12
|
|
11
13
|
ActionText::RichText.where(record_type: ['Effective::CpdCycle', 'Effective::CpdCycle', 'Effective::CpdActivity', 'Effective::CpdAudit', 'Effective::CpdAuditLevelSection', 'Effective::CpdAuditLevelQuestion']).delete_all
|
12
14
|
end
|
data/lib/effective_cpd.rb
CHANGED
@@ -8,7 +8,7 @@ module EffectiveCpd
|
|
8
8
|
def self.config_keys
|
9
9
|
[
|
10
10
|
:cpd_categories_table_name, :cpd_activities_table_name,
|
11
|
-
:cpd_cycles_table_name, :cpd_rules_table_name,
|
11
|
+
:cpd_cycles_table_name, :cpd_rules_table_name, :cpd_special_rules_table_name, :cpd_special_rule_mates_table_name,
|
12
12
|
:cpd_statements_table_name, :cpd_statement_activities_table_name,
|
13
13
|
:cpd_audit_levels_table_name, :cpd_audit_level_sections_table_name,
|
14
14
|
:cpd_audit_level_questions_table_name, :cpd_audit_level_question_options_table_name,
|
@@ -25,6 +25,8 @@ module EffectiveCpd
|
|
25
25
|
|
26
26
|
@cpd_cycles_table_name = ':' + EffectiveCpd.cpd_cycles_table_name.to_s
|
27
27
|
@cpd_rules_table_name = ':' + EffectiveCpd.cpd_rules_table_name.to_s
|
28
|
+
@cpd_special_rules_table_name = ':' + EffectiveCpd.cpd_special_rules_table_name.to_s
|
29
|
+
@cpd_special_rule_mates_table_name = ':' + EffectiveCpd.cpd_special_rule_mates_table_name.to_s
|
28
30
|
|
29
31
|
@cpd_statements_table_name = ':' + EffectiveCpd.cpd_statements_table_name.to_s
|
30
32
|
@cpd_statement_activities_table_name = ':' + EffectiveCpd.cpd_statement_activities_table_name.to_s
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_cpd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
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: 2021-05-
|
11
|
+
date: 2021-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -188,6 +188,7 @@ files:
|
|
188
188
|
- app/controllers/admin/cpd_categories_controller.rb
|
189
189
|
- app/controllers/admin/cpd_cycles_controller.rb
|
190
190
|
- app/controllers/admin/cpd_rules_controller.rb
|
191
|
+
- app/controllers/admin/cpd_special_rules_controller.rb
|
191
192
|
- app/controllers/admin/cpd_statements_controller.rb
|
192
193
|
- app/controllers/effective/cpd_audit_reviews_controller.rb
|
193
194
|
- app/controllers/effective/cpd_audits_controller.rb
|
@@ -202,6 +203,7 @@ files:
|
|
202
203
|
- app/datatables/admin/effective_cpd_categories_datatable.rb
|
203
204
|
- app/datatables/admin/effective_cpd_cycles_datatable.rb
|
204
205
|
- app/datatables/admin/effective_cpd_rules_datatable.rb
|
206
|
+
- app/datatables/admin/effective_cpd_special_rules_datatable.rb
|
205
207
|
- app/datatables/admin/effective_cpd_statements_datatable.rb
|
206
208
|
- app/datatables/effective_cpd_available_audit_reviews_datatable.rb
|
207
209
|
- app/datatables/effective_cpd_available_audits_datatable.rb
|
@@ -227,6 +229,8 @@ files:
|
|
227
229
|
- app/models/effective/cpd_cycle.rb
|
228
230
|
- app/models/effective/cpd_rule.rb
|
229
231
|
- app/models/effective/cpd_scorer.rb
|
232
|
+
- app/models/effective/cpd_special_rule.rb
|
233
|
+
- app/models/effective/cpd_special_rule_mate.rb
|
230
234
|
- app/models/effective/cpd_statement.rb
|
231
235
|
- app/models/effective/cpd_statement_activity.rb
|
232
236
|
- app/views/admin/cpd_activities/_form.html.haml
|
@@ -253,6 +257,8 @@ files:
|
|
253
257
|
- app/views/admin/cpd_cycles/_form_content.html.haml
|
254
258
|
- app/views/admin/cpd_cycles/_form_cpd_cycle.html.haml
|
255
259
|
- app/views/admin/cpd_cycles/_form_cpd_rules.html.haml
|
260
|
+
- app/views/admin/cpd_cycles/_form_cpd_special_rules.html.haml
|
261
|
+
- app/views/admin/cpd_special_rules/_form.html.haml
|
256
262
|
- app/views/admin/cpd_statements/_cpd_statement.html.haml
|
257
263
|
- app/views/effective/cpd_audit_level_questions/_cpd_audit_level_question.html.haml
|
258
264
|
- app/views/effective/cpd_audit_responses/_cpd_audit_response.html.haml
|