effective_memberships 0.4.16 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/admin/registrar_actions_controller.rb +8 -0
  3. data/app/controllers/admin/statuses_controller.rb +19 -0
  4. data/app/datatables/admin/effective_membership_histories_datatable.rb +10 -0
  5. data/app/datatables/admin/effective_memberships_datatable.rb +2 -1
  6. data/app/datatables/admin/effective_statuses_datatable.rb +21 -0
  7. data/app/models/concerns/effective_memberships_applicant.rb +3 -0
  8. data/app/models/concerns/effective_memberships_category.rb +2 -1
  9. data/app/models/concerns/effective_memberships_fee_payment.rb +2 -1
  10. data/app/models/concerns/effective_memberships_owner.rb +37 -7
  11. data/app/models/concerns/effective_memberships_registrar.rb +50 -3
  12. data/app/models/concerns/effective_memberships_status.rb +71 -0
  13. data/app/models/effective/applicant_experience.rb +1 -1
  14. data/app/models/effective/membership.rb +41 -3
  15. data/app/models/effective/membership_history.rb +17 -4
  16. data/app/models/effective/membership_status.rb +13 -0
  17. data/app/models/effective/registrar_action.rb +38 -4
  18. data/app/models/effective/status.rb +7 -0
  19. data/app/views/admin/applicants/_form.html.haml +1 -54
  20. data/app/views/admin/applicants/_form_applicant.html.haml +56 -0
  21. data/app/views/admin/membership_histories/_form.html.haml +2 -0
  22. data/app/views/admin/registrar_actions/_form.html.haml +7 -0
  23. data/app/views/admin/registrar_actions/_form_assign.html.haml +29 -9
  24. data/app/views/admin/registrar_actions/_form_register.html.haml +7 -2
  25. data/app/views/admin/registrar_actions/_form_status_change.html.haml +41 -0
  26. data/app/views/admin/statuses/_form.html.haml +8 -0
  27. data/app/views/admin/statuses/_form_status.html.haml +9 -0
  28. data/app/views/effective/applicants/select.html.haml +1 -0
  29. data/config/effective_memberships.rb +4 -0
  30. data/config/routes.rb +2 -1
  31. data/db/migrate/01_create_effective_memberships.rb.erb +31 -0
  32. data/lib/effective_memberships/engine.rb +1 -0
  33. data/lib/effective_memberships/version.rb +1 -1
  34. data/lib/effective_memberships.rb +9 -6
  35. metadata +11 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 774b42acc07d3dae76bd17888dd5c323b3a47463cb339caa96162ea323ddf4a7
4
- data.tar.gz: e9ee1f7769177827ad627d61e68d294a6d868ac26ec133396b8c861b221a0b2f
3
+ metadata.gz: e719afd32d55f610b718c370497cceb43760450cfca029e618efc99dd73a8d28
4
+ data.tar.gz: 4564cce2a02072ad8db4c81b4c7507b522a4a1a03683899797d9c2d8aa1f89b5
5
5
  SHA512:
6
- metadata.gz: 7684254166c10f7f1c826e2e5d2a747f0d8061818355e45242303bdd8438f612a1836228298416f7f6d5bb7ee132cd92a09ecd4334fc72301755e6432d57811c
7
- data.tar.gz: 555d6bbfd89c287031d106998548f76a0d26a5c5e560a018cabb1f82ae8344126e26bdb398a8ff3508ac7e51cca6d8dfc7137d08f0784da4bd43670065719f01
6
+ metadata.gz: 0d711bedd67af762919f71c2d52a3848c70c14af8e756cab24018a4b45d616f92f42510329f53c2e5f886bfceb248e522a9d87f62a89f24641add4b208f8d0c8
7
+ data.tar.gz: 0f11ce742fc500785d1203c87fe3dae05d855deb4f7a51953de4a6efe3e1dff4dc12b06f72631da580cdda039552265abcf2d3c94bdc0291fb787e76c69773c8
@@ -14,6 +14,14 @@ module Admin
14
14
  success: -> { "#{resource.owner} has been reclassified to #{resource.owner.membership.category}" },
15
15
  redirect: -> { admin_owners_path(resource) }
16
16
 
17
+ submit :status_change, 'Change Status',
18
+ success: -> { "#{resource.owner} has been status changed to #{resource.owner.membership.status || 'None'}" },
19
+ redirect: -> { admin_owners_path(resource) }
20
+
21
+ submit :status_remove, 'Remove Status',
22
+ success: -> { "#{resource.owner} has had their status removed" },
23
+ redirect: -> { admin_owners_path(resource) }
24
+
17
25
  submit :assign, 'Assign',
18
26
  success: -> { "#{resource.owner} has been assigned to #{resource.owner.membership.categories.to_sentence}" },
19
27
  redirect: -> { admin_owners_path(resource) }
@@ -0,0 +1,19 @@
1
+ module Admin
2
+ class StatusesController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_memberships) }
5
+
6
+ include Effective::CrudController
7
+
8
+ resource_scope -> { EffectiveMemberships.Status.deep.all }
9
+ datatable -> { Admin::EffectiveStatusesDatatable.new }
10
+
11
+ private
12
+
13
+ def permitted_params
14
+ model = (params.key?(:effective_status) ? :effective_status : :status)
15
+ params.require(model).permit!
16
+ end
17
+
18
+ end
19
+ end
@@ -21,9 +21,19 @@ module Admin
21
21
  end.join.html_safe
22
22
  end
23
23
 
24
+ col :statuses, label: 'Status' do |history|
25
+ history.statuses.map.with_index do |status, index|
26
+ status_id = history.status_ids[index]
27
+ link = link_to(status, effective_memberships.edit_admin_status_path(status_id))
28
+
29
+ content_tag(:div, link, class: 'col-resource_item')
30
+ end.join.html_safe
31
+ end
32
+
24
33
  col :number
25
34
 
26
35
  col :category_ids, visible: false
36
+ col :status_ids, visible: false
27
37
 
28
38
  col :bad_standing
29
39
  col :removed
@@ -9,7 +9,8 @@ module Admin
9
9
  col :owner_type, visible: false
10
10
 
11
11
  val :owner
12
- col :categories
12
+ col :categories, search: EffectiveMemberships.Category.sorted.map(&:to_s)
13
+ col :statuses, search: EffectiveMemberships.Status.sorted.map(&:to_s)
13
14
 
14
15
  col :number
