effective_memberships 0.3.10 → 0.3.13
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/applicants_controller.rb +14 -0
- data/app/controllers/effective/applicants_controller.rb +2 -0
- data/app/datatables/admin/effective_applicants_datatable.rb +7 -2
- data/app/datatables/admin/effective_fees_datatable.rb +5 -3
- data/app/datatables/effective_applicants_datatable.rb +10 -4
- data/app/helpers/effective_memberships_helper.rb +9 -0
- data/app/mailers/effective/memberships_mailer.rb +19 -8
- data/app/models/concerns/effective_memberships_applicant.rb +71 -18
- data/app/models/concerns/effective_memberships_owner.rb +8 -2
- data/app/views/admin/applicants/_form.html.haml +10 -6
- data/app/views/admin/applicants/_form_approve.html.haml +1 -5
- data/app/views/admin/applicants/_form_complete.html.haml +8 -0
- data/app/views/admin/applicants/_form_missing_info.html.haml +11 -0
- data/app/views/admin/applicants/_form_process.html.haml +16 -12
- data/app/views/admin/applicants/_status.html.haml +67 -49
- data/app/views/effective/applicants/_missing_info.html.haml +18 -0
- data/app/views/effective/applicants/_summary.html.haml +1 -1
- data/app/views/effective/applicants/submitted.html.haml +11 -9
- data/app/views/effective/applicants/summary.html.haml +7 -1
- data/app/views/effective/memberships_mailer/applicant_completed.liquid +15 -0
- data/app/views/effective/memberships_mailer/applicant_missing_info.liquid +17 -0
- data/config/effective_memberships.rb +19 -21
- data/db/migrate/01_create_effective_memberships.rb.erb +4 -0
- data/lib/effective_memberships/version.rb +1 -1
- data/lib/effective_memberships.rb +5 -29
- metadata +7 -3
- data/app/views/layouts/effective_memberships_mailer_layout.html.haml +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38134acc9619d9ea0404332803f0c17535fee985688ddcc628db39c1cbf9987c
|
4
|
+
data.tar.gz: 781c42e6cdeb6c501aa696c1a13bc9917db90c5090b05a845754b2547b4a9689
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ea602b5671e84066f96d77d996c08f6524ff46659ff1ede3b0b730a133c95693aa83b1e4dbf837b06f271c8d01ee73fa9c1c44528a2fd4bb3b3e10123e60888
|
7
|
+
data.tar.gz: dc6909b2b20ef4db2200be6cd8bcbf2bcc2ea5492e2c745ae64b48158b4092b78db8305b43d0ae46f2fa800e41767bbb1faf9ad13a9547b0676b3dd8ff283520
|
@@ -8,6 +8,20 @@ module Admin
|
|
8
8
|
resource_scope -> { EffectiveMemberships.Applicant.deep.all }
|
9
9
|
datatable -> { Admin::EffectiveApplicantsDatatable.new }
|
10
10
|
|
11
|
+
submit :complete, 'Complete Applicant', success: -> {
|
12
|
+
[
|
13
|
+
"Successfully completed #{resource.owner} #{resource}",
|
14
|
+
("and sent #{resource.owner.email} a notification" unless resource.email_form_skip)
|
15
|
+
].compact.join(' ')
|
16
|
+
}
|
17
|
+
|
18
|
+
submit :missing, 'Missing Info Applicant', success: -> {
|
19
|
+
[
|
20
|
+
"Successfully marked #{resource.owner} #{resource} as missing info",
|
21
|
+
("and sent #{resource.owner.email} a notification" unless resource.email_form_skip)
|
22
|
+
].compact.join(' ')
|
23
|
+
}
|
24
|
+
|
11
25
|
submit :approve, 'Approve Applicant', success: -> {
|
12
26
|
[
|
13
27
|
"Successfully approved #{resource.owner} #{resource}",
|
@@ -11,14 +11,19 @@ module Admin
|
|
11
11
|
order :id
|
12
12
|
col :id, visible: false
|
13
13
|
|
14
|
-
col :status
|
14
|
+
col :status, search: effective_memberships_status_collection()
|
15
15
|
|
16
16
|
col :created_at, label: 'Created', as: :date, visible: false
|
17
17
|
col :updated_at, label: 'Updated', visible: false
|
18
18
|
|
19
19
|
col :submitted_at, label: 'Submitted', visible: false, as: :date
|
20
20
|
col :completed_at, label: 'Completed', visible: false, as: :date
|
21
|
-
col :
|
21
|
+
col :missing_info_at, label: 'Missing Info', visible: false, as: :date
|
22
|
+
|
23
|
+
if EffectiveMemberships.applicant_reviews?
|
24
|
+
col :reviewed_at, label: 'Reviewed', visible: false, as: :date
|
25
|
+
end
|
26
|
+
|
22
27
|
col :approved_at, label: 'Approved', visible: false, as: :date
|
23
28
|
|
24
29
|
col :owner
|
@@ -33,7 +33,9 @@ module Admin
|
|
33
33
|
|
34
34
|
col :category, search: { collection: EffectiveMemberships.Category.all, polymorphic: false }
|
35
35
|
|
36
|
-
|
36
|
+
unless attributes[:total] == false
|
37
|
+
aggregate :total
|
38
|
+
end
|
37
39
|
|
38
40
|
if attributes[:applicant_id]
|
39
41
|
actions_col(new: false)
|
@@ -63,11 +65,11 @@ module Admin
|
|
63
65
|
end
|
64
66
|
|
65
67
|
def applicant
|
66
|
-
@applicant ||= EffectiveMemberships.Applicant.
|
68
|
+
@applicant ||= EffectiveMemberships.Applicant.where(id: attributes[:applicant_id]).first!
|
67
69
|
end
|
68
70
|
|
69
71
|
def fee_payment
|
70
|
-
@fee_payment ||= EffectiveMemberships.FeePayment.
|
72
|
+
@fee_payment ||= EffectiveMemberships.FeePayment.where(id: attributes[:fee_payment_id]).first!
|
71
73
|
end
|
72
74
|
|
73
75
|
end
|
@@ -6,14 +6,20 @@ class EffectiveApplicantsDatatable < Effective::Datatable
|
|
6
6
|
col :id, visible: false
|
7
7
|
|
8
8
|
col :category, label: 'Category'
|
9
|
-
col :status
|
9
|
+
col :status, search: effective_memberships_status_collection()
|
10
10
|
|
11
11
|
col :created_at, label: 'Created', as: :date
|
12
12
|
col :updated_at, label: 'Updated', as: :date, visible: false
|
13
|
+
|
13
14
|
col :submitted_at, label: 'Submitted', as: :date
|
14
|
-
col :completed_at, label: 'Completed', as: :date
|
15
|
-
col :
|
16
|
-
|
15
|
+
col :completed_at, label: 'Completed', as: :date, visible: false
|
16
|
+
col :missing_info_at, label: 'Missing Info', as: :date, visible: false
|
17
|
+
|
18
|
+
if EffectiveMemberships.applicant_reviews?
|
19
|
+
col :reviewed_at, label: 'Reviewed', as: :date
|
20
|
+
end
|
21
|
+
|
22
|
+
col :approved_at, label: 'Approved', as: :date
|
17
23
|
|
18
24
|
col :orders
|
19
25
|
|
@@ -1,2 +1,11 @@
|
|
1
1
|
module EffectiveMembershipsHelper
|
2
|
+
|
3
|
+
def effective_memberships_status_collection
|
4
|
+
EffectiveMemberships.Applicant::STATUSES.map do |status|
|
5
|
+
next if status == :reviewed && !EffectiveMemberships.applicant_reviews?
|
6
|
+
|
7
|
+
[status.to_s.gsub('_', ' '), status]
|
8
|
+
end.compact
|
9
|
+
end
|
10
|
+
|
2
11
|
end
|
@@ -1,18 +1,29 @@
|
|
1
1
|
module Effective
|
2
2
|
class MembershipsMailer < EffectiveMemberships.parent_mailer_class
|
3
|
-
|
3
|
+
|
4
|
+
include EffectiveEmailTemplatesMailer if EffectiveMemberships.use_effective_email_templates
|
4
5
|
|
5
6
|
default from: -> { EffectiveMemberships.mailer_sender }
|
6
|
-
layout -> { EffectiveMemberships.mailer_layout
|
7
|
+
layout -> { EffectiveMemberships.mailer_layout }
|
8
|
+
|
9
|
+
def applicant_completed(resource, opts = {})
|
10
|
+
@assigns = assigns_for(resource)
|
11
|
+
mail(to: resource.owner.email, **headers_for(resource, opts))
|
12
|
+
end
|
13
|
+
|
14
|
+
def applicant_missing_info(resource, opts = {})
|
15
|
+
@assigns = assigns_for(resource)
|
16
|
+
mail(to: resource.owner.email, **headers_for(resource, opts))
|
17
|
+
end
|
7
18
|
|
8
19
|
def applicant_approved(resource, opts = {})
|
9
20
|
@assigns = assigns_for(resource)
|
10
|
-
mail(to:
|
21
|
+
mail(to: resource.owner.email, **headers_for(resource, opts))
|
11
22
|
end
|
12
23
|
|
13
24
|
def applicant_declined(resource, opts = {})
|
14
25
|
@assigns = assigns_for(resource)
|
15
|
-
mail(to:
|
26
|
+
mail(to: resource.owner.email, **headers_for(resource, opts))
|
16
27
|
end
|
17
28
|
|
18
29
|
def applicant_reference_notification(resource, opts = {})
|
@@ -49,11 +60,11 @@ module Effective
|
|
49
60
|
|
50
61
|
url: effective_memberships.applicant_url(applicant),
|
51
62
|
admin_url: effective_memberships.edit_admin_applicant_url(applicant),
|
52
|
-
}
|
53
63
|
|
54
|
-
|
55
|
-
|
56
|
-
|
64
|
+
# Optional
|
65
|
+
declined_reason: applicant.declined_reason.presence,
|
66
|
+
missing_info_reason: applicant.missing_info_reason.presence
|
67
|
+
}.compact
|
57
68
|
|
58
69
|
{ applicant: values }
|
59
70
|
end
|
@@ -32,12 +32,13 @@ module EffectiveMembershipsApplicant
|
|
32
32
|
acts_as_tokened
|
33
33
|
|
34
34
|
acts_as_statused(
|
35
|
-
:draft,
|
36
|
-
:submitted,
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
35
|
+
:draft, # Just Started
|
36
|
+
:submitted, # Completed wizard. Paid applicant fee.
|
37
|
+
:missing_info, # Admin has indicated information is missing. The applicant can edit applicant and add info
|
38
|
+
:completed, # Admin has received all deliverables. The application is complete and ready for review.
|
39
|
+
:reviewed, # All applicant reviews completed
|
40
|
+
:declined, # Exit state. Application was declined.
|
41
|
+
:approved # Exit state. Application was approved.
|
41
42
|
)
|
42
43
|
|
43
44
|
acts_as_wizard(
|
@@ -121,18 +122,22 @@ module EffectiveMembershipsApplicant
|
|
121
122
|
declined_at :datetime
|
122
123
|
declined_reason :text
|
123
124
|
|
125
|
+
# Missing Info
|
126
|
+
missing_info_at :datetime
|
127
|
+
missing_info_reason :text
|
128
|
+
|
124
129
|
# Applicant Educations
|
125
|
-
applicant_educations_details
|
130
|
+
applicant_educations_details :text
|
126
131
|
|
127
132
|
# Applicant Experiences
|
128
|
-
applicant_experiences_months
|
129
|
-
applicant_experiences_details
|
133
|
+
applicant_experiences_months :integer
|
134
|
+
applicant_experiences_details :text
|
130
135
|
|
131
136
|
# Additional Information
|
132
|
-
additional_information
|
137
|
+
additional_information :text
|
133
138
|
|
134
139
|
# Acts as Wizard
|
135
|
-
wizard_steps
|
140
|
+
wizard_steps :text, permitted: false
|
136
141
|
|
137
142
|
timestamps
|
138
143
|
end
|
@@ -264,9 +269,12 @@ module EffectiveMembershipsApplicant
|
|
264
269
|
# Admin Decline
|
265
270
|
validates :declined_reason, presence: true, if: -> { declined? }
|
266
271
|
|
272
|
+
# Admin Missing Info
|
273
|
+
validates :missing_info_reason, presence: true, if: -> { missing_info? }
|
274
|
+
|
267
275
|
# These two try completed and try reviewed
|
268
|
-
before_save(if: -> { submitted? }) { complete! }
|
269
|
-
before_save(if: -> { completed? }) { review! }
|
276
|
+
# before_save(if: -> { submitted? }) { complete! }
|
277
|
+
# before_save(if: -> { completed? }) { review! }
|
270
278
|
|
271
279
|
# Clear required steps memoization
|
272
280
|
after_save { @_required_steps = nil }
|
@@ -290,6 +298,14 @@ module EffectiveMembershipsApplicant
|
|
290
298
|
end
|
291
299
|
end
|
292
300
|
|
301
|
+
def can_visit_step?(step)
|
302
|
+
if missing_info?
|
303
|
+
return [:start, :select, :billing, :checkout].exclude?(step)
|
304
|
+
end
|
305
|
+
|
306
|
+
can_revisit_completed_steps(step)
|
307
|
+
end
|
308
|
+
|
293
309
|
# All Fees and Orders
|
294
310
|
def submit_fees
|
295
311
|
# Find or build submit fee
|
@@ -374,6 +390,10 @@ module EffectiveMembershipsApplicant
|
|
374
390
|
approved? || declined?
|
375
391
|
end
|
376
392
|
|
393
|
+
def status_label
|
394
|
+
(status_was || status).to_s.gsub('_', ' ')
|
395
|
+
end
|
396
|
+
|
377
397
|
def summary
|
378
398
|
case status_was
|
379
399
|
when 'draft'
|
@@ -388,6 +408,8 @@ module EffectiveMembershipsApplicant
|
|
388
408
|
else
|
389
409
|
"This application has been completed and is now ready for an admin to approve or decline it. If approved, prorated fees will be generated."
|
390
410
|
end
|
411
|
+
when 'missing_info'
|
412
|
+
"Missing the following information: <ul><li>#{missing_info_reason}</li></ul>"
|
391
413
|
when 'reviewed'
|
392
414
|
"This application has been reviewed and is now ready for an admin to approve or decline it. If approved, prorated fees will be generated."
|
393
415
|
when 'approved'
|
@@ -489,7 +511,8 @@ module EffectiveMembershipsApplicant
|
|
489
511
|
min_applicant_references > 0
|
490
512
|
end
|
491
513
|
|
492
|
-
# When an application is submitted, these must be done to go to completed
|
514
|
+
# When an application is submitted, these must be done to go to completed.
|
515
|
+
# An Admin can override this and just set them to completed.
|
493
516
|
def completed_requirements
|
494
517
|
{
|
495
518
|
'Applicant References' => (!applicant_references_required? || applicant_references.count(&:completed?) >= min_applicant_references)
|
@@ -497,9 +520,34 @@ module EffectiveMembershipsApplicant
|
|
497
520
|
end
|
498
521
|
|
499
522
|
def complete!
|
500
|
-
|
501
|
-
|
523
|
+
raise('applicant must have been submitted to complete!') unless was_submitted?
|
524
|
+
|
525
|
+
# Let an admin ignore these requirements if need be
|
526
|
+
# return false unless submitted? && completed_requirements.values.all?
|
527
|
+
|
528
|
+
assign_attributes(missing_info_reason: nil)
|
502
529
|
completed!
|
530
|
+
|
531
|
+
after_commit { send_email(:applicant_completed) }
|
532
|
+
true
|
533
|
+
end
|
534
|
+
|
535
|
+
def missing!
|
536
|
+
raise('applicant must have been submitted to missing!') unless was_submitted?
|
537
|
+
|
538
|
+
missing_info!
|
539
|
+
|
540
|
+
after_commit { send_email(:applicant_missing_info) }
|
541
|
+
true
|
542
|
+
end
|
543
|
+
|
544
|
+
def resubmit!
|
545
|
+
raise('applicant must have been submitted and missing info to resubmit!') unless was_submitted? && was_missing_info?
|
546
|
+
raise('already submitted') if submitted?
|
547
|
+
raise('expected a purchased order') unless submit_order&.purchased?
|
548
|
+
|
549
|
+
assign_attributes(skip_to_step: :submitted, submitted_at: Time.zone.now)
|
550
|
+
submitted!
|
503
551
|
end
|
504
552
|
|
505
553
|
# Completed -> Reviewed requirements
|
@@ -512,6 +560,7 @@ module EffectiveMembershipsApplicant
|
|
512
560
|
end
|
513
561
|
|
514
562
|
# When an application is completed, these must be done to go to reviewed
|
563
|
+
# An Admin can override this and just set them to reviewed.
|
515
564
|
def reviewed_requirements
|
516
565
|
{
|
517
566
|
'Applicant Reviews' => (!applicant_reviews_required? || applicant_reviews.count(&:completed?) >= min_applicant_reviews)
|
@@ -519,8 +568,10 @@ module EffectiveMembershipsApplicant
|
|
519
568
|
end
|
520
569
|
|
521
570
|
def review!
|
522
|
-
|
523
|
-
|
571
|
+
raise('applicant must have been submitted to review!') unless was_submitted?
|
572
|
+
|
573
|
+
# Let an admin ignore these requirements if need be
|
574
|
+
# return false unless completed? && reviewed_requirements.values.all?
|
524
575
|
reviewed!
|
525
576
|
end
|
526
577
|
|
@@ -532,6 +583,8 @@ module EffectiveMembershipsApplicant
|
|
532
583
|
# Complete the wizard step. Just incase this is run out of order.
|
533
584
|
wizard_steps[:checkout] ||= Time.zone.now
|
534
585
|
wizard_steps[:submitted] ||= Time.zone.now
|
586
|
+
assign_attributes(missing_info_reason: nil)
|
587
|
+
|
535
588
|
approved!
|
536
589
|
|
537
590
|
if apply_to_join?
|
@@ -56,7 +56,9 @@ module EffectiveMembershipsOwner
|
|
56
56
|
owners = organizations if self.class.respond_to?(:effective_organizations_user?)
|
57
57
|
owners = users if self.class.respond_to?(:effective_organizations_organization?)
|
58
58
|
|
59
|
-
owners = Array(owners)
|
59
|
+
owners = Array(owners)
|
60
|
+
.select { |owner| owner.class.respond_to?(:effective_memberships_owner?) }
|
61
|
+
.reject { |owner| owner.try(:archived?) }
|
60
62
|
|
61
63
|
owners.presence || [self]
|
62
64
|
end
|
@@ -73,7 +75,11 @@ module EffectiveMembershipsOwner
|
|
73
75
|
|
74
76
|
def organization_membership_present?(except: nil)
|
75
77
|
return false unless self.class.respond_to?(:effective_organizations_user?)
|
76
|
-
|
78
|
+
|
79
|
+
organizations
|
80
|
+
.select { |organization| organization.class.respond_to?(:effective_memberships_owner?) }
|
81
|
+
.reject { |organization| organization.try(:archived?) }
|
82
|
+
.any? { |organization| organization != except && organization.membership_present? }
|
77
83
|
end
|
78
84
|
|
79
85
|
def assign_member_role
|
@@ -25,13 +25,17 @@
|
|
25
25
|
= tab 'References' do
|
26
26
|
.mb-4= render_inline_datatable(Admin::EffectiveApplicantReferencesDatatable.new(applicant: applicant))
|
27
27
|
|
28
|
-
- if applicant.fees.present?
|
28
|
+
- if applicant.fees.present? || applicant.orders.present?
|
29
29
|
= tab 'Fees' do
|
30
|
-
.mb-4
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
30
|
+
.mb-4
|
31
|
+
%h2 Fees
|
32
|
+
- datatable = Admin::EffectiveFeesDatatable.new(applicant: applicant, total: false)
|
33
|
+
= render_datatable(datatable, simple: true, inline: true)
|
34
|
+
|
35
|
+
.mb-4
|
36
|
+
%h2 Orders
|
37
|
+
- datatable = Admin::EffectiveOrdersDatatable.new(parent: applicant, owner: applicant.owner, user: applicant.owner, total: false)
|
38
|
+
= render_datatable(datatable, simple: true)
|
35
39
|
|
36
40
|
- if applicant.owner.applicants.any? { |other| other.was_submitted? && other.id != applicant.id }
|
37
41
|
= tab 'Other Applications' do
|
@@ -1,13 +1,9 @@
|
|
1
1
|
= effective_form_with(model: [:admin, applicant], engine: true) do |f|
|
2
|
-
%p The #{applicant} will be <strong>approved</strong> to the following membership category
|
3
|
-
|
4
|
-
%h3 Category
|
5
|
-
= f.static_field :category, label: 'Applied for'
|
2
|
+
%p The #{applicant} will be <strong>approved</strong> to the following membership category:
|
6
3
|
|
7
4
|
- categories = EffectiveMemberships.Category.all
|
8
5
|
= f.select :category_id, categories, label: 'Approve to'
|
9
6
|
|
10
|
-
%h3 Number
|
11
7
|
%p
|
12
8
|
- if applicant.owner.membership&.number_was.present?
|
13
9
|
The member will keep their existing membership number: #{applicant.owner.membership.number}.
|
@@ -0,0 +1,8 @@
|
|
1
|
+
= effective_form_with(model: [:admin, applicant], engine: true) do |f|
|
2
|
+
%p The #{applicant} will be <strong>completed</strong>. All deliverables have been received and all requirements completed.
|
3
|
+
|
4
|
+
%h3 Email to send
|
5
|
+
%p The following email will be sent:
|
6
|
+
= email_form_fields(f, :applicant_completed)
|
7
|
+
|
8
|
+
= f.submit 'Complete Applicant', border: false, center: true, 'data-confirm': "Complete #{f.object.owner}?"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
= effective_form_with(model: [:admin, applicant], engine: true) do |f|
|
2
|
+
%p This applicant will be marked as <strong>missing information</strong> with the following:
|
3
|
+
|
4
|
+
= f.text_field :missing_info_reason, required: true, label: 'Explanation of missing info'
|
5
|
+
|
6
|
+
%h3 Email to send
|
7
|
+
|
8
|
+
%p The following email will be sent:
|
9
|
+
= email_form_fields(f, :applicant_missing_info)
|
10
|
+
|
11
|
+
= f.submit 'Missing Info Applicant', border: false, center: true, 'data-confirm': "Missing Info #{f.object.owner}?"
|
@@ -1,18 +1,22 @@
|
|
1
1
|
%p
|
2
|
-
%span.badge.badge-secondary= applicant.
|
2
|
+
%span.badge.badge-secondary= applicant.status_label
|
3
3
|
= applicant.summary
|
4
4
|
|
5
|
-
|
5
|
+
%p Process applicant:
|
6
|
+
|
7
|
+
= accordion do
|
8
|
+
- if EffectiveResources.authorized?(self, :complete, applicant)
|
9
|
+
= collapse 'Complete this Applicant' do
|
10
|
+
= render('admin/applicants/form_complete', applicant: applicant)
|
11
|
+
|
12
|
+
- if EffectiveResources.authorized?(self, :missing, applicant)
|
13
|
+
= collapse 'Missing Information' do
|
14
|
+
= render('admin/applicants/form_missing_info', applicant: applicant)
|
15
|
+
|
6
16
|
- if EffectiveResources.authorized?(self, :approve, applicant)
|
7
|
-
=
|
8
|
-
|
9
|
-
.card-body
|
10
|
-
%h5.card-title Approve
|
11
|
-
= render('admin/applicants/form_approve', applicant: applicant)
|
17
|
+
= collapse 'Approve this Applicant' do
|
18
|
+
= render('admin/applicants/form_approve', applicant: applicant)
|
12
19
|
|
13
20
|
- if EffectiveResources.authorized?(self, :decline, applicant)
|
14
|
-
=
|
15
|
-
|
16
|
-
.card-body
|
17
|
-
%h5.card-title Decline
|
18
|
-
= render('admin/applicants/form_decline', applicant: applicant)
|
21
|
+
= collapse 'Decline this Applicant' do
|
22
|
+
= render('admin/applicants/form_decline', applicant: applicant)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
%p
|
2
|
-
%span.badge.badge-secondary= applicant.
|
2
|
+
%span.badge.badge-secondary= applicant.status_label
|
3
3
|
= applicant.summary
|
4
4
|
|
5
5
|
%table.table.table-sm.table-striped
|
@@ -11,6 +11,8 @@
|
|
11
11
|
%th
|
12
12
|
- # Next action button
|
13
13
|
%tbody
|
14
|
+
|
15
|
+
-# Draft
|
14
16
|
%tr
|
15
17
|
%td In Progress
|
16
18
|
%td= applicant.created_at.strftime('%F')
|
@@ -21,6 +23,8 @@
|
|
21
23
|
- else
|
22
24
|
= '-'
|
23
25
|
%td
|
26
|
+
|
27
|
+
- # Submitted
|
24
28
|
%tr
|
25
29
|
%td Application Submitted
|
26
30
|
%td= applicant.submitted_at&.strftime('%F') || '-'
|
@@ -30,6 +34,8 @@
|
|
30
34
|
- else
|
31
35
|
= '-'
|
32
36
|
%td
|
37
|
+
|
38
|
+
- # Waiting to Complete
|
33
39
|
%tr
|
34
40
|
%td Waiting to Complete
|
35
41
|
%td= applicant.submitted_at&.strftime('%F') || '-'
|
@@ -63,71 +69,83 @@
|
|
63
69
|
References Not Required
|
64
70
|
|
65
71
|
%td
|
66
|
-
|
67
|
-
|
72
|
+
- if applicant.submitted?
|
73
|
+
= link_to 'Complete Applicant', '#process', 'data-click-tab': true, class: 'btn btn-sm btn-primary'
|
68
74
|
|
69
|
-
|
70
|
-
|
75
|
+
- # Missing Information
|
76
|
+
%tr
|
77
|
+
%td Missing Information
|
78
|
+
%td= applicant.missing_info_at&.strftime('%F') || '-'
|
79
|
+
%td= applicant.missing_info_reason
|
80
|
+
%td
|
71
81
|
|
82
|
+
- # Completed
|
72
83
|
%tr
|
73
|
-
%td Application
|
84
|
+
%td Application Completed
|
74
85
|
%td= applicant.completed_at&.strftime('%F') || '-'
|
75
86
|
%td
|
87
|
+
- if applicant.completed_at.present?
|
88
|
+
= icon('check', class: 'small-1')
|
89
|
+
Done
|
76
90
|
%td
|
77
91
|
|
78
|
-
|
79
|
-
|
80
|
-
%
|
81
|
-
|
82
|
-
|
83
|
-
|
92
|
+
- # Reviewed
|
93
|
+
- if EffectiveMemberships.applicant_reviews?
|
94
|
+
%tr.effective-memberships-applicant-status-reviewed
|
95
|
+
%td Reviews
|
96
|
+
%td= applicant.reviewed_at&.strftime('%F') || '-'
|
97
|
+
%td
|
98
|
+
- applicant.reviewed_requirements.each do |requirement, completed|
|
99
|
+
- next if requirement.to_s == 'Applicant Reviews'
|
84
100
|
|
85
|
-
|
86
|
-
|
87
|
-
|
101
|
+
%p
|
102
|
+
= icon((completed ? 'check' : 'x'), class: 'small-1')
|
103
|
+
= requirement
|
88
104
|
|
89
|
-
|
90
|
-
|
91
|
-
|
105
|
+
- if applicant.applicant_reviews_required?
|
106
|
+
%p
|
107
|
+
- if applicant.reviewed_requirements['Applicant Reviews']
|
108
|
+
= icon('check', class: 'small-1')
|
109
|
+
|
110
|
+
= applicant.applicant_reviews.count(&:completed?)
|
111
|
+
= '/'
|
112
|
+
= applicant.min_applicant_reviews
|
113
|
+
Reviews Completed
|
114
|
+
- else
|
115
|
+
%p
|
92
116
|
= icon('check', class: 'small-1')
|
117
|
+
Reviews Not Required
|
93
118
|
|
94
|
-
|
95
|
-
|
96
|
-
= applicant.min_applicant_reviews
|
97
|
-
Reviews Completed
|
98
|
-
- else
|
99
|
-
%p
|
100
|
-
= icon('check', class: 'small-1')
|
101
|
-
Reviews Not Required
|
119
|
+
%td
|
120
|
+
- # Button to create reviews here
|
102
121
|
|
122
|
+
%tr
|
123
|
+
%td Waiting to Process
|
103
124
|
%td
|
104
|
-
- if
|
125
|
+
- if EffectiveMemberships.applicant_reviews?
|
126
|
+
= applicant.reviewed_at&.strftime('%F') || '-'
|
127
|
+
- else
|
128
|
+
= applicant.completed_at&.strftime('%F') || '-'
|
129
|
+
%td
|
130
|
+
%td
|
131
|
+
- if applicant.was_submitted? && !(applicant.approved? || applicant.declined?)
|
105
132
|
= link_to 'Process Applicant', '#process', 'data-click-tab': true, class: 'btn btn-sm btn-primary'
|
106
133
|
|
107
|
-
|
108
|
-
%
|
109
|
-
|
110
|
-
|
111
|
-
|
134
|
+
%tr
|
135
|
+
%td Processed
|
136
|
+
%td= (applicant.approved_at&.strftime('%F') || applicant.declined_at&.strftime('%F') || '-')
|
137
|
+
%td
|
138
|
+
- if applicant.was_approved? && !applicant.approved?
|
139
|
+
= icon('check', class: 'small-1')
|
140
|
+
Approved
|
141
|
+
|
142
|
+
- elsif applicant.was_declined? || applicant.declined?
|
112
143
|
= icon('check', class: 'small-1')
|
113
144
|
Declined
|
114
145
|
%br
|
115
146
|
= applicant.declined_reason
|
116
|
-
%td
|
117
147
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
%td
|
123
|
-
- if applicant.was_approved?
|
124
|
-
= icon('check', class: 'small-1')
|
125
|
-
Approved
|
126
|
-
- elsif applicant.declined?
|
127
|
-
= icon('check', class: 'small-1')
|
128
|
-
Declined
|
129
|
-
%br
|
130
|
-
= applicant.declined_reason
|
131
|
-
- else
|
132
|
-
= '-'
|
133
|
-
%td
|
148
|
+
- elsif applicant.approved?
|
149
|
+
= icon('check', class: 'small-1')
|
150
|
+
Approved
|
151
|
+
%td
|
@@ -0,0 +1,18 @@
|
|
1
|
+
%h3 Missing Information
|
2
|
+
%p The following information is missing: #{resource.missing_info_reason}.
|
3
|
+
|
4
|
+
%p
|
5
|
+
Please revisit each wizard step and
|
6
|
+
= link_to 'complete all missing information', wizard_path(:demographics)
|
7
|
+
for this application.
|
8
|
+
|
9
|
+
%p
|
10
|
+
Once you're ready, click below to re-submit your application with the updated information.
|
11
|
+
|
12
|
+
%p
|
13
|
+
= effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
|
14
|
+
= f.hidden_field :id
|
15
|
+
= f.save 'Submit Application', 'data-confirm': "Really submit application?"
|
16
|
+
|
17
|
+
%p
|
18
|
+
%small * No additional payment required.
|
@@ -5,8 +5,7 @@
|
|
5
5
|
- raise('expected a purchased applicant submit_order') unless resource.submit_order&.purchased?
|
6
6
|
|
7
7
|
.alert.alert-success.mb-4
|
8
|
-
This application was submitted on
|
9
|
-
= resource.submit_order.purchased_at.strftime('%F')
|
8
|
+
This application was submitted on #{resource.submitted_at.strftime('%F')}
|
10
9
|
|
11
10
|
- unless resource.approved?
|
12
11
|
.card
|
@@ -20,15 +19,18 @@
|
|
20
19
|
.card
|
21
20
|
.card-body= render 'effective/applicants/summary', applicant: resource
|
22
21
|
|
22
|
+
- if resource.missing_info?
|
23
|
+
= card do
|
24
|
+
= render 'effective/applicants/missing_info', applicant: resource
|
25
|
+
|
23
26
|
- if resource.min_applicant_references.to_i > 0 || resource.applicant_references.present?
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
Click 'New' to add an additional reference, or click 'Notify' to resend the reference request.
|
27
|
+
= card do
|
28
|
+
%h3 Confidential References
|
29
|
+
%p
|
30
|
+
References are automatically sent a reference request.
|
31
|
+
Click 'New' to add an additional reference, or click 'Notify' to resend the reference request.
|
30
32
|
|
31
|
-
|
33
|
+
= render_datatable(EffectiveApplicantReferencesDatatable.new(applicant: resource), inline: true, simple: true)
|
32
34
|
|
33
35
|
.mb-4
|
34
36
|
= collapse('Show application...', card_class: 'my-2') do
|
@@ -5,4 +5,10 @@
|
|
5
5
|
|
6
6
|
= effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
|
7
7
|
= f.hidden_field :id
|
8
|
-
|
8
|
+
|
9
|
+
= f.submit(border: false, left: true) do
|
10
|
+
-# Missing Info
|
11
|
+
- if EffectiveResources.authorized?(self, :resubmit, resource)
|
12
|
+
= f.save 'Submit Application'
|
13
|
+
- else
|
14
|
+
= f.save 'Save and Continue'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
subject: 'Your application was marked as completed!'
|
3
|
+
from: 'admin@example.com'
|
4
|
+
---
|
5
|
+
Hello {{ user.name }},
|
6
|
+
|
7
|
+
Your application for {{ applicant.to_category }} has been marked completed.
|
8
|
+
|
9
|
+
It is ready for review and a final decision to approve or decline.
|
10
|
+
|
11
|
+
{{ applicant.url }}
|
12
|
+
|
13
|
+
Thank you.
|
14
|
+
|
15
|
+
Please contact us for assistance.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
---
|
2
|
+
subject: 'Your application is missing information'
|
3
|
+
from: 'admin@example.com'
|
4
|
+
---
|
5
|
+
Hello {{ user.name }},
|
6
|
+
|
7
|
+
Your application for {{ applicant.to_category }} is missing information:
|
8
|
+
|
9
|
+
{{ applicant.missing_info_reason }}
|
10
|
+
|
11
|
+
Please update your application with this info.
|
12
|
+
|
13
|
+
{{ applicant.url }}
|
14
|
+
|
15
|
+
Thank you.
|
16
|
+
|
17
|
+
Please contact us for assistance.
|
@@ -21,27 +21,25 @@ EffectiveMemberships.setup do |config|
|
|
21
21
|
# The defaults include: Applicant, Prorated, Renewal, Late, Admin
|
22
22
|
# config.additional_fee_types = []
|
23
23
|
|
24
|
-
#
|
24
|
+
# Applicant Reviews
|
25
|
+
# When true, display the reviewed state and require Category.min_applicant_reviews
|
26
|
+
# When false, hide the reviewed state entirely
|
27
|
+
# config.applicant_reviews = false
|
28
|
+
|
29
|
+
# Mailer Settings
|
30
|
+
# Please see config/initializers/effective_resources.rb for default effective_* gem mailer settings
|
31
|
+
#
|
25
32
|
# Configure the class responsible to send e-mails.
|
26
33
|
# config.mailer = 'Effective::MembershipsMailer'
|
27
|
-
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
#
|
32
|
-
# config.
|
33
|
-
|
34
|
-
# Default
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
config.mailer_sender = "no-reply@example.com"
|
39
|
-
|
40
|
-
# Send Admin correspondence To
|
41
|
-
config.mailer_admin = "admin@example.com"
|
42
|
-
|
43
|
-
# Will work with effective_email_templates gem:
|
44
|
-
# - The audit and audit review email content will be preopulated based off the template
|
45
|
-
# - Uses an EmailTemplatesMailer mailer instead of ActionMailer::Base for default parent_mailer
|
46
|
-
config.use_effective_email_templates = false
|
34
|
+
#
|
35
|
+
# Override effective_resource mailer defaults
|
36
|
+
#
|
37
|
+
# config.parent_mailer = nil # The parent class responsible for sending emails
|
38
|
+
# config.deliver_method = nil # The deliver method, deliver_later or deliver_now
|
39
|
+
# config.mailer_layout = nil # Default mailer layout
|
40
|
+
# config.mailer_sender = nil # Default From value
|
41
|
+
# config.mailer_admin = nil # Default To value for Admin correspondence
|
42
|
+
|
43
|
+
# Will work with effective_email_templates gem
|
44
|
+
config.use_effective_email_templates = true
|
47
45
|
end
|
@@ -151,6 +151,10 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
|
|
151
151
|
t.datetime :declined_at
|
152
152
|
t.text :declined_reason
|
153
153
|
|
154
|
+
# Missing
|
155
|
+
t.datetime :missing_info_at
|
156
|
+
t.text :missing_info_reason
|
157
|
+
|
154
158
|
# Applicant Educations
|
155
159
|
t.text :applicant_educations_details
|
156
160
|
|
@@ -8,7 +8,7 @@ module EffectiveMemberships
|
|
8
8
|
[
|
9
9
|
:categories_table_name, :applicants_table_name, :applicant_reviews_table_name, :fee_payments_table_name,
|
10
10
|
:category_class_name, :applicant_class_name, :applicant_review_class_name, :fee_payment_class_name, :registrar_class_name, :membership_card_class_name,
|
11
|
-
:additional_fee_types,
|
11
|
+
:additional_fee_types, :applicant_reviews,
|
12
12
|
:layout,
|
13
13
|
:mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :use_effective_email_templates
|
14
14
|
]
|
@@ -36,6 +36,10 @@ module EffectiveMemberships
|
|
36
36
|
membership_card_class_name&.constantize || Effective::MembershipCard
|
37
37
|
end
|
38
38
|
|
39
|
+
def self.applicant_reviews?
|
40
|
+
applicant_reviews == true
|
41
|
+
end
|
42
|
+
|
39
43
|
# Singleton
|
40
44
|
def self.Registrar
|
41
45
|
klass = registrar_class_name&.constantize || Effective::Registrar
|
@@ -46,17 +50,6 @@ module EffectiveMemberships
|
|
46
50
|
mailer&.constantize || Effective::MembershipsMailer
|
47
51
|
end
|
48
52
|
|
49
|
-
def self.parent_mailer_class
|
50
|
-
return parent_mailer.constantize if parent_mailer.present?
|
51
|
-
|
52
|
-
if use_effective_email_templates
|
53
|
-
require 'effective_email_templates'
|
54
|
-
Effective::EmailTemplatesMailer
|
55
|
-
else
|
56
|
-
ActionMailer::Base
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
53
|
def self.fee_types
|
61
54
|
required = ['Applicant', 'Prorated', 'Discount', 'Renewal', 'Late', 'Admin']
|
62
55
|
additional = Array(additional_fee_types)
|
@@ -69,21 +62,4 @@ module EffectiveMemberships
|
|
69
62
|
['Admin']
|
70
63
|
end
|
71
64
|
|
72
|
-
def self.send_email(email, *args)
|
73
|
-
raise('expected args to be an Array') unless args.kind_of?(Array)
|
74
|
-
|
75
|
-
if defined?(Tenant)
|
76
|
-
tenant = Tenant.current || raise('expected a current tenant')
|
77
|
-
args.last.kind_of?(Hash) ? args.last.merge!(tenant: tenant) : args << { tenant: tenant }
|
78
|
-
end
|
79
|
-
|
80
|
-
deliver_method = EffectiveMemberships.deliver_method || EffectiveResources.deliver_method
|
81
|
-
|
82
|
-
begin
|
83
|
-
EffectiveMemberships.mailer_class.send(email, *args).send(deliver_method)
|
84
|
-
rescue => e
|
85
|
-
raise if Rails.env.development? || Rails.env.test?
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
65
|
end
|
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.3.
|
4
|
+
version: 0.3.13
|
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-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -317,7 +317,9 @@ files:
|
|
317
317
|
- app/views/admin/applicant_references/_applicant_reference.html.haml
|
318
318
|
- app/views/admin/applicants/_form.html.haml
|
319
319
|
- app/views/admin/applicants/_form_approve.html.haml
|
320
|
+
- app/views/admin/applicants/_form_complete.html.haml
|
320
321
|
- app/views/admin/applicants/_form_decline.html.haml
|
322
|
+
- app/views/admin/applicants/_form_missing_info.html.haml
|
321
323
|
- app/views/admin/applicants/_form_process.html.haml
|
322
324
|
- app/views/admin/applicants/_status.html.haml
|
323
325
|
- app/views/admin/categories/_form.html.haml
|
@@ -360,6 +362,7 @@ files:
|
|
360
362
|
- app/views/effective/applicants/_experience.html.haml
|
361
363
|
- app/views/effective/applicants/_files.html.haml
|
362
364
|
- app/views/effective/applicants/_layout.html.haml
|
365
|
+
- app/views/effective/applicants/_missing_info.html.haml
|
363
366
|
- app/views/effective/applicants/_orders.html.haml
|
364
367
|
- app/views/effective/applicants/_references.html.haml
|
365
368
|
- app/views/effective/applicants/_select.html.haml
|
@@ -403,9 +406,10 @@ files:
|
|
403
406
|
- app/views/effective/memberships/_membership.html.haml
|
404
407
|
- app/views/effective/memberships_directory/index.html.haml
|
405
408
|
- app/views/effective/memberships_mailer/applicant_approved.liquid
|
409
|
+
- app/views/effective/memberships_mailer/applicant_completed.liquid
|
406
410
|
- app/views/effective/memberships_mailer/applicant_declined.liquid
|
411
|
+
- app/views/effective/memberships_mailer/applicant_missing_info.liquid
|
407
412
|
- app/views/effective/memberships_mailer/applicant_reference_notification.liquid
|
408
|
-
- app/views/layouts/effective_memberships_mailer_layout.html.haml
|
409
413
|
- config/effective_memberships.rb
|
410
414
|
- config/routes.rb
|
411
415
|
- db/migrate/01_create_effective_memberships.rb.erb
|