effective_memberships 0.8.7 → 0.9.1

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: a05ef926bab6297cf92f4df0dce83af5380ed575945461b2afe5f63d853b385c
4
- data.tar.gz: 747ff46a96635c7a434bd98931cc7569d18cc29a314da06f2dedc5cc968ee6b6
3
+ metadata.gz: 6e82e009171632439c6f52ec8932a7e5f3f254c26148b41cbdc864e3d003bca9
4
+ data.tar.gz: 58fb7dee1b53c29b4c8f2b00ae29e9ce56537249937edaa48a8873c31e03b6d0
5
5
  SHA512:
6
- metadata.gz: a3a206e225335ba504c963976d3ea73fd5e6a141c3e041f8c9f9bcff26a1020c8b76c5e799811b7045108d8f54c660605d08991ea6e50e9adef90d0b16a289cb
7
- data.tar.gz: 93db46c6155328b3882192eb2041c7f49e35f14fcd607c47df8cce0a61bc8a365f032554fa8b5c6058a14dc45b4d809af5a5272a12e7a369437517d425501c3d
6
+ metadata.gz: d689ddb87455e6344f838d13c622e1a8312b7740754c79e18a6a06e56f7cb283f4a824a270357e17997cc1728aa30108eac774937f0c89881b06b0935349261b
7
+ data.tar.gz: 78064744e55a7fbb0a4e4285b1a29a469342461b0607f93877223fc456016d61ea614f4f40663b69dbf2f141cdb60cb59b3a2c9890c08a10c897ed54fdc5e68e
@@ -31,8 +31,9 @@ module Admin
31
31
  col :organization, visible: false
32
32
 
33
33
  col :applicant_type
34
- col :category, search: { collection: EffectiveMemberships.Category.all, polymorphic: false }
35
- col :from_category, search: { collection: EffectiveMemberships.Category.all, polymorphic: false }, visible: false
34
+ col :category, label: 'Applicant Category', search: { collection: EffectiveMemberships.Category.all, polymorphic: false }
35
+ col :from_category, search: { collection: EffectiveMemberships.Category.all, polymorphic: false }
36
+ col :from_status, search: { collection: EffectiveMemberships.Status.all, polymorphic: false }
36
37
 
37
38
  col :orders, visible: false
38
39
 
@@ -19,19 +19,22 @@ module Admin
19
19
  col :owner
20
20
  end
21
21
 
22
- unless attributes[:applicant_id] || attributes[:fee_payment_id]
23
- col :parent, search: :string, visible: false
24
- end
25
-
26
22
  col :fee_type, search: EffectiveMemberships.fee_types
23
+
27
24
  col :price, as: :price
25
+ col :qb_item_name, label: 'Quickbooks Item Name'
28
26
  col :tax_exempt, visible: false
29
- col :qb_item_name, visible: false
30
27
 
31
28
  col :purchased?, as: :boolean
29
+
30
+ unless attributes[:applicant_id] || attributes[:fee_payment_id]
31
+ col :parent, search: :string, visible: false
32
+ end
33
+
32
34
  col :purchased_order, visible: false
33
35
 
34
36
  col :category, search: { collection: EffectiveMemberships.Category.all, polymorphic: false }
37
+ col :checkout_type, search: Effective::Fee::CHECKOUT_TYPES, visible: false
35
38
 
36
39
  unless attributes[:total] == false
37
40
  aggregate :total
@@ -236,9 +236,10 @@ module EffectiveMembershipsApplicant
236
236
  validates :category, presence: true
237
237
  end
238
238
 
239
- validate(if: -> { current_step == :select && owner.present? }) do
240
- self.errors.add(:base, 'may not have outstanding fees') if owner.outstanding_fee_payment_fees.present?
241
- end
239
+ # They can checkout with outstanding fees
240
+ # validate(if: -> { current_step == :select && owner.present? }) do
241
+ # self.errors.add(:base, 'may not have outstanding fees') if owner.outstanding_fee_payment_fees.present?
242
+ # end
242
243
 