15
16
  col :number_as_integer, visible: false
@@ -0,0 +1,21 @@
1
+ module Admin
2
+ class EffectiveStatusesDatatable < Effective::Datatable
3
+ datatable do
4
+ reorder :position
5
+
6
+ col :updated_at, visible: false
7
+ col :created_at, visible: false
8
+ col :id, visible: false
9
+
10
+ col :title
11
+ col :status_type, search: EffectiveMemberships.Status.status_types
12
+
13
+ actions_col
14
+ end
15
+
16
+ collection do
17
+ EffectiveMemberships.Status.deep.all
18
+ end
19
+
20
+ end
21
+ end
@@ -92,7 +92,9 @@ module EffectiveMembershipsApplicant
92
92
  accepts_nested_attributes_for :organization
93
93
 
94
94
  belongs_to :category, polymorphic: true, optional: true
95
+
95
96
  belongs_to :from_category, polymorphic: true, optional: true
97
+ belongs_to :from_status, polymorphic: true, optional: true
96
98
 
97
99
  has_many :applicant_reviews, -> { order(:id) }, as: :applicant, inverse_of: :applicant, dependent: :destroy
98
100
  accepts_nested_attributes_for :applicant_reviews, reject_if: :all_blank, allow_destroy: true
@@ -186,6 +188,7 @@ module EffectiveMembershipsApplicant
186
188
  before_validation(if: -> { (new_record? || current_step == :select) && owner.present? }) do
187
189
  self.applicant_type = (owner.membership.blank? ? 'Apply to Join' : 'Apply to Reclassify')
188
190
  self.from_category = owner.membership&.category
191
+ self.from_status = owner.membership&.status
189
192
  end
190
193
 
191
194
  before_validation(if: -> { current_step == :experience }) do
@@ -42,7 +42,7 @@ module EffectiveMembershipsCategory
42
42
  category_type :string
43
43
 
44
44
  title :string
45
- category :string
45
+ category :string # Unused but must belong to self.class.categories
46
46
  position :integer
47
47
 
48
48
  # Applicants
@@ -101,6 +101,7 @@ module EffectiveMembershipsCategory
101
101
 
102
102
  serialize :can_apply_restricted_ids, Array
103
103
  serialize :applicant_wizard_steps, Array
104
+ serialize :applicant_review_wizard_steps, Array
104
105
  serialize :fee_payment_wizard_steps, Array
105
106
 
106
107
  scope :deep, -> { includes(:rich_texts) }
@@ -56,8 +56,8 @@ module EffectiveMembershipsFeePayment
56
56
  belongs_to :organization, polymorphic: true, optional: true
57
57
  accepts_nested_attributes_for :organization
58
58
 
59
- # Like maybe optionally it makes sense.
60
59
  belongs_to :category, polymorphic: true, optional: true
60
+ belongs_to :from_status, polymorphic: true, optional: true
61
61
 
62
62
  # Effective Namespace
63
63
  has_many :fees, -> { order(:id) }, as: :parent, class_name: 'Effective::Fee', dependent: :nullify
@@ -102,6 +102,7 @@ module EffectiveMembershipsFeePayment
102
102
 
103
103
  before_validation(if: -> { current_step == :start && user && user.membership }) do
104
104
  self.category ||= user.membership.categories.first if user.membership.categories.length == 1
105
+ self.from_status ||= user.membership.statuses.first if user.membership.statuses.length == 1
105
106
  end
106
107
 
107
108
  # All Steps validations
@@ -53,6 +53,24 @@ module EffectiveMembershipsOwner
53
53
  where(id: with_paid_fees_through.select(:owner_id))
54
54
  }
55
55
 
56
+ scope :members_with_category, -> (categories) {
57
+ raise('expected an EffectiveMemberships.Category') unless Array(categories).all? { |cat| cat.kind_of?(EffectiveMemberships.Category) }
58
+
59
+ membership_categories = Effective::MembershipCategory.where(category: categories)
60
+ memberships = Effective::Membership.where(id: membership_categories.select(:membership_id))
61
+
62
+ where(id: memberships.where(owner_type: name).select(:owner_id))
63
+ }
64
+
65
+ scope :members_with_status, -> (statuses) {
66
+ raise('expected an EffectiveMemberships.Status') unless Array(statuses).all? { |status| status.kind_of?(EffectiveMemberships.Status) }
67
+
68
+ membership_statuses = Effective::MembershipStatus.where(status: statuses)
69
+ memberships = Effective::Membership.where(id: membership_statuses.select(:membership_id))
70
+
71
+ where(id: memberships.where(owner_type: name).select(:owner_id))
72
+ }
73
+
56
74
  end
57
75
 
58
76
  def assign_member_role
@@ -103,6 +121,10 @@ module EffectiveMembershipsOwner
103
121
  EffectiveMemberships.Category.sorted.all
104
122
  end
105
123
 
124
+ def registrar_action_statuses(action)
125
+ EffectiveMemberships.Status.sorted.all
126
+ end
127
+
106
128
  # Instance Methods
107
129
  def build_prorated_fee(date: nil)
108
130
  raise('must have an existing membership') unless membership.present?
@@ -271,21 +293,29 @@ module EffectiveMembershipsOwner
271
293
 
272
294
  # The date of change
273
295
  start_on ||= Time.zone.now
274
- removed = membership.marked_for_destruction?
275
296
 
276
297
  # End the other membership histories
277
298
  membership_histories.each { |history| history.end_on ||= start_on }
278
299
 
279
300
  # Snapshot of the current membership at this time
