effective_memberships 0.5.0 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e719afd32d55f610b718c370497cceb43760450cfca029e618efc99dd73a8d28
4
- data.tar.gz: 4564cce2a02072ad8db4c81b4c7507b522a4a1a03683899797d9c2d8aa1f89b5
3
+ metadata.gz: 20013e5735497e62dd4c8224ef8fe0a97f9cc12d285871541cea4ceaefa13796
4
+ data.tar.gz: 0b652f51e8b7ac62c99c11b7a6a5fe6961e8b79a579048aaa7e06b8ad5dca204
5
5
  SHA512:
6
- metadata.gz: 0d711bedd67af762919f71c2d52a3848c70c14af8e756cab24018a4b45d616f92f42510329f53c2e5f886bfceb248e522a9d87f62a89f24641add4b208f8d0c8
7
- data.tar.gz: 0f11ce742fc500785d1203c87fe3dae05d855deb4f7a51953de4a6efe3e1dff4dc12b06f72631da580cdda039552265abcf2d3c94bdc0291fb787e76c69773c8
6
+ metadata.gz: bde5324d4cadb8f64caca5fa6cc8eb0910015514df5bcad58170a78be4e27e736fcbd1d306b3fa19f919a49183d4a0e940b82b17d2f7401d6d87927b5c9a36b6
7
+ data.tar.gz: b3cd7c41dc00b22804ab6e8df8904807b0099758ce479807f682e2686cd5c64362fd0be534af0181868a29f8c2935e4f7dd7c72d6b1d2f3e56f78ebcc543d2c2
@@ -0,0 +1,20 @@
1
+ # For the Endorser's dashboard to display endorsements to complete
2
+ class EffectiveApplicantEndorsersDatatable < Effective::Datatable
3
+
4
+ datatable do
5
+ length :all
6
+
7
+ col :created_at
8
+ col :applicant
9
+
10
+ actions_col do |applicant_endorsement|
11
+ dropdown_link_to 'Show', effective_memberships.applicant_endorsement_path(applicant_endorsement)
12
+ end
13
+
14
+ end
15
+
16
+ collection do
17
+ Effective::ApplicantEndorsement.deep.needs_endorser.where(endorser: current_user)
18
+ end
19
+
20
+ end
@@ -22,7 +22,7 @@ module EffectiveMembershipsApplicant
22
22
  end
23
23
 
24
24
  def categories
25
- ['Apply to Join', 'Apply to Reclassify']
25
+ ['Apply to Join', 'Apply to Reclassify', 'Apply for Reinstatement']
26
26
  end
27
27
 
28
28
  def transcripts_statuses
@@ -51,6 +51,7 @@ module EffectiveMembershipsApplicant
51
51
  select: 'Select Application Type',
52
52
  demographics: 'Demographics', # Individual only. Users fields.
53
53
  organization: 'Organization', # Organization only. Organization fields.
54
+ reinstatement: 'Reinstatement', # Apply for Reinstatement only
54
55
  education: 'Education',
55
56
  course_amounts: 'Courses',
56
57
  equivalences: 'Equivalent Memberships',
@@ -80,6 +81,9 @@ module EffectiveMembershipsApplicant
80
81
  attr_accessor :declare_code_of_ethics
81
82
  attr_accessor :declare_truth
82
83
 
84
+ # Reinstatements Step
85
+ attr_accessor :declare_reinstatement
86
+
83
87
  # Admin Approve Step
84
88
  attr_accessor :approved_membership_number
85
89
  attr_accessor :approved_membership_date
@@ -93,7 +97,10 @@ module EffectiveMembershipsApplicant
93
97
 
94
98
  belongs_to :category, polymorphic: true, optional: true
95
99
 
100
+ # Required for Apply to Reclassify
96
101
  belongs_to :from_category, polymorphic: true, optional: true
102
+
103
+ # Required for Apply for Reinstatement
97
104
  belongs_to :from_status, polymorphic: true, optional: true
98
105
 
99
106
  has_many :applicant_reviews, -> { order(:id) }, as: :applicant, inverse_of: :applicant, dependent: :destroy
@@ -171,7 +178,7 @@ module EffectiveMembershipsApplicant
171
178
  timestamps
172
179
  end
173
180
 
174
- scope :deep, -> { includes(:user, :organization, :category, :from_category, :orders) }
181
+ scope :deep, -> { includes(:user, :organization, :category, :from_category, :from_status, :orders) }
175
182
  scope :sorted, -> { order(:id) }
176
183
 
177
184
  scope :in_progress, -> { where.not(status: [:approved, :declined]) }
@@ -186,7 +193,7 @@ module EffectiveMembershipsApplicant
186
193
 
187
194
  # Set Apply to Join or Reclassification
188
195
  before_validation(if: -> { (new_record? || current_step == :select) && owner.present? }) do
189
- self.applicant_type = (owner.membership.blank? ? 'Apply to Join' : 'Apply to Reclassify')
196
+ self.applicant_type ||= can_apply_applicant_types_collection().first
190
197
  self.from_category = owner.membership&.category
191
198
  self.from_status = owner.membership&.status
192
199
  end
@@ -197,12 +204,18 @@ module EffectiveMembershipsApplicant
197
204
 
198
205
  # All Steps validations
199
206
  validates :user, presence: true
207
+
200
208
  validates :from_category, presence: true, if: -> { reclassification? }
209
+ validates :from_status, presence: true, if: -> { reinstatement? }
201
210
 
202
- validate(if: -> { reclassification? }) do
211
+ validate(if: -> { reclassification? && category_id.present? }) do
203
212
  errors.add(:category_id, "can't reclassify to existing category") if category_id == from_category_id
204
213
  end
205
214
 
215
+ validate(if: -> { reinstatement? && category_id.present? }) do
216
+ errors.add(:category_id, "must match existing category when reinstatement") unless category_id == from_category_id
217
+ end
218
+
206
219
  validate(if: -> { category.present? }) do
207
220
  self.errors.add(:organization_id, "can't be blank when organization category") if category.organization? && organization.blank?
208
221
  self.errors.add(:organization_id, "must be blank when individual category") if category.individual? && organization.present?
@@ -315,6 +328,12 @@ module EffectiveMembershipsApplicant
315
328
  validates :declare_truth, acceptance: true
316
329
  end
317
330
 
331
+ # Reinstatements step
332
+ with_options(if: -> { current_step == :reinstatement }) do
333
+ validates :declare_reinstatement, acceptance: true
334
+ end
335
+
336
+
318
337
  # Admin Approve
319
338
  validate(if: -> { approved_membership_date.present? }) do
320
339
  if approved_membership_date.to_date > Time.zone.now.to_date
@@ -340,16 +359,19 @@ module EffectiveMembershipsApplicant
340
359
  # This required_steps is defined inside the included do .. end block so it overrides the acts_as_wizard one.
341
360
  def required_steps
342
361
  return self.class.test_required_steps if Rails.env.test? && self.class.test_required_steps.present?
362
+ return self.class.all_wizard_steps if category.blank?
343
363
 
344
364
  @_required_steps ||= begin
345
- wizard_steps = self.class.all_wizard_steps
365
+ # All required
346
366
  required_steps = self.class.required_wizard_steps
347
367
 
348
- applicant_steps = Array(category&.applicant_wizard_steps)
368
+ # Based on current applicant
369
+ applicant_steps = (reinstatement? ? category.applicant_reinstatement_wizard_steps : category.applicant_wizard_steps)
349
370
 
350
- # Special logic for stamp step
371
+ # Sanity check
351
372
  applicant_steps.delete(:stamp) unless apply_to_join?
352
373
  applicant_steps.delete(:organization) unless category&.organization?
374
+ applicant_steps.delete(:reinstatement) unless reinstatement?
353
375
 
354
376
  # change_wizard_steps is defined in effective_resources acts_as_wizard
355
377
  applicant_steps = change_wizard_steps(applicant_steps)
@@ -358,44 +380,63 @@ module EffectiveMembershipsApplicant
358
380
  raise('expected change_wizard_steps to return an Array of steps with no nils')
359
381
  end
360
382
 
361
- wizard_steps.select do |step|
362
- required_steps.include?(step) || category.blank? || applicant_steps.include?(step)
383
+ self.class.all_wizard_steps.select do |step|
384
+ required_steps.include?(step) || applicant_steps.include?(step)
363
385
  end
364
386
  end
365
387
  end
366
388
 
367
389
  def sidebar_steps
368
- return self.class.required_wizard_steps unless category.present?
369
- required_steps
390
+ has_completed_step?(:select) ? required_steps : self.class.required_wizard_steps
370
391
  end
371
392
 
372
393
  def can_visit_step?(step)
373
- if missing_info?
374
- return [:start, :select, :billing, :checkout].exclude?(step)
375
- end
376
-
394
+ return [:start, :select, :billing, :checkout].exclude?(step) if missing_info?
377
395
  can_revisit_completed_steps(step)
378
396
  end
379
397
 
398
+ # Find fee
399
+ def fee(fee_type:)
400
+ fees.find { |fee| fee.fee_type == fee_type }
401
+ end
402
+
403
+ # Find or build
404
+ def build_fee(fee_type:)
405
+ fee(fee_type: fee_type) || fees.build(parent: self, owner: owner, fee_type: fee_type)
406
+ end
407
+
408
+ def applicant_fee_type
409
+ return 'Reinstatement' if reinstatement?
410
+ 'Applicant'
411
+ end
412
+
380
413
  def applicant_fee_category
