effective_memberships 0.1.20 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2cbe81e83cfde35743c82714d341ec6630d11999b89efb6dba5d4fe63d1f2b3
4
- data.tar.gz: 33504263d9b05a49d2811ac8b187cbf4bacae380b7d1dc93570a205fa2764313
3
+ metadata.gz: 2f8c32ed9ffd17db6a7c0826bfb9eb72615ec3e7049adbb9f18b99cb8957c905
4
+ data.tar.gz: 5685ca74db5bd94d757c6a209b135160a015fddd2900ba6d66b55976a495eaa9
5
5
  SHA512:
6
- metadata.gz: 1274f2edc9e0879b19bd1353d57af7baa9a5519ab489004d833a6371f51dbb3e93e3bc90489dedfa0046e5a83a55016170d3db1079d05cc250ad929a0ba4df24
7
- data.tar.gz: '08bc66d42dd4e1bf51d3d739489db673f4b1166451bb40d7c7a20b212ac76a4eeb4d6c00ca32486199634dc90c904bca0bf694e95dc5e1128b4a5a397264778f'
6
+ metadata.gz: 9590986cb17a70c70183acfa7a4bf7dbc23959fd9482058737a916f767feedeb77a14444f2b6f1ed9631bb1c4d7d70affaf46e38f879a0af1a6acdc4ac480c94
7
+ data.tar.gz: 4dc42f6e02b50adad0c8c714ee64e97ef398828a391736db51348fed377ced92784cf116f21f147edec98eea06c365925d4d0efce559001c839d2ad89826e7ca
@@ -16,10 +16,6 @@ module Effective
16
16
  end
17
17
  end
18
18
 
19
- before_render(only: :show, if: -> { step == :checkout }) do
20
- resource.ready!
21
- end
22
-
23
19
  after_save do
24
20
  flash.now[:success] = ''
25
21
  end
@@ -16,10 +16,6 @@ module Effective
16
16
  end
17
17
  end
18
18
 
19
- before_render(only: :show, if: -> { step == :checkout }) do
20
- resource.ready!
21
- end
22
-
23
19
  after_save do
24
20
  flash.now[:success] = ''
25
21
  end
@@ -60,6 +60,8 @@ module EffectiveMembershipsApplicant
60
60
  submitted: 'Submitted'
61
61
  )
62
62
 
63
+ acts_as_purchasable_wizard
64
+
63
65
  log_changes(except: :wizard_steps) if respond_to?(:log_changes)
64
66
 
65
67
  has_many_attached :applicant_files
@@ -247,12 +249,6 @@ module EffectiveMembershipsApplicant
247
249
  validates :declare_truth, acceptance: true
248
250
  end
249
251
 
250
- # Billing Step
251
- validate(if: -> { current_step == :billing && owner.present? }) do
252
- self.errors.add(:base, "must have a billing address") unless owner.billing_address.present?
253
- self.errors.add(:base, "must have an email") unless owner.email.present?
254
- end
255
-
256
252
  # Admin Approve
257
253
  validate(if: -> { approved_membership_date.present? }) do
258
254
  if approved_membership_date.to_date > Time.zone.now.to_date
@@ -288,10 +284,47 @@ module EffectiveMembershipsApplicant
288
284
  end
289
285
  end
290
286
 
291
- after_purchase do |_|
292
- raise('expected submit_order to be purchased') unless submit_order&.purchased?
293
- submit_purchased!
287
+ # All Fees and Orders
288
+ def submit_fees
289
+ fees.select { |fee| fee.applicant_submit_fee? }
290
+ end
291
+
292
+ def submit_order
293
+ orders.find { |order| order.purchasables.any?(&:applicant_submit_fee?) }
294
+ end
295
+
296
+ def submit_fee_qb_item_name
297
+ 'Applicant'
294
298
  end
299
+
300
+ def find_or_build_submit_fees
301
+ return submit_fees if submit_fees.present?
302
+
303
+ fees.build(
304
+ owner: owner,
305
+ fee_type: 'Applicant',
306
+ category: category,
307
+ price: category.applicant_fee,
308
+ qb_item_name: submit_fee_qb_item_name()
309
+ )
310
+
311
+ submit_fees
312
+ end
313
+
314
+ # Draft -> Submitted requirements
315
+ def submit!
316
+ raise('already submitted') if was_submitted?
317
+ raise('expected a purchased order') unless submit_order&.purchased?
318
+
319
+ after_commit do
320
+ applicant_references.each { |reference| reference.notify! if reference.submitted? }
321
+ end
322
+
323
+ wizard_steps[:checkout] ||= Time.zone.now
324
+ wizard_steps[:submitted] = Time.zone.now
325
+ submitted!
326
+ end
327
+
295
328
  end
296
329
 
297
330
  # Instance Methods
@@ -330,10 +363,6 @@ module EffectiveMembershipsApplicant
330
363
  approved? || declined?
331
364
  end
332
365
 
333
- def can_visit_step?(step)
334
- can_revisit_completed_steps(step)
335
- end
336
-
337
366
  def summary
338
367
  case status_was
339
368
  when 'draft'
@@ -435,96 +464,9 @@ module EffectiveMembershipsApplicant
435
464
  category&.min_applicant_files.to_i
436
465
  end
437
466
 
438
- # All Fees and Orders
439
- def submit_fees
440
- fees.select { |fee| fee.applicant_submit_fee? }
441
- end
442
-
443
- def submit_order
444
- orders.find { |order| order.purchasables.any?(&:applicant_submit_fee?) }
445
- end
446
-
447
- def find_or_build_submit_fees
448
- return submit_fees if submit_fees.present?
449
-
450
- fees.build(
451
- owner: owner,
452
- fee_type: 'Applicant',
453
- category: category,
454
- price: category.applicant_fee
455
- )
456
-
457
- submit_fees
458
- end
459
-
460
- def find_or_build_submit_order
461
- order = submit_order || orders.build(user: owner)
462
- fees = submit_fees()
463
-
464
- # Adds fees, but does not overwrite any existing price.
465
- fees.each do |fee|
466
- order.add(fee) unless order.purchasables.include?(fee)
467
- end
468
-
469
- order.purchasables.each do |purchasable|
470
- order.remove(purchasable) unless fees.include?(purchasable)
471
- end
472
-
473
- # From Billing Step
474
- order.billing_address = owner.billing_address if owner.billing_address.present?
475
-
476
- order.save
477
-
478
- order
479
- end
480
-
481
- # Should be indempotent.
482
- def build_submit_fees_and_order
483
- return false if was_submitted?
484
-
485
- fees = find_or_build_submit_fees()
486
- raise('already has purchased submit fees') if fees.any? { |fee| fee.purchased? }
487
-
488
- order = find_or_build_submit_order()
489
- raise('already has purchased submit order') if order.purchased?
490
-
491
- true
492
- end
493
-
494
- # Owner clicks on the Billing step. Next step is Checkout
495
- def billing!
496
- ready!
497
- end
498
-
499
- # Ready to check out
500
- def ready!
501
- build_submit_fees_and_order
502
- save!
503
- end
504
-
505
- # Called automatically via after_purchase hook above
506
- def submit_purchased!
507
- return false if was_submitted?
508
-
509
- wizard_steps[:checkout] = Time.zone.now
510
- submit!
511
- end
512
-
513
- # Draft -> Submitted requirements
514
- def submit!
515
- raise('already submitted') if was_submitted?
516
- raise('expected a purchased order') unless submit_order&.purchased?
517
-
518
- after_commit do
519
- applicant_references.each { |reference| reference.notify! if reference.submitted? }
520
- end
521
-
522
- wizard_steps[:checkout] ||= Time.zone.now
523
- wizard_steps[:submitted] = Time.zone.now
524
- submitted!
525
- end
526
-
527
- # Submitted -> Completed requirements
467
+ # The submit! method used to be here
468
+ # But it needs to be inside the included do block
469
+ # So see above. Sorry.
528
470
 
