effective_memberships 0.16.1 → 0.17.0
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/datatables/admin/effective_categories_datatable.rb +5 -0
- data/app/models/concerns/effective_memberships_category.rb +20 -1
- data/app/models/concerns/effective_memberships_owner.rb +28 -0
- data/app/models/concerns/effective_memberships_registrar.rb +66 -8
- data/app/models/effective/fee.rb +5 -4
- data/app/models/effective/membership.rb +1 -1
- data/app/models/effective/registrar.rb +8 -0
- data/app/views/admin/categories/_fees_early.html.haml +14 -0
- data/app/views/admin/categories/_fees_late.html.haml +4 -3
- data/app/views/admin/categories/_fees_renewal.html.haml +2 -2
- data/app/views/admin/categories/_form_fees.html.haml +16 -3
- data/app/views/effective/applicants/_resignation_fields.html.haml +1 -0
- data/app/views/effective/applicants/resignation.html.haml +1 -3
- data/config/locales/effective_memberships.en.yml +1 -0
- data/db/migrate/01_create_effective_memberships.rb.erb +3 -0
- data/lib/effective_memberships/version.rb +1 -1
- data/lib/effective_memberships.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09fbb8a22bb53806fe272999514bc8cc4d8b8cf5784aaab5428777ffe43af61e'
|
4
|
+
data.tar.gz: cc6fd66a60a0db18c98a44849e3768e8c6d892b6af9cd297485b18f65290457b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e286896d066c61cb0bb65b325837152d275f43c158e0f8df95302c36aee81ef1fcd3359efd37a71ec3f78b182a87fa0ee587c6ffe017d3971013af32b3647e67
|
7
|
+
data.tar.gz: 37c79f3c9a254275346c352832082bf9014690144720fd3ea2fef642dfe2740f3e72f3597870754f4c0076574ade33c65a1227d8fefa4f2325903aaacef9bd7f
|
@@ -35,9 +35,14 @@ module Admin
|
|
35
35
|
col :qb_item_name, visible: false
|
36
36
|
|
37
37
|
col :create_renewal_fees, visible: false
|
38
|
+
col :create_early_fees, visible: false
|
38
39
|
col :create_late_fees, visible: false
|
39
40
|
col :create_not_in_good_standing, visible: false
|
40
41
|
|
42
|
+
col :renewal_fee, as: :price, visible: false
|
43
|
+
col :early_fee, as: :price, visible: false
|
44
|
+
col :late_fee, as: :price, visible: false
|
45
|
+
|
41
46
|
col :category_type, search: EffectiveMemberships.Category.category_types, visible: false
|
42
47
|
|
43
48
|
col :optional_applicant_wizard_steps, label: 'Applicant Steps', visible: false
|
@@ -99,13 +99,19 @@ module EffectiveMembershipsCategory
|
|
99
99
|
fee_payment_wizard_steps :text
|
100
100
|
fee_payment_cpd_step_requirement :string
|
101
101
|
|
102
|
-
#
|
102
|
+
# Renewal Fees
|
103
103
|
create_renewal_fees :boolean
|
104
104
|
renewal_fee :integer
|
105
105
|
|
106
|
+
# Early Fees
|
107
|
+
create_early_fees :boolean
|
108
|
+
early_fee :integer
|
109
|
+
|
110
|
+
# Late Fees
|
106
111
|
create_late_fees :boolean
|
107
112
|
late_fee :integer
|
108
113
|
|
114
|
+
# NIGS Status
|
109
115
|
create_not_in_good_standing :boolean
|
110
116
|
|
111
117
|
# Pricing
|
@@ -167,6 +173,19 @@ module EffectiveMembershipsCategory
|
|
167
173
|
validates :qb_item_name, presence: true
|
168
174
|
validates :tax_exempt, inclusion: { in: [true, false] }
|
169
175
|
end
|
176
|
+
|
177
|
+
with_options(if: -> { create_renewal_fees? }) do
|
178
|
+
validates :renewal_fee, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
179
|
+
end
|
180
|
+
|
181
|
+
with_options(if: -> { create_early_fees? }) do
|
182
|
+
validates :early_fee, presence: true, numericality: { less_than_or_equal_to: 0 }
|
183
|
+
end
|
184
|
+
|
185
|
+
with_options(if: -> { create_late_fees? }) do
|
186
|
+
validates :late_fee, presence: true, numericality: { greater_than_or_equal_to: 0 }
|
187
|
+
end
|
188
|
+
|
170
189
|
end
|
171
190
|
|
172
191
|
# Instance Methods
|
@@ -304,6 +304,34 @@ module EffectiveMembershipsOwner
|
|
304
304
|
fee
|
305
305
|
end
|
306
306
|
|
307
|
+
def build_early_fee(category:, period:)
|
308
|
+
raise('must have an existing membership') unless membership.present?
|
309
|
+
|
310
|
+
# Return existing but do not build yet
|
311
|
+
fee = fees.find { |fee| fee.fee_type == 'Early' && fee.period == period && fee.category_id == category.id && fee.category_type == category.class.name }
|
312
|
+
return fee if fee&.purchased?
|
313
|
+
|
314
|
+
# Only continue if there is an early renewal fee for the same period
|
315
|
+
renewal_fee = fees.find { |fee| fee.fee_type == 'Renewal' && fee.period == period && fee.category_id == category.id && fee.category_type == category.class.name }
|
316
|
+
return if fee.blank? && (renewal_fee.blank? || renewal_fee.early? == false)
|
317
|
+
|
318
|
+
# Build the early fee
|
319
|
+
fee ||= fees.build()
|
320
|
+
|
321
|
+
fee.assign_attributes(
|
322
|
+
fee_type: 'Early',
|
323
|
+
category: category,
|
324
|
+
period: period,
|
325
|
+
price: category.early_fee.to_i,
|
326
|
+
tax_exempt: category.tax_exempt,
|
327
|
+
qb_item_name: category.qb_item_name
|
328
|
+
)
|
329
|
+
|
330
|
+
after_build_fee(fee)
|
331
|
+
|
332
|
+
fee
|
333
|
+
end
|
334
|
+
|
307
335
|
def build_late_fee(category:, period:)
|
308
336
|
raise('must have an existing membership') unless membership.present?
|
309
337
|
|
@@ -24,7 +24,7 @@ module EffectiveMembershipsRegistrar
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def late_fee_date(period:)
|
27
|
-
Time.zone.local(period.year, 2, 1) # Fees are late after February 1st
|
27
|
+
Time.zone.local(period.year, 2, 1) # Fees are late after February 1st.
|
28
28
|
raise('to be implemented by app registrar')
|
29
29
|
end
|
30
30
|
|
@@ -33,6 +33,22 @@ module EffectiveMembershipsRegistrar
|
|
33
33
|
raise('to be implemented by app registrar')
|
34
34
|
end
|
35
35
|
|
36
|
+
# The early fee dates are calculated based on period
|
37
|
+
# The period is a date that starts on Jan 1st of a year.
|
38
|
+
# When Time.zone.now is December the period will be one ahead.
|
39
|
+
|
40
|
+
# Assumed to be the same as renewal_fee_date
|
41
|
+
def early_fee_date(period:)
|
42
|
+
Time.zone.local(period.year - 1, 12, 1) # Fees roll over every December 1st
|
43
|
+
raise('to be implemented by app registrar')
|
44
|
+
end
|
45
|
+
|
46
|
+
# Assumed to be just before the period actually starts
|
47
|
+
def early_fee_end_date(period:)
|
48
|
+
Time.zone.local(period.year - 1, 12, 31) # Early fees are destroyed on December 31st
|
49
|
+
raise('to be implemented by app registrar')
|
50
|
+
end
|
51
|
+
|
36
52
|
# A renewal fee must be at least this old to be considered late?
|
37
53
|
# Must be less than (late_fee_date - renewal_fee_date) but this is not enforced
|
38
54
|
def min_late_duration
|
@@ -112,6 +128,10 @@ module EffectiveMembershipsRegistrar
|
|
112
128
|
periods(from: from, to: to).reverse.map { |period| [period_end_on(date: period), period] }
|
113
129
|
end
|
114
130
|
|
131
|
+
def early_fee_date_range(period:)
|
132
|
+
(early_fee_date(period: period).beginning_of_day)..(early_fee_end_date(period: period).beginning_of_day)
|
133
|
+
end
|
134
|
+
|
115
135
|
# Category is required, statuses are optional
|
116
136
|
def assign!(owner, categories:, statuses: nil, date: nil, number: nil)
|
117
137
|
categories = Array(categories)
|
@@ -492,31 +512,48 @@ module EffectiveMembershipsRegistrar
|
|
492
512
|
# rake effective_memberships:create_fees
|
493
513
|
# Create Renewal and Late fees
|
494
514
|
# Assigns NIGS
|
495
|
-
def create_all_fees!(period: nil)
|
515
|
+
def create_all_fees!(period: nil, force: false)
|
496
516
|
period ||= current_period
|
497
517
|
memberships = Effective::Membership.deep.with_unpaid_fees_through(period)
|
498
518
|
|
499
519
|
memberships.find_each do |membership|
|
500
|
-
create_fees!(membership, period: period); GC.start
|
520
|
+
create_fees!(membership, period: period, force: force); GC.start
|
501
521
|
end
|
502
522
|
|
503
523
|
true
|
504
524
|
end
|
505
525
|
|
506
|
-
def create_fees!(resource, period: nil)
|
526
|
+
def create_fees!(resource, period: nil, force: false)
|
527
|
+
today = Time.zone.now.beginning_of_day
|
507
528
|
period ||= current_period
|
508
529
|
|
509
530
|
membership = (resource.class.respond_to?(:effective_memberships_owner?) ? resource.membership : resource)
|
510
531
|
raise('expected a membership') unless membership.present? && membership.kind_of?(Effective::Membership)
|
511
532
|
|
512
533
|
# Create Renewal Fees
|
513
|
-
|
534
|
+
if force || today == renewal_fee_date(date: today)
|
535
|
+
create_renewal_fees!(membership, period: period)
|
536
|
+
end
|
537
|
+
|
538
|
+
# Create Early Fees
|
539
|
+
if force || today == early_fee_date(period: period)
|
540
|
+
create_early_fees!(membership, period: period)
|
541
|
+
end
|
542
|
+
|
543
|
+
# Destroy Early Fees
|
544
|
+
if force || today == early_fee_end_date(period: period)
|
545
|
+
destroy_early_fees!(membership, period: period)
|
546
|
+
end
|
514
547
|
|
515
548
|
# Create Late Fees
|
516
|
-
|
549
|
+
if force || today == late_fee_date(period: period)
|
550
|
+
create_late_fees!(membership, period: period)
|
551
|
+
end
|
517
552
|
|
518
553
|
# Update Membership Status - Assign Not In Good Standing
|
519
|
-
|
554
|
+
if force || today == not_in_good_standing_date(period: period)
|
555
|
+
create_not_in_good_standing!(membership, period: period)
|
556
|
+
end
|
520
557
|
|
521
558
|
true
|
522
559
|
end
|
@@ -536,6 +573,28 @@ module EffectiveMembershipsRegistrar
|
|
536
573
|
end
|
537
574
|
end
|
538
575
|
|
576
|
+
def create_early_fees!(membership, period:)
|
577
|
+
membership.categories.select(&:create_early_fees?).map do |category|
|
578
|
+
fee = membership.owner.build_early_fee(category: category, period: period)
|
579
|
+
next if fee.blank? || fee.persisted?
|
580
|
+
|
581
|
+
puts("Created early fee for #{membership.owner}") if debug?
|
582
|
+
|
583
|
+
fee.save!
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
def destroy_early_fees!(membership, period:)
|
588
|
+
membership.categories.select(&:create_early_fees?).map do |category|
|
589
|
+
fee = membership.owner.build_early_fee(category: category, period: period)
|
590
|
+
next if fee.blank? || fee.early? || fee.purchased? || fee.deferred?
|
591
|
+
|
592
|
+
puts("Destroyed early fee for #{membership.owner}") if debug?
|
593
|
+
|
594
|
+
fee.destroy!
|
595
|
+
end
|
596
|
+
end
|
597
|
+
|
539
598
|
def create_late_fees!(membership, period:)
|
540
599
|
membership.categories.select(&:create_late_fees?).map do |category|
|
541
600
|
fee = membership.owner.build_late_fee(category: category, period: period)
|
@@ -548,7 +607,6 @@ module EffectiveMembershipsRegistrar
|
|
548
607
|
end
|
549
608
|
|
550
609
|
def create_not_in_good_standing!(membership, period:)
|
551
|
-
return unless Time.zone.now.beginning_of_day == not_in_good_standing_date(period: period).beginning_of_day
|
552
610
|
return unless membership.categories.any?(&:create_not_in_good_standing?)
|
553
611
|
|
554
612
|
membership.owner.update_membership_status!
|
data/app/models/effective/fee.rb
CHANGED
@@ -92,6 +92,11 @@ module Effective
|
|
92
92
|
title.presence || default_title()
|
93
93
|
end
|
94
94
|
|
95
|
+
def early?
|
96
|
+
return false if purchased?
|
97
|
+
EffectiveMemberships.Registrar.early_fee_date_range(period: period).cover?(Time.zone.now)
|
98
|
+
end
|
99
|
+
|
95
100
|
def late?
|
96
101
|
return false if late_on.blank?
|
97
102
|
return false if purchased?
|
@@ -144,10 +149,6 @@ module Effective
|
|
144
149
|
['Prorated', 'Renewal'].include?(fee_type)
|
145
150
|
end
|
146
151
|
|
147
|
-
def renewal_fee?
|
148
|
-
fee_type == 'Renewal'
|
149
|
-
end
|
150
|
-
|
151
152
|
def custom_fee?
|
152
153
|
EffectiveMemberships.custom_fee_types.include?(fee_type)
|
153
154
|
end
|
@@ -306,7 +306,7 @@ module Effective
|
|
306
306
|
|
307
307
|
# Otherwise build fees right now
|
308
308
|
EffectiveMemberships.Registrar.delete_fees!(self)
|
309
|
-
EffectiveMemberships.Registrar.create_fees!(self, period: period)
|
309
|
+
EffectiveMemberships.Registrar.create_fees!(self, period: period, force: true)
|
310
310
|
|
311
311
|
true
|
312
312
|
end
|
@@ -15,5 +15,13 @@ module Effective
|
|
15
15
|
Time.zone.local(period.year, 3, 1) # Membership are Not In Good Standing after March 1st
|
16
16
|
end
|
17
17
|
|
18
|
+
def early_fee_date(period:)
|
19
|
+
Time.zone.local(period.year - 1, 12, 1) # Fees roll over every December 1st
|
20
|
+
end
|
21
|
+
|
22
|
+
def early_fee_end_date(period:)
|
23
|
+
Time.zone.local(period.year - 1, 12, 31) # Early fees are destroyed on December 31st
|
24
|
+
end
|
25
|
+
|
18
26
|
end
|
19
27
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
%h3= ets('effective_memberships.fees.early')
|
2
|
+
|
3
|
+
= f.check_box :create_early_fees, label: "Yes, #{ets('effective_memberships.fees.early')} should be created"
|
4
|
+
|
5
|
+
= f.show_if(:create_early_fees, true) do
|
6
|
+
- period = EffectiveMemberships.Registrar.current_period
|
7
|
+
- date = EffectiveMemberships.Registrar.early_fee_date(period: period)
|
8
|
+
- end_date = EffectiveMemberships.Registrar.early_fee_end_date(period: period)
|
9
|
+
|
10
|
+
%p Charged to members, between #{date.strftime('%B %e')} and #{end_date.strftime('%B %e')}, with outstanding renewal dues.
|
11
|
+
|
12
|
+
.row
|
13
|
+
.col-md-3
|
14
|
+
= f.price_field :early_fee, hint: 'Expecting a price less than zero. Please enter the early fee discount from the regular price'
|
@@ -1,5 +1,6 @@
|
|
1
|
-
%h3
|
2
|
-
|
1
|
+
%h3= ets('effective_memberships.fees.late')
|
2
|
+
|
3
|
+
= f.check_box :create_late_fees, label: "Yes, #{ets('effective_memberships.fees.late')} should be created"
|
3
4
|
|
4
5
|
= f.show_if(:create_late_fees, true) do
|
5
6
|
- period = EffectiveMemberships.Registrar.current_period
|
@@ -7,4 +8,4 @@
|
|
7
8
|
|
8
9
|
%p Charged to members, on #{date.strftime('%B %e')}, with outstanding renewal dues or other fees.
|
9
10
|
.row
|
10
|
-
.col-3= f.price_field :late_fee
|
11
|
+
.col-md-3= f.price_field :late_fee
|
@@ -1,5 +1,5 @@
|
|
1
|
-
%h3
|
2
|
-
= f.check_box :create_renewal_fees, label:
|
1
|
+
%h3= ets('effective_memberships.fees.renewal')
|
2
|
+
= f.check_box :create_renewal_fees, label: "Yes, #{ets('effective_memberships.fees.renewal')} should be created"
|
3
3
|
|
4
4
|
= f.show_if(:create_renewal_fees, true) do
|
5
5
|
- date = EffectiveMemberships.Registrar.renewal_fee_date(date: Time.zone.now)
|
@@ -1,7 +1,20 @@
|
|
1
1
|
= effective_form_with(model: [:admin, category], engine: true) do |f|
|
2
2
|
= render('admin/categories/fees_applicant', f: f)
|
3
|
-
|
4
|
-
|
3
|
+
|
4
|
+
- now = Time.zone.now
|
5
|
+
|
6
|
+
- if EffectiveMemberships.Registrar.renewal_fee_date(date: now).present?
|
7
|
+
= render('admin/categories/fees_renewal', f: f)
|
8
|
+
|
9
|
+
- if EffectiveMemberships.Registrar.early_fee_date(period: now).present?
|
10
|
+
= render('admin/categories/fees_early', f: f)
|
11
|
+
|
12
|
+
- if EffectiveMemberships.Registrar.late_fee_date(period: now).present?
|
13
|
+
= render('admin/categories/fees_late', f: f)
|
14
|
+
|
5
15
|
= render('admin/categories/fees_additional', f: f)
|
6
|
-
|
16
|
+
|
17
|
+
- if EffectiveMemberships.Registrar.not_in_good_standing_date(period: now).present?
|
18
|
+
= render('admin/categories/fees_nigs', f: f)
|
19
|
+
|
7
20
|
= f.submit
|
@@ -0,0 +1 @@
|
|
1
|
+
= f.check_box :declare_resignation, label: "Yes, I am applying for resignation from #{f.object.category}"
|
@@ -8,8 +8,6 @@
|
|
8
8
|
= effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
|
9
9
|
= f.hidden_field :id
|
10
10
|
|
11
|
-
=
|
12
|
-
|
13
|
-
= f.check_box :declare_resignation, label: "Yes, I am applying for resignation from #{f.object.category}"
|
11
|
+
= render("effective/applicants/resignation_fields", f: f)
|
14
12
|
|
15
13
|
= f.save 'Save and Continue'
|
@@ -52,6 +52,9 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
|
|
52
52
|
t.boolean :create_renewal_fees, default: false
|
53
53
|
t.integer :renewal_fee
|
54
54
|
|
55
|
+
t.boolean :create_early_fees, default: false
|
56
|
+
t.integer :early_fee
|
57
|
+
|
55
58
|
t.boolean :create_late_fees, default: false
|
56
59
|
t.integer :late_fee
|
57
60
|
|
@@ -58,7 +58,7 @@ module EffectiveMemberships
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def self.fee_types
|
61
|
-
required = ['Applicant', 'Reinstatement', 'Prorated', 'Discount', 'Renewal', 'Late', 'Admin']
|
61
|
+
required = ['Applicant', 'Reinstatement', 'Prorated', 'Discount', 'Renewal', 'Early', 'Late', 'Admin']
|
62
62
|
additional = Array(additional_fee_types)
|
63
63
|
|
64
64
|
(required + additional).uniq.sort
|
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
|
+
version: 0.17.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -367,6 +367,7 @@ files:
|
|
367
367
|
- app/views/admin/applicants/_status.html.haml
|
368
368
|
- app/views/admin/categories/_fees_additional.html.haml
|
369
369
|
- app/views/admin/categories/_fees_applicant.html.haml
|
370
|
+
- app/views/admin/categories/_fees_early.html.haml
|
370
371
|
- app/views/admin/categories/_fees_late.html.haml
|
371
372
|
- app/views/admin/categories/_fees_nigs.html.haml
|
372
373
|
- app/views/admin/categories/_fees_renewal.html.haml
|
@@ -458,6 +459,7 @@ files:
|
|
458
459
|
- app/views/effective/applicants/_reinstatement.html.haml
|
459
460
|
- app/views/effective/applicants/_reinstatement_fields.html.haml
|
460
461
|
- app/views/effective/applicants/_resignation.html.haml
|
462
|
+
- app/views/effective/applicants/_resignation_fields.html.haml
|
461
463
|
- app/views/effective/applicants/_select.html.haml
|
462
464
|
- app/views/effective/applicants/_select_organization.html.haml
|
463
465
|
- app/views/effective/applicants/_stamp.html.haml
|