280
- membership_histories.build(
301
+ history = membership_histories.build(
281
302
  start_on: start_on,
282
303
  end_on: nil,
283
- removed: removed,
284
- bad_standing: membership.bad_standing?,
285
- categories: (membership.categories.map(&:to_s) unless removed),
286
- category_ids: (membership.categories.map(&:id) unless removed),
287
- number: (membership.number unless removed)
304
+ removed: membership.marked_for_destruction?,
305
+ bad_standing: membership.bad_standing?
288
306
  )
307
+
308
+ unless history.removed?
309
+ history.assign_attributes(
310
+ number: membership.number,
311
+ categories: membership.categories.map(&:to_s),
312
+ category_ids: membership.categories.map(&:id),
313
+ statuses: membership.statuses.map(&:to_s),
314
+ status_ids: membership.statuses.map(&:id)
315
+ )
316
+ end
317
+
318
+ history
289
319
  end
290
320
 
291
321
  def membership_history_on(date)
@@ -42,11 +42,14 @@ module EffectiveMembershipsRegistrar
42
42
  period(date: date).end_of_year
43
43
  end
44
44
 
45
- def assign!(owner, categories:, date: nil, number: nil)
45
+ # Category is required, statuses are optional
46
+ def assign!(owner, categories:, statuses: nil, date: nil, number: nil)
46
47
  categories = Array(categories)
48
+ statuses = Array(statuses)
47
49
 
48
50
  raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
49
- raise('expecting a membership category') unless categories.present? && categories.all? { |cat| cat.class.respond_to?(:effective_memberships_category?) }
51
+ raise('expecting a membership category') if categories.blank? || categories.any? { |cat| !cat.class.respond_to?(:effective_memberships_category?) }
52
+ raise('expecting an membership status (optional)') if statuses.present? && statuses.any? { |status| !status.class.respond_to?(:effective_memberships_status?) }
50
53
 
51
54
  # Default Date and next number
52
55
  date ||= Time.zone.now
@@ -64,6 +67,17 @@ module EffectiveMembershipsRegistrar
64
67
  membership.number ||= number
65
68
  membership.number_as_integer ||= (Integer(number) rescue nil)
66
69
 
70
+ # Delete any removed statuses
71
+ membership.membership_statuses.each do |membership_status|
72
+ next if statuses.include?(membership_status.status)
73
+ membership_status.mark_for_destruction
74
+ end
75
+
76
+ # Build any additional statuses
77
+ statuses.each do |status|
78
+ membership.build_membership_status(status: status)
79
+ end
80
+
67
81
  # Delete any removed categories
68
82
  membership.membership_categories.each do |membership_category|
69
83
  next if categories.include?(membership_category.category)
@@ -76,6 +90,7 @@ module EffectiveMembershipsRegistrar
76
90
  end
77
91
 
78
92
  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? }
79
94
 
80
95
  if changed
81
96
  membership.registration_on = date # Always new registration_on
@@ -88,9 +103,10 @@ module EffectiveMembershipsRegistrar
88
103
  owner.update_membership_status!
89
104
  end
90
105
 
91
- def register!(owner, to:, date: nil, number: nil, skip_fees: false)
106
+ def register!(owner, to:, status: nil, date: nil, number: nil, skip_fees: false)
92
107
  raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
93
108
  raise('expecting a memberships category') unless to.class.respond_to?(:effective_memberships_category?)
109
+ raise('expecting a memberships status') unless status.nil? || status.class.respond_to?(:effective_memberships_status?)
94
110
  raise('owner has existing membership. use reclassify! instead.') if owner.membership.present?
95
111
 
96
112
  # Default Date and next number
@@ -113,6 +129,9 @@ module EffectiveMembershipsRegistrar
113
129
  # Assign Category
114
130
  membership.build_membership_category(category: to)
115
131
 
132
+ # Assign Status
133
+ membership.build_membership_status(status: status) if status.present?
134
+
116
135
  # Assign fees paid through period
117
136
  if skip_fees
118
137
  membership.fees_paid_period = period
@@ -164,6 +183,34 @@ module EffectiveMembershipsRegistrar
164
183
  save!(owner, date: date)
165
184
  end
166
185
 
186
+ # This clears the status entirely from user
187
+ def status_remove!(owner, date: nil)
188
+ status_change!(owner, to: nil, date: date)
189
+ end
190
+
191
+ # To can be nil to clear the status entirely
192
+ def status_change!(owner, to:, date: nil)
193
+ raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
194
+ raise('owner must have an existing membership. use register! instead') if owner.membership.blank?
195
+
196
+ from = owner.membership.status
197
+
198
+ raise('expecting a to memberships status') if to.present? && !to.class.respond_to?(:effective_memberships_status?)
199
+ raise('expecting a from memberships status') if from.present? && !from.class.respond_to?(:effective_memberships_status?)
200
+ raise('expected to and from to be different') if from == to
201
+
202
+ date ||= Time.zone.now
203
+
204
+ membership = owner.membership
205
+
206
+ # Assign Status
207
+ membership.build_membership_status(status: to) if to.present?
208
+ membership.membership_status(status: from).mark_for_destruction if from.present?
209
+
210
+ # Save
211
+ save!(owner, date: date)
212
+ end
213
+
167
214
  def remove!(owner, date: nil)
168
215
  raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
169
216
  raise('expected a member') unless owner.membership.present?
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ # EffectiveMembershipsStatus
4
+ #
5
+ # Mark your status model with effective_memberships_status to get all the includes
6
+
7
+ module EffectiveMembershipsStatus
8
+ extend ActiveSupport::Concern
9
+
10
+ module Base
11
+ def effective_memberships_status
12
+ include ::EffectiveMembershipsStatus
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def effective_memberships_status?; true; end
18
+
19
+ def status_types
20
+ ['Individual', 'Organization']
21
+ end
22
+
23
+ def statuses
24
+ []
25
+ end
26
+ end
27
+
28
+ included do
29
+ log_changes(except: :memberships) if respond_to?(:log_changes)
30
+
31
+ has_many :membership_statuses, class_name: 'Effective::MembershipStatus', as: :status
32
+
33
+ effective_resource do
34
+ status_type :string
35
+
36
+ title :string
37
+ status :string # Unused but must belong to self.class.statuses
38
+ position :integer
39
+
40
+ timestamps
41
+ end
42
+
43
+ scope :deep, -> { all }
44
+ scope :sorted, -> { order(:position) }
45
+
46
+ validates :title, presence: true, uniqueness: true
47
+ validates :status_type, presence: true
48
+ validates :position, presence: true
49
+
50
+ before_validation do
51
+ self.position ||= (self.class.pluck(:position).compact.max || -1) + 1
52
+ self.status_type ||= self.class.status_types.first
53
+ end
54
+
55
+ end
56
+
57
+ # Instance Methods
58
+
59
+ def to_s
60
+ title.presence || 'New Membership Status'
61
+ end
62
+
63
+ def individual?
64
+ status_type == 'Individual'
65
+ end
66
+
67
+ def organization?
68
+ status_type == 'Organization'
69
+ end
70
+
71
+ end
@@ -34,7 +34,7 @@ module Effective
34
34
  validates :position, presence: true
35
35
  validates :employer, presence: true
36
36
  validates :start_on, presence: true
37
- validates :end_on, presence: true
37
+ validates :end_on, presence: true, unless: -> { still_work_here? }
38
38
  validates :level, presence: true, inclusion: { in: LEVELS }
39
39
  validates :months, presence: true
40
40
 
@@ -7,6 +7,9 @@ module Effective
7
7
  has_many :membership_categories, -> { order(:id) }, inverse_of: :membership, dependent: :delete_all
8
8
  accepts_nested_attributes_for :membership_categories
9
9
 
10
+ has_many :membership_statuses, -> { order(:id) }, inverse_of: :membership, dependent: :delete_all
11
+ accepts_nested_attributes_for :membership_statuses
12
+
10
13
  log_changes(to: :owner) if respond_to?(:log_changes)
11
14
 
12
15
  effective_resource do
@@ -74,7 +77,8 @@ module Effective
74
77
  summary = [
75
78
  owner.to_s,
76
79
  'is',
77
- (categories.to_sentence),
80
+ (statuses.to_sentence if statuses.present?),
81
+ (categories.to_sentence if categories.present?),
78
82
  'member',
79
83
  "##{number_was}",
80
84
  "who joined #{joined_on&.strftime('%F') || '-'}",
@@ -85,6 +89,8 @@ module Effective
85
89
  (summary + '.').html_safe
86
90
  end
87
91
 
92
+ ## Membership Categories
93
+
88
94
  # We can't use the polymorphic has_many. So this is a helper.
89
95
  def categories
90
96
  membership_categories.reject(&:marked_for_destruction?).map(&:category)
@@ -96,12 +102,12 @@ module Effective
96
102
 
97
103
  # We might want to use singular memberships.
98
104
  def category
99
- raise('expected singular usage but there are more than one membership') if categories.length > 1
105
+ raise('expected singular usage but there are more than one membership category') if categories.length > 1
100
106
  categories.first
101
107
  end
102
108
 
103
109
  def category_id
104
- raise('expected singular usage but there are more than one membership') if categories.length > 1
110
+ raise('expected singular usage but there are more than one membership category') if categories.length > 1
105
111
  categories.first.id
106
112
  end
107
113
 
@@ -115,6 +121,38 @@ module Effective
115
121
  membership_category(category: category) || membership_categories.build(category: category)
116
122
  end
117
123
 
124
+ ## Membership Statuses
125
+
126
+ # We can't use the polymorphic has_many. So this is a helper.
127
+ def statuses
128
+ membership_statuses.reject(&:marked_for_destruction?).map(&:status)
129
+ end
130
+
131
+ def status_ids
132
+ membership_statuses.reject(&:marked_for_destruction?).map(&:status_id)
133
+ end
134
+
135
+ # We might want to use singular memberships.
136
+ def status
137
+ raise('expected singular usage but there are more than one membership status') if statuses.length > 1
138
+ statuses.first
139
+ end
140
+
141
+ def status_id
142
+ raise('expected singular usage but there are more than one membership status') if statuses.length > 1
143
+ statuses.first.id
144
+ end
145
+
146
+ def membership_status(status:)
147
+ raise('expected a status') unless status.class.respond_to?(:effective_memberships_status?)
148
+ membership_statuses.find { |ms| ms.status_id == status.id && ms.status_type == status.class.name }
149
+ end
150
+
151
+ # find or build
152
+ def build_membership_status(status:)
153
+ membership_status(status: status) || membership_statuses.build(status: status)
154
+ end
155
+
118
156
  def good_standing?
119
157
  !bad_standing?
120
158
  end
@@ -22,16 +22,15 @@ module Effective
22
22
  serialize :categories, Array
23
23
  serialize :category_ids, Array
24
24
 
25
+ serialize :statuses, Array
26
+ serialize :status_ids, Array
27
+
25
28
  scope :deep, -> { includes(:owner) }
26
29
  scope :sorted, -> { order(:start_on) }
27
30
 
28
31
  scope :removed, -> { where(removed: true) }
29
32
 
30
33
  validates :owner, presence: true
31
-
32
- # validates :categories, presence: true, unless: -> { removed? }
33
- # validates :category_ids, presence: true, unless: -> { removed? }
34
-
35
34
  validates :start_on, presence: true
36
35
 
37
36
  def to_s
@@ -44,6 +43,10 @@ module Effective
44
43
  category_ids.present? ? EffectiveMemberships.Category.where(id: category_ids) : []
45
44
  end
46
45
 
46
+ def membership_statuses
47
+ status_ids.present? ? EffectiveMemberships.Status.where(id: status_ids) : []
48
+ end
49
+
47
50
  def membership_category_ids
48
51
  membership_categories.map(&:id)
49
52
  end
@@ -53,5 +56,15 @@ module Effective
53
56
  assign_attributes(categories: categories.map(&:to_s), category_ids: categories.map(&:id))
54
57
  end
55
58
 
59
+ def membership_status_ids
60
+ membership_statuses.map(&:id)
61
+ end
62
+
63
+ def membership_status_ids=(ids)
64
+ statuses = EffectiveMemberships.Status.where(id: ids)
65
+ assign_attributes(statuses: statuses.map(&:to_s), status_ids: statuses.map(&:id))
66
+ end
67
+
68
+
56
69
  end
57
70
  end
@@ -0,0 +1,13 @@
1
+ module Effective
2
+ class MembershipStatus < ActiveRecord::Base
3
+ belongs_to :status, polymorphic: true
4
+ belongs_to :membership, polymorphic: true
5
+
6
+ log_changes(to: :membership) if respond_to?(:log_changes)
7
+
8
+ def to_s
9
+ status&.to_s || 'membership status'
10
+ end
11
+
12
+ end
13
+ end
@@ -12,13 +12,21 @@ module Effective
12
12
  # Bad Standing
13
13
  attr_accessor :bad_standing_reason
14
14
 
15
+ # Register
16
+ attr_accessor :status_id
17
+
15
18
  # Reclassify & Register
16
19
  attr_accessor :category_id
17
20
  attr_accessor :membership_number
18
21
  attr_accessor :skip_fees
19
22
 
23
+ # Status Change
24
+ attr_accessor :status_id
25
+ attr_accessor :status_remove_action
26
+
20
27
  # Assign
21
28
  attr_accessor :category_ids
29
+ attr_accessor :status_ids
22
30
 
23
31
  # Mark Fees Paid - Order Attributes
24
32
  attr_accessor :payment_provider
@@ -38,6 +46,10 @@ module Effective
38
46
  validates :category_id, presence: true,
39
47
  if: -> { current_action == :reclassify || current_action == :register }
40
48
 
49
+ # Status Change
50
+ validates :status_id, presence: true, if: -> { current_action == :status_change }
51
+
52
+ # Assign
41
53
  validates :category_ids, presence: true, if: -> { current_action == :assign }
42
54
 
43
55
  def to_s
@@ -46,7 +58,7 @@ module Effective
46
58
 
47
59
  def register!
48
60
  update!(current_action: :register)
49
- EffectiveMemberships.Registrar.register!(owner, to: category, number: membership_number.presence, skip_fees: skip_fees?)
61
+ EffectiveMemberships.Registrar.register!(owner, to: category, status: status, number: number, skip_fees: skip_fees?)
50
62
  end
51
63
 
52
64
  def reclassify!
@@ -54,9 +66,19 @@ module Effective
54
66
  EffectiveMemberships.Registrar.reclassify!(owner, to: category, skip_fees: skip_fees?)
55
67
  end
56
68
 
69
+ def status_change!
70
+ update!(current_action: :status_change)
71
+ EffectiveMemberships.Registrar.status_change!(owner, to: status)
72
+ end
73
+
74
+ def status_remove!
75
+ update!(current_action: :status_remove)
76
+ EffectiveMemberships.Registrar.status_remove!(owner)
77
+ end
78
+
57
79
  def assign!
58
80
  update!(current_action: :assign)
59
- EffectiveMemberships.Registrar.assign!(owner, categories: categories, number: membership_number.presence)
81
+ EffectiveMemberships.Registrar.assign!(owner, categories: categories, statuses: statuses, number: number)
60
82
  end
61
83
 
62
84
  def good_standing!
@@ -102,11 +124,23 @@ module Effective
102
124
  private
103
125
 
104
126
  def category
105
- EffectiveMemberships.Category.find(@category_id) if @category_id
127
+ EffectiveMemberships.Category.find(@category_id) if @category_id.present?
106
128
  end
107
129
 
108
130
  def categories
109
- EffectiveMemberships.Category.where(id: @category_ids) if @category_ids
131
+ EffectiveMemberships.Category.where(id: @category_ids) if @category_ids.present?
132
+ end
133
+
134
+ def status
135
+ EffectiveMemberships.Status.find(@status_id) if @status_id.present?
136
+ end
137
+
138
+ def statuses
139
+ EffectiveMemberships.Status.where(id: @status_ids) if @status_ids.present?
140
+ end
141
+
142
+ def number
143
+ membership_number.presence
110
144
  end
111
145
 
112
146
  def order_attributes
@@ -0,0 +1,7 @@
1
+ module Effective
2
+ class Status < ActiveRecord::Base
3
+ self.table_name = EffectiveMemberships.statuses_table_name.to_s
4
+
5
+ effective_memberships_status
6
+ end
7
+ end
@@ -1,54 +1 @@
1
- = tabs do
2
- - # Done applicants have the Applicant tab first. In progress ones the Status tab
3
- - if applicant.done?
4
- = tab 'Applicant' do
5
- .mb-4= render 'effective/applicants/summary', applicant: applicant, namespace: :admin
6
- = render 'effective/applicants/applicant', applicant: applicant, namespace: :admin
7
-
8
- = tab 'Status' do
9
- = render 'admin/applicants/status', applicant: applicant, namespace: :admin
10
-
11
- - if applicant.in_progress?
12
- = tab 'Status' do
13
- = render 'admin/applicants/status', applicant: applicant, namespace: :admin
14
-
15
- = tab 'Applicant' do
16
- .mb-4= render 'effective/applicants/summary', applicant: applicant, namespace: :admin
17
- = render 'effective/applicants/applicant', applicant: applicant, namespace: :admin
18
-
19
- - # Just normal tabs now
20
- - if applicant.was_submitted? && !applicant.was_approved?
21
- = tab 'Process' do
22
- = render 'admin/applicants/form_process', applicant: applicant
23
-
24
- - if applicant.applicant_references.present?
25
- = tab 'References' do
26
- .mb-4= render_inline_datatable(Admin::EffectiveApplicantReferencesDatatable.new(applicant: applicant))
27
-
28
- - if applicant.applicant_endorsements.present?
29
- = tab 'Endorsements' do
30
- .mb-4= render_inline_datatable(Admin::EffectiveApplicantEndorsementsDatatable.new(applicant: applicant))
31
-
32
- - if applicant.transcripts_required?
33
- = tab 'Transcripts' do
34
- = render 'admin/applicants/form_transcripts', applicant: applicant
35
-
36
- - if applicant.fees.present? || applicant.orders.present?
37
- = tab 'Fees' do
38
- .mb-4
39
- %h2 Fees
40
- - datatable = Admin::EffectiveFeesDatatable.new(applicant: applicant, total: false)
41
- = render_datatable(datatable, simple: true, inline: true)
42
-
43
- .mb-4
44
- %h2 Orders
45
- - datatable = Admin::EffectiveOrdersDatatable.new(parent: applicant, owner: applicant.owner, user: applicant.owner, total: false)
46
- = render_datatable(datatable, simple: true)
47
-
48
- - if applicant.owner.applicants.any? { |other| other.was_submitted? && other.id != applicant.id }
49
- = tab 'Other Applications' do
50
- = render_datatable(Admin::EffectiveApplicantsDatatable.new(owner: applicant.owner, except_id: applicant.id))
51
-
52
- - if applicant.persisted? && applicant.respond_to?(:log_changes_datatable)
53
- = tab 'Logs' do
54
- = render_inline_datatable(applicant.log_changes_datatable)
1
+ = render('admin/applicants/form_applicant', applicant: applicant)
@@ -0,0 +1,56 @@
1
+ = tabs do
2
+ - # Done applicants have the Applicant tab first. In progress ones the Status tab
3
+ - if applicant.done?
4
+ = tab 'Applicant' do
5
+ .mb-4= render 'effective/applicants/summary', applicant: applicant, namespace: :admin
6
+ = render 'effective/applicants/applicant', applicant: applicant, namespace: :admin
7
+
8
+ = tab 'Status' do
9
+ = render 'admin/applicants/status', applicant: applicant, namespace: :admin
10
+
11
+ - if applicant.in_progress?
12
+ = tab 'Status' do
13
+ = render 'admin/applicants/status', applicant: applicant, namespace: :admin
14
+
15
+ = tab 'Applicant' do
16
+ .mb-4= render 'effective/applicants/summary', applicant: applicant, namespace: :admin
17
+ = render 'effective/applicants/applicant', applicant: applicant, namespace: :admin
18
+
19
+ - # Just normal tabs now
20
+ - if applicant.was_submitted? && !applicant.was_approved?
21
+ = tab 'Process' do
22
+ = render 'admin/applicants/form_process', applicant: applicant
23
+
24
+ - if applicant.applicant_references.present?
25
+ = tab 'References' do
26
+ .mb-4= render_inline_datatable(Admin::EffectiveApplicantReferencesDatatable.new(applicant: applicant))
27
+
28
+ - if applicant.applicant_endorsements.present?
29
+ = tab 'Endorsements' do
30
+ .mb-4= render_inline_datatable(Admin::EffectiveApplicantEndorsementsDatatable.new(applicant: applicant))
31
+
32
+ - if applicant.transcripts_required?
33
+ = tab 'Transcripts' do
34
+ = render 'admin/applicants/form_transcripts', applicant: applicant
35
+
36
+ = yield
37
+
38
+ - if applicant.fees.present? || applicant.orders.present?
39
+ = tab 'Fees' do
40
+ .mb-4
41
+ %h2 Fees
42
+ - datatable = Admin::EffectiveFeesDatatable.new(applicant: applicant, total: false)
43
+ = render_datatable(datatable, simple: true, inline: true)
44
+
45
+ .mb-4
46
+ %h2 Orders
47
+ - datatable = Admin::EffectiveOrdersDatatable.new(parent: applicant, owner: applicant.owner, user: applicant.owner, total: false)
48
+ = render_datatable(datatable, simple: true)
49
+
50
+ - if applicant.owner.applicants.any? { |other| other.was_submitted? && other.id != applicant.id }
51
+ = tab 'Other Applications' do
52
+ = render_datatable(Admin::EffectiveApplicantsDatatable.new(owner: applicant.owner, except_id: applicant.id))
53
+
54
+ - if applicant.persisted? && applicant.respond_to?(:log_changes_datatable)
55
+ = tab 'Logs' do
56
+ = render_inline_datatable(applicant.log_changes_datatable)
@@ -11,7 +11,9 @@
11
11
 
12
12
  = f.date_field :end_on, hint: 'The end date of this period in history. Must be present for all past histories. Must be blank in the most recent history, unless membership removed.'
13
13
  = f.text_field :number, hint: 'The membership number'
14
+
14
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
+ = f.select :membership_status_ids, EffectiveMemberships.Status.all.sorted, label: 'Membership Statuses', hint: 'The membership status or statuses held during this period in history.'
15
17
 
16
18
  = f.check_box :bad_standing, hint: 'Membership in bad standing'
17
19
  = f.check_box :removed, hint: 'Membership removed'
@@ -1,10 +1,17 @@
1
1
  - registrar_action = Effective::RegistrarAction.new(current_user: current_user, owner: owner)
2
2
 
3
+ -# This form is great if we want to do multiple categories or statuses
4
+ -#.mb-4= render 'admin/registrar_actions/form_assign', registrar_action: registrar_action
5
+
3
6
  - if owner.membership.blank?
4
7
  .mb-4= render 'admin/registrar_actions/form_register', registrar_action: registrar_action
5
8
 
6
9
  - if owner.membership.present?
7
10
  .mb-4= render 'admin/registrar_actions/form_reclassify', registrar_action: registrar_action
11
+
12
+ - if owner.registrar_action_statuses(:status_change).present?
13
+ .mb-4= render 'admin/registrar_actions/form_status_change', registrar_action: registrar_action
14
+
8
15
  .mb-4= render 'admin/registrar_actions/form_bad_standing', registrar_action: registrar_action
9
16
  .mb-4= render 'admin/registrar_actions/form_fees_paid', registrar_action: registrar_action
10
17
  .mb-4= render 'admin/registrar_actions/form_remove', registrar_action: registrar_action
@@ -8,21 +8,41 @@
8
8
 
9
9
  - membership = f.object.owner.membership
10
10
 
11
+ - categories = f.object.owner.registrar_action_categories(:assign)
12
+ - statuses = f.object.owner.registrar_action_statuses(:assign)
13
+ - label = [('categories' if categories.present?), ('statuses' if statuses.present?)].join(' or ')
14
+
15
+ - if membership.present?
16
+ - f.object.category_ids = membership.category_ids
17
+ - f.object.status_ids = membership.status_ids
18
+
11
19
  %p.text-muted
12
- Assign to one or more categories.
20
+ Assign to #{label}.
21
+
22
+ - if categories.present?
23
+ = f.static_field :current_action, label: 'Current Categories' do
24
+ - Array(membership&.categories).each do |category|
25
+ %div= link_to(category, effective_memberships.edit_admin_category_path(category))
13
26
 
14
- = f.static_field :current_action, label: 'Current Categories' do
15
- - Array(membership&.categories).each do |category|
16
- %div= link_to(category, effective_memberships.edit_admin_category_path(category))
27
+ - if membership&.categories.blank?
28
+ None
17
29
 
18
- - if membership.blank?
19
- None
30
+ - if statuses.present?
31
+ = f.static_field :current_action, label: 'Current Statuses' do
32
+ - Array(membership&.statuses).each do |status|
33
+ %div= link_to(status, effective_memberships.edit_admin_status_path(status))
20
34
 
21
- = f.check_box :current_action, label: 'Yes, assign this member to categories'
35
+ - if membership&.statuses.blank?
36
+ None
37
+
38
+ = f.check_box :current_action, label: "Yes, assign this member to #{label}"
22
39
 
23
40
  = f.show_if :current_action, true do
24
- - categories = f.object.owner.registrar_action_categories(:assign)
25
- = f.select :category_ids, categories, label: 'Assign to', required: true, multiple: true
41
+ - if categories.present?
42
+ = f.select :category_ids, categories, label: 'Assign to', required: true, multiple: true
43
+
44
+ - if statuses.present?
45
+ = f.select :status_ids, statuses, label: false, required: true, multiple: true
26
46
 
27
47
  - if membership.present?
28
48
  %p The member will keep their existing membership number: #{membership.number}.
@@ -7,6 +7,8 @@
7
7
  = f.hidden_field :owner_type
8
8
 
9
9
  - period = EffectiveMemberships.Registrar.current_period
10
+ - categories = f.object.owner.registrar_action_categories(:register)
11
+ - statuses = f.object.owner.registrar_action_statuses(:register)
10
12
 
11
13
  %p.text-muted
12
14
  Register into a new category and optionally create fees.
@@ -17,8 +19,11 @@
17
19
  = f.check_box :current_action, label: 'Yes, register to a membership'
18
20
 
19
21
  = f.show_if :current_action, true do
20
- - categories = f.object.owner.registrar_action_categories(:register)
21
- = f.select :category_id, categories, label: 'Register to'
22
+ - if categories.present?
23
+ = f.select :category_id, categories, label: 'Register to'
24
+
25
+ - if statuses.present?
26
+ = f.select :status_id, statuses, label: false
22
27
 
23
28
  = f.text_field :membership_number, hint: "leave blank to assign the next number"
24
29
 
@@ -0,0 +1,41 @@
1
+ .card
2
+ .card-body
3
+ %h5.card-title Status Change
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
+ - period = EffectiveMemberships.Registrar.current_period
11
+
12
+ %p.text-muted
13
+ Change or remove a member's existing status.
14
+
15
+ = f.static_field :current_action, label: 'Current Status' do
16
+ = (membership.status || 'None').to_s
17
+
18
+ = f.check_box :current_action, label: 'Yes, change member status'
19
+
20
+ = f.show_if :current_action, true do
21
+ %p The member will keep their existing membership number: #{membership.number}.
22
+
23
+ - statuses = f.object.owner.registrar_action_statuses(:status_change) - membership.statuses
24
+ = f.select :status_id, statuses, label: 'Change status to', required: true
25
+
26
+ %p No fees will be created
27
+
28
+ = f.submit 'Change Status', border: false, center: true, 'data-confirm': "Really change #{f.object.owner}?"
29
+
30
+ - # Remove Action
31
+ - if membership.status.present?
32
+ = f.check_box :status_remove_action, label: "Yes, remove #{membership.status} status"
33
+
34
+ = f.show_if :status_remove_action, true do
35
+ %p The member will keep their existing membership number: #{membership.number}
36
+
37
+ %p This action will remove the #{membership.status} status
38
+
39
+ %p No fees will be created
40
+
41
+ = f.submit 'Remove Status', border: false, center: true, 'data-confirm': "Really remove status #{f.object.owner}?"
@@ -0,0 +1,8 @@
1
+ = tabs do
2
+ = tab 'Status' do
3
+ = render 'admin/statuses/form_status', status: status
4
+
5
+ - if status.persisted?
6
+ - if status.respond_to?(:log_changes_datatable)
7
+ = tab 'Logs' do
8
+ = render_inline_datatable(status.log_changes_datatable)
@@ -0,0 +1,9 @@
1
+ = effective_form_with(model: [:admin, status], engine: true) do |f|
2
+ = f.text_field :title
3
+
4
+ = f.select :status_type, f.object.class.status_types
5
+
6
+ - if f.object.class.statuses.present?
7
+ = f.select :status, f.object.class.statuses
8
+
9
+ = f.submit
@@ -16,6 +16,7 @@
16
16
  = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
17
17
  = f.hidden_field :id
18
18
 
19
+ = f.hidden_field :stream, value: nil
19
20
  = f.hidden_field :organization_id, value: nil
20
21
  = f.hidden_field :organization_type, value: nil
21
22
  = f.hidden_field :category_type, value: EffectiveMemberships.Category.name
@@ -5,6 +5,7 @@ EffectiveMemberships.setup do |config|
5
5
  config.fee_payments_table_name = :fee_payments
6
6
  config.organizations_table_name = :organizations
7
7
  config.representatives_table_name = :representatives
8
+ config.statuses_table_name = :statuses
8
9
 
9
10
  # Layout Settings
10
11
  # Configure the Layout per controller, or all at once
@@ -17,8 +18,11 @@ EffectiveMemberships.setup do |config|
17
18
  # config.category_class_name = 'Effective::Category'
18
19
  # config.applicant_class_name = 'Effective::Applicant'
19
20
  # config.applicant_review_class_name = 'Effective::ApplicantReview'
21
+ # config.fee_payment_class_name = 'Effective::FeePayment'
22
+ # config.membership_card_class_name = 'Effective::MembershipCard'
20
23
  # config.registrar_class_name = 'Effective::Registrar'
21
24
  # config.organization_class_name = 'Effective::Organization'
25
+ # config.status_class_name = 'Effective::Status'
22
26
 
23
27
  # Fee Categories
24
28
  # The defaults include: Applicant, Prorated, Renewal, Late, Admin
data/config/routes.rb CHANGED
@@ -46,7 +46,7 @@ EffectiveMemberships::Engine.routes.draw do
46
46
  end
47
47
 
48
48
  resources :fees
49
- resources :categories, except: [:show]
49
+ resources :categories, only: [:index, :edit, :update]
50
50
 
51
51
  resources :applicant_course_areas, except: [:show]
52
52
  resources :applicant_course_names, except: [:show]
@@ -62,6 +62,7 @@ EffectiveMemberships::Engine.routes.draw do
62
62
  end
63
63
 
64
64
  resources :representatives, except: [:show]
65
+ resources :statuses, only: [:index, :edit, :update]
65
66
  end
66
67
 
67
68
  end
@@ -65,6 +65,22 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
65
65
  add_index :categories, :title
66
66
  add_index :categories, :position
67
67
 
68
+ # Statuses
69
+ create_table :statuses do |t|
70
+ t.string :status_type # Individual or Organization
71
+
72
+ t.string :title
73
+ t.string :status # Freeform
74
+
75
+ t.integer :position
76
+
77
+ t.datetime :updated_at
78
+ t.datetime :created_at
79
+ end
80
+
81
+ add_index :statuses, :title
82
+ add_index :statuses, :position
83
+
68
84
  # Memberships
69
85
  create_table :memberships do |t|
70
86
  t.integer :owner_id
@@ -98,6 +114,15 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
98
114
  t.string :membership_type
99
115
  end
100
116
 
117
+ # Membership Statuses Join table
118
+ create_table :membership_statuses do |t|
119
+ t.integer :status_id
120
+ t.string :status_type
121
+
122
+ t.integer :membership_id
123
+ t.string :membership_type
124
+ end
125
+
101
126
  # Membership Histories
102
127
  create_table :membership_histories do |t|
103
128
  t.integer :owner_id
@@ -106,6 +131,9 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
106
131
  t.text :categories
107
132
  t.text :category_ids
108
133
 
134
+ t.text :statuses
135
+ t.text :status_ids
136
+
109
137
  t.date :start_on
110
138
  t.date :end_on
111
139
 
@@ -182,6 +210,9 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
182
210
  t.integer :from_category_id
183
211
  t.string :from_category_type
184
212
 
213
+ t.integer :from_status_id
214
+ t.string :from_status_type
215
+
185
216
  # Acts as Statused
186
217
  t.string :status
187
218
  t.text :status_steps
@@ -12,6 +12,7 @@ module EffectiveMemberships
12
12
  ActiveSupport.on_load :active_record do
13
13
  ActiveRecord::Base.extend(EffectiveMembershipsOwner::Base)
14
14
  ActiveRecord::Base.extend(EffectiveMembershipsCategory::Base)
15
+ ActiveRecord::Base.extend(EffectiveMembershipsStatus::Base)
15
16
 
16
17
  ActiveRecord::Base.extend(EffectiveMembershipsUser::Base)
17
18
  ActiveRecord::Base.extend(EffectiveMembershipsOrganization::Base)
@@ -1,3 +1,3 @@
1
1
  module EffectiveMemberships
2
- VERSION = '0.4.16'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -6,8 +6,8 @@ module EffectiveMemberships
6
6
 
7
7
  def self.config_keys
8
8
  [
9
- :categories_table_name, :applicants_table_name, :applicant_reviews_table_name, :fee_payments_table_name, :organizations_table_name, :representatives_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,
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,
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,14 +40,13 @@ module EffectiveMemberships
40
40
  membership_card_class_name&.constantize || Effective::MembershipCard
41
41
  end
42
42
 
43
- def self.applicant_reviews?
44
- applicant_reviews == true
43
+ def self.Status
44
+ status_class_name&.constantize || Effective::Status
45
45
  end
46
46
 
47
47
  # Singleton
48
48
  def self.Registrar
49
- klass = registrar_class_name&.constantize || Effective::Registrar
50
- klass.new
49
+ (registrar_class_name&.constantize || Effective::Registrar).new
51
50
  end
52
51
 
53
52
  def self.mailer_class
@@ -66,4 +65,8 @@ module EffectiveMemberships
66
65
  ['Admin']
67
66
  end
68
67
 
68
+ def self.applicant_reviews?
69
+ applicant_reviews == true
70
+ end
71
+
69
72
  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.4.16
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-06 00:00:00.000000000 Z
11
+ date: 2022-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -267,6 +267,7 @@ files:
267
267
  - app/controllers/admin/organizations_controller.rb
268
268
  - app/controllers/admin/registrar_actions_controller.rb
269
269
  - app/controllers/admin/representatives_controller.rb
270
+ - app/controllers/admin/statuses_controller.rb
270
271
  - app/controllers/effective/applicant_endorsements_controller.rb
271
272
  - app/controllers/effective/applicant_references_controller.rb
272
273
  - app/controllers/effective/applicants_controller.rb
@@ -287,6 +288,7 @@ files:
287
288
  - app/datatables/admin/effective_memberships_datatable.rb
288
289
  - app/datatables/admin/effective_organizations_datatable.rb
289
290
  - app/datatables/admin/effective_representatives_datatable.rb
291
+ - app/datatables/admin/effective_statuses_datatable.rb
290
292
  - app/datatables/effective_applicant_courses_datatable.rb
291
293
  - app/datatables/effective_applicant_educations_datatable.rb
292
294
  - app/datatables/effective_applicant_endorsements_datatable.rb
@@ -308,6 +310,7 @@ files:
308
310
  - app/models/concerns/effective_memberships_organization.rb
309
311
  - app/models/concerns/effective_memberships_owner.rb
310
312
  - app/models/concerns/effective_memberships_registrar.rb
313
+ - app/models/concerns/effective_memberships_status.rb
311
314
  - app/models/concerns/effective_memberships_user.rb
312
315
  - app/models/effective/applicant.rb
313
316
  - app/models/effective/applicant_course.rb
@@ -326,10 +329,12 @@ files:
326
329
  - app/models/effective/membership_card.rb
327
330
  - app/models/effective/membership_category.rb
328
331
  - app/models/effective/membership_history.rb
332
+ - app/models/effective/membership_status.rb
329
333
  - app/models/effective/organization.rb
330
334
  - app/models/effective/registrar.rb
331
335
  - app/models/effective/registrar_action.rb
332
336
  - app/models/effective/representative.rb
337
+ - app/models/effective/status.rb
333
338
  - app/views/admin/applicant_course_areas/_form.html.haml
334
339
  - app/views/admin/applicant_course_areas/_form_applicant_course_area.html.haml
335
340
  - app/views/admin/applicant_course_areas/index.html.haml
@@ -337,6 +342,7 @@ files:
337
342
  - app/views/admin/applicant_endorsements/_applicant_endorsement.html.haml
338
343
  - app/views/admin/applicant_references/_applicant_reference.html.haml
339
344
  - app/views/admin/applicants/_form.html.haml
345
+ - app/views/admin/applicants/_form_applicant.html.haml
340
346
  - app/views/admin/applicants/_form_approve.html.haml
341
347
  - app/views/admin/applicants/_form_complete.html.haml
342
348
  - app/views/admin/applicants/_form_decline.html.haml
@@ -373,8 +379,11 @@ files:
373
379
  - app/views/admin/registrar_actions/_form_reclassify.html.haml
374
380
  - app/views/admin/registrar_actions/_form_register.html.haml
375
381
  - app/views/admin/registrar_actions/_form_remove.html.haml
382
+ - app/views/admin/registrar_actions/_form_status_change.html.haml
376
383
  - app/views/admin/representatives/_form.html.haml
377
384
  - app/views/admin/representatives/_user_fields.html.haml
385
+ - app/views/admin/statuses/_form.html.haml
386
+ - app/views/admin/statuses/_form_status.html.haml
378
387
  - app/views/admin/users/_col.html.haml
379
388
  - app/views/effective/applicant_endorsements/_applicant_endorsement.html.haml
380
389
  - app/views/effective/applicant_endorsements/_datatable_actions.html.haml