529
471
  def applicant_references_required?
530
472
  min_applicant_references > 0
@@ -44,6 +44,8 @@ module EffectiveMembershipsFeePayment
44
44
  submitted: 'Submitted'
45
45
  )
46
46
 
47
+ acts_as_purchasable_wizard
48
+
47
49
  log_changes(except: :wizard_steps) if respond_to?(:log_changes)
48
50
 
49
51
  # Declarations Step
@@ -110,12 +112,6 @@ module EffectiveMembershipsFeePayment
110
112
  validates :declare_truth, acceptance: true
111
113
  end
112
114
 
113
- # Billing Step
114
- validate(if: -> { current_step == :billing && owner.present? }) do
115
- self.errors.add(:base, "must have a billing address") unless owner.billing_address.present?
116
- self.errors.add(:base, "must have an email") unless owner.email.present?
117
- end
118
-
119
115
  # Clear required steps memoization
120
116
  after_save { @_required_steps = nil }
121
117
 
@@ -135,13 +131,30 @@ module EffectiveMembershipsFeePayment
135
131
  end
136
132
  end
137
133
 
138
- after_purchase do |_order|
139
- raise('expected submit_order to be purchased') unless submit_order&.purchased?
134
+ # All Fees and Orders
135
+ # Overriding acts_as_purchasable_wizard
136
+ def outstanding_fees
137
+ owner&.outstanding_fee_payment_fees
138
+ end
139
+
140
+ def submit_fees
141
+ fees
142
+ end
143
+
144
+ def submit_order
145
+ orders.first
146
+ end
147
+
148
+ # We take over the owner's outstanding fees.
149
+ def find_or_build_submit_fees
150
+ Array(outstanding_fees).each { |fee| fees << fee unless fees.include?(fee) }
151
+ submit_fees
152
+ end
140
153
 
141
- submit_purchased!
142
- after_submit_purchased!
154
+ def after_submit_purchased!
143
155
  EffectiveMemberships.Registrar.fee_payment_purchased!(owner)
144
156
  end
157
+
145
158
  end
146
159
 
147
160
  def to_s
@@ -157,14 +170,6 @@ module EffectiveMembershipsFeePayment
157
170
  submitted?
158
171
  end
159
172
 
160
- def can_visit_step?(step)
161
- can_revisit_completed_steps(step)
162
- end
163
-
164
- def outstanding_fees
165
- owner&.outstanding_fee_payment_fees
166
- end
167
-
168
173
  def select!
169
174
  reset!
170
175
  end
@@ -200,83 +205,4 @@ module EffectiveMembershipsFeePayment
200
205
  owner.representatives.any?(&:marked_for_destruction?)
201
206
  end
202
207
 
203
- # All Fees and Orders
204
- def submit_fees
205
- fees
206
- end
207
-
208
- def submit_order
209
- orders.first
210
- end
211
-
212
- # We take over the owner's outstanding fees.
213
- def find_or_build_submit_fees
214
- Array(outstanding_fees).each { |fee| fees << fee unless fees.include?(fee) }
215
- submit_fees
216
- end
217
-
218
- def find_or_build_submit_order
219
- order = submit_order || orders.build(user: owner)
220
- fees = submit_fees()
221
-
222
- fees.each do |fee|
223
- order.add(fee) unless order.purchasables.include?(fee)
224
- end
225
-
226
- order.purchasables.each do |purchasable|
227
- order.remove(purchasable) unless fees.include?(purchasable)
228
- end
229
-
230
- order.billing_address = owner.billing_address if owner.billing_address.present?
231
-
232
- order.save
233
-
234
- order
235
- end
236
-
237
- # Should be indempotent.
238
- def build_submit_fees_and_order
239
- return false if was_submitted?
240
-
241
- fees = find_or_build_submit_fees()
242
- raise('already has purchased submit fees') if fees.any? { |fee| fee.purchased? }
243
-
244
- order = find_or_build_submit_order()
245
- raise('already has purchased submit order') if order.purchased?
246
-
247
- true
248
- end
249
-
250
- # Owner clicks on the Billing Submit. Next step is Checkout
251
- def billing!
252
- ready!
253
- end
254
-
255
- def ready!
256
- build_submit_fees_and_order
257
- save!
258
- end
259
-
260
- # Called automatically via after_purchase hook above
261
- def submit_purchased!
262
- return false if was_submitted?
263
-
264
- wizard_steps[:checkout] = Time.zone.now
265
- submit!
266
- end
267
-
268
- # A hook to extend
269
- def after_submit_purchased!
270
- end
271
-
272
- # Draft -> Submitted
273
- def submit!
274
- raise('already submitted') if was_submitted?
275
- raise('expected a purchased order') unless submit_order&.purchased?
276
-
277
- wizard_steps[:checkout] ||= Time.zone.now
278
- wizard_steps[:submitted] = Time.zone.now
279
- submitted!
280
- end
281
-
282
208
  end