243
244
  # Applicant Educations Step
244
245
  with_options(if: -> { current_step == :education }) do
@@ -453,17 +454,27 @@ module EffectiveMembershipsApplicant
453
454
  end
454
455
 
455
456
  # All Fees and Orders
457
+
458
+ # We take over the owner's outstanding applicant fees.
459
+ # These may have been created by an admin and assigned to the next applicant
460
+ def find_or_build_submit_fees
461
+ Array(owner.outstanding_applicant_submit_fees).each { |fee| fees << fee unless fees.include?(fee) }
462
+ submit_fees
463
+ end
464
+
456
465
  def submit_fees
457
466
  default_applicant_submit_fees
458
467
  end
459
468
 
460
469
  def default_applicant_submit_fees
461
- # Find or build submit fee
462
- fee = fees.first || build_fee(fee_type: applicant_fee_type)
470
+ raise('expected an applicant fee type') if applicant_fee_type.blank?
471
+ raise('expected an applicant fee price') if applicant_fee_price.blank?
463
472
 
464
- raise('expected a present applicant fee price') if applicant_fee_price.blank?
473
+ # Find or build Applicant or Reinstatement submit fee
474
+ fee = fees.find { |fee| fee.fee_type == applicant_fee_type } || build_fee(fee_type: applicant_fee_type)
465
475
 
