effective_memberships 0.7.7 → 0.8.1

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.
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)