@@ -21,6 +21,8 @@ module EffectiveMembershipsOwner
21
21
  end
22
22
 
23
23
  included do
24
+ acts_as_role_restricted unless respond_to?(:acts_as_role_restricted?)
25
+
24
26
  # App scoped
25
27
  has_many :applicants, -> { order(:id) }, inverse_of: :owner, as: :owner
26
28
  has_many :fee_payments, -> { order(:id) }, inverse_of: :owner, as: :owner
@@ -57,6 +59,31 @@ module EffectiveMembershipsOwner
57
59
  owners || [self]
58
60
  end
59
61
 
62
+ # This is the calculated way of determining if an owner is a member or not.
63
+ # The correct way to check for membership is: current_user.is?(:member)
64
+ def membership_present?
65
+ individual_membership_present? || organization_membership_present?
66
+ end
67
+
68
+ def individual_membership_present?
69
+ membership.present? && !membership.marked_for_destruction?
70
+ end
71
+
72
+ def organization_membership_present?(except: nil)
73
+ return false unless self.class.respond_to?(:effective_organizations_user?)
74
+ organizations.any? { |organization| organization != except && organization.membership_present? }
75
+ end
76
+
77
+ def assign_member_role
78
+ membership_present? ? add_role(:member) : remove_role(:member)
79
+ end
80
+
81
+ # This can be called by a script to recalculate the owner role based on current membership
82
+ def update_member_role!
83
+ assign_member_role
84
+ save!
85
+ end
86
+
60
87
  def outstanding_fee_payment_owners
61
88
  effective_memberships_owners.select { |owner| !owner.membership_fees_paid? }
62
89
  end
@@ -230,6 +257,7 @@ module EffectiveMembershipsOwner
230
257
  fee
231
258
  end
232
259
 
260
+ # Called by the registrar.
233
261
  def update_membership_status!
234
262
  raise('expected membership to be present') unless membership.present?
235
263
 
@@ -37,7 +37,7 @@ module EffectiveMembershipsRegistrar
37
37
  categories = Array(categories)
38
38
 
39
39
  raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
40
- raise('expecting a membership category') unless categories.all? { |cat| cat.class.respond_to?(:effective_memberships_category?) }
40
+ raise('expecting a membership category') unless categories.present? && categories.all? { |cat| cat.class.respond_to?(:effective_memberships_category?) }
41
41
 
42
42
  # Default Date and next number
43
43
  date ||= Time.zone.now
@@ -73,6 +73,9 @@ module EffectiveMembershipsRegistrar
73
73
  save!(owner, date: date)
74
74
  end
75
75
 
76
+ # Assign member role
77
+ add_member_role(owner)
78
+
76
79
  owner.update_membership_status!
77
80
  end
78
81
 
@@ -113,6 +116,9 @@ module EffectiveMembershipsRegistrar
113
116
  raise('already has purchased prorated fee') if fee.purchased?
114
117
  end
115
118
 
119
+ # Assign member role
120
+ add_member_role(owner)
121
+
116
122
  # Save owner
117
123
  save!(owner, date: date)
118
124
  end