466
- unless fee.purchased?
476
+ # This wasn't created by an admin, so we should apply our prices.
477
+ if (fee.new_record? || fee.checkout_type.blank?) && !fee.purchased?
467
478
  fee.assign_attributes(
468
479
  fee_type: applicant_fee_type,
469
480
  category: applicant_fee_category,
@@ -156,7 +156,7 @@ module EffectiveMembershipsFeePayment
156
156
  orders.first
157
157
  end
158
158
 
159
- # We take over the owner's outstanding fees.
159
+ # We take over the owner's outstanding fee payment fees.
160
160
  def find_or_build_submit_fees
161
161
  Array(owner.outstanding_fee_payment_fees).each { |fee| fees << fee unless fees.include?(fee) }
162
162
  submit_fees
@@ -27,10 +27,10 @@ module EffectiveMembershipsOwner
27
27
  has_many :orders, -> { order(:id) }, inverse_of: :user, as: :user, class_name: 'Effective::Order', dependent: :nullify
28
28
  accepts_nested_attributes_for :orders, reject_if: :all_blank, allow_destroy: true
29
29
 
30
- has_one :membership, inverse_of: :owner, as: :owner, class_name: 'Effective::Membership'
30
+ has_one :membership, inverse_of: :owner, as: :owner, class_name: 'Effective::Membership', dependent: :destroy
31
31
  accepts_nested_attributes_for :membership
32
32
 
33
- has_many :membership_histories, -> { Effective::MembershipHistory.sorted }, inverse_of: :owner, as: :owner, class_name: 'Effective::MembershipHistory'
33
+ has_many :membership_histories, -> { Effective::MembershipHistory.sorted }, inverse_of: :owner, as: :owner, class_name: 'Effective::MembershipHistory', dependent: :delete_all
34
34
  accepts_nested_attributes_for :membership_histories
35
35
 
36
36
  scope :members, -> { joins(:membership) }
@@ -91,6 +91,10 @@ module EffectiveMembershipsOwner
91
91
  outstanding_fee_payment_fees.blank? && membership && membership.fees_paid?
92
92
  end
93
93
 
94
+ def outstanding_applicant_submit_fees
95
+ fees.select { |fee| fee.applicant_submit_fee? && !fee.purchased? }
96
+ end
97
+
94
98
  def outstanding_fee_payment_fees
95
99
  fees.select { |fee| fee.fee_payment_fee? && !fee.purchased? }
96
100
  end
@@ -16,8 +16,11 @@ module Effective
16
16
  # The membership status for this fee, if there's only 1 membership.statuses
17
17
  belongs_to :with_status, polymorphic: true, optional: true
18
18
 
19
+ CHECKOUT_TYPES = ['Default', 'Applicant', 'Fee Payment']
20
+
19
21
  effective_resource do
20
22
  fee_type :string
23
+ checkout_type :string # When created by Admin can override default Applicant or Fee Payment
21
24
 
22
25
  title :string
23
26
 
@@ -46,6 +49,11 @@ module Effective
46
49
  self.title ||= default_title()
47
50
  end
48
51
 
52
+ before_validation(if: -> { fee_type == 'Renewal' && category.present? && period.present? }) do
53
+ self.late_on ||= EffectiveMemberships.Registrar.late_fee_date(period: period) if category.create_late_fees?
54
+ self.not_in_good_standing_on ||= EffectiveMemberships.Registrar.not_in_good_standing_date(period: period) if category.create_not_in_good_standing?
55
+ end
56
+
49
57
  validates :fee_type, presence: true
50
58
 
51
59
  validates :title, presence: true
@@ -55,6 +63,8 @@ module Effective
55
63
  validates :tax_exempt, inclusion: { in: [true, false] }
56
64
  validates :qb_item_name, presence: true
57
65
 
66
+ validates :checkout_type, inclusion: { in: CHECKOUT_TYPES, allow_blank: true }
67
+
58
68
  validate(if: -> { fee_type.present? }) do
59
69
  self.errors.add(:fee_type, 'is not included') unless EffectiveMemberships.fee_types.include?(fee_type)
60
70
  end
@@ -87,12 +97,20 @@ module Effective
87
97
  def applicant_submit_fee?
88
98
  return true if parent.kind_of?(EffectiveMemberships.Applicant)
89
99
 
100
+ return false if checkout_type == 'Fee Payment'
101
+ return true if checkout_type == 'Applicant'
102
+
103
+ # Default
90
104
  ['Applicant', 'Reinstatement'].include?(fee_type)
91
105
  end
92
106
 
93
107
  def fee_payment_fee?
94
108
  return false if parent.kind_of?(EffectiveMemberships.Applicant)
95
109
 
110
+ return false if checkout_type == 'Applicant'
111
+ return true if checkout_type == 'Fee Payment'
112
+
113
+ # Default
96
114
  ['Applicant', 'Reinstatement'].exclude?(fee_type)
97
115
  end
98
116
 
@@ -101,6 +119,10 @@ module Effective
101
119
  ['Prorated', 'Renewal'].include?(fee_type)
102
120
  end
103
121
 
122
+ def renewal_fee?
123
+ fee_type == 'Renewal'
124
+ end
125
+
104
126
  def custom_fee?
105
127
  EffectiveMemberships.custom_fee_types.include?(fee_type)
106
128
  end
@@ -6,13 +6,47 @@
6
6
  - collection = { 'Users' => current_user.class.sorted, 'Organizations' => EffectiveMemberships.Organization.sorted }
7
7
  = f.select :owner, collection, polymorphic: true
8
8
 
9
+ - fee_types = EffectiveMemberships.fee_types
10
+ - membership_period_fee_types = fee_types.select { |fee_type| Effective::Fee.new(fee_type: fee_type).membership_period_fee? }
11
+
9
12
  - if f.object.new_record?
10
- = f.select :fee_type, EffectiveMemberships.custom_fee_types
13
+ = f.select :fee_type, fee_types
11
14
  - else
12
15
  = f.static_field :fee_type
13
16
 
14
- = f.price_field :price
17
+ = f.show_if_any(:fee_type, membership_period_fee_types) do
18
+ = card do
19
+ %p This is a membership period fee. It will advance the membership fees paid through period when purchased.
20
+ %p Only one membership period fee -- Prorated or Renewal -- is expected to exist per membership period.
21
+
22
+ - registrar = EffectiveMemberships.Registrar
23
+ - periods = registrar.periods(from: Time.zone.now - 10.years)
24
+ - collection = periods.reverse.map { |period| [registrar.period_end_on(date: period), period] }
25
+
26
+ - f.object.period ||= registrar.current_period
27
+ = f.select :period, collection, label: 'Membership period', hint: 'When purchased, set the membership fees paid through period to this period'
28
+
29
+ - # Renewal Fees Only
30
+ - if f.object.persisted? && f.object.renewal_fee?
31
+ - if f.object.category.create_late_fees?
32
+ = f.date_field :late_on, hint: 'A late fee will be applied on this date unless purchased'
33
+
34
+ - if f.object.category.create_not_in_good_standing?
35
+ = f.date_field :not_in_good_standing_on, hint: 'The membership will be marked NIGS on this date unless purchased'
15
36
 
16
- = f.text_field :qb_item_name
37
+ - f.object.category_id = f.object.owner&.membership&.categories&.first&.id
38
+ = f.select :category_id, EffectiveMemberships.Category.all
39
+
40
+ - if f.object.parent.blank?
41
+ - f.object.checkout_type ||= 'Default'
42
+
43
+ = f.radios :checkout_type, Effective::Fee::CHECKOUT_TYPES, inline: true, label: 'Checkout wizard',
44
+ hint: 'When default, Applicant and Reinstatement fees will be charged from the applicant wizard, and all other fee types from the fee payment wizard'
45
+ - else
46
+ = f.static_field :parent
47
+
48
+ = f.price_field :price
49
+ = f.text_field :qb_item_name, label: 'Quickbooks Item Name'
50
+ = f.check_box :tax_exempt, label: 'Yes, this fee is tax exempt'
17
51
 
18
52
  = effective_submit(f)
@@ -1,17 +1,16 @@
1
1
  %table.table.table-sm
2
2
  %tbody
3
3
  %tr
4
- %th Category
5
- %td= fee.category
4
+ %th Title
5
+ %td= fee.title
6
6
 
7
- - if fee.category.present?
8
- %tr
9
- %th Membership Category
10
- %td
11
- - if request.path.start_with?('/admin')
12
- = link_to(fee.category, effective_memberships.edit_admin_category_path(fee.category))
13
- - else
14
- = fee.category
7
+ %tr
8
+ %th Membership Category
9
+ %td
10
+ - if fee.category.present? && request.path.start_with?('/admin')
11
+ = link_to(fee.category, effective_memberships.edit_admin_category_path(fee.category))
12
+ - else
13
+ = fee.category.presence || 'None'
15
14
 
16
15
  - if request.path.start_with?('/admin')
17
16
  %tr
@@ -35,3 +34,18 @@
35
34
  %tr
36
35
  %th Price
37
36
  %td= price_to_currency(fee.price)
37
+
38
+ - if fee.late_on.present?
39
+ %tr
40
+ %th Late On
41
+ %td= fee.late_on.strftime('%F')
42
+
43
+ - if fee.not_in_good_standing_on.present?
44
+ %tr
45
+ %th Not In Good Standing On
46
+ %td= fee.not_in_good_standing_on.strftime('%F')
47
+
48
+ - if fee.checkout_type.present?
49
+ %tr
50
+ %th Checkout Type
51
+ %td= fee.checkout_type
@@ -458,6 +458,7 @@ class CreateEffectiveMemberships < ActiveRecord::Migration[6.0]
458
458
  t.string :with_status_type
459
459
 
460
460
  t.string :fee_type
461
+ t.string :checkout_type
461
462
 
462
463
  t.integer :purchased_order_id
463
464
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveMemberships
2
- VERSION = '0.8.7'
2
+ VERSION = '0.9.1'
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.8.7
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-07 00:00:00.000000000 Z
11
+ date: 2022-11-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails