effective_memberships 0.7.7 → 0.8.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/controllers/admin/registrar_actions_controller.rb +0 -8
- data/app/datatables/admin/effective_categories_datatable.rb +1 -1
- data/app/datatables/admin/effective_membership_histories_datatable.rb +2 -1
- data/app/datatables/admin/effective_memberships_datatable.rb +0 -4
- data/app/models/concerns/effective_memberships_category.rb +1 -1
- data/app/models/concerns/effective_memberships_owner.rb +28 -41
- data/app/models/concerns/effective_memberships_registrar.rb +28 -43
- data/app/models/concerns/effective_memberships_status.rb +4 -0
- data/app/models/effective/fee.rb +7 -7
- data/app/models/effective/membership.rb +40 -13
- data/app/models/effective/membership_history.rb +5 -7
- data/app/models/effective/registrar.rb +2 -2
- data/app/models/effective/registrar_action.rb +0 -16
- data/app/views/admin/categories/_form_fees.html.haml +4 -4
- data/app/views/admin/membership_histories/_form.html.haml +2 -1
- data/app/views/admin/registrar_actions/_form.html.haml +1 -1
- data/app/views/admin/registrar_actions/_form_not_in_good_standing.html.haml +23 -0
- data/app/views/effective/fees/_dashboard.html.haml +3 -3
- data/app/views/effective/memberships/_dashboard.html.haml +2 -2
- data/app/views/effective/memberships/_membership.html.haml +15 -8
- data/db/migrate/01_create_effective_memberships.rb.erb +2 -7
- data/db/seeds.rb +1 -0
- data/lib/effective_memberships/version.rb +1 -1
- metadata +3 -3
- data/app/views/admin/registrar_actions/_form_bad_standing.html.haml +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5088dfc90ed9a12111011d7f9c8b639553abf0b03af9eea5a197c80d3b5c97f9
|
4
|
+
data.tar.gz: cbedc16b06e69feac3e1921c8963d0d1e2bb3f44b4efeb4aabab0682efe582c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ebdebc9b7673481c1d49cca98ad7a8ead414296783dcf886e0ebdd5edec24a75f71c88d1698748b4035cfec97b14029c186c9d8e7277c6065404e3f5c837f15
|
7
|
+
data.tar.gz: 3ed063f4063d1c40187b4366163dd349a4087a25e18b4083aa781ecc4b7d003c5022e1eae5db0854066ce4d48f3b3b0ba4cedbb7d21a9f3598977fc2e770c6dd
|
@@ -30,14 +30,6 @@ module Admin
|
|
30
30
|
success: -> { "#{resource.owner} has been removed" },
|
31
31
|
redirect: -> { admin_owners_path(resource) }
|
32
32
|
|
33
|
-
submit :bad_standing, 'Set In Bad Standing',
|
34
|
-
success: -> { "#{resource.owner} is now In Bad Standing" },
|
35
|
-
redirect: -> { admin_owners_path(resource) }
|
36
|
-
|
37
|
-
submit :good_standing, 'Remove In Bad Standing',
|
38
|
-
success: -> { "#{resource.owner} is now In Good Standing" },
|
39
|
-
redirect: -> { admin_owners_path(resource) }
|
40
|
-
|
41
33
|
submit :fees_paid, 'Mark Fees Paid',
|
42
34
|
success: -> { "#{resource.owner} has now paid their fees through #{resource.owner.membership.fees_paid_through_period&.strftime('%F')}" },
|
43
35
|
redirect: -> { admin_owners_path(resource) }
|
@@ -36,7 +36,7 @@ module Admin
|
|
36
36
|
|
37
37
|
col :create_renewal_fees, visible: false
|
38
38
|
col :create_late_fees, visible: false
|
39
|
-
col :
|
39
|
+
col :create_not_in_good_standing, visible: false
|
40
40
|
|
41
41
|
col :category_type, search: EffectiveMemberships.Category.category_types, visible: false
|
42
42
|
|
@@ -21,10 +21,6 @@ module Admin
|
|
21
21
|
col :fees_paid_period, visible: false, label: 'Fees Paid'
|
22
22
|
col :fees_paid_through_period, label: 'Fees Paid Through'
|
23
23
|
|
24
|
-
col :bad_standing
|
25
|
-
col :bad_standing_admin, visible: false
|
26
|
-
col :bad_standing_reason, visible: false
|
27
|
-
|
28
24
|
col :email do |membership|
|
29
25
|
email = membership.owner.try(:email)
|
30
26
|
mail_to(email) if email.present?
|
@@ -43,14 +43,14 @@ module EffectiveMembershipsOwner
|
|
43
43
|
without_role(:member).where(id: removed.select(:owner_id))
|
44
44
|
}
|
45
45
|
|
46
|
-
scope :
|
47
|
-
|
48
|
-
where(id:
|
46
|
+
scope :membership_not_in_good_standing, -> {
|
47
|
+
not_in_good_standing = Effective::Membership.not_in_good_standing.where(owner_type: name)
|
48
|
+
where(id: not_in_good_standing.select(:owner_id))
|
49
49
|
}
|
50
50
|
|
51
|
-
scope :
|
52
|
-
|
53
|
-
where(id:
|
51
|
+
scope :membership_in_good_standing, -> {
|
52
|
+
in_good_standing = Effective::Membership.in_good_standing.where(owner_type: name)
|
53
|
+
where(id: in_good_standing.select(:owner_id))
|
54
54
|
}
|
55
55
|
|
56
56
|
scope :membership_renewed_this_period, -> {
|
@@ -59,33 +59,21 @@ module EffectiveMembershipsOwner
|
|
59
59
|
}
|
60
60
|
|
61
61
|
scope :members_with_category, -> (categories) {
|
62
|
-
|
63
|
-
|
64
|
-
membership_categories = Effective::MembershipCategory.where(category: categories)
|
65
|
-
memberships = Effective::Membership.where(id: membership_categories.select(:membership_id))
|
66
|
-
|
67
|
-
where(id: memberships.where(owner_type: name).select(:owner_id))
|
62
|
+
with_category = Effective::Membership.with_category(categories).where(owner_type: name)
|
63
|
+
where(id: with_category.select(:owner_id))
|
68
64
|
}
|
69
65
|
|
70
66
|
scope :members_with_status, -> (statuses) {
|
71
|
-
|
72
|
-
|
73
|
-
membership_statuses = Effective::MembershipStatus.where(status: statuses)
|
74
|
-
memberships = Effective::Membership.where(id: membership_statuses.select(:membership_id))
|
75
|
-
|
76
|
-
where(id: memberships.where(owner_type: name).select(:owner_id))
|
67
|
+
with_status = Effective::Membership.with_status(statuses).where(owner_type: name)
|
68
|
+
where(id: with_status.select(:owner_id))
|
77
69
|
}
|
78
70
|
|
79
71
|
scope :membership_joined_before, -> (date) {
|
80
|
-
raise('expected a date') unless date.respond_to?(:strftime)
|
81
|
-
|
82
72
|
joined_before = Effective::Membership.joined_before(date).where(owner_type: name)
|
83
73
|
where(id: joined_before.select(:owner_id))
|
84
74
|
}
|
85
75
|
|
86
76
|
scope :membership_joined_after, -> (date) {
|
87
|
-
raise('expected a date') unless date.respond_to?(:strftime)
|
88
|
-
|
89
77
|
joined_after = Effective::Membership.joined_after(date).where(owner_type: name)
|
90
78
|
where(id: joined_after.select(:owner_id))
|
91
79
|
}
|
@@ -114,8 +102,8 @@ module EffectiveMembershipsOwner
|
|
114
102
|
orders.select { |order| order.parent_type.to_s.include?('FeePayment') && !order.purchased? }
|
115
103
|
end
|
116
104
|
|
117
|
-
def
|
118
|
-
fees.select { |fee| fee.
|
105
|
+
def not_in_good_standing_fees
|
106
|
+
fees.select { |fee| fee.not_in_good_standing? }
|
119
107
|
end
|
120
108
|
|
121
109
|
def max_fees_paid_period
|
@@ -141,7 +129,7 @@ module EffectiveMembershipsOwner
|
|
141
129
|
end
|
142
130
|
|
143
131
|
def registrar_action_statuses(action)
|
144
|
-
EffectiveMemberships.Status.sorted.all
|
132
|
+
EffectiveMemberships.Status.sorted.all.where.not(id: EffectiveMemberships.Registrar.not_in_good_standing_status)
|
145
133
|
end
|
146
134
|
|
147
135
|
# Instance Methods
|
@@ -192,7 +180,7 @@ module EffectiveMembershipsOwner
|
|
192
180
|
fee
|
193
181
|
end
|
194
182
|
|
195
|
-
# Only thing optional is category, late_on and
|
183
|
+
# Only thing optional is category, late_on and not_in_good_standing_on
|
196
184
|
def build_title_fee(title:, fee_type:, period:, price: nil, tax_exempt: nil, qb_item_name: nil, category: nil)
|
197
185
|
fee = fees.find do |fee|
|
198
186
|
fee.fee_type == fee_type && fee.period == period && fee.title == title &&
|
@@ -223,7 +211,7 @@ module EffectiveMembershipsOwner
|
|
223
211
|
fees.find { |fee| fee.membership_period_fee? && fee.period == period && fee.category_id == category.id && fee.category_type == category.class.name && (except.blank? || fee.fee_type != except) }
|
224
212
|
end
|
225
213
|
|
226
|
-
def build_renewal_fee(category:, period:, late_on: nil,
|
214
|
+
def build_renewal_fee(category:, period:, late_on: nil, not_in_good_standing_on: nil)
|
227
215
|
raise('must have an existing membership') unless membership.present?
|
228
216
|
|
229
217
|
# Sanity check.
|
@@ -239,7 +227,7 @@ module EffectiveMembershipsOwner
|
|
239
227
|
fee ||= fees.build()
|
240
228
|
|
241
229
|
late_on ||= EffectiveMemberships.Registrar.late_fee_date(period: period) if category.create_late_fees?
|
242
|
-
|
230
|
+
not_in_good_standing_on ||= EffectiveMemberships.Registrar.not_in_good_standing_date(period: period) if category.create_not_in_good_standing?
|
243
231
|
|
244
232
|
fee.assign_attributes(
|
245
233
|
fee_type: 'Renewal',
|
@@ -249,7 +237,7 @@ module EffectiveMembershipsOwner
|
|
249
237
|
tax_exempt: category.tax_exempt,
|
250
238
|
qb_item_name: category.qb_item_name,
|
251
239
|
late_on: late_on,
|
252
|
-
|
240
|
+
not_in_good_standing_on: not_in_good_standing_on,
|
253
241
|
)
|
254
242
|
|
255
243
|
fee
|
@@ -289,25 +277,24 @@ module EffectiveMembershipsOwner
|
|
289
277
|
membership.fees_paid_period = max_fees_paid_period()
|
290
278
|
membership.fees_paid_through_period = max_fees_paid_through_period()
|
291
279
|
|
292
|
-
#
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
membership.bad_standing_reason = nil
|
280
|
+
# Add or remove Not In Good Standing status
|
281
|
+
in_good_standing = membership.in_good_standing?
|
282
|
+
not_in_good_standing = membership.not_in_good_standing?
|
283
|
+
|
284
|
+
if in_good_standing && not_in_good_standing_fees.present?
|
285
|
+
EffectiveMemberships.Registrar.not_in_good_standing!(self)
|
286
|
+
elsif not_in_good_standing && not_in_good_standing_fees.blank?
|
287
|
+
EffectiveMemberships.Registrar.in_good_standing!(self)
|
301
288
|
end
|
302
289
|
|
303
|
-
if
|
290
|
+
if membership_histories.blank?
|
304
291
|
build_membership_history()
|
305
292
|
end
|
306
293
|
|
307
294
|
save!
|
308
295
|
end
|
309
296
|
|
310
|
-
def build_membership_history(start_on: nil)
|
297
|
+
def build_membership_history(start_on: nil, notes: nil)
|
311
298
|
raise('expected membership to be present') unless membership.present?
|
312
299
|
|
313
300
|
# The date of change
|
@@ -321,7 +308,7 @@ module EffectiveMembershipsOwner
|
|
321
308
|
start_on: start_on,
|
322
309
|
end_on: nil,
|
323
310
|
removed: membership.marked_for_destruction?,
|
324
|
-
|
311
|
+
notes: notes
|
325
312
|
)
|
326
313
|
|
327
314
|
unless history.removed?
|
@@ -28,11 +28,20 @@ module EffectiveMembershipsRegistrar
|
|
28
28
|
raise('to be implemented by app registrar')
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
31
|
+
def not_in_good_standing_date(period:)
|
32
32
|
Date.new(period.year, 3, 1) # Membership in bad standing after March 1st
|
33
33
|
raise('to be implemented by app registrar')
|
34
34
|
end
|
35
35
|
|
36
|
+
# scope
|
37
|
+
def not_in_good_standing_status
|
38
|
+
EffectiveMemberships.Status.where(title: 'Not In Good Standing')
|
39
|
+
end
|
40
|
+
|
41
|
+
def not_in_good_standing_status!
|
42
|
+
EffectiveMemberships.Status.where(title: 'Not In Good Standing').first!
|
43
|
+
end
|
44
|
+
|
36
45
|
# Should two could be overridden if we do non 1-year periods
|
37
46
|
def advance_period(period:, number:)
|
38
47
|
period.advance(years: number).beginning_of_year
|
@@ -90,7 +99,6 @@ module EffectiveMembershipsRegistrar
|
|
90
99
|
end
|
91
100
|
|
92
101
|
changed = membership.membership_categories.any? { |mc| mc.new_record? || mc.marked_for_destruction? }
|
93
|
-
changed ||= membership.membership_statuses.any? { |ms| ms.new_record? || ms.marked_for_destruction? }
|
94
102
|
|
95
103
|
if changed
|
96
104
|
membership.registration_on = date # Always new registration_on
|
@@ -214,21 +222,21 @@ module EffectiveMembershipsRegistrar
|
|
214
222
|
status_assign!(owner, date: date, status: [])
|
215
223
|
end
|
216
224
|
|
217
|
-
def status_add!(owner, status:, date: nil)
|
225
|
+
def status_add!(owner, status:, date: nil, notes: nil)
|
218
226
|
raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
|
219
227
|
raise('owner must have an existing membership. use register! instead') if owner.membership.blank?
|
220
228
|
|
221
|
-
status_assign!(owner, date: date, status: owner.membership.statuses + Array(status))
|
229
|
+
status_assign!(owner, date: date, notes: notes, status: owner.membership.statuses + Array(status))
|
222
230
|
end
|
223
231
|
|
224
|
-
def status_remove!(owner, status:, date: nil)
|
232
|
+
def status_remove!(owner, status:, date: nil, notes: nil)
|
225
233
|
raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
|
226
234
|
raise('owner must have an existing membership. use register! instead') if owner.membership.blank?
|
227
235
|
|
228
|
-
status_assign!(owner, date: date, status: owner.membership.statuses - Array(status))
|
236
|
+
status_assign!(owner, date: date, notes: notes, status: owner.membership.statuses - Array(status))
|
229
237
|
end
|
230
238
|
|
231
|
-
def status_assign!(owner, status:, date: nil)
|
239
|
+
def status_assign!(owner, status:, date: nil, notes: nil)
|
232
240
|
raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
|
233
241
|
|
234
242
|
membership = owner.membership
|
@@ -252,10 +260,7 @@ module EffectiveMembershipsRegistrar
|
|
252
260
|
changed = membership.membership_statuses.any? { |ms| ms.new_record? || ms.marked_for_destruction? }
|
253
261
|
|
254
262
|
if changed
|
255
|
-
date
|
256
|
-
|
257
|
-
membership.registration_on = date # Always new registration_on
|
258
|
-
save!(owner, date: date)
|
263
|
+
save!(owner, date: date, notes: notes)
|
259
264
|
end
|
260
265
|
|
261
266
|
true
|
@@ -281,36 +286,20 @@ module EffectiveMembershipsRegistrar
|
|
281
286
|
save!(owner, date: date)
|
282
287
|
end
|
283
288
|
|
284
|
-
def
|
289
|
+
def not_in_good_standing!(owner, date: nil, notes: nil)
|
285
290
|
raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
|
286
291
|
raise('expected a member') unless owner.membership.present?
|
287
|
-
raise('expected owner to be in good standing')
|
288
|
-
|
289
|
-
# Date
|
290
|
-
date ||= Time.zone.now
|
291
|
-
membership = owner.membership
|
292
|
+
raise('expected owner to be in good standing') unless owner.membership.in_good_standing?
|
292
293
|
|
293
|
-
|
294
|
-
membership.bad_standing_admin = true
|
295
|
-
membership.bad_standing_reason = reason
|
296
|
-
|
297
|
-
save!(owner, date: date)
|
294
|
+
status_add!(owner, status: not_in_good_standing_status!, date: date, notes: notes)
|
298
295
|
end
|
299
296
|
|
300
|
-
def
|
297
|
+
def in_good_standing!(owner, date: nil, notes: nil)
|
301
298
|
raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
|
302
299
|
raise('expected a member') unless owner.membership.present?
|
303
|
-
raise('expected owner to be in
|
304
|
-
|
305
|
-
# Date
|
306
|
-
date ||= Time.zone.now
|
307
|
-
membership = owner.membership
|
308
|
-
|
309
|
-
membership.bad_standing = false
|
310
|
-
membership.bad_standing_admin = false
|
311
|
-
membership.bad_standing_reason = nil
|
300
|
+
raise('expected owner to be not in good standing') unless owner.membership.not_in_good_standing?
|
312
301
|
|
313
|
-
|
302
|
+
status_remove!(owner, status: not_in_good_standing_status!, date: date, notes: notes)
|
314
303
|
end
|
315
304
|
|
316
305
|
def fees_paid!(owner, date: nil, order_attributes: nil)
|
@@ -400,8 +389,8 @@ module EffectiveMembershipsRegistrar
|
|
400
389
|
memberships.find_each { |membership| create_late_fees!(membership, period: period) }
|
401
390
|
GC.start
|
402
391
|
|
403
|
-
# Update Membership Status - Assign In
|
404
|
-
memberships.find_each { |membership|
|
392
|
+
# Update Membership Status - Assign Not In Good Standing
|
393
|
+
memberships.find_each { |membership| create_not_in_good_standing!(membership, period: period) }
|
405
394
|
GC.start
|
406
395
|
|
407
396
|
true
|
@@ -433,12 +422,8 @@ module EffectiveMembershipsRegistrar
|
|
433
422
|
end
|
434
423
|
end
|
435
424
|
|
436
|
-
def
|
437
|
-
return unless membership.categories.any?(&:
|
438
|
-
update_membership_status!(membership, period: period)
|
439
|
-
end
|
440
|
-
|
441
|
-
def update_membership_status!(membership, period: nil)
|
425
|
+
def create_not_in_good_standing!(membership, period:)
|
426
|
+
return unless membership.categories.any?(&:create_not_in_good_standing?)
|
442
427
|
membership.owner.update_membership_status!
|
443
428
|
end
|
444
429
|
|
@@ -482,8 +467,8 @@ module EffectiveMembershipsRegistrar
|
|
482
467
|
true
|
483
468
|
end
|
484
469
|
|
485
|
-
def save!(owner, date: Time.zone.now)
|
486
|
-
owner.build_membership_history(start_on: date)
|
470
|
+
def save!(owner, date: Time.zone.now, notes: nil)
|
471
|
+
owner.build_membership_history(start_on: date, notes: notes)
|
487
472
|
owner.save!
|
488
473
|
end
|
489
474
|
|
data/app/models/effective/fee.rb
CHANGED
@@ -23,8 +23,8 @@ module Effective
|
|
23
23
|
|
24
24
|
period :date
|
25
25
|
|
26
|
-
late_on
|
27
|
-
|
26
|
+
late_on :date
|
27
|
+
not_in_good_standing_on :date
|
28
28
|
|
29
29
|
price :integer
|
30
30
|
qb_item_name :string
|
@@ -62,8 +62,8 @@ module Effective
|
|
62
62
|
validates :late_on, presence: true,
|
63
63
|
if: -> { fee_type == 'Renewal' && category&.create_late_fees? }
|
64
64
|
|
65
|
-
validates :
|
66
|
-
if: -> { fee_type == 'Renewal' && category&.
|
65
|
+
validates :not_in_good_standing_on, presence: true,
|
66
|
+
if: -> { fee_type == 'Renewal' && category&.create_not_in_good_standing? }
|
67
67
|
|
68
68
|
def to_s
|
69
69
|
title.presence || default_title()
|
@@ -76,11 +76,11 @@ module Effective
|
|
76
76
|
late_on <= Time.zone.now.to_date
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
80
|
-
return false if
|
79
|
+
def not_in_good_standing?
|
80
|
+
return false if not_in_good_standing_on.blank?
|
81
81
|
return false if purchased?
|
82
82
|
|
83
|
-
|
83
|
+
not_in_good_standing_on <= Time.zone.now.to_date
|
84
84
|
end
|
85
85
|
|
86
86
|
# Used by applicant.applicant_submit_fees
|
@@ -18,26 +18,47 @@ module Effective
|
|
18
18
|
number_as_integer :integer # A unique integer
|
19
19
|
|
20
20
|
joined_on :date # When they first receive a membership category
|
21
|
-
registration_on :date # When the membership category last changed. Applied or reclassified.
|
21
|
+
registration_on :date # When the membership category last changed. Applied or reclassified. Not status change.
|
22
22
|
|
23
23
|
# Membership Status
|
24
24
|
fees_paid_period :date # The most recent period they have paid in. Start date of period.
|
25
25
|
fees_paid_through_period :date # The most recent period they have paid in. End date of period. Kind of an expires.
|
26
26
|
|
27
|
-
bad_standing :boolean # Calculated value. Is this owner in bad standing? (fees due)
|
28
|
-
bad_standing_admin :boolean # Admin set this
|
29
|
-
bad_standing_reason :text # Reason for bad standing
|
30
|
-
|
31
27
|
timestamps
|
32
28
|
end
|
33
29
|
|
34
30
|
scope :deep, -> { includes(membership_categories: :category) }
|
35
31
|
scope :sorted, -> { order(:id) }
|
36
32
|
|
37
|
-
scope :
|
33
|
+
scope :with_status, -> (statuses) {
|
34
|
+
raise('expected an EffectiveMemberships.Status') unless Array(statuses).all? { |status| status.kind_of?(EffectiveMemberships.Status) }
|
35
|
+
where(id: MembershipStatus.where(status: statuses).select(:membership_id))
|
36
|
+
}
|
37
|
+
|
38
|
+
scope :without_status, -> (statuses) {
|
39
|
+
raise('expected an EffectiveMemberships.Status') unless Array(statuses).all? { |status| status.kind_of?(EffectiveMemberships.Status) }
|
40
|
+
where.not(id: MembershipStatus.where(status: statuses).select(:membership_id))
|
41
|
+
}
|
42
|
+
|
43
|
+
scope :with_category, -> (categories) {
|
44
|
+
raise('expected an EffectiveMemberships.Category') unless Array(categories).all? { |cat| cat.kind_of?(EffectiveMemberships.Category) }
|
45
|
+
where(id: MembershipCategory.where(category: categories).select(:membership_id))
|
46
|
+
}
|
47
|
+
|
48
|
+
scope :without_category, -> (categories) {
|
49
|
+
raise('expected an EffectiveMemberships.Category') unless Array(categories).all? { |cat| cat.kind_of?(EffectiveMemberships.Category) }
|
50
|
+
where.not(id: MembershipCategory.where(category: categories).select(:membership_id))
|
51
|
+
}
|
52
|
+
|
53
|
+
scope :joined_before, -> (date) {
|
54
|
+
raise('expected a date') unless date.respond_to?(:strftime)
|
55
|
+
where(arel_table[:joined_on].lt(date))
|
56
|
+
}
|
38
57
|
|
39
|
-
scope :
|
40
|
-
|
58
|
+
scope :joined_after, -> (date) {
|
59
|
+
raise('expected a date') unless date.respond_to?(:strftime)
|
60
|
+
where(arel_table[:joined_on].gteq(date))
|
61
|
+
}
|
41
62
|
|
42
63
|
scope :with_paid_fees_through, -> (period = nil) {
|
43
64
|
where(arel_table[:fees_paid_period].gteq(period || EffectiveMemberships.Registrar.current_period))
|
@@ -49,6 +70,9 @@ module Effective
|
|
49
70
|
joined.merge(unpaid)
|
50
71
|
}
|
51
72
|
|
73
|
+
scope :not_in_good_standing, -> { with_status(EffectiveMemberships.Registrar.not_in_good_standing_status) }
|
74
|
+
scope :in_good_standing, -> { without_status(EffectiveMemberships.Registrar.not_in_good_standing_status) }
|
75
|
+
|
52
76
|
before_validation do
|
53
77
|
self.registration_on ||= joined_on
|
54
78
|
end
|
@@ -87,8 +111,7 @@ module Effective
|
|
87
111
|
'member',
|
88
112
|
("##{number_was}" if number_was.present?),
|
89
113
|
"who joined #{joined_on&.strftime('%F') || '-'}",
|
90
|
-
("and last registered #{registration_on.strftime('%F')}" if registration_on > joined_on)
|
91
|
-
(". Membership is Not In Good Standing because #{bad_standing_reason}" if bad_standing?)
|
114
|
+
("and last registered #{registration_on.strftime('%F')}" if registration_on > joined_on)
|
92
115
|
].compact.join(' ')
|
93
116
|
|
94
117
|
(summary + '.').html_safe
|
@@ -170,8 +193,12 @@ module Effective
|
|
170
193
|
registration_on.present? && joined_on.present? && registration_on > joined_on
|
171
194
|
end
|
172
195
|
|
173
|
-
def
|
174
|
-
|
196
|
+
def not_in_good_standing?
|
197
|
+
membership_statuses.any? { |ms| ms.status.not_in_good_standing? }
|
198
|
+
end
|
199
|
+
|
200
|
+
def in_good_standing?
|
201
|
+
membership_statuses.none? { |ms| ms.status.not_in_good_standing? }
|
175
202
|
end
|
176
203
|
|
177
204
|
def fees_paid?
|
@@ -222,7 +249,7 @@ module Effective
|
|
222
249
|
# Otherwise build fees right now
|
223
250
|
EffectiveMemberships.Registrar.create_renewal_fees!(self, period: period)
|
224
251
|
EffectiveMemberships.Registrar.create_late_fees!(self, period: period)
|
225
|
-
EffectiveMemberships.Registrar.
|
252
|
+
EffectiveMemberships.Registrar.create_not_in_good_standing!(self, period: period)
|
226
253
|
|
227
254
|
true
|
228
255
|
end
|
@@ -3,18 +3,17 @@ module Effective
|
|
3
3
|
belongs_to :owner, polymorphic: true
|
4
4
|
|
5
5
|
effective_resource do
|
6
|
-
start_on
|
7
|
-
end_on
|
6
|
+
start_on :date
|
7
|
+
end_on :date
|
8
8
|
|
9
|
-
number
|
9
|
+
number :string
|
10
10
|
|
11
|
-
|
12
|
-
removed :boolean
|
11
|
+
removed :boolean
|
13
12
|
|
14
13
|
categories :text
|
15
14
|
category_ids :text
|
16
15
|
|
17
|
-
notes
|
16
|
+
notes :text
|
18
17
|
|
19
18
|
timestamps
|
20
19
|
end
|
@@ -65,6 +64,5 @@ module Effective
|
|
65
64
|
assign_attributes(statuses: statuses.map(&:to_s), status_ids: statuses.map(&:id))
|
66
65
|
end
|
67
66
|
|
68
|
-
|
69
67
|
end
|
70
68
|
end
|
@@ -11,8 +11,8 @@ module Effective
|
|
11
11
|
Date.new(period.year, 2, 1) # Fees are late after February 1st
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
Date.new(period.year, 3, 1) # Membership
|
14
|
+
def not_in_good_standing_date(period:)
|
15
|
+
Date.new(period.year, 3, 1) # Membership are Not In Good Standing after March 1st
|
16
16
|
end
|
17
17
|
|
18
18
|
end
|
@@ -9,9 +9,6 @@ module Effective
|
|
9
9
|
attr_accessor :current_action
|
10
10
|
attr_accessor :owner, :owner_id, :owner_type
|
11
11
|
|
12
|
-
# Bad Standing
|
13
|
-
attr_accessor :bad_standing_reason
|
14
|
-
|
15
12
|
# Register
|
16
13
|
attr_accessor :status_id
|
17
14
|
|
@@ -39,9 +36,6 @@ module Effective
|
|
39
36
|
validates :current_user, presence: true
|
40
37
|
validates :owner, presence: true
|
41
38
|
|
42
|
-
# Bad Standing
|
43
|
-
validates :bad_standing_reason, presence: true, if: -> { current_action == :bad_standing }
|
44
|
-
|
45
39
|
# Reclassification & Register
|
46
40
|
validates :category_id, presence: true,
|
47
41
|
if: -> { current_action == :reclassify || current_action == :register }
|
@@ -84,16 +78,6 @@ module Effective
|
|
84
78
|
EffectiveMemberships.Registrar.assign!(owner, categories: categories, statuses: statuses, number: number)
|
85
79
|
end
|
86
80
|
|
87
|
-
def good_standing!
|
88
|
-
update!(current_action: :good_standing)
|
89
|
-
EffectiveMemberships.Registrar.good_standing!(owner)
|
90
|
-
end
|
91
|
-
|
92
|
-
def bad_standing!
|
93
|
-
update!(current_action: :bad_standing)
|
94
|
-
EffectiveMemberships.Registrar.bad_standing!(owner, reason: bad_standing_reason)
|
95
|
-
end
|
96
|
-
|
97
81
|
def fees_paid!
|
98
82
|
update!(current_action: :fees_paid)
|
99
83
|
EffectiveMemberships.Registrar.fees_paid!(owner, order_attributes: order_attributes)
|
@@ -45,12 +45,12 @@
|
|
45
45
|
.col-3= f.price_field :late_fee
|
46
46
|
|
47
47
|
%h3 Bad Standing
|
48
|
-
= f.check_box :
|
48
|
+
= f.check_box :create_not_in_good_standing, label: 'Yes, Not in Good Standing status should be applied'
|
49
49
|
|
50
|
-
= f.show_if(:
|
50
|
+
= f.show_if(:create_not_in_good_standing, true) do
|
51
51
|
- period = EffectiveMemberships.Registrar.current_period
|
52
|
-
- date = EffectiveMemberships.Registrar.
|
52
|
+
- date = EffectiveMemberships.Registrar.not_in_good_standing_date(period: period)
|
53
53
|
|
54
|
-
%p Members with outstanding fees, on #{date.strftime('%B %e')}, will automatically be marked
|
54
|
+
%p Members with outstanding fees, on #{date.strftime('%B %e')}, will automatically be marked #{badge('Not In Good Standing')}.
|
55
55
|
|
56
56
|
= f.submit
|
@@ -15,7 +15,8 @@
|
|
15
15
|
= f.select :membership_category_ids, EffectiveMemberships.Category.all.sorted, label: 'Membership Categories', hint: 'The membership category or categories held during this period in history.'
|
16
16
|
= f.select :membership_status_ids, EffectiveMemberships.Status.all.sorted, label: 'Membership Statuses', hint: 'The membership status or statuses held during this period in history.'
|
17
17
|
|
18
|
-
= f.check_box :bad_standing, hint: 'Membership in bad standing'
|
19
18
|
= f.check_box :removed, hint: 'Membership removed'
|
20
19
|
|
20
|
+
= f.text_area :notes
|
21
|
+
|
21
22
|
= f.submit 'Update History', border: false, center: true, 'data-confirm': "Really update #{f.object.owner}?"
|
@@ -12,6 +12,6 @@
|
|
12
12
|
- if owner.registrar_action_statuses(:status_change).present?
|
13
13
|
.mb-4= render 'admin/registrar_actions/form_status_change', registrar_action: registrar_action
|
14
14
|
|
15
|
-
.mb-4= render 'admin/registrar_actions/
|
15
|
+
.mb-4= render 'admin/registrar_actions/form_not_in_good_standing', registrar_action: registrar_action
|
16
16
|
.mb-4= render 'admin/registrar_actions/form_fees_paid', registrar_action: registrar_action
|
17
17
|
.mb-4= render 'admin/registrar_actions/form_remove', registrar_action: registrar_action
|
@@ -0,0 +1,23 @@
|
|
1
|
+
.card
|
2
|
+
.card-body
|
3
|
+
%h5.card-title Not In Good Standing
|
4
|
+
|
5
|
+
- period = EffectiveMemberships.Registrar.current_period
|
6
|
+
- date = (EffectiveMemberships.Registrar.not_in_good_standing_date(period: period) rescue false)
|
7
|
+
|
8
|
+
%p.text-muted
|
9
|
+
- if date.present?
|
10
|
+
Members with outstanding renewal fees are automatically marked
|
11
|
+
not in good standing on #{date.strftime('%B %e')}.
|
12
|
+
The status is cleared when they pay their fees.
|
13
|
+
- else
|
14
|
+
Members with outstanding renewal fees are not automatically marked not in good standing.
|
15
|
+
|
16
|
+
= effective_form_with(model: [:admin, registrar_action], url: effective_memberships.admin_registrar_actions_path) do |f|
|
17
|
+
- membership = f.object.owner.membership
|
18
|
+
|
19
|
+
= f.static_field :current_action, label: 'Current Status' do
|
20
|
+
- if membership.not_in_good_standing?
|
21
|
+
Not In Good Standing
|
22
|
+
- else
|
23
|
+
In Good Standing
|
@@ -12,9 +12,9 @@
|
|
12
12
|
- date = EffectiveMemberships.Registrar.late_fee_date(period: Time.zone.now)
|
13
13
|
%p Late fees will be applied on #{date.strftime('%B %e')}.
|
14
14
|
|
15
|
-
- if memberships.any? { |membership| membership.categories.any?(&:
|
16
|
-
- date = EffectiveMemberships.Registrar.
|
17
|
-
%p Memberships with unpaid fees or dues will be marked
|
15
|
+
- if memberships.any? { |membership| membership.categories.any?(&:create_not_in_good_standing?) }
|
16
|
+
- date = EffectiveMemberships.Registrar.not_in_good_standing_date(period: Time.zone.now)
|
17
|
+
%p Memberships with unpaid fees or dues will be marked Not In Good Standing on #{date.strftime('%B %e')}.
|
18
18
|
|
19
19
|
- if outstanding_owners.present?
|
20
20
|
.alert.alert-warning.mb-3 You have outstanding fees or dues ready to purchase.
|
@@ -30,8 +30,8 @@
|
|
30
30
|
- if membership.registration_on > membership.joined_on
|
31
31
|
%p You last changed categories on #{membership.registration_on.strftime('%F')}.
|
32
32
|
|
33
|
-
- if membership.
|
34
|
-
%p Your membership is
|
33
|
+
- if membership.not_in_good_standing?
|
34
|
+
%p Your membership is Not In Good Standing because of unpurchased fees or dues. Please purchase these dues or contact us.
|
35
35
|
|
36
36
|
- if current_user.membership_removed?
|
37
37
|
%p Your membership was removed on #{current_user.membership_removed_on.strftime('%F')}.
|
@@ -23,6 +23,21 @@
|
|
23
23
|
- membership.categories.each do |category|
|
24
24
|
%div= category
|
25
25
|
|
26
|
+
- if membership.statuses.length == 0
|
27
|
+
%tr
|
28
|
+
%th Status
|
29
|
+
%td None
|
30
|
+
- elsif membership.statuses.length == 1
|
31
|
+
%tr
|
32
|
+
%th Status
|
33
|
+
%td= membership.status
|
34
|
+
- else
|
35
|
+
%tr
|
36
|
+
%th Statuses
|
37
|
+
%td
|
38
|
+
- membership.statuses.each do |status|
|
39
|
+
%div= status
|
40
|
+
|
26
41
|
%tr
|
27
42
|
%th Number
|
28
43
|
%td= membership.number
|
@@ -30,11 +45,3 @@
|
|
30
45
|
%tr
|
31
46
|
%th Fees Paid Through
|
32
47
|
%td= membership.fees_paid_through_period&.strftime('%F') || '-'
|
33
|
-
|
34
|
-
%tr
|
35
|
-
%th In Bad Standing
|
36
|
-
%td
|
37
|
-
- if membership.bad_standing?
|
38
|
-
%p Yes. #{membership.bad_standing_reason}
|
39
|
-
- else
|
40
|
-
= '-'
|
@@ -54,7 +54,7 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
|
|
54
54
|
t.boolean :create_late_fees, default: false
|
55
55
|
t.integer :late_fee
|
56
56
|
|
57
|
-
t.boolean :
|
57
|
+
t.boolean :create_not_in_good_standing, default: false
|
58
58
|
|
59
59
|
t.string :qb_item_name
|
60
60
|
t.boolean :tax_exempt, default: false
|
@@ -95,10 +95,6 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
|
|
95
95
|
t.date :fees_paid_period
|
96
96
|
t.date :fees_paid_through_period
|
97
97
|
|
98
|
-
t.boolean :bad_standing, default: false
|
99
|
-
t.boolean :bad_standing_admin, default: false
|
100
|
-
t.text :bad_standing_reason
|
101
|
-
|
102
98
|
t.datetime :updated_at
|
103
99
|
t.datetime :created_at
|
104
100
|
end
|
@@ -140,7 +136,6 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
|
|
140
136
|
|
141
137
|
t.string :number
|
142
138
|
|
143
|
-
t.boolean :bad_standing, default: false
|
144
139
|
t.boolean :removed, default: false
|
145
140
|
|
146
141
|
t.text :notes
|
@@ -474,7 +469,7 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
|
|
474
469
|
|
475
470
|
t.date :period
|
476
471
|
t.date :late_on
|
477
|
-
t.date :
|
472
|
+
t.date :not_in_good_standing_on
|
478
473
|
|
479
474
|
t.string :title
|
480
475
|
t.integer :price
|
data/db/seeds.rb
CHANGED
@@ -12,6 +12,7 @@ end
|
|
12
12
|
Effective::Status.where(title: 'Resigned').first_or_create!
|
13
13
|
Effective::Status.where(title: 'Deceased').first_or_create!
|
14
14
|
Effective::Status.where(title: 'On Leave').first_or_create!
|
15
|
+
Effective::Status.where(title: 'Not In Good Standing').first_or_create!
|
15
16
|
|
16
17
|
member = Effective::Category.create!(
|
17
18
|
title: "Full Member",
|
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.8.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: 2022-10-
|
11
|
+
date: 2022-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -377,8 +377,8 @@ files:
|
|
377
377
|
- app/views/admin/organizations/_form_organization.html.haml
|
378
378
|
- app/views/admin/registrar_actions/_form.html.haml
|
379
379
|
- app/views/admin/registrar_actions/_form_assign.html.haml
|
380
|
-
- app/views/admin/registrar_actions/_form_bad_standing.html.haml
|
381
380
|
- app/views/admin/registrar_actions/_form_fees_paid.html.haml
|
381
|
+
- app/views/admin/registrar_actions/_form_not_in_good_standing.html.haml
|
382
382
|
- app/views/admin/registrar_actions/_form_reclassify.html.haml
|
383
383
|
- app/views/admin/registrar_actions/_form_register.html.haml
|
384
384
|
- app/views/admin/registrar_actions/_form_remove.html.haml
|
@@ -1,44 +0,0 @@
|
|
1
|
-
.card
|
2
|
-
.card-body
|
3
|
-
%h5.card-title Not In Good Standing
|
4
|
-
|
5
|
-
= effective_form_with(model: [:admin, registrar_action], url: effective_memberships.admin_registrar_actions_path) do |f|
|
6
|
-
= f.hidden_field :owner_id
|
7
|
-
= f.hidden_field :owner_type
|
8
|
-
|
9
|
-
- membership = f.object.owner.membership
|
10
|
-
|
11
|
-
- period = EffectiveMemberships.Registrar.current_period
|
12
|
-
- date = (EffectiveMemberships.Registrar.bad_standing_date(period: period) rescue false)
|
13
|
-
|
14
|
-
%p.text-muted
|
15
|
-
- if date.present?
|
16
|
-
Members with outstanding renewal fees are automatically marked
|
17
|
-
not in good standing on #{date.strftime('%B %e')}.
|
18
|
-
The status is cleared when they pay their fees.
|
19
|
-
You can also mark a member as always in bad standing.
|
20
|
-
|
21
|
-
= f.static_field :current_action, label: 'Current Status' do
|
22
|
-
|
23
|
-
- if membership.bad_standing_admin?
|
24
|
-
In Bad Standing (set by an Admin) with the following reason: #{membership.bad_standing_reason}.
|
25
|
-
- elsif membership.bad_standing?
|
26
|
-
In Bad Standing with the following reason: #{membership.bad_standing_reason}.
|
27
|
-
- else
|
28
|
-
In Good Standing
|
29
|
-
|
30
|
-
- if membership.good_standing?
|
31
|
-
= f.check_box :current_action, label: 'Yes, set this member in bad standing'
|
32
|
-
|
33
|
-
= f.show_if :current_action, true do
|
34
|
-
= f.text_area :bad_standing_reason, required: true
|
35
|
-
|
36
|
-
= f.submit 'Set In Bad Standing', border: false, center: true,
|
37
|
-
'data-confirm': "Really set #{f.object.owner} in bad standing?"
|
38
|
-
|
39
|
-
- if membership.bad_standing_admin?
|
40
|
-
= f.check_box :current_action, label: 'Yes, remove in bad standing status'
|
41
|
-
|
42
|
-
= f.show_if :current_action, true do
|
43
|
-
= f.submit 'Remove In Bad Standing', border: false, center: true,
|
44
|
-
'data-confirm': "Really remove #{f.object.owner} bad standing?"
|