effective_memberships 0.6.8 → 0.6.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/datatables/admin/effective_membership_histories_datatable.rb +1 -1
- data/app/mailers/effective/memberships_mailer.rb +15 -1
- data/app/models/concerns/effective_memberships_applicant.rb +17 -2
- data/app/models/concerns/effective_memberships_user.rb +9 -0
- data/app/models/effective/membership.rb +4 -0
- data/app/views/admin/applicants/_form_approve.html.haml +27 -3
- data/app/views/admin/categories/_form.html.haml +3 -12
- data/app/views/admin/categories/_form_applicant_content.html.haml +3 -2
- data/app/views/admin/categories/_form_category.html.haml +12 -2
- data/app/views/admin/categories/{_form_renewals.html.haml → _form_fees.html.haml} +29 -3
- data/app/views/effective/applicants/_summary.html.haml +15 -1
- data/lib/effective_memberships/version.rb +1 -1
- metadata +3 -5
- data/app/views/admin/categories/_form_applicant_eligibility.html.haml +0 -9
- data/app/views/admin/categories/_form_applicant_fees.html.haml +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d38d7c30fe73cb0b97797cad055c8c4d92b5ea509f7d3f9a2df8b2f47692b485
|
4
|
+
data.tar.gz: bb62d7035ddfbe41cfe2824c4a045e0f9481cf0bc9533b7bec0beb982a797419
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4251303f22271a28b46f12111888338949949d076956df8fde66a3cf8e70c383eeeef557860073d6aeb7e88b5a9f0e686fbb6af00b84b795c61394bc1c6a2fe
|
7
|
+
data.tar.gz: f9a694918489449dfc6d020320256342ac9a2455df74cade89dc6ef3042535bea5be68b034fc2cabda4ece0b7587c32ccba932d7b4c16a92565fd70f030b0286
|
@@ -68,7 +68,7 @@ module Effective
|
|
68
68
|
|
69
69
|
def assigns_for(resource)
|
70
70
|
if resource.class.respond_to?(:effective_memberships_applicant?)
|
71
|
-
return applicant_assigns(resource).merge(owner_assigns(resource.owner))
|
71
|
+
return applicant_assigns(resource).merge(owner_assigns(resource.owner)).merge(membership_assigns(resource.owner.membership))
|
72
72
|
end
|
73
73
|
|
74
74
|
if resource.kind_of?(Effective::ApplicantEndorsement)
|
@@ -87,6 +87,7 @@ module Effective
|
|
87
87
|
|
88
88
|
values = {
|
89
89
|
date: (applicant.submitted_at || Time.zone.now).strftime('%F'),
|
90
|
+
approved_at: (applicant.approved_at&.strftime('%F') || 'not approved'),
|
90
91
|
|
91
92
|
to_category: applicant.category.to_s,
|
92
93
|
from_category: applicant.from_category.to_s,
|
@@ -102,6 +103,19 @@ module Effective
|
|
102
103
|
{ applicant: values }
|
103
104
|
end
|
104
105
|
|
106
|
+
def membership_assigns(membership)
|
107
|
+
return {} if membership.blank?
|
108
|
+
raise('expected a membership') unless membership.kind_of?(Effective::Membership)
|
109
|
+
|
110
|
+
values = {
|
111
|
+
number: (membership.number || 'no membership number'),
|
112
|
+
joined_on: (membership.joined_on&.strftime('%F') || 'unknown'),
|
113
|
+
registration_on: (membership.registration_on.strftime('%F') || 'unknown')
|
114
|
+
}
|
115
|
+
|
116
|
+
{ membership: values }
|
117
|
+
end
|
118
|
+
|
105
119
|
def endorsement_assigns(applicant_endorsement)
|
106
120
|
raise('expected a endorsement') unless applicant_endorsement.kind_of?(Effective::ApplicantEndorsement)
|
107
121
|
|
@@ -87,6 +87,7 @@ module EffectiveMembershipsApplicant
|
|
87
87
|
# Admin Approve Step
|
88
88
|
attr_accessor :approved_membership_number
|
89
89
|
attr_accessor :approved_membership_date
|
90
|
+
attr_accessor :approved_email_action
|
90
91
|
|
91
92
|
# Application Namespace
|
92
93
|
belongs_to :user, polymorphic: true
|
@@ -763,6 +764,19 @@ module EffectiveMembershipsApplicant
|
|
763
764
|
reviewed!
|
764
765
|
end
|
765
766
|
|
767
|
+
def approve_email_templates
|
768
|
+
raise('expected EffectiveEmailTemplates') unless defined?(EffectiveEmailTemplates)
|
769
|
+
Effective::EmailTemplate.where('template_name ILIKE ?', 'applicant_approve%').order(:template_name)
|
770
|
+
end
|
771
|
+
|
772
|
+
def to_category
|
773
|
+
category
|
774
|
+
end
|
775
|
+
|
776
|
+
def to_status
|
777
|
+
nil
|
778
|
+
end
|
779
|
+
|
766
780
|
# Admin approves an applicant. Registers the owner. Sends an email.
|
767
781
|
def approve!
|
768
782
|
raise('already approved') if was_approved?
|
@@ -778,12 +792,13 @@ module EffectiveMembershipsApplicant
|
|
778
792
|
if apply_to_join?
|
779
793
|
EffectiveMemberships.Registrar.register!(
|
780
794
|
owner,
|
781
|
-
to:
|
795
|
+
to: to_category,
|
796
|
+
status: to_status,
|
782
797
|
date: approved_membership_date.presence, # Set by the Admin Process form, or nil
|
783
798
|
number: approved_membership_number.presence # Set by the Admin Process form, or nil
|
784
799
|
)
|
785
800
|
elsif reclassification?
|
786
|
-
EffectiveMemberships.Registrar.reclassify!(owner, to:
|
801
|
+
EffectiveMemberships.Registrar.reclassify!(owner, to: to_category, status: to_status)
|
787
802
|
elsif reinstatement?
|
788
803
|
EffectiveMemberships.Registrar.reinstate!(owner, from: from_status)
|
789
804
|
else
|
@@ -76,4 +76,13 @@ module EffectiveMembershipsUser
|
|
76
76
|
organizations.select { |organization| organization.is?(:member) && !organization.archived? }
|
77
77
|
end
|
78
78
|
|
79
|
+
def membership_history_on(date)
|
80
|
+
raise('expected a date') unless date.respond_to?(:strftime)
|
81
|
+
membership_histories.find { |history| (history.start_on..history.end_on).cover?(date) } # Ruby 2.6 supports endless ranges
|
82
|
+
end
|
83
|
+
|
84
|
+
def membership_categories_on(date)
|
85
|
+
membership_history_on(date).try(:membership_categories)
|
86
|
+
end
|
87
|
+
|
79
88
|
end
|
@@ -163,6 +163,10 @@ module Effective
|
|
163
163
|
membership_status(status: status) || membership_statuses.build(status: status)
|
164
164
|
end
|
165
165
|
|
166
|
+
def reregistered?
|
167
|
+
registration_on.present? && joined_on.present? && registration_on > joined_on
|
168
|
+
end
|
169
|
+
|
166
170
|
def good_standing?
|
167
171
|
!bad_standing?
|
168
172
|
end
|
@@ -9,7 +9,11 @@
|
|
9
9
|
The member will keep their existing membership number: #{applicant.owner.membership.number}.
|
10
10
|
- else
|
11
11
|
- number = EffectiveMemberships.Registrar.next_membership_number(applicant.owner, to: applicant.category)
|
12
|
-
|
12
|
+
|
13
|
+
- if number.present?
|
14
|
+
= f.text_field :approved_membership_number, hint: "leave blank to assign the next number: #{number || 'none'}."
|
15
|
+
- else
|
16
|
+
No membership number will be assigned.
|
13
17
|
|
14
18
|
%h3 Fees
|
15
19
|
%p The following fee(s) will be created:
|
@@ -24,7 +28,27 @@
|
|
24
28
|
%li A #{month} discount fee from their old category
|
25
29
|
|
26
30
|
%h3 Email to send
|
27
|
-
|
28
|
-
|
31
|
+
- email_templates = applicant.approve_email_templates
|
32
|
+
|
33
|
+
- f.object.approved_email_action ||= email_templates.first&.id
|
34
|
+
= f.hidden_field :approved_email_action
|
35
|
+
|
36
|
+
- if email_templates.length == 0
|
37
|
+
%p The following email will be sent:
|
38
|
+
= email_form_fields(f, :applicant_approve)
|
39
|
+
|
40
|
+
- if email_templates.length == 1
|
41
|
+
- template = email_templates.first
|
42
|
+
%p The following #{link_to(template, effective_email_templates.edit_admin_email_template_path(template), target: '_blank')} email will be sent:
|
43
|
+
= email_form_fields(f, template)
|
44
|
+
|
45
|
+
- if email_templates.length > 1
|
46
|
+
- collection = email_templates.map { |et| [et.to_s.titleize.sub('Applicant ', '') + " (#{et})", et.id] }
|
47
|
+
= f.select :approved_email_action, collection
|
48
|
+
|
49
|
+
- email_templates.each do |template|
|
50
|
+
= f.show_if(:approved_email_action, template.id) do
|
51
|
+
%p The following #{link_to(template, effective_email_templates.edit_admin_email_template_path(template), target: '_blank')} email will be sent:
|
52
|
+
= email_form_fields(f, template)
|
29
53
|
|
30
54
|
= f.submit 'Approve Applicant', border: false, center: true, 'data-confirm': "Approve #{f.object.owner}?"
|
@@ -3,11 +3,7 @@
|
|
3
3
|
= render 'admin/categories/form_category', category: category
|
4
4
|
|
5
5
|
- if category.persisted?
|
6
|
-
= render 'admin/categories/
|
7
|
-
|
8
|
-
= render 'admin/categories/form_applicant_fees', category: category
|
9
|
-
= render 'admin/categories/form_renewals', category: category
|
10
|
-
|
6
|
+
= render 'admin/categories/form_fees', category: category
|
11
7
|
|
12
8
|
- if category.persisted?
|
13
9
|
= tab 'Content - Applicants' do
|
@@ -18,14 +14,9 @@
|
|
18
14
|
|
19
15
|
= tab 'Wizards' do
|
20
16
|
.row
|
21
|
-
.col
|
22
|
-
|
23
|
-
|
24
|
-
.col
|
25
|
-
= render 'admin/categories/form_fee_payment_steps', category: category
|
17
|
+
.col= render 'admin/categories/form_applicant_steps', category: category
|
18
|
+
.col= render 'admin/categories/form_fee_payment_steps', category: category
|
26
19
|
|
27
20
|
- if category.respond_to?(:log_changes_datatable)
|
28
21
|
= tab 'Logs' do
|
29
22
|
= render_inline_datatable(category.log_changes_datatable)
|
30
|
-
|
31
|
-
|
@@ -4,10 +4,11 @@
|
|
4
4
|
= f.article_editor "rich_text_applicant_all_steps_content", label: false, hint: "displayed on all steps"
|
5
5
|
- else
|
6
6
|
= f.rich_text_area "rich_text_applicant_all_steps_content", label: false, hint: "displayed on all steps"
|
7
|
-
|
7
|
+
|
8
|
+
- enabled_steps = f.object.applicant_wizard_steps
|
8
9
|
|
9
10
|
- EffectiveMemberships.Applicant::WIZARD_STEPS.each do |step, title|
|
10
|
-
- next unless
|
11
|
+
- next unless enabled_steps.include?(step)
|
11
12
|
|
12
13
|
= card("#{title}") do
|
13
14
|
- if defined?(EffectiveArticleEditor)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
= effective_form_with(model: [:admin, category], engine: true) do |f|
|
2
2
|
.row
|
3
|
-
.col
|
3
|
+
.col
|
4
|
+
= f.text_field :title, label: 'Category title'
|
4
5
|
|
5
6
|
.col
|
6
7
|
= f.select :category_type, f.object.class.category_types,
|
@@ -14,4 +15,13 @@
|
|
14
15
|
- else
|
15
16
|
= f.rich_text_area :rich_text_body, label: 'Description shown in the Application to Join wizard'
|
16
17
|
|
17
|
-
|
18
|
+
%h3 Applicant Eligibility
|
19
|
+
= f.check_box :can_apply_new, label: 'Anyone may apply for this category'
|
20
|
+
= f.check_box :can_apply_existing, label: 'Any current member may apply to join'
|
21
|
+
= f.check_box :can_apply_restricted, label: 'Only some current members may apply to join'
|
22
|
+
|
23
|
+
= f.show_if(:can_apply_restricted, true) do
|
24
|
+
- categories = f.object.class.where.not(id: f.object)
|
25
|
+
= f.select :can_apply_restricted_ids, categories, label: 'Existing member categories'
|
26
|
+
|
27
|
+
= effective_submit(f)
|
@@ -1,4 +1,28 @@
|
|
1
1
|
= effective_form_with(model: [:admin, category], engine: true) do |f|
|
2
|
+
%h3 Applicant Fees
|
3
|
+
.row
|
4
|
+
.col= f.price_field :applicant_fee
|
5
|
+
.col= f.text_field :qb_item_name, label: "Quickbooks Item Name"
|
6
|
+
|
7
|
+
%h3 Pro-rated fees based on date of approval
|
8
|
+
.row
|
9
|
+
.col-lg-3
|
10
|
+
= f.price_field :prorated_jan, label: "January"
|
11
|
+
= f.price_field :prorated_feb, label: "February"
|
12
|
+
= f.price_field :prorated_mar, label: "March"
|
13
|
+
.col-lg-3
|
14
|
+
= f.price_field :prorated_apr, label: "April"
|
15
|
+
= f.price_field :prorated_may, label: "May"
|
16
|
+
= f.price_field :prorated_jun, label: "June"
|
17
|
+
.col-lg-3
|
18
|
+
= f.price_field :prorated_jul, label: "July"
|
19
|
+
= f.price_field :prorated_aug, label: "August"
|
20
|
+
= f.price_field :prorated_sep, label: "September"
|
21
|
+
.col-lg-3
|
22
|
+
= f.price_field :prorated_oct, label: "October"
|
23
|
+
= f.price_field :prorated_nov, label: "November"
|
24
|
+
= f.price_field :prorated_dec, label: "December"
|
25
|
+
|
2
26
|
%h3 Renewal Fees
|
3
27
|
= f.check_box :create_renewal_fees, label: 'Yes, annual renewal fees should be created'
|
4
28
|
|
@@ -6,7 +30,8 @@
|
|
6
30
|
- date = EffectiveMemberships.Registrar.renewal_fee_date(date: Time.zone.now)
|
7
31
|
|
8
32
|
%p Charged to members, every #{date.strftime('%B %e')}, to renew their dues.
|
9
|
-
|
33
|
+
.row
|
34
|
+
.col-3= f.price_field :renewal_fee
|
10
35
|
|
11
36
|
%h3 Late Fees
|
12
37
|
= f.check_box :create_late_fees, label: 'Yes, late fees should be created'
|
@@ -16,7 +41,8 @@
|
|
16
41
|
- date = EffectiveMemberships.Registrar.late_fee_date(period: period)
|
17
42
|
|
18
43
|
%p Charged to members, on #{date.strftime('%B %e')}, with outstanding renewal fees
|
19
|
-
|
44
|
+
.row
|
45
|
+
.col-3= f.price_field :late_fee
|
20
46
|
|
21
47
|
%h3 Bad Standing
|
22
48
|
= f.check_box :create_bad_standing, label: 'Yes, bad standing status should be applied'
|
@@ -27,4 +53,4 @@
|
|
27
53
|
|
28
54
|
%p Members with outstanding fees, on #{date.strftime('%B %e')}, will automatically be marked in bad standing.
|
29
55
|
|
30
|
-
=
|
56
|
+
= f.submit
|
@@ -22,11 +22,25 @@
|
|
22
22
|
- else
|
23
23
|
None
|
24
24
|
|
25
|
+
- if request.path.start_with?('/admin')
|
26
|
+
- if (membership = applicant.owner.membership).present?
|
27
|
+
%tr
|
28
|
+
%th Membership
|
29
|
+
%td
|
30
|
+
Joined on #{membership.joined_on.strftime('%F')}
|
31
|
+
- if membership.reregistered?
|
32
|
+
and last changed on #{membership.reregistered_on.strftime('%F')}
|
33
|
+
|
34
|
+
= collapse('show more', card_class: '') do
|
35
|
+
%p #{applicant.owner} membership history
|
36
|
+
= render_datatable(Admin::EffectiveMembershipHistoriesDatatable.new(owner: applicant.owner, actions: false), simple: true)
|
37
|
+
|
25
38
|
- if applicant.from_status.present?
|
26
39
|
%tr
|
27
40
|
%th From Status
|
28
41
|
%td= applicant.from_status
|
29
|
-
|
42
|
+
|
43
|
+
- if applicant.from_category.present?
|
30
44
|
%tr
|
31
45
|
%th From Category
|
32
46
|
%td= applicant.from_category
|
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.6.
|
4
|
+
version: 0.6.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-09-
|
11
|
+
date: 2022-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -353,13 +353,11 @@ files:
|
|
353
353
|
- app/views/admin/applicants/_status.html.haml
|
354
354
|
- app/views/admin/categories/_form.html.haml
|
355
355
|
- app/views/admin/categories/_form_applicant_content.html.haml
|
356
|
-
- app/views/admin/categories/_form_applicant_eligibility.html.haml
|
357
|
-
- app/views/admin/categories/_form_applicant_fees.html.haml
|
358
356
|
- app/views/admin/categories/_form_applicant_steps.html.haml
|
359
357
|
- app/views/admin/categories/_form_category.html.haml
|
360
358
|
- app/views/admin/categories/_form_fee_payment_content.html.haml
|
361
359
|
- app/views/admin/categories/_form_fee_payment_steps.html.haml
|
362
|
-
- app/views/admin/categories/
|
360
|
+
- app/views/admin/categories/_form_fees.html.haml
|
363
361
|
- app/views/admin/fee_payments/_fee_payment.html.haml
|
364
362
|
- app/views/admin/fees/_fee.html.haml
|
365
363
|
- app/views/admin/fees/_form.html.haml
|
@@ -1,9 +0,0 @@
|
|
1
|
-
= effective_form_with(model: [:admin, category], engine: true) do |f|
|
2
|
-
%h3 Applicant Eligibility
|
3
|
-
= f.check_box :can_apply_new, label: 'Anyone may apply for this category'
|
4
|
-
= f.check_box :can_apply_existing, label: 'Any current member may apply to join'
|
5
|
-
= f.check_box :can_apply_restricted, label: 'Only some current members may apply to join'
|
6
|
-
|
7
|
-
= f.show_if(:can_apply_restricted, true) do
|
8
|
-
- categories = f.object.class.where.not(id: f.object)
|
9
|
-
= f.select :can_apply_restricted_ids, categories, label: 'Existing member categories'
|
@@ -1,24 +0,0 @@
|
|
1
|
-
= effective_form_with(model: [:admin, category], engine: true) do |f|
|
2
|
-
%h3 Applicant Fees
|
3
|
-
.row
|
4
|
-
.col= f.price_field :applicant_fee
|
5
|
-
.col= f.text_field :qb_item_name, label: "Quickbooks Item Name"
|
6
|
-
|
7
|
-
%h3 Pro-rated fees based on date of approval
|
8
|
-
.row
|
9
|
-
.col-lg-3
|
10
|
-
= f.price_field :prorated_jan, label: "January"
|
11
|
-
= f.price_field :prorated_feb, label: "February"
|
12
|
-
= f.price_field :prorated_mar, label: "March"
|
13
|
-
.col-lg-3
|
14
|
-
= f.price_field :prorated_apr, label: "April"
|
15
|
-
= f.price_field :prorated_may, label: "May"
|
16
|
-
= f.price_field :prorated_jun, label: "June"
|
17
|
-
.col-lg-3
|
18
|
-
= f.price_field :prorated_jul, label: "July"
|
19
|
-
= f.price_field :prorated_aug, label: "August"
|
20
|
-
= f.price_field :prorated_sep, label: "September"
|
21
|
-
.col-lg-3
|
22
|
-
= f.price_field :prorated_oct, label: "October"
|
23
|
-
= f.price_field :prorated_nov, label: "November"
|
24
|
-
= f.price_field :prorated_dec, label: "December"
|