effective_memberships 0.7.7 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/admin/registrar_actions_controller.rb +0 -8
  3. data/app/controllers/effective/membership_directory_controller.rb +36 -0
  4. data/app/datatables/admin/effective_categories_datatable.rb +1 -1
  5. data/app/datatables/admin/effective_membership_histories_datatable.rb +2 -1
  6. data/app/datatables/admin/effective_memberships_datatable.rb +0 -4
  7. data/app/datatables/effective_memberships_directory_datatable.rb +2 -6
  8. data/app/models/concerns/effective_memberships_category.rb +1 -1
  9. data/app/models/concerns/effective_memberships_directory.rb +118 -0
  10. data/app/models/concerns/effective_memberships_owner.rb +28 -44
  11. data/app/models/concerns/effective_memberships_registrar.rb +28 -43
  12. data/app/models/concerns/effective_memberships_status.rb +4 -0
  13. data/app/models/effective/fee.rb +7 -7
  14. data/app/models/effective/membership.rb +48 -14
  15. data/app/models/effective/membership_directory.rb +5 -0
  16. data/app/models/effective/membership_history.rb +5 -7
  17. data/app/models/effective/registrar.rb +2 -2
  18. data/app/models/effective/registrar_action.rb +0 -16
  19. data/app/views/admin/categories/_form_fees.html.haml +4 -4
  20. data/app/views/admin/membership_histories/_form.html.haml +3 -2
  21. data/app/views/admin/registrar_actions/_form.html.haml +1 -1
  22. data/app/views/admin/registrar_actions/_form_not_in_good_standing.html.haml +23 -0
  23. data/app/views/effective/fees/_dashboard.html.haml +3 -3
  24. data/app/views/effective/membership_directory/_form.html.haml +11 -0
  25. data/app/views/effective/membership_directory/_layout.html.haml +2 -0
  26. data/app/views/effective/membership_directory/_membership.html.haml +4 -0
  27. data/app/views/effective/membership_directory/_membership_directory.html.haml +16 -0
  28. data/app/views/effective/membership_directory/index.html.haml +2 -0
  29. data/app/views/effective/memberships/_dashboard.html.haml +2 -2
  30. data/app/views/effective/memberships/_membership.html.haml +15 -8
  31. data/config/effective_memberships.rb +1 -0
  32. data/config/routes.rb +2 -1
  33. data/db/migrate/01_create_effective_memberships.rb.erb +2 -7
  34. data/db/seeds.rb +1 -0
  35. data/lib/effective_memberships/version.rb +1 -1
  36. data/lib/effective_memberships.rb +5 -1
  37. metadata +11 -5
  38. data/app/controllers/effective/memberships_directory_controller.rb +0 -14
  39. data/app/views/admin/registrar_actions/_form_bad_standing.html.haml +0 -44
  40. data/app/views/effective/memberships_directory/index.html.haml +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 504773afcda5b7dcae14e65e794047b836bf36cee856712def292310318b69e5
4
- data.tar.gz: 197949c35571956f3062f41de8096c9affea15bf086288f3173f403d2b13b772
3
+ metadata.gz: 0a2ae153f152ca4d2295c8847e7848d10dde99d015c77367606cc1d00feb8743
4
+ data.tar.gz: f41d582a3c5da8491cfb82ac7129aaa796c3f4fc14ee49e5eff6e2770d725200
5
5
  SHA512:
6
- metadata.gz: 40a854be5c36060fc00699df969ec482037b62688f6be2976b5c362fe1d6e3fd1a597de32f6074d4e66f2495e875d4ea21c121a72ad8c88cae636ca1e3d07f7e
7
- data.tar.gz: 6596da1652d19c7a436917cd05390ddbb9d233c0109fd1efd91c046e165791faf22dbe4fddf1d8ce0b56c1c0e1d931cca6c37eb934b44d47acc269f9d30646e5
6
+ metadata.gz: 218f5706b65bfc70fa9cd458678fb24cfa106751f91c98a636e304dc66494879789e95bcccfebf79eb993dd7797b56b72cf640de69013ded6b117e2ca6fb0f64
7
+ data.tar.gz: 2fcba0dab68d21ce5653e9d9e227895e227d887c3fbc80c2533be72cd190b1ad6a8a02b7b7041692957cd4edca505d24533fcb8653c82c3ace37623122d4498a
@@ -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) }
@@ -0,0 +1,36 @@
1
+ module Effective
2
+ class MembershipDirectoryController < ApplicationController
3
+ include Effective::CrudController
4
+
5
+ def index
6
+ @page_title = 'Directory'
7
+ EffectiveResources.authorize!(self, :index, Effective::Membership)
8
+
9
+ # Sometimes we just display a Datatable for the membership directory
10
+ @datatable = EffectiveResources.best('EffectiveMembershipsDirectoryDatatable').new
11
+
12
+ # But more often we do a full membership directory search screen
13
+ @membership_directory = build_membership_directory
14
+ @membership_directory.search!
15
+
16
+ @memberships = @membership_directory.results(page: params[:page])
17
+ end
18
+
19
+ def build_membership_directory
20
+ directory = EffectiveMemberships.MembershipDirectory.new(search_params)
21
+ directory.current_user = current_user
22
+ directory
23
+ end
24
+
25
+ def search_params
26
+ return {} unless params[:q].present?
27
+
28
+ if params[:q].respond_to?(:to_h) # From the search form
29
+ params.require(:q).permit!
30
+ else
31
+ { term: params.permit(:q).fetch(:q) } # From the url /directory?q=asdf
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -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 :create_bad_standing, visible: false
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
 
@@ -35,9 +35,10 @@ module Admin
35
35
  col :category_ids, visible: false
36
36
  col :status_ids, visible: false
37
37
 
38
- col :bad_standing
39
38
  col :removed
40
39
 
40
+ col :notes
41
+
41
42
  actions_col unless attributes[:actions] == false
42
43
  end
43
44
 
@@ -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?
@@ -11,7 +11,7 @@ class EffectiveMembershipsDirectoryDatatable < Effective::Datatable
11
11
  end
12
12
 
13
13
  collection do
14
- scope = Effective::Membership.deep.good_standing.includes(:owner)
14
+ scope = Effective::Membership.directory.all
15
15
 
16
16
  archived_klasses.each do |klass|
17
17
  scope = scope.where.not(owner_id: klass.archived.select('id'), owner_type: klass.name)
@@ -21,11 +21,7 @@ class EffectiveMembershipsDirectoryDatatable < Effective::Datatable
21
21
  end
22
22
 
23
23
  def archived_klasses
24
- @archived_klasses ||= begin
25
- klasses = Effective::Membership.distinct(:owner_type).pluck(:owner_type)
26
- klasses = klasses.select { |klass| klass.safe_constantize.try(:acts_as_archived?) }
27
- klasses.map { |klass| klass.constantize }
28
- end
24
+ @archived_klasses ||= Effective::Membership.owner_klasses.select { |klass| klass.try(:acts_as_archived?) }
29
25
  end
30
26
 
31
27
  end
@@ -91,7 +91,7 @@ module EffectiveMembershipsCategory
91
91
  create_late_fees :boolean
92
92
  late_fee :integer
93
93
 
94
- create_bad_standing :boolean
94
+ create_not_in_good_standing :boolean
95
95
 
96
96
  # Pricing
97
97
  qb_item_name :string
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is a search model for the MembershipDirectories screen
4
+ #
5
+ # EffectiveMembershipsDirectory
6
+ # Mark your directory search model with include EffectiveMembershipsDirectory
7
+
8
+ module EffectiveMembershipsDirectory
9
+ extend ActiveSupport::Concern
10
+
11
+ module ClassMethods
12
+ def effective_memberships_directory?; true; end
13
+ end
14
+
15
+ included do
16
+ include ActiveModel::Model
17
+
18
+ attr_accessor :current_user
19
+ attr_accessor :term
20
+ attr_accessor :category
21
+
22
+ attr_accessor :first_name
23
+ attr_accessor :last_name
24
+
25
+ validates :term, length: { minimum: 3, allow_blank: true }
26
+ validates :first_name, length: { minimum: 2, allow_blank: true }
27
+ validates :last_name, length: { minimum: 2, allow_blank: true }
28
+ end
29
+
30
+ # Base collection to search. Can be configured per tenant.
31
+ def collection
32
+ Effective::Membership.directory
33
+ end
34
+
35
+ # Search Users and Organizations for only these fields. Passed into search_any. Return nil for all.
36
+ # Should this include email?
37
+ def search_any_columns
38
+ [:title, :name, :first_name, :middle_name, :last_name]
39
+ end
40
+
41
+ def per_page
42
+ 24
43
+ end
44
+
45
+ def present?
46
+ term.present? || first_name.present? || last_name.present? || category.present?
47
+ end
48
+
49
+ # Search and assigns the collection
50
+ # Assigns the entire collection() if there are no search terms
51
+ # Otherwise validate the search terms
52
+ def search!
53
+ @memberships = build_collection()
54
+ @memberships = @memberships.none if present? && !valid?
55
+ @memberships
56
+ end
57
+
58
+ # The unpaginated results of the search
59
+ def memberships
60
+ @memberships || collection
61
+ end
62
+
63
+ # The paginated results
64
+ def results(page: nil)
65
+ page = (page || 1).to_i
66
+ offset = [(page - 1), 0].max * per_page
67
+
68
+ memberships().limit(per_page).offset(offset)
69
+ end
70
+
71
+ protected
72
+
73
+ def build_collection
74
+ memberships = collection()
75
+ raise('expected an ActiveRecord collection') unless memberships.kind_of?(ActiveRecord::Relation)
76
+
77
+ # Filter by term
78
+ if term.present?
79
+ memberships = search_owners(memberships, term, search_any_columns)
80
+ end
81
+
82
+ # Filter by first name
83
+ if first_name.present?
84
+ memberships = search_owners(memberships, first_name, :first_name)
85
+ end
86
+
87
+ # Filter by last name
88
+ if last_name.present?
89
+ memberships = search_owners(memberships, last_name, :last_name)
90
+ end
91
+
92
+ # Filter by category
93
+ if category.present?
94
+ cat = EffectiveMemberships.Category.where(id: category)
95
+ memberships = memberships.with_category(cat) if cat.present?
96
+ end
97
+
98
+ memberships
99
+ end
100
+
101
+ def search_owners(collection, term, columns = nil)
102
+ results = collection.none()
103
+
104
+ owner_klasses.each do |klass|
105
+ search = Effective::Resource.new(klass).search_any(term, columns: columns)
106
+ searched = collection.where(owner_type: klass.name, owner_id: search.select('id'))
107
+
108
+ results = results.or(searched)
109
+ end
110
+
111
+ collection.merge(results)
112
+ end
113
+
114
+ def owner_klasses
115
+ @owner_klasses ||= Effective::Membership.owner_klasses
116
+ end
117
+
118
+ end
@@ -7,12 +7,9 @@
7
7
  module EffectiveMembershipsOwner
8
8
  extend ActiveSupport::Concern
9
9
 
10
- mattr_accessor :descendants
11
-
12
10
  module Base
13
11
  def effective_memberships_owner
14
12
  include ::EffectiveMembershipsOwner
15
- (EffectiveMembershipsOwner.descendants ||= []) << self
16
13
  end
17
14
  end
18
15
 
@@ -43,14 +40,14 @@ module EffectiveMembershipsOwner
43
40
  without_role(:member).where(id: removed.select(:owner_id))
44
41
  }
45
42
 
46
- scope :membership_good_standing, -> {
47
- bad_standing = Effective::Membership.where(bad_standing: false).where(owner_type: name)
48
- where(id: bad_standing.select(:owner_id))
43
+ scope :membership_not_in_good_standing, -> {
44
+ not_in_good_standing = Effective::Membership.not_in_good_standing.where(owner_type: name)
45
+ where(id: not_in_good_standing.select(:owner_id))
49
46
  }
50
47
 
51
- scope :membership_bad_standing, -> {
52
- bad_standing = Effective::Membership.where(bad_standing: true).where(owner_type: name)
53
- where(id: bad_standing.select(:owner_id))
48
+ scope :membership_in_good_standing, -> {
49
+ in_good_standing = Effective::Membership.in_good_standing.where(owner_type: name)
50
+ where(id: in_good_standing.select(:owner_id))
54
51
  }
55
52
 
56
53
  scope :membership_renewed_this_period, -> {
@@ -59,33 +56,21 @@ module EffectiveMembershipsOwner
59
56
  }
60
57
 
61
58
  scope :members_with_category, -> (categories) {
62
- raise('expected an EffectiveMemberships.Category') unless Array(categories).all? { |cat| cat.kind_of?(EffectiveMemberships.Category) }
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))
59
+ with_category = Effective::Membership.with_category(categories).where(owner_type: name)
60
+ where(id: with_category.select(:owner_id))
68
61
  }
69
62
 
70
63
  scope :members_with_status, -> (statuses) {
71
- raise('expected an EffectiveMemberships.Status') unless Array(statuses).all? { |status| status.kind_of?(EffectiveMemberships.Status) }
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))
64
+ with_status = Effective::Membership.with_status(statuses).where(owner_type: name)
65
+ where(id: with_status.select(:owner_id))
77
66
  }
78
67
 
79
68
  scope :membership_joined_before, -> (date) {
80
- raise('expected a date') unless date.respond_to?(:strftime)
81
-
82
69
  joined_before = Effective::Membership.joined_before(date).where(owner_type: name)
83
70
  where(id: joined_before.select(:owner_id))
84
71
  }
85
72
 
86
73
  scope :membership_joined_after, -> (date) {
87
- raise('expected a date') unless date.respond_to?(:strftime)
88
-
89
74
  joined_after = Effective::Membership.joined_after(date).where(owner_type: name)
90
75
  where(id: joined_after.select(:owner_id))
91
76
  }
@@ -114,8 +99,8 @@ module EffectiveMembershipsOwner
114
99
  orders.select { |order| order.parent_type.to_s.include?('FeePayment') && !order.purchased? }
115
100
  end
116
101
 
117
- def bad_standing_fees
118
- fees.select { |fee| fee.bad_standing? }
102
+ def not_in_good_standing_fees
103
+ fees.select { |fee| fee.not_in_good_standing? }
119
104
  end
120
105
 
121
106
  def max_fees_paid_period
@@ -141,7 +126,7 @@ module EffectiveMembershipsOwner
141
126
  end
142
127
 
143
128
  def registrar_action_statuses(action)
144
- EffectiveMemberships.Status.sorted.all
129
+ EffectiveMemberships.Status.sorted.all.where.not(id: EffectiveMemberships.Registrar.not_in_good_standing_status)
145
130
  end
146
131
 
147
132
  # Instance Methods
@@ -192,7 +177,7 @@ module EffectiveMembershipsOwner
192
177
  fee
193
178
  end
194
179
 
195
- # Only thing optional is category, late_on and bad_standing_on
180
+ # Only thing optional is category, late_on and not_in_good_standing_on
196
181
  def build_title_fee(title:, fee_type:, period:, price: nil, tax_exempt: nil, qb_item_name: nil, category: nil)
197
182
  fee = fees.find do |fee|
198
183
  fee.fee_type == fee_type && fee.period == period && fee.title == title &&
@@ -223,7 +208,7 @@ module EffectiveMembershipsOwner
223
208
  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
209
  end
225
210
 
226
- def build_renewal_fee(category:, period:, late_on: nil, bad_standing_on: nil)
211
+ def build_renewal_fee(category:, period:, late_on: nil, not_in_good_standing_on: nil)
227
212
  raise('must have an existing membership') unless membership.present?
228
213
 
229
214
  # Sanity check.
@@ -239,7 +224,7 @@ module EffectiveMembershipsOwner
239
224
  fee ||= fees.build()
240
225
 
241
226
  late_on ||= EffectiveMemberships.Registrar.late_fee_date(period: period) if category.create_late_fees?
242
- bad_standing_on ||= EffectiveMemberships.Registrar.bad_standing_date(period: period) if category.create_bad_standing?
227
+ not_in_good_standing_on ||= EffectiveMemberships.Registrar.not_in_good_standing_date(period: period) if category.create_not_in_good_standing?
243
228
 
244
229
  fee.assign_attributes(
245
230
  fee_type: 'Renewal',
@@ -249,7 +234,7 @@ module EffectiveMembershipsOwner
249
234
  tax_exempt: category.tax_exempt,
250
235
  qb_item_name: category.qb_item_name,
251
236
  late_on: late_on,
252
- bad_standing_on: bad_standing_on,
237
+ not_in_good_standing_on: not_in_good_standing_on,
253
238
  )
254
239
 
255
240
  fee
@@ -289,25 +274,24 @@ module EffectiveMembershipsOwner
289
274
  membership.fees_paid_period = max_fees_paid_period()
290
275
  membership.fees_paid_through_period = max_fees_paid_through_period()
291
276
 
292
- # Assign in bad standing
293
- if membership.bad_standing_admin?
294
- # Nothing to do
295
- elsif bad_standing_fees.present? && membership.categories.any?(&:create_bad_standing?)
296
- membership.bad_standing = true
297
- membership.bad_standing_reason = 'Unpaid Fees'
298
- else
299
- membership.bad_standing = false
300
- membership.bad_standing_reason = nil
277
+ # Add or remove Not In Good Standing status
278
+ in_good_standing = membership.in_good_standing?
279
+ not_in_good_standing = membership.not_in_good_standing?
280
+
281
+ if in_good_standing && not_in_good_standing_fees.present?
282
+ EffectiveMemberships.Registrar.not_in_good_standing!(self)
283
+ elsif not_in_good_standing && not_in_good_standing_fees.blank?
284
+ EffectiveMemberships.Registrar.in_good_standing!(self)
301
285
  end
302
286
 
303
- if membership.bad_standing_changed? || membership_histories.blank?
287
+ if membership_histories.blank?
304
288
  build_membership_history()
305
289
  end
306
290
 
307
291
  save!
308
292
  end
309
293
 
310
- def build_membership_history(start_on: nil)
294
+ def build_membership_history(start_on: nil, notes: nil)
311
295
  raise('expected membership to be present') unless membership.present?
312
296
 
313
297
  # The date of change
@@ -321,7 +305,7 @@ module EffectiveMembershipsOwner
321
305
  start_on: start_on,
322
306
  end_on: nil,
323
307
  removed: membership.marked_for_destruction?,
324
- bad_standing: membership.bad_standing?
308
+ notes: notes
325
309
  )
326
310
 
327
311
  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 bad_standing_date(period:)
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 ||= Time.zone.now
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 bad_standing!(owner, reason:, date: nil)
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') if owner.membership.bad_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
- membership.bad_standing = true
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 good_standing!(owner, date: nil)
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 bad standing') unless owner.membership.bad_standing?
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
- save!(owner, date: date)
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 Bad Standing
404
- memberships.find_each { |membership| create_bad_standing!(membership, period: period) }
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 create_bad_standing!(membership, period:)
437
- return unless membership.categories.any?(&:create_bad_standing?)
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
 
@@ -68,6 +68,10 @@ module EffectiveMembershipsStatus
68
68
  status_type == 'Organization'
69
69
  end
70
70
 
71
+ def not_in_good_standing?
72
+ title == 'Not In Good Standing'
73
+ end
74
+
71
75
  # Used for Apply to Join Reinstatement
72
76
  def reinstatable?
73
77
  true
@@ -23,8 +23,8 @@ module Effective
23
23
 
24
24
  period :date
25
25
 
26
- late_on :date
27
- bad_standing_on :date
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 :bad_standing_on, presence: true,
66
- if: -> { fee_type == 'Renewal' && category&.create_bad_standing? }
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 bad_standing?
80
- return false if bad_standing_on.blank?
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
- bad_standing_on <= Time.zone.now.to_date
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
- scope :deep, -> { includes(membership_categories: :category) }
30
+ scope :deep, -> { includes(:owner, membership_categories: :category) }
35
31
  scope :sorted, -> { order(:id) }
36
32
 
37
- scope :good_standing, -> { where(bad_standing: [nil, false]) }
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
+ }
38
37
 
39
- scope :joined_before, -> (date) { where(arel_table[:joined_on].lt(date)) }
40
- scope :joined_after, -> (date) { where(arel_table[:joined_on].gteq(date)) }
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
+ }
57
+
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,11 @@ 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
+
76
+ scope :directory, -> { deep.in_good_standing.order(:id) }
77
+
52
78
  before_validation do
53
79
  self.registration_on ||= joined_on
54
80
  end
@@ -76,6 +102,11 @@ module Effective
76
102
  maximum('number_as_integer') || 0
77
103
  end
78
104
 
105
+ def self.owner_klasses
106
+ klasses = Effective::Membership.distinct(:owner_type).pluck(:owner_type)
107
+ klasses.select { |klass| klass.safe_constantize }.map { |klass| klass.constantize }
108
+ end
109
+
79
110
  def to_s
80
111
  return 'membership' if owner.blank?
81
112
 
@@ -87,8 +118,7 @@ module Effective
87
118
  'member',
88
119
  ("##{number_was}" if number_was.present?),
89
120
  "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?)
121
+ ("and last registered #{registration_on.strftime('%F')}" if registration_on > joined_on)
92
122
  ].compact.join(' ')
93
123
 
94
124
  (summary + '.').html_safe
@@ -170,8 +200,12 @@ module Effective
170
200
  registration_on.present? && joined_on.present? && registration_on > joined_on
171
201
  end
172
202
 
173
- def good_standing?
174
- !bad_standing?
203
+ def not_in_good_standing?
204
+ membership_statuses.any? { |ms| ms.status.not_in_good_standing? }
205
+ end
206
+
207
+ def in_good_standing?
208
+ membership_statuses.none? { |ms| ms.status.not_in_good_standing? }
175
209
  end
176
210
 
177
211
  def fees_paid?
@@ -222,7 +256,7 @@ module Effective
222
256
  # Otherwise build fees right now
223
257
  EffectiveMemberships.Registrar.create_renewal_fees!(self, period: period)
224
258
  EffectiveMemberships.Registrar.create_late_fees!(self, period: period)
225
- EffectiveMemberships.Registrar.update_membership_status!(self, period: period)
259
+ EffectiveMemberships.Registrar.create_not_in_good_standing!(self, period: period)
226
260
 
227
261
  true
228
262
  end
@@ -0,0 +1,5 @@
1
+ module Effective
2
+ class MembershipDirectory
3
+ include EffectiveMembershipsDirectory
4
+ end
5
+ end
@@ -3,18 +3,17 @@ module Effective
3
3
  belongs_to :owner, polymorphic: true
4
4
 
5
5
  effective_resource do
6
- start_on :date
7
- end_on :date
6
+ start_on :date
7
+ end_on :date
8
8
 
9
- number :string
9
+ number :string
10
10
 
11
- bad_standing :boolean
12
- removed :boolean
11
+ removed :boolean
13
12
 
14
13
  categories :text
15
14
  category_ids :text
16
15
 
17
- notes :text
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 bad_standing_date(period:)
15
- Date.new(period.year, 3, 1) # Membership in bad standing after March 1st
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 :create_bad_standing, label: 'Yes, bad standing status should be applied'
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(:create_bad_standing, true) do
50
+ = f.show_if(:create_not_in_good_standing, true) do
51
51
  - period = EffectiveMemberships.Registrar.current_period
52
- - date = EffectiveMemberships.Registrar.bad_standing_date(period: period)
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 in bad standing.
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
@@ -4,7 +4,7 @@
4
4
  = f.hidden_field :owner_type
5
5
  - else
6
6
  - raise('todo')
7
- - collection = EffectiveMembershipsOwner.descendants.map { |d| [d.name.to_s, d.members.sorted] }.to_h
7
+ /- collection = EffectiveMembershipsOwner.descendants.map { |d| [d.name.to_s, d.members.sorted] }.to_h
8
8
  = f.select :owner_id, collection, polymorphic: true
9
9
 
10
10
  = f.date_field :start_on, hint: 'The start date of this period in history. Must be present.'
@@ -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/form_bad_standing', registrar_action: registrar_action
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?(&:create_bad_standing?) }
16
- - date = EffectiveMemberships.Registrar.bad_standing_date(period: Time.zone.now)
17
- %p Memberships with unpaid fees or dues will be marked in bad standing on #{date.strftime('%B %e')}.
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.
@@ -0,0 +1,11 @@
1
+ = effective_form_with(scope: :q, model: membership_directory, method: :get, url: request.path) do |f|
2
+ - if f.object.term.present?
3
+ = f.search_field :term, label: 'Name'
4
+
5
+ = f.search_field :first_name
6
+ = f.search_field :last_name
7
+
8
+ = f.select :category, EffectiveMemberships.Category.all
9
+
10
+ = f.save('Search', class: 'btn btn-primary btn-search mr-3', name: nil)
11
+ = link_to 'Reset filters', request.path
@@ -0,0 +1,2 @@
1
+ .effective-membership-directory
2
+ = yield
@@ -0,0 +1,4 @@
1
+ = card do
2
+ %h6= membership.owner
3
+ %p= membership.categories.to_sentence
4
+ %p= membership.statuses.to_sentence
@@ -0,0 +1,16 @@
1
+ = render 'layout' do
2
+ = render('effective/membership_directory/form', membership_directory: membership_directory)
3
+
4
+ - results = membership_directory.results(page: params[:page])
5
+
6
+ - if membership_directory.present? && results.length == 0
7
+ .alert.alert-info There are no results for your search. Please try again.
8
+
9
+ - results.in_groups_of(3).each do |group|
10
+ .row.mt-4
11
+ - group.each do |membership|
12
+ - next unless membership
13
+ .col-md= render('effective/membership_directory/membership', membership: membership)
14
+
15
+ %nav.d-flex.justify-content-center
16
+ = bootstrap_paginate(results, per_page: membership_directory.per_page)
@@ -0,0 +1,2 @@
1
+ /= render_datatable(@datatable, buttons: false)
2
+ = render('effective/membership_directory/membership_directory', membership_directory: @membership_directory)
@@ -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.bad_standing?
34
- %p Your membership is in bad standing with the following reason: #{membership.bad_standing_reason}.
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
- = '-'
@@ -20,6 +20,7 @@ EffectiveMemberships.setup do |config|
20
20
  # config.applicant_review_class_name = 'Effective::ApplicantReview'
21
21
  # config.fee_payment_class_name = 'Effective::FeePayment'
22
22
  # config.membership_card_class_name = 'Effective::MembershipCard'
23
+ # config.membership_directory_class_name = 'Effective::MembershipDirectory'
23
24
  # config.registrar_class_name = 'Effective::Registrar'
24
25
  # config.organization_class_name = 'Effective::Organization'
25
26
  # config.status_class_name = 'Effective::Status'
data/config/routes.rb CHANGED
@@ -26,7 +26,8 @@ EffectiveMemberships::Engine.routes.draw do
26
26
  resources :build, controller: :fee_payments, only: [:show, :update]
27
27
  end
28
28
 
29
- get '/directory', to: 'memberships_directory#index'
29
+ resources :membership_directory, only: :index
30
+ get '/directory', to: 'membership_directory#index'
30
31
 
31
32
  resources :membership_cards, only: :index
32
33
 
@@ -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 :create_bad_standing, default: false
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 :bad_standing_on
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",
@@ -1,3 +1,3 @@
1
1
  module EffectiveMemberships
2
- VERSION = '0.7.7'
2
+ VERSION = '0.8.1'
3
3
  end
@@ -7,7 +7,7 @@ module EffectiveMemberships
7
7
  def self.config_keys
8
8
  [
9
9
  :categories_table_name, :applicants_table_name, :applicant_reviews_table_name, :fee_payments_table_name, :organizations_table_name, :representatives_table_name, :statuses_table_name,
10
- :category_class_name, :organization_class_name, :applicant_class_name, :applicant_review_class_name, :fee_payment_class_name, :registrar_class_name, :membership_card_class_name, :status_class_name,
10
+ :category_class_name, :organization_class_name, :applicant_class_name, :applicant_review_class_name, :fee_payment_class_name, :registrar_class_name, :membership_card_class_name, :membership_directory_class_name, :status_class_name,
11
11
  :additional_fee_types, :applicant_reviews, :applicant_endorsements_endorser_collection,
12
12
  :layout,
13
13
  :mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject, :use_effective_email_templates
@@ -40,6 +40,10 @@ module EffectiveMemberships
40
40
  membership_card_class_name&.constantize || Effective::MembershipCard
41
41
  end
42
42
 
43
+ def self.MembershipDirectory
44
+ membership_directory_class_name&.constantize || Effective::MembershipDirectory
45
+ end
46
+
43
47
  def self.Status
44
48
  status_class_name&.constantize || Effective::Status
45
49
  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.7.7
4
+ version: 0.8.1
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-13 00:00:00.000000000 Z
11
+ date: 2022-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -275,7 +275,7 @@ files:
275
275
  - app/controllers/effective/applicants_controller.rb
276
276
  - app/controllers/effective/fee_payments_controller.rb
277
277
  - app/controllers/effective/membership_cards_controller.rb
278
- - app/controllers/effective/memberships_directory_controller.rb
278
+ - app/controllers/effective/membership_directory_controller.rb
279
279
  - app/controllers/effective/organizations_controller.rb
280
280
  - app/controllers/effective/representatives_controller.rb
281
281
  - app/datatables/admin/effective_applicant_course_areas_datatable.rb
@@ -312,6 +312,7 @@ files:
312
312
  - app/models/concerns/effective_memberships_applicant_review.rb
313
313
  - app/models/concerns/effective_memberships_card.rb
314
314
  - app/models/concerns/effective_memberships_category.rb
315
+ - app/models/concerns/effective_memberships_directory.rb
315
316
  - app/models/concerns/effective_memberships_fee_payment.rb
316
317
  - app/models/concerns/effective_memberships_organization.rb
317
318
  - app/models/concerns/effective_memberships_owner.rb
@@ -334,6 +335,7 @@ files:
334
335
  - app/models/effective/membership.rb
335
336
  - app/models/effective/membership_card.rb
336
337
  - app/models/effective/membership_category.rb
338
+ - app/models/effective/membership_directory.rb
337
339
  - app/models/effective/membership_history.rb
338
340
  - app/models/effective/membership_status.rb
339
341
  - app/models/effective/organization.rb
@@ -377,8 +379,8 @@ files:
377
379
  - app/views/admin/organizations/_form_organization.html.haml
378
380
  - app/views/admin/registrar_actions/_form.html.haml
379
381
  - app/views/admin/registrar_actions/_form_assign.html.haml
380
- - app/views/admin/registrar_actions/_form_bad_standing.html.haml
381
382
  - app/views/admin/registrar_actions/_form_fees_paid.html.haml
383
+ - app/views/admin/registrar_actions/_form_not_in_good_standing.html.haml
382
384
  - app/views/admin/registrar_actions/_form_reclassify.html.haml
383
385
  - app/views/admin/registrar_actions/_form_register.html.haml
384
386
  - app/views/admin/registrar_actions/_form_remove.html.haml
@@ -477,9 +479,13 @@ files:
477
479
  - app/views/effective/fees/_dashboard.html.haml
478
480
  - app/views/effective/fees/_fee.html.haml
479
481
  - app/views/effective/membership_cards/index.html.haml
482
+ - app/views/effective/membership_directory/_form.html.haml
483
+ - app/views/effective/membership_directory/_layout.html.haml
484
+ - app/views/effective/membership_directory/_membership.html.haml
485
+ - app/views/effective/membership_directory/_membership_directory.html.haml
486
+ - app/views/effective/membership_directory/index.html.haml
480
487
  - app/views/effective/memberships/_dashboard.html.haml
481
488
  - app/views/effective/memberships/_membership.html.haml
482
- - app/views/effective/memberships_directory/index.html.haml
483
489
  - app/views/effective/memberships_mailer/applicant_approved.liquid
484
490
  - app/views/effective/memberships_mailer/applicant_completed.liquid
485
491
  - app/views/effective/memberships_mailer/applicant_declined.liquid
@@ -1,14 +0,0 @@
1
- module Effective
2
- class MembershipsDirectoryController < ApplicationController
3
- include Effective::CrudController
4
-
5
- def index
6
- @page_title = 'Directory'
7
-
8
- EffectiveResources.authorize!(self, :index, Effective::Membership)
9
-
10
- @datatable = EffectiveResources.best('EffectiveMembershipsDirectoryDatatable').new
11
- end
12
-
13
- end
14
- end
@@ -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?"
@@ -1 +0,0 @@
1
- = render_datatable(@datatable, buttons: false)