effective_memberships 0.4.8 → 0.4.11
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_memberships/applicant_experiences.js +0 -5
- data/app/controllers/admin/applicant_endorsements_controller.rb +9 -0
- data/app/controllers/effective/applicant_endorsements_controller.rb +48 -0
- data/app/controllers/effective/applicant_references_controller.rb +1 -1
- data/app/datatables/admin/effective_applicant_endorsements_datatable.rb +35 -0
- data/app/datatables/effective_applicant_endorsements_datatable.rb +38 -0
- data/app/datatables/effective_applicant_equivalences_datatable.rb +23 -0
- data/app/datatables/effective_applicant_experiences_datatable.rb +1 -0
- data/app/datatables/effective_applicant_references_datatable.rb +1 -1
- data/app/mailers/effective/memberships_mailer.rb +25 -0
- data/app/models/concerns/effective_memberships_applicant.rb +52 -6
- data/app/models/concerns/effective_memberships_category.rb +2 -0
- data/app/models/concerns/effective_memberships_fee_payment.rb +0 -1
- data/app/models/concerns/effective_memberships_organization.rb +5 -0
- data/app/models/concerns/effective_memberships_owner.rb +16 -0
- data/app/models/concerns/effective_memberships_user.rb +5 -0
- data/app/models/effective/applicant_endorsement.rb +100 -0
- data/app/models/effective/applicant_equivalence.rb +32 -0
- data/app/models/effective/membership_history.rb +2 -0
- data/app/views/admin/applicant_endorsements/_applicant_endorsement.html.haml +1 -0
- data/app/views/admin/applicants/_form.html.haml +4 -0
- data/app/views/admin/categories/_form_applicant_steps.html.haml +12 -0
- data/app/views/admin/fee_payments/_fee_payment.html.haml +4 -0
- data/app/views/admin/fees/_form.html.haml +2 -3
- data/app/views/admin/users/_col.html.haml +12 -0
- data/app/views/effective/applicant_endorsements/_applicant_endorsement.html.haml +46 -0
- data/app/views/effective/applicant_endorsements/_datatable_actions.html.haml +4 -0
- data/app/views/effective/applicant_endorsements/_form.html.haml +9 -0
- data/app/views/effective/applicant_endorsements/_form_declaration.html.haml +22 -0
- data/app/views/effective/applicant_endorsements/complete.html.haml +3 -0
- data/app/views/effective/applicant_endorsements/edit.html.haml +8 -0
- data/app/views/effective/applicants/_endorsements.html.haml +15 -0
- data/app/views/effective/applicants/_equivalences.html.haml +10 -0
- data/app/views/effective/applicants/course_amounts.html.haml +2 -0
- data/app/views/effective/applicants/declarations.html.haml +2 -0
- data/app/views/effective/applicants/education.html.haml +1 -1
- data/app/views/effective/applicants/endorsements.html.haml +34 -0
- data/app/views/effective/applicants/equivalences.html.haml +25 -0
- data/app/views/effective/applicants/experience.html.haml +3 -3
- data/app/views/effective/applicants/files.html.haml +2 -0
- data/app/views/effective/applicants/references.html.haml +2 -0
- data/app/views/effective/applicants/select.html.haml +6 -1
- data/app/views/effective/fee_payments/_orders.html.haml +1 -1
- data/app/views/effective/memberships_mailer/applicant_endorsement_notification.liquid +15 -0
- data/config/effective_memberships.rb +3 -0
- data/config/routes.rb +9 -0
- data/db/migrate/01_create_effective_memberships.rb.erb +49 -0
- data/lib/effective_memberships/version.rb +1 -1
- data/lib/effective_memberships.rb +1 -1
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a08504cb78fd8324ad3a72904249556ba0761b490a4574e1be3a4f6ac22ef51f
|
4
|
+
data.tar.gz: 409b51e03245bd8e331aeaf2acd038c111eb060e2852ffdfdbd282e4a20d7e9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca160549bff37e5194ca4eaea87f1479426b9f019631497892d564ec4e4be828dc41513085418c89a5b08aa3fa5b2190ee7eb30a3b84acec7f6b5f03a15ff82e
|
7
|
+
data.tar.gz: 184c786911efb0309e0d988e288f3d61f7ce9cb440e850e45a2c6fb13903e9a2f5eb79ef6b414a4b9f1365c3af9dfdd5536e050f780d1f50f60b19fd47008586
|
@@ -31,8 +31,3 @@ $(document).on('change dp.change keyup', "[data-applicant-experiences-month]", f
|
|
31
31
|
const $form = $(event.currentTarget).closest('form');
|
32
32
|
sumApplicantExperiences($form);
|
33
33
|
});
|
34
|
-
|
35
|
-
|
36
|
-
// $(document).on 'cocoon:after-remove', (event) ->
|
37
|
-
// $form = $(event.target).closest('form')
|
38
|
-
// sumMonths($form) if $form.find('[data-experience-month]').length > 0
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Admin
|
2
|
+
class ApplicantEndorsementsController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_memberships) }
|
5
|
+
|
6
|
+
include Effective::CrudController
|
7
|
+
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Effective
|
2
|
+
class ApplicantEndorsementsController < ApplicationController
|
3
|
+
include Effective::CrudController
|
4
|
+
include Effective::Select2AjaxController
|
5
|
+
|
6
|
+
page_title 'Confidential Endorsement Form'
|
7
|
+
|
8
|
+
# The show and update actions are public routes but can only be reached by the token.
|
9
|
+
# The endorser must declare and submit the form
|
10
|
+
# To move an applicant endorsement from submitted to completed
|
11
|
+
|
12
|
+
submit :notify, 'Resend email notification',
|
13
|
+
success: -> { "Sent email notification to #{resource.email}" }
|
14
|
+
|
15
|
+
submit :complete, 'Complete Endorsement'
|
16
|
+
|
17
|
+
def show
|
18
|
+
@applicant_endorsement = ApplicantEndorsement.submitted.find(params[:id])
|
19
|
+
EffectiveResources.authorize!(self, :show, @applicant_endorsement)
|
20
|
+
|
21
|
+
render 'edit'
|
22
|
+
end
|
23
|
+
|
24
|
+
# Must be signed in
|
25
|
+
def select2_ajax_endorser
|
26
|
+
authenticate_user! if defined?(Devise)
|
27
|
+
|
28
|
+
applicant = EffectiveMemberships.Applicant.find(params[:applicant_id])
|
29
|
+
collection = Effective::ApplicantEndorsement.endorser_collection(applicant)
|
30
|
+
|
31
|
+
respond_with_select2_ajax(collection)
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
|
36
|
+
def permitted_params
|
37
|
+
permitted = params.require(:effective_applicant_endorsement).permit!.except(:token, :last_notified_at, :status, :status_steps, :applicant_id, :endorser_id)
|
38
|
+
|
39
|
+
if current_user && current_user.memberships_owners.include?(resource.applicant&.owner)
|
40
|
+
permitted.except(:notes, :accept_declaration)
|
41
|
+
else
|
42
|
+
permitted
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -23,7 +23,7 @@ module Effective
|
|
23
23
|
protected
|
24
24
|
|
25
25
|
def permitted_params
|
26
|
-
permitted = params.require(:effective_applicant_reference).permit!.except(:token, :last_notified_at, :status, :status_steps)
|
26
|
+
permitted = params.require(:effective_applicant_reference).permit!.except(:token, :last_notified_at, :status, :status_steps, :applicant_id)
|
27
27
|
|
28
28
|
if current_user && current_user.memberships_owners.include?(resource.applicant&.owner)
|
29
29
|
permitted.except(:reservations, :reservations_reason, :work_history, :accept_declaration)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Admin
|
2
|
+
class EffectiveApplicantEndorsementsDatatable < Effective::Datatable
|
3
|
+
|
4
|
+
datatable do
|
5
|
+
order :name
|
6
|
+
|
7
|
+
col :applicant
|
8
|
+
|
9
|
+
col :endorser
|
10
|
+
col :email
|
11
|
+
col :name
|
12
|
+
col :phone
|
13
|
+
col :unknown_member, visible: false
|
14
|
+
|
15
|
+
col :status do |endorsement|
|
16
|
+
if endorsement.submitted?
|
17
|
+
'Waiting on response'
|
18
|
+
elsif endorsement.completed?
|
19
|
+
'Completed'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
col :last_notified_at do |endorsement|
|
24
|
+
endorsement.last_notified_at&.strftime('%F') unless endorsement.completed?
|
25
|
+
end
|
26
|
+
|
27
|
+
actions_col
|
28
|
+
end
|
29
|
+
|
30
|
+
collection do
|
31
|
+
Effective::ApplicantEndorsement.deep.all
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# For the applicant complete step to add additional endorsements
|
2
|
+
class EffectiveApplicantEndorsementsDatatable < Effective::Datatable
|
3
|
+
|
4
|
+
datatable do
|
5
|
+
length :all
|
6
|
+
order :name
|
7
|
+
|
8
|
+
col :name do |endorsement|
|
9
|
+
endorser&.to_s || name
|
10
|
+
end
|
11
|
+
|
12
|
+
col :email
|
13
|
+
col :phone
|
14
|
+
|
15
|
+
col :status do |reference|
|
16
|
+
if reference.submitted?
|
17
|
+
'Waiting on response'
|
18
|
+
elsif reference.completed?
|
19
|
+
'Completed'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
col :last_notified_at do |endorsement|
|
24
|
+
endorsement.last_notified_at&.strftime('%F') unless endorsement.completed?
|
25
|
+
end
|
26
|
+
|
27
|
+
actions_col partial: 'effective/applicant_endorsements/datatable_actions', partial_as: :applicant_endorsement
|
28
|
+
end
|
29
|
+
|
30
|
+
collection do
|
31
|
+
Effective::ApplicantEndorsement.deep.where(applicant: applicant)
|
32
|
+
end
|
33
|
+
|
34
|
+
def applicant
|
35
|
+
@applicant ||= EffectiveMemberships.Applicant.where(id: attributes[:applicant_id]).first!
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class EffectiveApplicantEquivalencesDatatable < Effective::Datatable
|
2
|
+
datatable do
|
3
|
+
length :all
|
4
|
+
order :start_on
|
5
|
+
|
6
|
+
col :start_on
|
7
|
+
|
8
|
+
col :end_on do |applicant_equivalence|
|
9
|
+
applicant_equivalence.end_on&.strftime('%F') || '-'
|
10
|
+
end
|
11
|
+
|
12
|
+
col :name
|
13
|
+
col :notes
|
14
|
+
end
|
15
|
+
|
16
|
+
collection do
|
17
|
+
Effective::ApplicantEquivalence.deep.where(applicant: applicant)
|
18
|
+
end
|
19
|
+
|
20
|
+
def applicant
|
21
|
+
@applicant ||= EffectiveMemberships.Applicant.where(id: attributes[:applicant_id]).first!
|
22
|
+
end
|
23
|
+
end
|
@@ -44,6 +44,16 @@ module Effective
|
|
44
44
|
mail(to: resource.user.email, subject: subject, **headers)
|
45
45
|
end
|
46
46
|
|
47
|
+
def applicant_endorsement_notification(resource, opts = {})
|
48
|
+
@assigns = assigns_for(resource)
|
49
|
+
@applicant_endorsement = resource
|
50
|
+
|
51
|
+
subject = subject_for(__method__, 'Endorsement Requested', resource, opts)
|
52
|
+
headers = headers_for(resource, opts)
|
53
|
+
|
54
|
+
mail(to: resource.email, subject: subject, **headers)
|
55
|
+
end
|
56
|
+
|
47
57
|
def applicant_reference_notification(resource, opts = {})
|
48
58
|
@assigns = assigns_for(resource)
|
49
59
|
@applicant_reference = resource
|
@@ -61,6 +71,10 @@ module Effective
|
|
61
71
|
return applicant_assigns(resource).merge(owner_assigns(resource.owner))
|
62
72
|
end
|
63
73
|
|
74
|
+
if resource.kind_of?(Effective::ApplicantEndorsement)
|
75
|
+
return endorsement_assigns(resource).merge(owner_assigns(resource.applicant.owner))
|
76
|
+
end
|
77
|
+
|
64
78
|
if resource.kind_of?(Effective::ApplicantReference)
|
65
79
|
return reference_assigns(resource).merge(owner_assigns(resource.applicant.owner))
|
66
80
|
end
|
@@ -88,6 +102,17 @@ module Effective
|
|
88
102
|
{ applicant: values }
|
89
103
|
end
|
90
104
|
|
105
|
+
def endorsement_assigns(applicant_endorsement)
|
106
|
+
raise('expected a endorsement') unless applicant_endorsement.kind_of?(Effective::ApplicantEndorsement)
|
107
|
+
|
108
|
+
values = {
|
109
|
+
name: (applicant_endorsement.endorser&.to_s || applicant_endorsement.name),
|
110
|
+
url: effective_memberships.applicant_endorsement_url(applicant_endorsement)
|
111
|
+
}
|
112
|
+
|
113
|
+
{ endorsement: values }
|
114
|
+
end
|
115
|
+
|
91
116
|
def reference_assigns(applicant_reference)
|
92
117
|
raise('expected a reference') unless applicant_reference.kind_of?(Effective::ApplicantReference)
|
93
118
|
|
@@ -93,6 +93,12 @@ module EffectiveMembershipsApplicant
|
|
93
93
|
has_many :applicant_educations, -> { order(:id) }, class_name: 'Effective::ApplicantEducation', as: :applicant, inverse_of: :applicant, dependent: :destroy
|
94
94
|
accepts_nested_attributes_for :applicant_educations, reject_if: :all_blank, allow_destroy: true
|
95
95
|
|
96
|
+
has_many :applicant_endorsements, -> { order(:id) }, class_name: 'Effective::ApplicantEndorsement', as: :applicant, inverse_of: :applicant, dependent: :destroy
|
97
|
+
accepts_nested_attributes_for :applicant_endorsements, reject_if: :all_blank, allow_destroy: true
|
98
|
+
|
99
|
+
has_many :applicant_equivalences, -> { order(:id) }, class_name: 'Effective::ApplicantEquivalence', as: :applicant, inverse_of: :applicant, dependent: :destroy
|
100
|
+
accepts_nested_attributes_for :applicant_equivalences, reject_if: :all_blank, allow_destroy: true
|
101
|
+
|
96
102
|
has_many :applicant_experiences, -> { order(:id) }, class_name: 'Effective::ApplicantExperience', as: :applicant, inverse_of: :applicant, dependent: :destroy
|
97
103
|
accepts_nested_attributes_for :applicant_experiences, reject_if: :all_blank, allow_destroy: true
|
98
104
|
|
@@ -238,6 +244,26 @@ module EffectiveMembershipsApplicant
|
|
238
244
|
end
|
239
245
|
end
|
240
246
|
|
247
|
+
# Applicant Endorsements Step
|
248
|
+
with_options(if: -> { current_step == :endorsements }) do
|
249
|
+
validate do
|
250
|
+
required = min_applicant_endorsements()
|
251
|
+
existing = applicant_endorsements().reject(&:marked_for_destruction?).length
|
252
|
+
|
253
|
+
self.errors.add(:applicant_endorsements, "please include #{required} or more endorsements") if existing < required
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Applicant Equivalences Step
|
258
|
+
with_options(if: -> { current_step == :equivalences }) do
|
259
|
+
validate do
|
260
|
+
required = min_applicant_equivalences()
|
261
|
+
existing = applicant_equivalences().reject(&:marked_for_destruction?).length
|
262
|
+
|
263
|
+
self.errors.add(:applicant_equivalences, "please include #{required} or more equivalences") if existing < required
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
241
267
|
# Applicant References Step
|
242
268
|
with_options(if: -> { current_step == :references }) do
|
243
269
|
validate do
|
@@ -361,6 +387,7 @@ module EffectiveMembershipsApplicant
|
|
361
387
|
stamps.each { |stamp| stamp.submit! }
|
362
388
|
|
363
389
|
after_commit do
|
390
|
+
applicant_endorsements.each { |endorsement| endorsement.notify! if endorsement.submitted? }
|
364
391
|
applicant_references.each { |reference| reference.notify! if reference.submitted? }
|
365
392
|
end
|
366
393
|
|
@@ -521,6 +548,16 @@ module EffectiveMembershipsApplicant
|
|
521
548
|
category&.min_applicant_references.to_i
|
522
549
|
end
|
523
550
|
|
551
|
+
# Endorsements Step
|
552
|
+
def min_applicant_endorsements
|
553
|
+
category&.min_applicant_endorsements.to_i
|
554
|
+
end
|
555
|
+
|
556
|
+
# Equivalences Step
|
557
|
+
def min_applicant_equivalences
|
558
|
+
category&.min_applicant_equivalences.to_i
|
559
|
+
end
|
560
|
+
|
524
561
|
# Files Step
|
525
562
|
def min_applicant_files
|
526
563
|
category&.min_applicant_files.to_i
|
@@ -536,6 +573,10 @@ module EffectiveMembershipsApplicant
|
|
536
573
|
)
|
537
574
|
end
|
538
575
|
|
576
|
+
def applicant_endorsements_required?
|
577
|
+
min_applicant_endorsements > 0
|
578
|
+
end
|
579
|
+
|
539
580
|
def applicant_references_required?
|
540
581
|
min_applicant_references > 0
|
541
582
|
end
|
@@ -543,13 +584,18 @@ module EffectiveMembershipsApplicant
|
|
543
584
|
# When an application is submitted, these must be done to go to completed.
|
544
585
|
# An Admin can override this and just set them to completed.
|
545
586
|
def completed_requirements
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
{}
|
587
|
+
requirements = {}
|
588
|
+
return requirements unless category.present?
|
589
|
+
|
590
|
+
if category.applicant_wizard_steps.include?(:references) || applicant_references_required?
|
591
|
+
requirements['Applicant References'] = (!applicant_references_required? || applicant_references.count(&:completed?) >= min_applicant_references)
|
552
592
|
end
|
593
|
+
|
594
|
+
if category.applicant_wizard_steps.include?(:endorsements) || applicant_endorsements_required?
|
595
|
+
requirements['Applicant Endorsements'] = (!applicant_endorsements_required? || applicant_endorsements.count(&:completed?) >= min_applicant_endorsements)
|
596
|
+
end
|
597
|
+
|
598
|
+
requirements
|
553
599
|
end
|
554
600
|
|
555
601
|
def complete!
|
@@ -55,6 +55,8 @@ module EffectiveMembershipsCategory
|
|
55
55
|
applicant_wizard_steps :text
|
56
56
|
|
57
57
|
min_applicant_educations :integer
|
58
|
+
min_applicant_endorsements :integer
|
59
|
+
min_applicant_equivalences :integer
|
58
60
|
min_applicant_experiences_months :integer
|
59
61
|
min_applicant_references :integer
|
60
62
|
min_applicant_courses :integer
|
@@ -62,6 +62,11 @@ module EffectiveMembershipsOrganization
|
|
62
62
|
scope :deep, -> { includes(:representatives) }
|
63
63
|
scope :sorted, -> { order(:title) }
|
64
64
|
|
65
|
+
scope :membership_applying, -> {
|
66
|
+
applicants = EffectiveMemberships.Applicant.all
|
67
|
+
without_role(:member).where(id: applicants.select(:organization_id))
|
68
|
+
}
|
69
|
+
|
65
70
|
validates :title, presence: true, uniqueness: true
|
66
71
|
validates :email, presence: true
|
67
72
|
end
|
@@ -37,6 +37,22 @@ module EffectiveMembershipsOwner
|
|
37
37
|
accepts_nested_attributes_for :membership_histories
|
38
38
|
|
39
39
|
scope :members, -> { joins(:membership) }
|
40
|
+
|
41
|
+
scope :membership_removed, -> {
|
42
|
+
removed = Effective::MembershipHistory.removed.where(owner_type: name)
|
43
|
+
without_role(:member).where(id: removed.select(:owner_id))
|
44
|
+
}
|
45
|
+
|
46
|
+
scope :membership_bad_standing, -> {
|
47
|
+
bad_standing = Effective::Membership.where(bad_standing: true).where(owner_type: name)
|
48
|
+
where(id: bad_standing.select(:owner_id))
|
49
|
+
}
|
50
|
+
|
51
|
+
scope :membership_renewed_this_period, -> {
|
52
|
+
with_paid_fees_through = Effective::Membership.with_paid_fees_through.where(owner_type: name)
|
53
|
+
where(id: with_paid_fees_through.select(:owner_id))
|
54
|
+
}
|
55
|
+
|
40
56
|
end
|
41
57
|
|
42
58
|
def assign_member_role
|
@@ -27,6 +27,11 @@ module EffectiveMembershipsUser
|
|
27
27
|
class_name: 'Effective::Representative', inverse_of: :user, dependent: :delete_all
|
28
28
|
|
29
29
|
accepts_nested_attributes_for :representatives, allow_destroy: true
|
30
|
+
|
31
|
+
scope :membership_applying, -> {
|
32
|
+
applicants = EffectiveMemberships.Applicant.all
|
33
|
+
without_role(:member).where(id: applicants.select(:user_id))
|
34
|
+
}
|
30
35
|
end
|
31
36
|
|
32
37
|
# Instance Methods
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# An ApplicantEndorsement is similar to a reference, except it must be an existing member
|
2
|
+
|
3
|
+
module Effective
|
4
|
+
class ApplicantEndorsement < ActiveRecord::Base
|
5
|
+
acts_as_tokened
|
6
|
+
|
7
|
+
acts_as_statused(
|
8
|
+
:submitted, # Was submitted by the applicant
|
9
|
+
:completed # Was completed by the endorser.
|
10
|
+
)
|
11
|
+
|
12
|
+
log_changes(to: :applicant) if respond_to?(:log_changes)
|
13
|
+
|
14
|
+
belongs_to :applicant, polymorphic: true
|
15
|
+
belongs_to :endorser, polymorphic: true, optional: true
|
16
|
+
|
17
|
+
effective_resource do
|
18
|
+
# These fields are submitted by the applicant
|
19
|
+
# They should try to select an endorser from the dropdown
|
20
|
+
# But we also allow a fallback
|
21
|
+
unknown_member :boolean
|
22
|
+
endorser_email :string
|
23
|
+
name :string
|
24
|
+
phone :string
|
25
|
+
|
26
|
+
# As per acts_as_statused. For tracking the state machine.
|
27
|
+
status :string
|
28
|
+
status_steps :text
|
29
|
+
|
30
|
+
# Endorser Declaration
|
31
|
+
notes :text
|
32
|
+
accept_declaration :boolean
|
33
|
+
|
34
|
+
# Tracking the submission
|
35
|
+
token :string
|
36
|
+
last_notified_at :datetime
|
37
|
+
|
38
|
+
timestamps
|
39
|
+
end
|
40
|
+
|
41
|
+
scope :deep, -> { all }
|
42
|
+
|
43
|
+
# All step validations
|
44
|
+
validates :applicant, presence: true
|
45
|
+
validates :endorser_id, presence: true, unless: -> { unknown_member? }
|
46
|
+
|
47
|
+
with_options(if: -> { unknown_member? }) do
|
48
|
+
validates :endorser_email, presence: true, email: true
|
49
|
+
validates :name, presence: true
|
50
|
+
validates :phone, presence: true
|
51
|
+
end
|
52
|
+
|
53
|
+
# When being submit by the reference
|
54
|
+
with_options(if: -> { completed? }) do
|
55
|
+
validates :accept_declaration, acceptance: true
|
56
|
+
end
|
57
|
+
|
58
|
+
after_commit(on: :create, if: -> { applicant.was_submitted? }) { notify! }
|
59
|
+
|
60
|
+
def self.endorser_collection(applicant)
|
61
|
+
raise('expected an effective memberships applicant') unless applicant.class.try(:effective_memberships_applicant?)
|
62
|
+
|
63
|
+
collection_method = EffectiveMemberships.applicant_endorsements_endorser_collection()
|
64
|
+
|
65
|
+
if collection_method.blank?
|
66
|
+
return (applicant.user.class.members)
|
67
|
+
end
|
68
|
+
|
69
|
+
collection = instance_exec(applicant, &collection_method)
|
70
|
+
|
71
|
+
unless collection.kind_of?(ActiveRecord::Relation)
|
72
|
+
raise("expected EffectiveMemberships.applicant_endorsements_endorsers_collection to return an ActiveRecord::Relation.")
|
73
|
+
end
|
74
|
+
|
75
|
+
collection
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_s
|
79
|
+
'endorsement'
|
80
|
+
end
|
81
|
+
|
82
|
+
def email
|
83
|
+
endorser&.email || endorser_email
|
84
|
+
end
|
85
|
+
|
86
|
+
def notify!
|
87
|
+
raise('expected endorsement email') unless email.present?
|
88
|
+
|
89
|
+
EffectiveMemberships.send_email(:applicant_endorsement_notification, self)
|
90
|
+
update!(last_notified_at: Time.zone.now)
|
91
|
+
end
|
92
|
+
|
93
|
+
def complete!
|
94
|
+
completed!
|
95
|
+
applicant.save!
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Effective
|
2
|
+
class ApplicantEquivalence < ActiveRecord::Base
|
3
|
+
belongs_to :applicant, polymorphic: true
|
4
|
+
|
5
|
+
log_changes(to: :applicant) if respond_to?(:log_changes)
|
6
|
+
|
7
|
+
effective_resource do
|
8
|
+
name :string
|
9
|
+
|
10
|
+
start_on :date
|
11
|
+
end_on :date
|
12
|
+
|
13
|
+
notes :text
|
14
|
+
|
15
|
+
timestamps
|
16
|
+
end
|
17
|
+
|
18
|
+
scope :deep, -> { all }
|
19
|
+
|
20
|
+
validates :name, presence: true
|
21
|
+
validates :start_on, presence: true
|
22
|
+
|
23
|
+
validate(if: -> { start_on.present? && end_on.present? }) do
|
24
|
+
errors.add(:end_on, 'must be after start date') unless start_on < end_on
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
name || 'equivalence'
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
= render '/effective/applicant_endorsements/applicant_endorsement', applicant_endorsement: applicant_endorsement, skip_actions: true
|
@@ -25,6 +25,10 @@
|
|
25
25
|
= tab 'References' do
|
26
26
|
.mb-4= render_inline_datatable(Admin::EffectiveApplicantReferencesDatatable.new(applicant: applicant))
|
27
27
|
|
28
|
+
- if applicant.applicant_endorsements.present?
|
29
|
+
= tab 'Endorsements' do
|
30
|
+
.mb-4= render_inline_datatable(Admin::EffectiveApplicantEndorsementsDatatable.new(applicant: applicant))
|
31
|
+
|
28
32
|
- if applicant.fees.present? || applicant.orders.present?
|
29
33
|
= tab 'Fees' do
|
30
34
|
.mb-4
|
@@ -32,6 +32,18 @@
|
|
32
32
|
%td= f.number_field :min_applicant_experiences_months, label: false
|
33
33
|
%td minimimum months of work experience
|
34
34
|
|
35
|
+
- if applicant.wizard_step_keys.include?(:endorsements)
|
36
|
+
%tr
|
37
|
+
%td= applicant.wizard_step_title(:endorsements)
|
38
|
+
%td= f.number_field :min_applicant_endorsements, label: false
|
39
|
+
%td minimimum number of endorsements
|
40
|
+
|
41
|
+
- if applicant.wizard_step_keys.include?(:equivalences)
|
42
|
+
%tr
|
43
|
+
%td= applicant.wizard_step_title(:equivalences)
|
44
|
+
%td= f.number_field :min_applicant_equivalences, label: false
|
45
|
+
%td minimimum number of equivalent memberships
|
46
|
+
|
35
47
|
- if applicant.wizard_step_keys.include?(:references)
|
36
48
|
%tr
|
37
49
|
%td= applicant.wizard_step_title(:references)
|
@@ -3,9 +3,8 @@
|
|
3
3
|
= f.hidden_field :owner_id
|
4
4
|
= f.hidden_field :owner_type
|
5
5
|
- else
|
6
|
-
-
|
7
|
-
|
8
|
-
= f.select :owner_id, collection, polymorphic: true
|
6
|
+
- collection = { 'Users' => current_user.class.sorted, 'Organizations' => EffectiveMemberships.Organization.sorted }
|
7
|
+
= f.select :owner, collection, polymorphic: true
|
9
8
|
|
10
9
|
- if f.object.new_record?
|
11
10
|
= f.select :fee_type, EffectiveMemberships.custom_fee_types
|
@@ -0,0 +1,12 @@
|
|
1
|
+
- user = (resource.respond_to?(:email) ? resource : resource.user)
|
2
|
+
|
3
|
+
= user.to_s
|
4
|
+
|
5
|
+
- if user.email.present?
|
6
|
+
%br
|
7
|
+
= mail_to user.email
|
8
|
+
|
9
|
+
- if user.membership.present?
|
10
|
+
%br
|
11
|
+
= '#' + user.membership.number
|
12
|
+
#{user.membership.categories.to_sentence}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
- endorsement = applicant_endorsement
|
2
|
+
|
3
|
+
%table.table.table-sm
|
4
|
+
%tbody
|
5
|
+
%tr
|
6
|
+
%th Endorser
|
7
|
+
%td
|
8
|
+
- if endorsement.endorser.present?
|
9
|
+
- endorser = endorsement.endorser
|
10
|
+
= link_to("#{endorser.to_s} <#{endorser.email}>", "mailto:#{endorser.email}")
|
11
|
+
- else
|
12
|
+
= link_to("#{endorsement.name} <#{endorsement.email}>", "mailto:#{endorsement.email}")
|
13
|
+
%td
|
14
|
+
|
15
|
+
- if endorsement.phone.present?
|
16
|
+
%tr
|
17
|
+
%th Phone
|
18
|
+
%td= endorsement.phone
|
19
|
+
|
20
|
+
- if endorsement.applicant.was_submitted?
|
21
|
+
%tr
|
22
|
+
%th Status
|
23
|
+
%td
|
24
|
+
- if endorsement.submitted?
|
25
|
+
Waiting on response
|
26
|
+
- elsif endorsement.completed?
|
27
|
+
Response completed
|
28
|
+
|
29
|
+
- unless endorsement.applicant.was_approved?
|
30
|
+
%tr
|
31
|
+
%th Last Notified at
|
32
|
+
%td= endorsement.last_notified_at&.strftime('%F') || 'Never'
|
33
|
+
|
34
|
+
- if can?(:notify, endorsement) && !local_assigns[:skip_actions]
|
35
|
+
%tr
|
36
|
+
%th Notification
|
37
|
+
%td= link_to('Resend email notification', effective_memberships.notify_applicant_endorsement_path(endorsement), 'data-method': :post, 'data-confirm': "Really resend email notification to #{endorsement.email}?")
|
38
|
+
|
39
|
+
- if endorsement.completed? && can?(:review, endorsement)
|
40
|
+
%tr
|
41
|
+
%th Notes
|
42
|
+
%td= endorsement.notes
|
43
|
+
|
44
|
+
%tr
|
45
|
+
%th Endorsed On
|
46
|
+
%td= endorsement.completed_at.strftime('%F')
|
@@ -0,0 +1,4 @@
|
|
1
|
+
= dropdown(variation: :dropleft) do
|
2
|
+
- unless applicant_endorsement.completed?
|
3
|
+
= dropdown_link_to 'Notify', effective_memberships.notify_applicant_endorsement_path(applicant_endorsement),
|
4
|
+
data: { method: :post, confirm: "Really notify #{applicant_endorsement.email}?" }
|
@@ -0,0 +1,9 @@
|
|
1
|
+
= effective_form_with(model: applicant_endorsement, engine: true) do |f|
|
2
|
+
= f.hidden_field :applicant_id
|
3
|
+
= f.hidden_field :applicant_type
|
4
|
+
|
5
|
+
- if f.object.new_record?
|
6
|
+
%p An email will be sent asking them to complete a endorsement declaration form.
|
7
|
+
= f.submit('Create and Notify endorser')
|
8
|
+
- else
|
9
|
+
= f.submit
|
@@ -0,0 +1,22 @@
|
|
1
|
+
= effective_form_with(model: applicant_endorsement, engine: true) do |f|
|
2
|
+
%h2 Applicant endorsement
|
3
|
+
|
4
|
+
%p
|
5
|
+
I endorse and sponser
|
6
|
+
= applicant_endorsement.applicant.owner
|
7
|
+
as a candidate for
|
8
|
+
= applicant_endorsement.applicant.category
|
9
|
+
membership and certify that I have personal knowledge of the professional ability
|
10
|
+
and character, methods of practice, and experience of the applicant.
|
11
|
+
|
12
|
+
%p
|
13
|
+
The candidate has satisfied the requirements for membership in this category,
|
14
|
+
and to the best of my personal knowledge,
|
15
|
+
the applicant observes and upholds the Code of Ethics and Professional Practice.
|
16
|
+
|
17
|
+
.mt-4
|
18
|
+
|
19
|
+
= f.text_area :notes, label: "Additional comments"
|
20
|
+
= f.check_box :accept_declaration, label: 'Yes, I declare that the above information is true and accurate'
|
21
|
+
|
22
|
+
= f.submit 'Complete Endorsement'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
.card
|
2
|
+
.card-body
|
3
|
+
.row
|
4
|
+
.col-sm
|
5
|
+
%h5.card-title= applicant.wizard_step_title(:endorsements)
|
6
|
+
.col-sm-auto.text-right
|
7
|
+
= link_to('Edit', wizard_path(:endorsements)) if edit_effective_wizard?
|
8
|
+
|
9
|
+
- applicant.applicant_endorsements.each_with_index do |applicant_endorsement, index|
|
10
|
+
- if index > 0
|
11
|
+
.mb-4
|
12
|
+
|
13
|
+
%h6 Endorsement ##{index + 1}
|
14
|
+
|
15
|
+
= render('effective/applicant_endorsements/applicant_endorsement', applicant_endorsement: applicant_endorsement)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
.card
|
2
|
+
.card-body
|
3
|
+
.row
|
4
|
+
.col-sm
|
5
|
+
%h5.card-title= applicant.wizard_step_title(:equivalences)
|
6
|
+
.col-sm-auto.text-right
|
7
|
+
= link_to('Edit', wizard_path(:equivalences)) if edit_effective_wizard?
|
8
|
+
|
9
|
+
- datatable = EffectiveApplicantEquivalencesDatatable.new(applicant: applicant)
|
10
|
+
.mb-4= render_simple_datatable(datatable)
|
@@ -22,6 +22,6 @@
|
|
22
22
|
|
23
23
|
= aef.text_field :degree_obtained, label: 'Degree, diploma or program'
|
24
24
|
|
25
|
-
|
25
|
+
= render_if_exists("effective/applicants/education_fields", f: f)
|
26
26
|
|
27
27
|
= f.save 'Save and Continue'
|
@@ -0,0 +1,34 @@
|
|
1
|
+
= render 'layout' do
|
2
|
+
= render 'effective/applicants/content', resource: resource
|
3
|
+
|
4
|
+
.card
|
5
|
+
.card-body
|
6
|
+
- if resource.min_applicant_endorsements > 0
|
7
|
+
%p You must include #{resource.min_applicant_endorsements} or more endorsements.
|
8
|
+
|
9
|
+
= effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
|
10
|
+
= f.hidden_field :id
|
11
|
+
|
12
|
+
- endorders_collection = Effective::ApplicantEndorsement.endorser_collection(resource)
|
13
|
+
|
14
|
+
= f.has_many(:applicant_endorsements, cards: true) do |aef|
|
15
|
+
- aef.object.endorser_type ||= endorders_collection.klass.name
|
16
|
+
|
17
|
+
%h4 Endorsement
|
18
|
+
|
19
|
+
= aef.hidden_field :endorser_id
|
20
|
+
= aef.hidden_field :endorser_type
|
21
|
+
|
22
|
+
= aef.select :endorser_id, endorders_collection, required: false,
|
23
|
+
ajax_url: effective_memberships.select2_ajax_endorser_applicant_endorsement_path(applicant_id: resource)
|
24
|
+
|
25
|
+
= aef.check_box :unknown_member, label: 'I cant find my endorser in the above list'
|
26
|
+
|
27
|
+
= aef.show_if(:unknown_member, true) do
|
28
|
+
= aef.text_field :name, label: 'Endorser name', required: true
|
29
|
+
= aef.email_field :endorser_email, label: 'Email', required: true
|
30
|
+
= aef.phone_field :phone, required: true
|
31
|
+
|
32
|
+
= render_if_exists("effective/applicants/endorsements_fields", f: f)
|
33
|
+
|
34
|
+
= f.save 'Save and Continue'
|
@@ -0,0 +1,25 @@
|
|
1
|
+
= render 'layout' do
|
2
|
+
= render 'effective/applicants/content', resource: resource
|
3
|
+
|
4
|
+
.card
|
5
|
+
.card-body
|
6
|
+
- if resource.min_applicant_equivalences > 0
|
7
|
+
.alert.alert-danger You must include #{resource.min_applicant_equivalences} or more equivalent memberships.
|
8
|
+
|
9
|
+
= effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
|
10
|
+
= f.hidden_field :id
|
11
|
+
|
12
|
+
= f.has_many(:applicant_equivalences, cards: true) do |aef|
|
13
|
+
%h4.mb-4 Equivalent Membership
|
14
|
+
|
15
|
+
= aef.text_field :name
|
16
|
+
|
17
|
+
.row
|
18
|
+
.col= aef.date_field :start_on, label: 'Start Date'
|
19
|
+
.col= aef.date_field :end_on, label: 'End Date'
|
20
|
+
|
21
|
+
= aef.text_area :notes
|
22
|
+
|
23
|
+
= render_if_exists("effective/applicants/equivalences_fields", f: f)
|
24
|
+
|
25
|
+
= f.save 'Save and Continue'
|
@@ -12,7 +12,7 @@
|
|
12
12
|
= f.error :applicant_experiences_months
|
13
13
|
|
14
14
|
= f.has_many(:applicant_experiences, cards: true) do |aef|
|
15
|
-
%h4 Work Experience
|
15
|
+
%h4.mb-4 Work Experience
|
16
16
|
|
17
17
|
.row
|
18
18
|
.col= aef.text_field :employer
|
@@ -21,7 +21,7 @@
|
|
21
21
|
.row
|
22
22
|
.col= aef.date_field :start_on, label: 'Start Date', 'data-applicant-experiences-month': true
|
23
23
|
.col
|
24
|
-
= aef.date_field :end_on, label: 'End Date', 'data-applicant-experiences-month': true
|
24
|
+
= aef.date_field :end_on, label: 'End Date', required: false, 'data-applicant-experiences-month': true
|
25
25
|
= aef.check_box :still_work_here, label: 'I still work here'
|
26
26
|
|
27
27
|
.row
|
@@ -46,6 +46,6 @@
|
|
46
46
|
|
47
47
|
= f.error :applicant_experiences_months
|
48
48
|
|
49
|
-
|
49
|
+
= render_if_exists("effective/applicants/experience_fields", f: f)
|
50
50
|
|
51
51
|
= f.save 'Save and Continue'
|
@@ -21,4 +21,6 @@
|
|
21
21
|
.col= arf.select :relationship, Effective::ApplicantReference::RELATIONSHIPS
|
22
22
|
.col= arf.select :known, Effective::ApplicantReference::KNOWNS, label: 'Known for'
|
23
23
|
|
24
|
+
= render_if_exists("effective/applicants/references_fields", f: f)
|
25
|
+
|
24
26
|
= f.save 'Save and Continue'
|
@@ -27,9 +27,14 @@
|
|
27
27
|
= f.show_if(:category_id, mc.id) do
|
28
28
|
.mb-4
|
29
29
|
%h3= mc.to_s
|
30
|
-
|
30
|
+
|
31
|
+
- if organization_categories.present?
|
32
|
+
%small.text-muted #{mc.category} #{mc.category_type} Membership
|
33
|
+
|
31
34
|
= mc.rich_text_body
|
32
35
|
|
36
|
+
= render_if_exists("effective/applicants/select/#{mc.to_s.parameterize.underscore}", f: f, category: mc)
|
37
|
+
|
33
38
|
- if organization_categories.present?
|
34
39
|
= f.show_if_any(:category_id, organization_categories.map(&:id)) do
|
35
40
|
= render('effective/applicants/select_organization', f: f)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
subject: 'Your endorsement has been requested'
|
3
|
+
from: 'admin@example.com'
|
4
|
+
---
|
5
|
+
Hello {{ endorsement.name }},
|
6
|
+
|
7
|
+
An applicant, {{ user.name }}, has requested your endorsement.
|
8
|
+
|
9
|
+
Would you please complete the endorsement declaration form at this url:
|
10
|
+
|
11
|
+
{{ endorsement.url }}
|
12
|
+
|
13
|
+
Thank you.
|
14
|
+
|
15
|
+
Please contact us for assistance.
|
@@ -24,6 +24,9 @@ EffectiveMemberships.setup do |config|
|
|
24
24
|
# The defaults include: Applicant, Prorated, Renewal, Late, Admin
|
25
25
|
# config.additional_fee_types = []
|
26
26
|
|
27
|
+
# Applicant Endorsements
|
28
|
+
# config.applicant_endorsements_endorser_collection = Proc.new { |applicant| applicant.user.class.members }
|
29
|
+
|
27
30
|
# Applicant Reviews
|
28
31
|
# When true, display the reviewed state and require Category.min_applicant_reviews
|
29
32
|
# When false, hide the reviewed state entirely
|
data/config/routes.rb
CHANGED
@@ -9,6 +9,11 @@ EffectiveMemberships::Engine.routes.draw do
|
|
9
9
|
resources :build, controller: :applicants, only: [:show, :update]
|
10
10
|
end
|
11
11
|
|
12
|
+
resources :applicant_endorsements, only: [:new, :create, :show, :update] do
|
13
|
+
get :select2_ajax_endorser, on: :member
|
14
|
+
post :notify, on: :member
|
15
|
+
end
|
16
|
+
|
12
17
|
resources :applicant_references, only: [:new, :create, :show, :update] do
|
13
18
|
post :notify, on: :member
|
14
19
|
end
|
@@ -32,6 +37,10 @@ EffectiveMemberships::Engine.routes.draw do
|
|
32
37
|
namespace :admin do
|
33
38
|
resources :applicants, except: [:new, :create, :show]
|
34
39
|
|
40
|
+
resources :applicant_endorsements do
|
41
|
+
post :notify, on: :member
|
42
|
+
end
|
43
|
+
|
35
44
|
resources :applicant_references do
|
36
45
|
post :notify, on: :member
|
37
46
|
end
|
@@ -24,6 +24,8 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
|
|
24
24
|
t.integer :min_applicant_educations
|
25
25
|
t.integer :min_applicant_experiences_months
|
26
26
|
t.integer :min_applicant_references
|
27
|
+
t.integer :min_applicant_endorsements
|
28
|
+
t.integer :min_applicant_equivalences
|
27
29
|
t.integer :min_applicant_courses
|
28
30
|
t.integer :min_applicant_files
|
29
31
|
|
@@ -295,6 +297,53 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
|
|
295
297
|
add_index :applicant_references, :applicant_id
|
296
298
|
add_index :applicant_references, :token
|
297
299
|
|
300
|
+
# Applicant Endorsements
|
301
|
+
create_table :applicant_endorsements do |t|
|
302
|
+
t.integer :applicant_id
|
303
|
+
t.string :applicant_type
|
304
|
+
|
305
|
+
t.integer :endorser_id
|
306
|
+
t.string :endorser_type
|
307
|
+
|
308
|
+
t.boolean :unknown_member, default: false
|
309
|
+
t.string :endorser_email
|
310
|
+
t.string :name
|
311
|
+
t.string :phone
|
312
|
+
|
313
|
+
t.string :status
|
314
|
+
t.text :status_steps
|
315
|
+
|
316
|
+
t.text :notes
|
317
|
+
t.boolean :accept_declaration
|
318
|
+
|
319
|
+
t.string :token
|
320
|
+
t.datetime :last_notified_at
|
321
|
+
|
322
|
+
t.datetime :created_at
|
323
|
+
t.datetime :updated_at
|
324
|
+
end
|
325
|
+
|
326
|
+
add_index :applicant_endorsements, :applicant_id
|
327
|
+
add_index :applicant_endorsements, :token
|
328
|
+
|
329
|
+
# Applicant Equivalences
|
330
|
+
create_table :applicant_equivalences do |t|
|
331
|
+
t.integer :applicant_id
|
332
|
+
t.string :applicant_type
|
333
|
+
|
334
|
+
t.string :name
|
335
|
+
|
336
|
+
t.date :start_on
|
337
|
+
t.date :end_on
|
338
|
+
|
339
|
+
t.text :notes
|
340
|
+
|
341
|
+
t.datetime :created_at
|
342
|
+
t.datetime :updated_at
|
343
|
+
end
|
344
|
+
|
345
|
+
add_index :applicant_equivalences, :applicant_id
|
346
|
+
|
298
347
|
# Applicant Courses
|
299
348
|
create_table :applicant_course_areas do |t|
|
300
349
|
t.string :title
|
@@ -8,7 +8,7 @@ module EffectiveMemberships
|
|
8
8
|
[
|
9
9
|
:categories_table_name, :applicants_table_name, :applicant_reviews_table_name, :fee_payments_table_name, :organizations_table_name, :representatives_table_name,
|
10
10
|
:category_class_name, :organization_class_name, :applicant_class_name, :applicant_review_class_name, :fee_payment_class_name, :registrar_class_name, :membership_card_class_name,
|
11
|
-
:additional_fee_types, :applicant_reviews,
|
11
|
+
:additional_fee_types, :applicant_reviews, :applicant_endorsements_endorser_collection,
|
12
12
|
:layout,
|
13
13
|
:mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject, :use_effective_email_templates
|
14
14
|
]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_memberships
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.11
|
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: 2022-
|
11
|
+
date: 2022-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -256,6 +256,7 @@ files:
|
|
256
256
|
- app/assets/stylesheets/effective_memberships/base.scss
|
257
257
|
- app/controllers/admin/applicant_course_areas_controller.rb
|
258
258
|
- app/controllers/admin/applicant_course_names_controller.rb
|
259
|
+
- app/controllers/admin/applicant_endorsements_controller.rb
|
259
260
|
- app/controllers/admin/applicant_references_controller.rb
|
260
261
|
- app/controllers/admin/applicants_controller.rb
|
261
262
|
- app/controllers/admin/categories_controller.rb
|
@@ -266,6 +267,7 @@ files:
|
|
266
267
|
- app/controllers/admin/organizations_controller.rb
|
267
268
|
- app/controllers/admin/registrar_actions_controller.rb
|
268
269
|
- app/controllers/admin/representatives_controller.rb
|
270
|
+
- app/controllers/effective/applicant_endorsements_controller.rb
|
269
271
|
- app/controllers/effective/applicant_references_controller.rb
|
270
272
|
- app/controllers/effective/applicants_controller.rb
|
271
273
|
- app/controllers/effective/fee_payments_controller.rb
|
@@ -275,6 +277,7 @@ files:
|
|
275
277
|
- app/controllers/effective/representatives_controller.rb
|
276
278
|
- app/datatables/admin/effective_applicant_course_areas_datatable.rb
|
277
279
|
- app/datatables/admin/effective_applicant_course_names_datatable.rb
|
280
|
+
- app/datatables/admin/effective_applicant_endorsements_datatable.rb
|
278
281
|
- app/datatables/admin/effective_applicant_references_datatable.rb
|
279
282
|
- app/datatables/admin/effective_applicants_datatable.rb
|
280
283
|
- app/datatables/admin/effective_categories_datatable.rb
|
@@ -286,6 +289,8 @@ files:
|
|
286
289
|
- app/datatables/admin/effective_representatives_datatable.rb
|
287
290
|
- app/datatables/effective_applicant_courses_datatable.rb
|
288
291
|
- app/datatables/effective_applicant_educations_datatable.rb
|
292
|
+
- app/datatables/effective_applicant_endorsements_datatable.rb
|
293
|
+
- app/datatables/effective_applicant_equivalences_datatable.rb
|
289
294
|
- app/datatables/effective_applicant_experiences_datatable.rb
|
290
295
|
- app/datatables/effective_applicant_references_datatable.rb
|
291
296
|
- app/datatables/effective_applicants_datatable.rb
|
@@ -309,6 +314,8 @@ files:
|
|
309
314
|
- app/models/effective/applicant_course_area.rb
|
310
315
|
- app/models/effective/applicant_course_name.rb
|
311
316
|
- app/models/effective/applicant_education.rb
|
317
|
+
- app/models/effective/applicant_endorsement.rb
|
318
|
+
- app/models/effective/applicant_equivalence.rb
|
312
319
|
- app/models/effective/applicant_experience.rb
|
313
320
|
- app/models/effective/applicant_reference.rb
|
314
321
|
- app/models/effective/applicant_review.rb
|
@@ -327,6 +334,7 @@ files:
|
|
327
334
|
- app/views/admin/applicant_course_areas/_form_applicant_course_area.html.haml
|
328
335
|
- app/views/admin/applicant_course_areas/index.html.haml
|
329
336
|
- app/views/admin/applicant_course_name/_form.html.haml
|
337
|
+
- app/views/admin/applicant_endorsements/_applicant_endorsement.html.haml
|
330
338
|
- app/views/admin/applicant_references/_applicant_reference.html.haml
|
331
339
|
- app/views/admin/applicants/_form.html.haml
|
332
340
|
- app/views/admin/applicants/_form_approve.html.haml
|
@@ -366,6 +374,13 @@ files:
|
|
366
374
|
- app/views/admin/registrar_actions/_form_remove.html.haml
|
367
375
|
- app/views/admin/representatives/_form.html.haml
|
368
376
|
- app/views/admin/representatives/_user_fields.html.haml
|
377
|
+
- app/views/admin/users/_col.html.haml
|
378
|
+
- app/views/effective/applicant_endorsements/_applicant_endorsement.html.haml
|
379
|
+
- app/views/effective/applicant_endorsements/_datatable_actions.html.haml
|
380
|
+
- app/views/effective/applicant_endorsements/_form.html.haml
|
381
|
+
- app/views/effective/applicant_endorsements/_form_declaration.html.haml
|
382
|
+
- app/views/effective/applicant_endorsements/complete.html.haml
|
383
|
+
- app/views/effective/applicant_endorsements/edit.html.haml
|
369
384
|
- app/views/effective/applicant_references/_applicant_reference.html.haml
|
370
385
|
- app/views/effective/applicant_references/_datatable_actions.html.haml
|
371
386
|
- app/views/effective/applicant_references/_form.html.haml
|
@@ -379,6 +394,8 @@ files:
|
|
379
394
|
- app/views/effective/applicants/_declarations.html.haml
|
380
395
|
- app/views/effective/applicants/_demographics.html.haml
|
381
396
|
- app/views/effective/applicants/_education.html.haml
|
397
|
+
- app/views/effective/applicants/_endorsements.html.haml
|
398
|
+
- app/views/effective/applicants/_equivalences.html.haml
|
382
399
|
- app/views/effective/applicants/_experience.html.haml
|
383
400
|
- app/views/effective/applicants/_files.html.haml
|
384
401
|
- app/views/effective/applicants/_layout.html.haml
|
@@ -396,6 +413,8 @@ files:
|
|
396
413
|
- app/views/effective/applicants/declarations.html.haml
|
397
414
|
- app/views/effective/applicants/demographics.html.haml
|
398
415
|
- app/views/effective/applicants/education.html.haml
|
416
|
+
- app/views/effective/applicants/endorsements.html.haml
|
417
|
+
- app/views/effective/applicants/equivalences.html.haml
|
399
418
|
- app/views/effective/applicants/experience.html.haml
|
400
419
|
- app/views/effective/applicants/files.html.haml
|
401
420
|
- app/views/effective/applicants/organization.html.haml
|
@@ -431,6 +450,7 @@ files:
|
|
431
450
|
- app/views/effective/memberships_mailer/applicant_approved.liquid
|
432
451
|
- app/views/effective/memberships_mailer/applicant_completed.liquid
|
433
452
|
- app/views/effective/memberships_mailer/applicant_declined.liquid
|
453
|
+
- app/views/effective/memberships_mailer/applicant_endorsement_notification.liquid
|
434
454
|
- app/views/effective/memberships_mailer/applicant_missing_info.liquid
|
435
455
|
- app/views/effective/memberships_mailer/applicant_reference_notification.liquid
|
436
456
|
- app/views/effective/organizations/_dashboard.html.haml
|