@@ -163,6 +169,9 @@ module EffectiveMembershipsRegistrar
163
169
  owner.outstanding_fee_payment_fees.each { |fee| fee.mark_for_destruction }
164
170
  owner.outstanding_fee_payment_orders.each { |order| order.mark_for_destruction }
165
171
 
172
+ # Remove member role
173
+ remove_member_role(owner)
174
+
166
175
  save!(owner, date: date)
167
176
  end
168
177
 
@@ -293,6 +302,34 @@ module EffectiveMembershipsRegistrar
293
302
 
294
303
  protected
295
304
 
305
+ def add_member_role(owner)
306
+ owner.add_role(:member)
307
+
308
+ if owner.class.respond_to?(:effective_organizations_organization?)
309
+ organization = owner
310
+ organization.representatives.each { |representative| representative.user.add_role(:member) }
311
+ end
312
+
313
+ true
314
+ end
315
+
316
+ def remove_member_role(owner)
317
+ owner.remove_role(:member)
318
+
319
+ if owner.class.respond_to?(:effective_organizations_organization?)
320
+ organization = owner
321
+
322
+ organization.representatives.each do |representative|
323
+ user = representative.user
324
+ member = user.individual_membership_present? || user.organization_membership_present?(except: organization)
325
+
326
+ user.remove_role(:member) if !member
327
+ end
328
+ end
329
+
330
+ true
331
+ end
332
+
296
333
  def save!(owner, date: Time.zone.now)
297
334
  owner.build_membership_history(start_on: date)
298
335
  owner.save!
@@ -107,8 +107,6 @@ module Effective
107
107
  EffectiveMemberships.custom_fee_types.include?(fee_type)
108
108
  end
109
109
 
110
- private
111
-
112
110
  def default_period
113
111
  EffectiveMemberships.Registrar.current_period
114
112
  end
@@ -131,7 +129,7 @@ module Effective
131
129
  end
132
130
 
133
131
  def default_qb_item_name
134
- category&.qb_item_name.presence || "#{fee_type} Fee"
132
+ category&.qb_item_name.presence || "#{fee_type}"
135
133
  end
136
134
 
137
135
  def default_tax_exempt
@@ -58,6 +58,7 @@ module Effective
58
58
  validates :number, presence: true, uniqueness: true
59
59
  validates :joined_on, presence: true
60
60
  validates :registration_on, presence: true
61
+ validates :membership_categories, presence: true
61
62
 
62
63
  validate(if: -> { owner.present? }) do
63
64
  self.errors.add(:owner_id, 'must be a memberships owner') unless owner.class.effective_memberships_owner?
@@ -6,6 +6,9 @@
6
6
  .row
7
7
  .col-lg-3= f.price_field :applicant_fee
8
8
 
9
+ .row
10
+ .col-lg-3= f.text_field :qb_item_name, label: "Quickbooks Item Name"
11
+
9
12
  %p Charged to join, based on the month of approval:
10
13
 
11
14
  .row
@@ -32,7 +32,7 @@ EffectiveMemberships.setup do |config|
32
32
  # config.deliver_method = :deliver_later
33
33
 
34
34
  # Default layout
35
- config.mailer_layout = 'effective_memberships_mailer_layout'
35
+ # config.mailer_layout = 'effective_memberships_mailer_layout'
36
36
 
37
37
  # Default From
38
38
  config.mailer_sender = "no-reply@example.com"
@@ -1,3 +1,3 @@
1
1
  module EffectiveMemberships
2
- VERSION = '0.1.20'
2
+ VERSION = '0.2.0'
3
3
  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.1.20
4
+ version: 0.2.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-01-11 00:00:00.000000000 Z
11
+ date: 2022-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: effective_roles
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: wicked
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +178,20 @@ dependencies:
164
178
  - - ">="
165
179
  - !ruby/object:Gem::Version
166
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: effective_organizations
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
167
195
  - !ruby/object:Gem::Dependency
168
196
  name: effective_developer
169
197
  requirement: !ruby/object:Gem::Requirement