effective_cpd 1.1.3 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 00e8ed14d47f2bb89d1a33e12c76bf8e99b0470e65f7abcd282f23e0ec8b3a96
4
- data.tar.gz: 835ab26687db053debee149640fe8b06d6e05ce518bc4601cd5e5e8a7d4e0bec
3
+ metadata.gz: 13796b4516c32b7fd046c28fdaa1f034446e31e244c3012e9d6a0e1018feadac
4
+ data.tar.gz: 0a6b9cefe19dc6b61194037bfd2856f90dc74d09033b78a3edcbb508cbd92239
5
5
  SHA512:
6
- metadata.gz: 79844be2e538ec196567018344f52de6bb233ff0fe24d6a29ae19fe83c3f8dc6065a9cf1413a6c909ed0027a107c222d9eb531d516d256c3ac35b799efce9cc6
7
- data.tar.gz: 248e3a12c2a0500fff24054b09b89fce3fb84ed7851edebecc14c613f4bc36f513cdbfffdef09afe14fb229f3921ee8d839a5a3641c291a00a38c6b18dd1e4b9
6
+ metadata.gz: ceaa617e8d6f772d12dd08009b00df480098c268ff65dc03e5ee11da3a556353cd4ae507324497c8a1b1610810a9cc4ac811803c7c02b6d28749f3715a19fe45
7
+ data.tar.gz: 6bae554b970a8edb702b57fb18a401191fc7da6ff5acddaf21db76c1d6a4ab452a7f53e8c72178d7ed451a94ed72f155d2f7e5f5a4e6d0abdfb794eeab7e8cf1
@@ -0,0 +1,19 @@
1
+ module Admin
2
+ class CpdBulkAuditsController < 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
+ resource_scope -> { EffectiveCpd.CpdBulkAudit.deep.all }
9
+ datatable -> { EffectiveResources.best('Admin::EffectiveCpdBulkAuditsDatatable').new }
10
+
11
+ private
12
+
13
+ def permitted_params
14
+ model = (params.key?(:effective_cpd_bulk_audit) ? :effective_cpd_bulk_audit : :cpd_bulk_audit)
15
+ params.require(model).permit!
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ module Admin
2
+ class EffectiveCpdBulkAuditAuditReviewersDatatable < Effective::Datatable
3
+
4
+ datatable do
5
+ order :updated_at, :desc
6
+
7
+ col :id, visible: false
8
+ col :updated_at, label: 'Updated', visible: false
9
+ col :created_at, label: 'Created', visible: false
10
+
11
+ col :first_name
12
+ col :last_name
13
+ col :email
14
+
15
+ actions_col(only: [:show, :edit])
16
+
17
+ end
18
+
19
+ collection do
20
+ current_user.class.send(EffectiveCpd.audit_reviewer_user_scope)
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ module Admin
2
+ class EffectiveCpdBulkAuditAuditeesDatatable < Effective::Datatable
3
+
4
+ datatable do
5
+ order :updated_at, :desc
6
+
7
+ col :id, visible: false
8
+ col :updated_at, label: 'Updated', visible: false
9
+ col :created_at, label: 'Created', visible: false
10
+
11
+ col :first_name
12
+ col :last_name
13
+ col :email
14
+
15
+ actions_col(only: [:show, :edit])
16
+ end
17
+
18
+ collection do
19
+ current_user.class.send(EffectiveCpd.auditee_user_scope)
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module Admin
2
+ class EffectiveCpdBulkAuditsDatatable < Effective::Datatable
3
+
4
+ datatable do
5
+ order :updated_at, :desc
6
+
7
+ col :id, visible: false
8
+ col :updated_at, label: 'Updated', visible: false
9
+ col :created_at, label: 'Created'
10
+
11
+ col :cpd_audit_level
12
+ col :audits
13
+ col :audit_reviewers_per_audit
14
+ col :notification_date
15
+ col :email_form_skip
16
+
17
+ actions_col
18
+ end
19
+
20
+ collection do
21
+ EffectiveCpd.CpdBulkAudit.all
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,10 @@
1
+ module Effective
2
+ class CpdBulkAuditJob < ApplicationJob
3
+
4
+ def perform(id)
5
+ bulk_audit = EffectiveCpd.CpdBulkAudit.find(id)
6
+ bulk_audit.create_audits!
7
+ end
8
+
9
+ end
10
+ end
@@ -308,7 +308,7 @@ module EffectiveCpdAudit
308
308
  end
309
309
 
310
310
  def draft?
311
- !was_submitted?
311
+ !was_submitted? && !closed?
312
312
  end
313
313
 
314
314
  def in_progress?
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ # EffectiveCpdBulkAudit
4
+ #
5
+ # Mark your owner model with effective_cpd_bulk_audit to get all the includes
6
+
7
+ module EffectiveCpdBulkAudit
8
+ extend ActiveSupport::Concern
9
+
10
+ module Base
11
+ def effective_cpd_bulk_audit
12
+ include ::EffectiveCpdBulkAudit
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def effective_cpd_bulk_audit?; true; end
18
+ end
19
+
20
+ included do
21
+ attr_accessor :current_user
22
+
23
+ # App scoped
24
+ belongs_to :cpd_audit_level, polymorphic: true
25
+
26
+ log_changes if respond_to?(:log_changes)
27
+
28
+ effective_resource do
29
+ cpd_user_class_name :string
30
+
31
+ audits :integer
32
+ audit_reviewers_per_audit :integer
33
+
34
+ notification_date :date
35
+ email_form_skip :boolean
36
+
37
+ auditees_count :integer
38
+ audit_reviewers_count :integer
39
+
40
+ timestamps
41
+ end
42
+
43
+ scope :deep, -> { includes(:cpd_audit_level) }
44
+ scope :sorted, -> { order(:id) }
45
+
46
+ before_validation(if: -> { current_user.present? }) do
47
+ self.cpd_user_class_name ||= current_user.class.name
48
+ end
49
+
50
+ before_validation do
51
+ self.notification_date ||= Time.zone.now
52
+ end
53
+
54
+ before_validation(if: -> { cpd_user_scope.present? }) do
55
+ self.auditees_count ||= cpd_auditees.count()
56
+ self.audit_reviewers_count ||= cpd_audit_reviewers.count()
57
+ end
58
+
59
+ validates :cpd_user_class_name, presence: true
60
+
61
+ validates :audits, presence: true, numericality: { greater_than: 0, less_than_or_equal_to: 1000 }
62
+ validates :audit_reviewers_per_audit, presence: true, numericality: { greater_than: 0, less_than_or_equal_to: 3 }
63
+
64
+ validates :auditees_count, numericality: { greater_than: 0 }
65
+ validates :audit_reviewers_count, numericality: { greater_than: 0 }
66
+
67
+ validate(if: -> { cpd_user_scope.present? }) do
68
+ self.errors.add(:cpd_user_class_name, "expecting an effective_cpd_user") unless cpd_user_scope.respond_to?(:effective_cpd_user?)
69
+ end
70
+
71
+ validate(if: -> { audits.present? && auditees_count.present? }) do
72
+ self.errors.add(:audits, "can't be more than the number of auditees #{auditees_count}") if audits > auditees_count
73
+ end
74
+
75
+ validate(if: -> { audit_reviewers_per_audit.present? && audit_reviewers_count.present? }) do
76
+ self.errors.add(:audit_reviewers_per_audit, "can't be more than the number of audit reviewers #{audit_reviewers_count}") if audit_reviewers_per_audit > audit_reviewers_count
77
+ end
78
+
79
+ after_commit(on: :create) { create_bulk_audit_job! }
80
+ end
81
+
82
+ def to_s
83
+ 'bulk audit'
84
+ end
85
+
86
+ def cpd_user_scope
87
+ cpd_user_class_name.constantize.all if cpd_user_class_name.present?
88
+ end
89
+
90
+ def cpd_auditees
91
+ cpd_user_scope.send(EffectiveCpd.auditee_user_scope)
92
+ end
93
+
94
+ def cpd_audit_reviewers
95
+ cpd_user_scope.send(EffectiveCpd.audit_reviewer_user_scope)
96
+ end
97
+
98
+ def create_bulk_audit_job!
99
+ raise('must be persisted') unless persisted?
100
+
101
+ Effective::CpdBulkAuditJob.perform_later(id)
102
+ end
103
+
104
+ # Called by Effective::CpdBulkAuditJob
105
+ def create_audits!
106
+ save!
107
+
108
+ @auditees = cpd_auditees.order('RANDOM()').limit(audits)
109
+ @reviewers = cpd_audit_reviewers.order('RANDOM()').limit(audits).to_a
110
+
111
+ @auditees.each do |auditee|
112
+ reviewers = audit_reviewers_per_audit.times.map { next_audit_reviewer() }
113
+
114
+ cpd_audit = build_cpd_audit(auditee, reviewers)
115
+ cpd_audit.save!
116
+ end
117
+
118
+ true
119
+ end
120
+
121
+ def build_cpd_audit(auditee, reviewers)
122
+ raise('expected auditee cpd user') unless auditee.class.respond_to?(:effective_cpd_user?)
123
+
124
+ reviewers = Array(reviewers)
125
+ raise('expected audit reviewers') unless reviewers.all? { |reviewer| reviewer.try(:cpd_audit_reviewer?) }
126
+
127
+ cpd_audit = EffectiveCpd.CpdAudit.new(
128
+ cpd_audit_level: cpd_audit_level,
129
+ email_form_skip: email_form_skip?,
130
+ user: auditee,
131
+ notification_date: notification_date
132
+ )
133
+
134
+ reviewers.each do |reviewer|
135
+ cpd_audit.cpd_audit_reviews.build(
136
+ cpd_audit_level: cpd_audit_level,
137
+ email_form_skip: email_form_skip?,
138
+ user: reviewer
139
+ )
140
+ end
141
+
142
+ cpd_audit
143
+ end
144
+
145
+ # Round robin
146
+ def next_audit_reviewer
147
+ raise('expected @audit_reviewers to be set') unless @reviewers
148
+
149
+ @reviewers_index ||= -1
150
+
151
+ # Next Reviewer
152
+ @reviewers_index += 1
153
+ @reviewers_index = 0 if @reviewers_index >= @reviewers.length
154
+
155
+ @reviewers[@reviewers_index]
156
+ end
157
+
158
+ end
@@ -24,7 +24,7 @@ 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
- scope :cpd_audit_auditees, -> { without_role(:cpd_audit_reviewer) }
27
+ scope :cpd_audit_auditees, -> { without_role(:cpd_audit_reviewer).without_role(:admin) }
28
28
  scope :cpd_audit_reviewers, -> { with_role(:cpd_audit_reviewer) }
29
29
  end
30
30
 
@@ -0,0 +1,5 @@
1
+ module Effective
2
+ class CpdBulkAudit < ActiveRecord::Base
3
+ effective_cpd_bulk_audit
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ = render('admin/cpd_bulk_audits/form_cpd_bulk_audit', cpd_bulk_audit: cpd_bulk_audit)
@@ -0,0 +1,60 @@
1
+ %h2 Bulk Create Audits
2
+
3
+ = effective_form_with(model: [:admin, cpd_bulk_audit], engine: true, url: effective_cpd.admin_cpd_bulk_audits_path) do |f|
4
+ = f.number_field :audits, label: 'How many audits to create', placeholder: 100
5
+ = f.number_field :audit_reviewers_per_audit, label: 'How many reviewers should be assigned to each audit', placeholder: 1
6
+
7
+ = f.hidden_field :cpd_audit_level_type, value: EffectiveCpd.CpdAuditLevel.name
8
+ = f.select :cpd_audit_level_id, EffectiveCpd.CpdAuditLevel.new_cpd_audit_level_collection, label: 'Audit level'
9
+
10
+ = f.date_field :notification_date, label: 'Date of notification', required: false, placeholder: Time.zone.now.strftime('%F'),
11
+ hint: "the starting date for any deadline calculations. leave blank for today's date"
12
+
13
+ %h3 Eligible Auditees
14
+ - datatable = EffectiveResources.best('Admin::EffectiveCpdBulkAuditAuditeesDatatable').new(self)
15
+ - raise('expected an auditees datatable') unless datatable.present?
16
+
17
+ %p The following #{pluralize(datatable.collection.count, 'auditee')} may be selected for audit:
18
+ = collapse('Show auditees...', card_class: '') do
19
+ = render_datatable(datatable)
20
+
21
+ %h3 Eligible Audit Reviewers
22
+ - datatable = EffectiveResources.best('Admin::EffectiveCpdBulkAuditAuditReviewersDatatable').new(self)
23
+ - raise('expected an auditees datatable') unless datatable.present?
24
+
25
+ %p The following #{pluralize(datatable.collection.count, 'audit reviewer')} may be selected to review audits:
26
+ = collapse('Show audit reviewers...', card_class: '') do
27
+ = render_datatable(datatable)
28
+
29
+ %h3 Email to send
30
+ = f.check_box :email_form_skip, label: 'Do not send email'
31
+
32
+ = f.show_if :email_form_skip, true do
33
+ %p No emails will be sent.
34
+
35
+ = f.hide_if :email_form_skip, true do
36
+ %p
37
+ The
38
+ - email = Effective::EmailTemplate.where(template_name: :cpd_audit_opened).first!
39
+ = link_to('cpd_audit_opened email', effective_email_templates.edit_admin_email_template_path(email), target: '_blank')
40
+ email will be sent to each auditee.
41
+
42
+ %p
43
+ The
44
+ - email = Effective::EmailTemplate.where(template_name: :cpd_audit_review_opened).first!
45
+ = link_to('cpd_audit_review_opened email', effective_email_templates.edit_admin_email_template_path(email), target: '_blank')
46
+ email will be sent to each audit reviewer.
47
+
48
+ %h3 Create Audits
49
+
50
+ %p
51
+ Upon clicking the button below, the audits will be created in a background process.
52
+
53
+ %p
54
+ The auditees will be randomly selected, and the audit reviewers assigned in a round robin fashion.
55
+ This process will take a few minutes.
56
+
57
+ %p
58
+ All created audits will be displayed on the #{link_to 'Audits', effective_cpd.admin_cpd_audits_path} screen.
59
+
60
+ = f.submit 'Create Bulk Audits', center: true, 'data-confirm': "Really create audits?"
@@ -1,4 +1,5 @@
1
- = wizard_card(cpd_audit) do
1
+ - # don't use wizard_card here
2
+ = card(cpd_audit.wizard_step_title(step)) do
2
3
  %table.table
3
4
  %tbody
4
5
  %tr
@@ -1,4 +1,5 @@
1
- = wizard_card(cpd_audit) do
1
+ - # don't use wizard_card here
2
+ = card(cpd_audit.wizard_step_title(step)) do
2
3
  %table.table
3
4
  %tbody
4
5
  %tr
@@ -1,4 +1,5 @@
1
- = wizard_card(cpd_audit) do
1
+ - # don't use wizard_card here
2
+ = card(cpd_audit.wizard_step_title(step)) do
2
3
  %table.table
3
4
  %tbody
4
5
  %tr
@@ -22,6 +22,8 @@ EffectiveCpd.setup do |config|
22
22
  config.cpd_audit_reviews_table_name = :cpd_audit_reviews
23
23
  config.cpd_audit_review_items_table_name = :cpd_audit_review_items
24
24
 
25
+ config.cpd_bulk_audits_table_name = :cpd_bulk_audits
26
+
25
27
  # Layout Settings
26
28
  # Configure the Layout per controller, or all at once
27
29
  config.layout = {
@@ -35,6 +37,7 @@ EffectiveCpd.setup do |config|
35
37
  # config.cpd_audit_class_name = 'Effective::CpdAudit'
36
38
  # config.cpd_audit_level_class_name = 'Effective::CpdAuditLevel'
37
39
  # config.cpd_audit_review_class_name = 'Effective::CpdAuditReview'
40
+ # config.cpd_bulk_audit_class_name = 'Effective::CpdBulkAudit'
38
41
 
39
42
  # Program label settings
40
43
  config.program_label = 'CPD' # CPD or MCE
data/config/routes.rb CHANGED
@@ -46,6 +46,8 @@ EffectiveCpd::Engine.routes.draw do
46
46
 
47
47
  resources :cpd_audits, except: [:show]
48
48
  resources :cpd_audit_reviews
49
+
50
+ resources :cpd_bulk_audits, only: [:index, :new, :create]
49
51
  end
50
52
 
51
53
  end
@@ -305,5 +305,22 @@ class CreateEffectiveCpd < ActiveRecord::Migration[6.0]
305
305
  t.datetime :created_at
306
306
  end
307
307
 
308
+ create_table <%= @cpd_bulk_audits_table_name %> do |t|
309
+ t.integer :cpd_audit_level_id
310
+ t.string :cpd_audit_level_type
311
+
312
+ t.integer :audits
313
+ t.integer :audit_reviewers_per_audit
314
+
315
+ t.date :notification_date
316
+ t.boolean :email_form_skip
317
+
318
+ t.string :user_klass
319
+ t.integer :auditees_count
320
+ t.integer :audit_reviewers_count
321
+
322
+ t.timestamps
323
+ end
324
+
308
325
  end
309
326
  end
@@ -11,11 +11,11 @@ module EffectiveCpd
11
11
  initializer 'effective_cpd.active_record' do |app|
12
12
  ActiveSupport.on_load :active_record do
13
13
  ActiveRecord::Base.extend(EffectiveCpdUser::Base)
14
- #ActiveRecord::Base.extend(EffectiveCpdCycle::Base)
15
14
  ActiveRecord::Base.extend(EffectiveCpdStatement::Base)
16
15
  ActiveRecord::Base.extend(EffectiveCpdAudit::Base)
17
16
  ActiveRecord::Base.extend(EffectiveCpdAuditLevel::Base)
18
17
  ActiveRecord::Base.extend(EffectiveCpdAuditReview::Base)
18
+ ActiveRecord::Base.extend(EffectiveCpdBulkAudit::Base)
19
19
  end
20
20
  end
21
21
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveCpd
2
- VERSION = '1.1.3'
2
+ VERSION = '1.2.1'
3
3
  end
data/lib/effective_cpd.rb CHANGED
@@ -13,11 +13,11 @@ module EffectiveCpd
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,
15
15
  :cpd_audits_table_name, :cpd_audit_responses_table_name, :cpd_audit_response_options_table_name,
16
- :cpd_audit_reviews_table_name, :cpd_audit_review_items_table_name,
16
+ :cpd_audit_reviews_table_name, :cpd_audit_review_items_table_name, :cpd_bulk_audits_table_name,
17
17
  :program_label, :cycle_label, :credit_label, :layout, :auditee_user_scope, :audit_reviewer_user_scope,
18
18
  :use_effective_messaging,
19
19
  :mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject, :use_effective_email_templates,
20
- :cpd_statement_class_name, :cpd_audit_class_name, :cpd_audit_level_class_name, :cpd_audit_review_class_name
20
+ :cpd_statement_class_name, :cpd_audit_class_name, :cpd_audit_level_class_name, :cpd_audit_review_class_name, :cpd_bulk_audit_class_name
21
21
  ]