381
414
  category
382
415
  end
383
416
 
384
417
  def applicant_fee_price
418
+ return category.applicant_reinstatement_fee if reinstatement?
385
419
  category.applicant_fee
386
420
  end
387
421
 
388
422
  # All Fees and Orders
389
423
  def submit_fees
424
+ default_applicant_submit_fees
425
+ end
426
+
427
+ def default_applicant_submit_fees
390
428
  # Find or build submit fee
391
- fee = fees.first || fees.build(owner: owner, fee_type: 'Applicant')
429
+ fee = fees.first || build_fee(fee_type: applicant_fee_type)
430
+
431
+ raise('expected a present applicant fee price') if applicant_fee_price.blank?
392
432
 
393
433
  unless fee.purchased?
394
434
  fee.assign_attributes(
395
- category: applicant_fee_category(),
396
- price: applicant_fee_price(),
397
- tax_exempt: applicant_fee_category().applicant_fee_tax_exempt,
398
- qb_item_name: applicant_fee_category().applicant_fee_qb_item_name
435
+ fee_type: applicant_fee_type,
436
+ category: applicant_fee_category,
437
+ price: applicant_fee_price,
438
+ tax_exempt: applicant_fee_category.applicant_fee_tax_exempt,
439
+ qb_item_name: applicant_fee_category.applicant_fee_qb_item_name
399
440
  )
400
441
  end
401
442
 
@@ -436,18 +477,9 @@ module EffectiveMembershipsApplicant
436
477
 
437
478
  # Instance Methods
438
479
  def to_s
439
- if category.present? && category.present?
440
- [
441
- owner.to_s,
442
- '-',
443
- category,
444
- 'for',
445
- category,
446
- ("from #{from_category}" if reclassification?)
447
- ].compact.join(' ')
448
- else
449
- 'New Applicant'
450
- end
480
+ return 'New Applicant' if applicant_type.blank? || category.blank? || owner.blank?
481
+
482
+ "#{owner} - #{applicant_type} to #{category}"
451
483
  end
452
484
 
453
485
  def owner
@@ -470,6 +502,10 @@ module EffectiveMembershipsApplicant
470
502
  applicant_type == 'Apply to Reclassify'
471
503
  end
472
504
 
505
+ def reinstatement?
506
+ applicant_type == 'Apply for Reinstatement'
507
+ end
508
+
473
509
  def individual?
474
510
  !(owner.kind_of?(EffectiveMemberships.Organization) && category&.organization?)
475
511
  end
@@ -519,6 +555,17 @@ module EffectiveMembershipsApplicant
519
555
  end.html_safe
520
556
  end
521
557
 
558
+ # Used by the select step
559
+ def can_apply_applicant_types_collection
560
+ if owner.blank? || owner.membership.blank? || owner.membership.categories.blank?
561
+ ['Apply to Join']
562
+ elsif owner.membership.statuses.present?
563
+ ['Apply for Reinstatement', 'Apply to Join']
564
+ else
565
+ ['Apply to Reclassify']
566
+ end
567
+ end
568
+
522
569
  # Used by the select step
523
570
  def can_apply_categories_collection
524
571
  categories = EffectiveMemberships.Category.sorted.can_apply
@@ -527,7 +574,7 @@ module EffectiveMembershipsApplicant
527
574
  return categories.where(can_apply_new: true)
528
575
  end
529
576
 
530
- category_ids = user.memberships.map(&:category_ids).flatten
577
+ category_ids = user.membership.category_ids
531
578
 
532
579
  categories.select do |cat|
533
580
  cat.can_apply_existing? ||
@@ -587,7 +634,7 @@ module EffectiveMembershipsApplicant
587
634
  end
588
635
 
589
636
  def applicant_references_required?
590
- min_applicant_references > 0
637
+ required_steps.include?(:references) && min_applicant_references > 0
591
638
  end
592
639
 
593
640
  # Endorsements Step
@@ -596,7 +643,7 @@ module EffectiveMembershipsApplicant
596
643
  end
597
644
 
598
645
  def applicant_endorsements_required?
599
- min_applicant_endorsements > 0
646
+ required_steps.include?(:endorsements) && min_applicant_endorsements > 0
600
647
  end
601
648
 
602
649
  # Equivalences Step
@@ -610,7 +657,7 @@ module EffectiveMembershipsApplicant
610
657
  end
611
658
 
612
659
  def transcripts_required?
613
- category.applicant_wizard_steps.include?(:transcripts)
660
+ required_steps.include?(:transcripts)
614
661
  end
615
662
 
616
663
  # Files Step
@@ -634,16 +681,16 @@ module EffectiveMembershipsApplicant
634
681
  requirements = {}
635
682
  return requirements unless category.present?
636
683
 
637
- if category.applicant_wizard_steps.include?(:endorsements) || applicant_endorsements_required?
638
- requirements['Applicant Endorsements'] = (!applicant_endorsements_required? || applicant_endorsements.count(&:completed?) >= min_applicant_endorsements)
684
+ if applicant_endorsements_required?
685
+ requirements['Applicant Endorsements'] = (applicant_endorsements.count(&:completed?) >= min_applicant_endorsements)
639
686
  end
640
687
 
641
- if category.applicant_wizard_steps.include?(:references) || applicant_references_required?
642
- requirements['Applicant References'] = (!applicant_references_required? || applicant_references.count(&:completed?) >= min_applicant_references)
688
+ if applicant_references_required?
689
+ requirements['Applicant References'] = (applicant_references.count(&:completed?) >= min_applicant_references)
643
690
  end
644
691
 
645
- if category.applicant_wizard_steps.include?(:transcripts) || transcripts_required?
646
- requirements['Applicant Transcripts'] = (!transcripts_required? || transcripts_received?)
692
+ if transcripts_required?
693
+ requirements['Applicant Transcripts'] = transcripts_received?
647
694
  end
648
695
 
649
696
  requirements
@@ -692,9 +739,14 @@ module EffectiveMembershipsApplicant
692
739
  # When an application is completed, these must be done to go to reviewed
693
740
  # An Admin can override this and just set them to reviewed.
694
741
  def reviewed_requirements
695
- {
696
- 'Applicant Reviews' => (!applicant_reviews_required? || applicant_reviews.count(&:completed?) >= min_applicant_reviews)
697
- }
742
+ requirements = {}
743
+ return requirements unless category.present?
744
+
745
+ if applicant_reviews_required?
746
+ requirements['Applicant Reviews'] = (applicant_reviews.count(&:completed?) >= min_applicant_reviews)
747
+ end
748
+
749
+ requirements
698
750
  end
699
751
 
700
752
  def review!
@@ -726,6 +778,8 @@ module EffectiveMembershipsApplicant
726
778
  )
727
779
  elsif reclassification?
728
780
  EffectiveMemberships.Registrar.reclassify!(owner, to: category)
781
+ elsif reinstatement?
782
+ EffectiveMemberships.Registrar.reinstate!(owner)
729
783
  else
730
784
  raise('unsupported approval applicant_type')
731
785
  end
@@ -51,8 +51,9 @@ module EffectiveMembershipsCategory
51
51
  can_apply_restricted :boolean
52
52
  can_apply_restricted_ids :text
53
53
 
54
- applicant_fee :integer
55
- applicant_wizard_steps :text
54
+ applicant_fee :integer
55
+ applicant_reinstatement_fee :integer
56
+ applicant_wizard_steps :text
56
57
 
57
58
  min_applicant_educations :integer
58
59
  min_applicant_endorsements :integer
@@ -192,10 +193,16 @@ module EffectiveMembershipsCategory
192
193
  applicant_review_wizard_steps - EffectiveMemberships.ApplicantReview.required_wizard_steps
193
194
  end
194
195
 
196
+ # Apply to Join or Apply to Reclassify
195
197
  def applicant_wizard_steps
196
198
  (Array(self[:applicant_wizard_steps]) - [nil, '']).map(&:to_sym)
197
199
  end
198
200
 
201
+ # Apply for Reinstatement
202
+ def applicant_reinstatement_wizard_steps
203
+ [:reinstatement]
204
+ end
205
+
199
206
  def fee_payment_wizard_steps
200
207
  (Array(self[:fee_payment_wizard_steps]) - [nil, '']).map(&:to_sym)
201
208
  end
@@ -57,7 +57,7 @@ module EffectiveMembershipsFeePayment
57
57
  accepts_nested_attributes_for :organization
58
58
 
59
59
  belongs_to :category, polymorphic: true, optional: true
60
- belongs_to :from_status, polymorphic: true, optional: true
60
+ belongs_to :with_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,7 +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
+ self.with_status ||= user.membership.statuses.first if user.membership.statuses.length == 1
106
106
  end
107
107
 
108
108
  # All Steps validations
@@ -121,17 +121,27 @@ module EffectiveMembershipsFeePayment
121
121
  # This required_steps is defined inside the included do .. end block so it overrides the acts_as_wizard one.
122
122
  def required_steps
123
123
  return self.class.test_required_steps if Rails.env.test? && self.class.test_required_steps.present?
124
+ return self.class.all_wizard_steps if category.blank?
124
125
 
125
126
  @_required_steps ||= begin
126
- wizard_steps = self.class.all_wizard_steps
127
+ # All required
127
128
  required_steps = self.class.required_wizard_steps
128
129
 
129
- fee_payment_steps = Array(category&.fee_payment_wizard_steps)
130
+ # Based on current fee payment
131
+ fee_payment_steps = Array(category.fee_payment_wizard_steps)
130
132
 
133
+ # Sanity Check
131
134
  fee_payment_steps.delete(:organization) unless organization?
132
135
 
133
- wizard_steps.select do |step|
134
- required_steps.include?(step) || category.blank? || fee_payment_steps.include?(step)
136
+ # change_wizard_steps is defined in effective_resources acts_as_wizard
137
+ fee_payment_steps = change_wizard_steps(fee_payment_steps)
138
+
139
+ unless fee_payment_steps.kind_of?(Array) && fee_payment_steps.all? { |step| step.kind_of?(Symbol) }
140
+ raise('expected change_wizard_steps to return an Array of steps with no nils')
141
+ end
142
+
143
+ self.class.all_wizard_steps.select do |step|
144
+ required_steps.include?(step) || fee_payment_steps.include?(step)
135
145
  end
136
146
  end
137
147
  end
@@ -155,7 +155,6 @@ module EffectiveMembershipsRegistrar
155
155
  raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
156
156
  raise('owner must have an existing membership. use register! instead') if owner.membership.blank?
157
157
 
158
- # Todo. I dunno this was owner.membership.category
159
158
  from = owner.membership.category
160
159
 
161
160
  raise('expecting a to memberships category') unless to.class.respond_to?(:effective_memberships_category?)
@@ -183,6 +182,26 @@ module EffectiveMembershipsRegistrar
183
182
  save!(owner, date: date)
184
183
  end
185
184
 
185
+ def reinstate!(owner, date: nil, skip_fees: false)
186
+ raise('expecting a memberships owner') unless owner.class.respond_to?(:effective_memberships_owner?)
187
+ raise('owner must have an existing membership. use register! instead') if owner.membership.blank?
188
+
189
+ from = owner.membership.status
190
+ raise('expecting a from memberships status') if from.present? && !from.class.respond_to?(:effective_memberships_status?)
191
+
192
+ date ||= Time.zone.now
193
+
194
+ membership = owner.membership
195
+ membership.membership_status(status: from).mark_for_destruction if from.present?
196
+
197
+ unless skip_fees
198
+ fee = owner.build_prorated_fee(date: date)
199
+ # This might already be present and purchased if joined and reinstated in the same period
200
+ end
201
+
202
+ save!(owner, date: date)
203
+ end
204
+
186
205
  # This clears the status entirely from user
187
206
  def status_remove!(owner, date: nil)
188
207
  status_change!(owner, to: nil, date: date)
@@ -28,6 +28,10 @@ module EffectiveMembershipsUser
28
28
 
29
29
  accepts_nested_attributes_for :representatives, allow_destroy: true
30
30
 
31
+ # I'm an endorser for these
32
+ has_many :applicant_endorsements, -> { Effective::ApplicantEndorsement.sorted },
33
+ class_name: 'Effective::ApplicantEndorsement', inverse_of: :endorser, as: :endorser, dependent: :nullify
34
+
31
35
  scope :membership_applying, -> {
32
36
  applicants = EffectiveMemberships.Applicant.all
33
37
  without_role(:member).where(id: applicants.select(:user_id))
@@ -39,6 +39,9 @@ module Effective
39
39
  end
40
40
 
41
41
  scope :deep, -> { all }
42
+ scope :sorted, -> { order(:id) }
43
+
44
+ scope :needs_endorser, -> { where(status: :submitted).where(applicant_id: EffectiveMemberships.Applicant.not_draft) }
42
45
 
43
46
  # All step validations
44
47
  validates :applicant, presence: true
@@ -13,6 +13,9 @@ module Effective
13
13
  # The membership category for this fee, if there's only 1 membership.categories
14
14
  belongs_to :category, polymorphic: true, optional: true
15
15
 
16
+ # The membership status for this fee, if there's only 1 membership.statuses
17
+ belongs_to :with_status, polymorphic: true, optional: true
18
+
16
19
  effective_resource do
17
20
  fee_type :string
18
21
 
@@ -35,6 +38,7 @@ module Effective
35
38
 
36
39
  before_validation(if: -> { owner && owner.membership }) do
37
40
  self.category ||= owner.membership.categories.first if owner.membership.categories.length == 1
41
+ self.with_status ||= owner.membership.statuses.first if owner.membership.statuses.length == 1
38
42
  end
39
43
 
40
44
  before_validation do
@@ -81,16 +85,20 @@ module Effective
81
85
 
82
86
  # Used by applicant.applicant_submit_fees
83
87
  def applicant_submit_fee?
84
- fee_type == 'Applicant'
88
+ return true if parent.kind_of?(EffectiveMemberships.Applicant)
89
+
90
+ ['Applicant', 'Reinstatement'].include?(fee_type)
85
91
  end
86
92
 
87
93
  def fee_payment_fee?
88
- fee_type != 'Applicant'
94
+ return false if parent.kind_of?(EffectiveMemberships.Applicant)
95
+
96
+ ['Applicant', 'Reinstatement'].exclude?(fee_type)
89
97
  end
90
98
 
91
99
  # Will advance a membership.fees_paid_through_year value when purchased
92
100
  def membership_period_fee?
93
- fee_type == 'Prorated' || fee_type == 'Renewal'
101
+ ['Prorated', 'Renewal'].include?(fee_type)
94
102
  end
95
103
 
96
104
  def custom_fee?
@@ -0,0 +1,10 @@
1
+ - datatable = EffectiveApplicantEndorsersDatatable.new(self, endorser: current_user)
2
+
3
+ %h2 Endorsements
4
+
5
+ - if datatable.present?
6
+ %p Your endorsement has been requested on the following applicants:
7
+ = render_simple_datatable(datatable)
8
+
9
+ - else
10
+ %p There are no applicant endorsements to complete.
@@ -0,0 +1,9 @@
1
+ = wizard_card(applicant) do
2
+ %table.table.table-sm
3
+ %tbody
4
+ %tr
5
+ %td= icon('check')
6
+ %td Yes, I am applying to reinstate from #{applicant.from_status || applicant.from_category}.
7
+ %tr
8
+ %td= icon('check')
9
+ %td Yes, I have read, understand and agree to the reinstatement declaration
@@ -0,0 +1,15 @@
1
+ = render 'layout' do
2
+ = render 'effective/applicants/content', resource: resource
3
+
4
+ - completed = resource.has_completed_step?(:reinstatement)
5
+ - resource.declare_reinstatement = completed
6
+
7
+ = card do
8
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
9
+ = f.hidden_field :id
10
+
11
+ = render_if_exists("effective/applicants/reinstatement_fields", f: f)
12
+
13
+ = f.check_box :declare_reinstatement, label: 'Yes, I accept and agree to the above'
14
+
15
+ = f.save 'Save and Continue'
@@ -0,0 +1,3 @@
1
+ - membership = f.object.owner.membership
2
+
3
+ %p Apply for reinstatement from #{membership.status || membership.category}.
@@ -0,0 +1 @@
1
+ %p Please select a category for your application to join:
@@ -0,0 +1,5 @@
1
+ - membership = f.object.owner.membership
2
+
3
+ %p Apply to reclassify from #{membership.category}.
4
+
5
+ %p Please select a category for your application to reclassify:
@@ -0,0 +1,25 @@
1
+ - organization_categories = categories.select(&:organization?)
2
+
3
+ - if categories.blank?
4
+ %p
5
+ There are no categories available for you to apply for.
6
+ Please contact us if you believe this is in error.
7
+
8
+ - if categories.present?
9
+ = f.select :category_id, categories, required: true
10
+
11
+ - categories.each do |mc|
12
+ = f.show_if(:category_id, mc.id) do
13
+ .mb-4
14
+ %h3= mc.to_s
15
+
16
+ - if organization_categories.present?
17
+ %small.text-muted #{mc.category} #{mc.category_type} Membership
18
+
19
+ = mc.rich_text_body
20
+
21
+ = render_if_exists("effective/applicants/select/#{mc.to_s.parameterize.underscore}", f: f, category: mc)
22
+
23
+ - if organization_categories.present?
24
+ = f.show_if_any(:category_id, organization_categories.map(&:id)) do
25
+ = render('effective/applicants/select_organization', f: f)
@@ -2,41 +2,49 @@
2
2
  = render 'effective/applicants/content', resource: resource
3
3
 
4
4
  - categories = resource.can_apply_categories_collection()
5
- - organization_categories = categories.select(&:organization?)
5
+ - applicant_types = resource.can_apply_applicant_types_collection()
6
+ - existing_category = resource.owner&.membership&.category
6
7
 
7
8
  = card do
8
- - if categories.blank?
9
- %p
10
- There are no categories available for you to apply for.
11
- Please contact us if you believe this is in error.
9
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
10
+ = f.hidden_field :id
12
11
 
13
- - if categories.present?
14
- %p Please select a category to continue.
12
+ = f.hidden_field :stream, value: nil
13
+ = f.hidden_field :organization_id, value: nil
14
+ = f.hidden_field :organization_type, value: nil
15
15
 
16
- = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
17
- = f.hidden_field :id
16
+ = f.hidden_field :applicant_type, value: applicant_types.first
17
+ = f.hidden_field :category_type, value: EffectiveMemberships.Category.name
18
18
 
19
- = f.hidden_field :stream, value: nil
20
- = f.hidden_field :organization_id, value: nil
21
- = f.hidden_field :organization_type, value: nil
22
- = f.hidden_field :category_type, value: EffectiveMemberships.Category.name
19
+ - if applicant_types == ['Apply to Join']
20
+ = render('effective/applicants/select/apply_to_join', f: f)
21
+ = render('effective/applicants/select/categories', f: f, categories: categories)
23
22
 
24
- = f.select :category_id, categories, required: true
23
+ - elsif applicant_types == ['Apply for Reinstatement']
24
+ = f.hidden_field :applicant_type, value: applicant_types.first
25
+ = f.hidden_field :category_id, value: existing_category.id
26
+ = render('effective/applicants/select/apply_for_reinstatement', f: f)
25
27
 
26
- - categories.each do |mc|
27
- = f.show_if(:category_id, mc.id) do
28
- .mb-4
29
- %h3= mc.to_s
28
+ - elsif applicant_types == ['Apply to Reclassify']
29
+ = render('effective/applicants/select/apply_to_reclassify', f: f)
30
+ = render('effective/applicants/select/categories', f: f, categories: categories - [existing_category])
30
31
 
31
- - if organization_categories.present?
32
- %small.text-muted #{mc.category} #{mc.category_type} Membership
32
+ - else
33
+ = f.select :applicant_type, applicant_types, label: 'Apply to...'
33
34
 
34
- = mc.rich_text_body
35
+ - if applicant_types.include?('Apply to Join')
36
+ = f.show_if :applicant_type, 'Apply to Join' do
37
+ = render('effective/applicants/select/apply_to_join', f: f)
38
+ = render('effective/applicants/select/categories', f: f, categories: categories)
35
39
 
36
- = render_if_exists("effective/applicants/select/#{mc.to_s.parameterize.underscore}", f: f, category: mc)
40
+ - if applicant_types.include?('Apply to Reclassify')
41
+ = f.show_if :applicant_type, 'Apply to Reclassify' do
42
+ = render('effective/applicants/select/apply_to_reclassify', f: f)
43
+ = render('effective/applicants/select/categories', f: f, categories: categories - [existing_category])
37
44
 
38
- - if organization_categories.present?
39
- = f.show_if_any(:category_id, organization_categories.map(&:id)) do
40
- = render('effective/applicants/select_organization', f: f)
45
+ - if applicant_types.include?('Apply for Reinstatement')
46
+ = f.show_if :applicant_type, 'Apply for Reinstatement' do
47
+ = f.hidden_field :category_id, value: existing_category.id
48
+ = render('effective/applicants/select/apply_for_reinstatement', f: f)
41
49
 
42
- = f.save 'Save and Continue'
50
+ = f.save 'Save and Continue'
@@ -18,6 +18,7 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
18
18
 
19
19
  t.text :applicant_wizard_steps
20
20
  t.integer :applicant_fee
21
+ t.integer :applicant_reinstatement_fee
21
22
 
22
23
  t.text :applicant_review_wizard_steps
23
24
 
@@ -458,6 +459,9 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
458
459
  t.integer :category_id
459
460
  t.string :category_type
460
461
 
462
+ t.integer :with_status_id
463
+ t.string :with_status_type
464
+
461
465
  t.string :fee_type
462
466
 
463
467
  t.integer :purchased_order_id
@@ -502,6 +506,9 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
502
506
  t.integer :category_id
503
507
  t.string :category_type
504
508
 
509
+ t.integer :with_status_id
510
+ t.string :with_status_type
511
+
505
512
  t.date :period
506
513
 
507
514
  # Acts as Statused
data/db/seeds.rb CHANGED
@@ -9,6 +9,8 @@ if Rails.env.test?
9
9
  Effective::ApplicantCourseName.delete_all
10
10
  end
11
11
 
12
+ Effective::Status.where(title: 'Resigned').first_or_create!
13
+
12
14
  member = Effective::Category.create!(
13
15
  title: "Full Member",
14
16
  can_apply_new: true,
@@ -18,6 +20,7 @@ member = Effective::Category.create!(
18
20
  min_applicant_references: 2,
19
21
  min_applicant_reviews: 2,
20
22
  applicant_fee: 100_00,
23
+ applicant_reinstatement_fee: 50_00,
21
24
  renewal_fee: 250_00,
22
25
  late_fee: 50_00,
23
26
  prorated_jan: 120_00, prorated_feb: 110_00, prorated_mar: 100_00, prorated_apr: 90_00, prorated_may: 80_00, prorated_jun: 70_00,
@@ -34,6 +37,7 @@ student = Effective::Category.create!(
34
37
  min_applicant_references: 0,
35
38
  min_applicant_reviews: 0,
36
39
  applicant_fee: 50_00,
40
+ applicant_reinstatement_fee: 25_00,
37
41
  renewal_fee: 125_00,
38
42
  late_fee: 25_00,
39
43
  prorated_jan: 120_00, prorated_feb: 110_00, prorated_mar: 100_00, prorated_apr: 90_00, prorated_may: 80_00, prorated_jun: 70_00,
@@ -49,6 +53,7 @@ retired = Effective::Category.create!(
49
53
  can_apply_restricted: true,
50
54
  can_apply_restricted_ids: [member.id],
51
55
  applicant_fee: 0,
56
+ applicant_reinstatement_fee: 0,
52
57
  renewal_fee: 0,
53
58
  prorated_jan: 120_00, prorated_feb: 110_00, prorated_mar: 100_00, prorated_apr: 90_00, prorated_may: 80_00, prorated_jun: 70_00,
54
59
  prorated_jul: 60_00, prorated_aug: 50_00, prorated_sep: 40_00, prorated_oct: 30_00, prorated_nov: 20_00, prorated_dec: 10_00,
@@ -66,6 +71,7 @@ member = Effective::Category.create!(
66
71
  min_applicant_references: 2,
67
72
  min_applicant_reviews: 2,
68
73
  applicant_fee: 100_00,
74
+ applicant_reinstatement_fee: 50_00,
69
75
  renewal_fee: 250_00,
70
76
  late_fee: 50_00,
71
77
  prorated_jan: 120_00, prorated_feb: 110_00, prorated_mar: 100_00, prorated_apr: 90_00, prorated_may: 80_00, prorated_jun: 70_00,
@@ -1,3 +1,3 @@
1
1
  module EffectiveMemberships
2
- VERSION = '0.5.0'
2
+ VERSION = '0.5.3'
3
3
  end
@@ -54,7 +54,7 @@ module EffectiveMemberships
54
54
  end
55
55
 
56
56
  def self.fee_types
57
- required = ['Applicant', 'Prorated', 'Discount', 'Renewal', 'Late', 'Admin']
57
+ required = ['Applicant', 'Reinstatement', 'Prorated', 'Discount', 'Renewal', 'Late', 'Admin']
58
58
  additional = Array(additional_fee_types)
59
59
 
60
60
  (required + additional).uniq.sort
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.5.0
4
+ version: 0.5.3
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-08-17 00:00:00.000000000 Z
11
+ date: 2022-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -292,6 +292,7 @@ files:
292
292
  - app/datatables/effective_applicant_courses_datatable.rb
293
293
  - app/datatables/effective_applicant_educations_datatable.rb
294
294
  - app/datatables/effective_applicant_endorsements_datatable.rb
295
+ - app/datatables/effective_applicant_endorsers_datatable.rb
295
296
  - app/datatables/effective_applicant_equivalences_datatable.rb
296
297
  - app/datatables/effective_applicant_experiences_datatable.rb
297
298
  - app/datatables/effective_applicant_references_datatable.rb
@@ -391,6 +392,7 @@ files:
391
392
  - app/views/effective/applicant_endorsements/_form_declaration.html.haml
392
393
  - app/views/effective/applicant_endorsements/complete.html.haml
393
394
  - app/views/effective/applicant_endorsements/edit.html.haml
395
+ - app/views/effective/applicant_endorsers/_dashboard.html.haml
394
396
  - app/views/effective/applicant_references/_applicant_reference.html.haml
395
397
  - app/views/effective/applicant_references/_datatable_actions.html.haml
396
398
  - app/views/effective/applicant_references/_form.html.haml
@@ -413,6 +415,7 @@ files:
413
415
  - app/views/effective/applicants/_orders.html.haml
414
416
  - app/views/effective/applicants/_organization.html.haml
415
417
  - app/views/effective/applicants/_references.html.haml
418
+ - app/views/effective/applicants/_reinstatement.html.haml
416
419
  - app/views/effective/applicants/_select.html.haml
417
420
  - app/views/effective/applicants/_select_organization.html.haml
418
421
  - app/views/effective/applicants/_stamp.html.haml
@@ -431,7 +434,12 @@ files:
431
434
  - app/views/effective/applicants/files.html.haml
432
435
  - app/views/effective/applicants/organization.html.haml
433
436
  - app/views/effective/applicants/references.html.haml
437
+ - app/views/effective/applicants/reinstatement.html.haml
434
438
  - app/views/effective/applicants/select.html.haml
439
+ - app/views/effective/applicants/select/_apply_for_reinstatement.html.haml
440
+ - app/views/effective/applicants/select/_apply_to_join.html.haml
441
+ - app/views/effective/applicants/select/_apply_to_reclassify.html.haml
442
+ - app/views/effective/applicants/select/_categories.html.haml
435
443
  - app/views/effective/applicants/stamp.html.haml
436
444
  - app/views/effective/applicants/start.html.haml
437
445
  - app/views/effective/applicants/submitted.html.haml