22
22
  end
23
23
 
@@ -43,6 +43,10 @@ module EffectiveCpd
43
43
  cpd_audit_review_class_name&.constantize || Effective::CpdAuditReview
44
44
  end
45
45
 
46
+ def self.CpdBulkAudit
47
+ cpd_bulk_audit_class_name&.constantize || Effective::CpdBulkAudit
48
+ end
49
+
46
50
  def self.use_effective_messaging?
47
51
  defined?(EffectiveMessaging) && !!use_effective_messaging
48
52
  end
@@ -43,6 +43,8 @@ module EffectiveCpd
43
43
  @cpd_audit_reviews_table_name = ':' + EffectiveCpd.cpd_audit_reviews_table_name.to_s
44
44
  @cpd_audit_review_items_table_name = ':' + EffectiveCpd.cpd_audit_review_items_table_name.to_s
45
45
 
46
+ @cpd_bulk_audits_table_name = ':' + EffectiveCpd.cpd_bulk_audits_table_name.to_s
47
+
46
48
  migration_template ('../' * 3) + 'db/migrate/01_create_effective_cpd.rb.erb', 'db/migrate/create_effective_cpd.rb'
47
49
  end
48
50
 
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.3
4
+ version: 1.2.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-01-20 00:00:00.000000000 Z
11
+ date: 2023-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: effective_developer
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: effective_email_templates
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +192,20 @@ dependencies:
178
192
  - - ">="
179
193
  - !ruby/object:Gem::Version
180
194
  version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: effective_roles
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
181
209
  description: Continuing professional development and audits rails engine
182
210
  email:
183
211
  - info@codeandeffect.com
@@ -199,6 +227,7 @@ files:
199
227
  - app/controllers/admin/cpd_audit_levels_controller.rb
200
228
  - app/controllers/admin/cpd_audit_reviews_controller.rb
201
229
  - app/controllers/admin/cpd_audits_controller.rb
230
+ - app/controllers/admin/cpd_bulk_audits_controller.rb
202
231
  - app/controllers/admin/cpd_categories_controller.rb
203
232
  - app/controllers/admin/cpd_cycles_controller.rb
204
233
  - app/controllers/admin/cpd_rules_controller.rb
@@ -215,6 +244,9 @@ files:
215
244
  - app/datatables/admin/effective_cpd_audit_levels_datatable.rb
216
245
  - app/datatables/admin/effective_cpd_audit_reviews_datatable.rb
217
246
  - app/datatables/admin/effective_cpd_audits_datatable.rb
247
+ - app/datatables/admin/effective_cpd_bulk_audit_audit_reviewers_datatable.rb
248
+ - app/datatables/admin/effective_cpd_bulk_audit_auditees_datatable.rb
249
+ - app/datatables/admin/effective_cpd_bulk_audits_datatable.rb
218
250
  - app/datatables/admin/effective_cpd_categories_datatable.rb
219
251
  - app/datatables/admin/effective_cpd_cycles_datatable.rb
220
252
  - app/datatables/admin/effective_cpd_rules_datatable.rb
@@ -229,10 +261,12 @@ files:
229
261
  - app/datatables/effective_cpd_completed_statements_datatable.rb
230
262
  - app/helpers/effective_cpd_audits_helper.rb
231
263
  - app/helpers/effective_cpd_helper.rb
264
+ - app/jobs/effective/cpd_bulk_audit_job.rb
232
265
  - app/mailers/effective/cpd_mailer.rb
233
266
  - app/models/concerns/effective_cpd_audit.rb
234
267
  - app/models/concerns/effective_cpd_audit_level.rb
235
268
  - app/models/concerns/effective_cpd_audit_review.rb
269
+ - app/models/concerns/effective_cpd_bulk_audit.rb
236
270
  - app/models/concerns/effective_cpd_statement.rb
237
271
  - app/models/concerns/effective_cpd_user.rb
238
272
  - app/models/effective/cpd_activity.rb
@@ -245,6 +279,7 @@ files:
245
279
  - app/models/effective/cpd_audit_response_option.rb
246
280
  - app/models/effective/cpd_audit_review.rb
247
281
  - app/models/effective/cpd_audit_review_item.rb
282
+ - app/models/effective/cpd_bulk_audit.rb
248
283
  - app/models/effective/cpd_category.rb
249
284
  - app/models/effective/cpd_cycle.rb
250
285
  - app/models/effective/cpd_rule.rb
@@ -278,6 +313,8 @@ files:
278
313
  - app/views/admin/cpd_audits/_form_new.html.haml
279
314
  - app/views/admin/cpd_audits/_form_process.html.haml
280
315
  - app/views/admin/cpd_audits/_status.html.haml
316
+ - app/views/admin/cpd_bulk_audits/_form.html.haml
317
+ - app/views/admin/cpd_bulk_audits/_form_cpd_bulk_audit.html.haml
281
318
  - app/views/admin/cpd_categories/_form.html.haml
282
319
  - app/views/admin/cpd_categories/_form_cpd_category.html.haml
283
320
  - app/views/admin/cpd_cycles/_form.html.haml