effective_memberships 0.4.4 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/datatables/admin/effective_categories_datatable.rb +4 -0
- data/app/datatables/admin/effective_organizations_datatable.rb +46 -3
- data/app/models/concerns/effective_memberships_category.rb +0 -5
- data/app/models/concerns/effective_memberships_organization.rb +1 -0
- data/app/models/concerns/effective_memberships_owner.rb +12 -0
- data/app/models/concerns/effective_memberships_registrar.rb +42 -6
- data/app/models/effective/membership.rb +13 -12
- data/app/views/admin/memberships/_form_membership.html.haml +6 -0
- data/app/views/admin/organizations/_fields.html.haml +0 -2
- data/app/views/admin/organizations/_form.html.haml +1 -5
- data/app/views/admin/organizations/_form_organization.html.haml +1 -3
- data/lib/effective_memberships/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a59918a13a42cc9da99200ecfa61ed9b45ae8881ca7e9c0d4e2fd0117605003
|
4
|
+
data.tar.gz: b1955f238384bbb8cfc4836ad06357b1b815c47c23a9e8ac11303e858feb8379
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2ad995fdad088a4db63c1f98467330a1315deb55fe6c912e12662a1a66d017365fd2c379038d7422f9cf5a5b9b7338aa24c05e65f519360be075098ffc4628d
|
7
|
+
data.tar.gz: de64346cc2ce1119672f925d2f60589b4e9e5cd0c5ab506438cee5e7ec2e31e36a79924ed26896c5e0bec639f6033401317e254adcdd03dc8ccf279d75f0a0c9
|
@@ -17,6 +17,10 @@ module Admin
|
|
17
17
|
col :tax_exempt
|
18
18
|
col :qb_item_name, visible: false
|
19
19
|
|
20
|
+
col :create_renewal_fees, visible: false
|
21
|
+
col :create_late_fees, visible: false
|
22
|
+
col :create_bad_standing, visible: false
|
23
|
+
|
20
24
|
col :category_type, search: EffectiveMemberships.Category.category_types
|
21
25
|
|
22
26
|
col :optional_applicant_wizard_steps, label: 'Applicant Steps'
|
@@ -1,7 +1,12 @@
|
|
1
1
|
module Admin
|
2
2
|
class EffectiveOrganizationsDatatable < Effective::Datatable
|
3
|
-
|
3
|
+
filters do
|
4
|
+
scope :unarchived, label: 'All'
|
5
|
+
scope :members
|
6
|
+
scope :archived
|
7
|
+
end
|
4
8
|
|
9
|
+
datatable do
|
5
10
|
col :updated_at, visible: false
|
6
11
|
col :created_at, visible: false
|
7
12
|
|
@@ -11,16 +16,54 @@ module Admin
|
|
11
16
|
col :category, search: categories
|
12
17
|
end
|
13
18
|
|
14
|
-
col :
|
19
|
+
col(:to_s, label: 'Organization', sql_column: true, action: :edit)
|
20
|
+
.search do |collection, term|
|
21
|
+
collection.where(id: effective_resource.search_any(term))
|
22
|
+
end.sort do |collection, direction|
|
23
|
+
collection.order(title: direction)
|
24
|
+
end
|
25
|
+
|
26
|
+
col :title, visible: false
|
27
|
+
|
28
|
+
col 'membership.joined_on'
|
29
|
+
col 'membership.fees_paid_through_period', label: 'Fees Paid Through'
|
30
|
+
col 'membership.categories'
|
15
31
|
|
16
32
|
col :representatives_count
|
17
33
|
col :representatives
|
18
34
|
|
35
|
+
col :email, visible: false
|
36
|
+
|
37
|
+
col :address1, visible: false do |organization|
|
38
|
+
organization.billing_address&.address1
|
39
|
+
end
|
40
|
+
col :address2, visible: false do |organization|
|
41
|
+
organization.billing_address&.address2
|
42
|
+
end
|
43
|
+
col :city, visible: false do |organization|
|
44
|
+
organization.billing_address&.city
|
45
|
+
end
|
46
|
+
col :state_code, label: 'Prov', visible: false do |organization|
|
47
|
+
organization.billing_address&.state_code
|
48
|
+
end
|
49
|
+
col :postal_code, label: 'Postal', visible: false do |organization|
|
50
|
+
organization.billing_address&.postal_code
|
51
|
+
end
|
52
|
+
col :country_code, label: 'Country', visible: false do |organization|
|
53
|
+
organization.billing_address&.country_code
|
54
|
+
end
|
55
|
+
|
56
|
+
col :phone, visible: false
|
57
|
+
col :fax, visible: false
|
58
|
+
col :website, visible: false
|
59
|
+
col :category, visible: false
|
60
|
+
col :notes, visible: false
|
61
|
+
|
19
62
|
actions_col
|
20
63
|
end
|
21
64
|
|
22
65
|
collection do
|
23
|
-
EffectiveMemberships.Organization.deep.
|
66
|
+
EffectiveMemberships.Organization.deep.left_joins(:membership).includes(:addresses, membership: :membership_categories)
|
24
67
|
end
|
25
68
|
|
26
69
|
def categories
|
@@ -110,11 +110,6 @@ module EffectiveMembershipsCategory
|
|
110
110
|
.or(where(can_apply_restricted: true))
|
111
111
|
}
|
112
112
|
|
113
|
-
# For the create_fees rake task
|
114
|
-
scope :create_renewal_fees, -> { where(create_renewal_fees: true) }
|
115
|
-
scope :create_late_fees, -> { where(create_late_fees: true) }
|
116
|
-
scope :create_bad_standing, -> { where(create_bad_standing: true) }
|
117
|
-
|
118
113
|
validates :title, presence: true, uniqueness: true
|
119
114
|
validates :category_type, presence: true
|
120
115
|
validates :position, presence: true
|
@@ -23,6 +23,7 @@ module EffectiveMembershipsOrganization
|
|
23
23
|
effective_memberships_owner
|
24
24
|
|
25
25
|
acts_as_addressable :billing # effective_addresses
|
26
|
+
acts_as_archived unless respond_to?(:acts_as_archived?)
|
26
27
|
log_changes(except: [:representatives, :users]) if respond_to?(:log_changes)
|
27
28
|
|
28
29
|
# rich_text_body
|
@@ -160,9 +160,21 @@ module EffectiveMembershipsOwner
|
|
160
160
|
fee
|
161
161
|
end
|
162
162
|
|
163
|
+
# These should be singular fees anyway.
|
164
|
+
def membership_period_fee(category:, period:, except: nil)
|
165
|
+
raise('expected except to be a string like Renewal') if except.present? && !except.kind_of?(String)
|
166
|
+
fees.find { |fee| fee.membership_period_fee? && fee.period == period && fee.category_id == category.id && fee.category_type == category.class.name && (except.blank? || fee.fee_type != except) }
|
167
|
+
end
|
168
|
+
|
163
169
|
def build_renewal_fee(category:, period:, late_on: nil, bad_standing_on: nil)
|
164
170
|
raise('must have an existing membership') unless membership.present?
|
165
171
|
|
172
|
+
# Sanity check.
|
173
|
+
# If there's already a purchased or unpurchased Prorated (or other membership period advancing fee) in this period
|
174
|
+
# We shouldn't be building renewal fees for the same period a prorated fee is purcahsed in
|
175
|
+
prorated = membership_period_fee(category: category, period: period, except: 'Renewal')
|
176
|
+
raise('must not have an existing membership_period (prorated) fee in this period') if prorated.present?
|
177
|
+
|
166
178
|
fee = fees.find { |fee| fee.fee_type == 'Renewal' && fee.period == period && fee.category_id == category.id && fee.category_type == category.class.name }
|
167
179
|
return fee if fee&.purchased?
|
168
180
|
|
@@ -33,6 +33,15 @@ module EffectiveMembershipsRegistrar
|
|
33
33
|
raise('to be implemented by app registrar')
|
34
34
|
end
|
35
35
|
|
36
|
+
# Should two could be overridden if we do non 1-year periods
|
37
|
+
def advance_period(period:, number:)
|
38
|
+
period.advance(years: number).beginning_of_year
|
39
|
+
end
|
40
|
+
|
41
|
+
def period_end_on(date:)
|
42
|
+
period(date: date).end_of_year
|
43
|
+
end
|
44
|
+
|
36
45
|
def assign!(owner, categories:, date: nil, number: nil)
|
37
46
|
categories = Array(categories)
|
38
47
|
|
@@ -243,18 +252,41 @@ module EffectiveMembershipsRegistrar
|
|
243
252
|
period(date: Time.zone.now)
|
244
253
|
end
|
245
254
|
|
255
|
+
def last_period
|
256
|
+
advance_period(period: current_period, number: -1)
|
257
|
+
end
|
258
|
+
|
246
259
|
# Returns a date of Jan 1, Year
|
247
260
|
def period(date:)
|
248
261
|
cutoff = renewal_fee_date(date: date) # period_end_on
|
249
|
-
period = (date < cutoff) ? date
|
262
|
+
period = (date < cutoff) ? advance_period(period: date, number: 0) : advance_period(period: date, number: 1)
|
250
263
|
period.to_date
|
251
264
|
end
|
252
265
|
|
253
|
-
|
254
|
-
|
266
|
+
# This is only used for a form collection on admin memberships
|
267
|
+
def periods(from:, to: nil)
|
268
|
+
to ||= Time.zone.now
|
269
|
+
|
270
|
+
raise('expected to date') unless to.respond_to?(:strftime)
|
271
|
+
raise('expected from date') unless from.respond_to?(:strftime)
|
272
|
+
|
273
|
+
from = period(date: from)
|
274
|
+
to = period(date: to)
|
275
|
+
|
276
|
+
retval = []
|
277
|
+
|
278
|
+
loop do
|
279
|
+
retval << from
|
280
|
+
from = advance_period(period: from, number: 1)
|
281
|
+
break if from > to
|
282
|
+
end
|
283
|
+
|
284
|
+
retval
|
255
285
|
end
|
256
286
|
|
287
|
+
|
257
288
|
# This is intended to be run once per day in a rake task
|
289
|
+
# rake effective_memberships:create_fees
|
258
290
|
# Create Renewal and Late fees
|
259
291
|
def create_fees!(period: nil, late_on: nil, bad_standing_on: nil)
|
260
292
|
# The current period, based on Time.zone.now
|
@@ -263,13 +295,17 @@ module EffectiveMembershipsRegistrar
|
|
263
295
|
bad_standing_on ||= bad_standing_date(period: period)
|
264
296
|
|
265
297
|
# Create Renewal Fees
|
266
|
-
Effective::Membership.
|
267
|
-
|
298
|
+
Effective::Membership.deep.with_unpaid_fees_through(period).find_each do |membership|
|
268
299
|
membership.categories.select(&:create_renewal_fees?).map do |category|
|
300
|
+
existing = membership.owner.membership_period_fee(category: category, period: period, except: 'Renewal')
|
301
|
+
next if existing.present? # This might be an existing Prorated fee
|
302
|
+
|
269
303
|
fee = membership.owner.build_renewal_fee(category: category, period: period, late_on: late_on, bad_standing_on: bad_standing_on)
|
270
304
|
raise("expected build_renewal_fee to return a fee for period #{period}") unless fee.kind_of?(Effective::Fee)
|
271
305
|
next if fee.purchased?
|
272
306
|
|
307
|
+
puts("Created renewal fee for #{membership.owner}") if fee.new_record? && !Rails.env.test?
|
308
|
+
|
273
309
|
fee.save!
|
274
310
|
end
|
275
311
|
end
|
@@ -277,7 +313,7 @@ module EffectiveMembershipsRegistrar
|
|
277
313
|
GC.start
|
278
314
|
|
279
315
|
# Create Late Fees
|
280
|
-
Effective::Membership.
|
316
|
+
Effective::Membership.deep.with_unpaid_fees_through(period).find_each do |membership|
|
281
317
|
membership.categories.select(&:create_late_fees?).map do |category|
|
282
318
|
fee = membership.owner.build_late_fee(category: category, period: period)
|
283
319
|
next if fee.blank? || fee.purchased?
|
@@ -42,18 +42,6 @@ module Effective
|
|
42
42
|
.or(where(fees_paid_period: nil))
|
43
43
|
}
|
44
44
|
|
45
|
-
scope :create_renewal_fees, -> (period = nil) {
|
46
|
-
deep.with_unpaid_fees_through(period).where.not(fees_paid_period: nil) # Must have purchased a Prorated or Renewal Fee before
|
47
|
-
}
|
48
|
-
|
49
|
-
scope :create_late_fees, -> (period = nil) {
|
50
|
-
deep.with_unpaid_fees_through(period).where.not(fees_paid_period: nil) # Must have purchased a Prorated or Renewal Fee before
|
51
|
-
}
|
52
|
-
|
53
|
-
scope :create_bad_standing, -> (period = nil) {
|
54
|
-
deep.with_unpaid_fees_through(period).where.not(fees_paid_period: nil) # Must have purchased a Prorated or Renewal Fee before
|
55
|
-
}
|
56
|
-
|
57
45
|
before_validation do
|
58
46
|
self.registration_on ||= joined_on
|
59
47
|
end
|
@@ -134,5 +122,18 @@ module Effective
|
|
134
122
|
fees_paid_period == EffectiveMemberships.Registrar.current_period
|
135
123
|
end
|
136
124
|
|
125
|
+
def change_fees_paid_period
|
126
|
+
fees_paid_period
|
127
|
+
end
|
128
|
+
|
129
|
+
def change_fees_paid_period=(date)
|
130
|
+
date = (date.respond_to?(:strftime) ? date : Date.parse(date))
|
131
|
+
|
132
|
+
period = EffectiveMemberships.Registrar.period(date: date)
|
133
|
+
period_end_on = EffectiveMemberships.Registrar.period_end_on(date: date)
|
134
|
+
|
135
|
+
assign_attributes(fees_paid_period: period, fees_paid_through_period: period_end_on)
|
136
|
+
end
|
137
|
+
|
137
138
|
end
|
138
139
|
end
|
@@ -17,6 +17,12 @@
|
|
17
17
|
= f.date_field :registration_on, label: 'Registered', hint: 'When the membership category last changed'
|
18
18
|
= f.text_field :number, hint: 'The membership number. Must be unique.'
|
19
19
|
|
20
|
+
- registrar = EffectiveMemberships.Registrar
|
21
|
+
- periods = registrar.periods(from: f.object.joined_on)
|
22
|
+
- collection = periods.reverse.map { |period| [registrar.period_end_on(date: period), period] }
|
23
|
+
|
24
|
+
= f.select :change_fees_paid_period, collection, label: 'Fees Paid Through', hint: 'Which period this user has fees paid through. Can change how renewal fees are created.'
|
25
|
+
|
20
26
|
%p.text-muted To update the current membership categories, use the 'Assign' or 'Reclassify' actions below
|
21
27
|
|
22
28
|
= f.submit 'Update Membership', border: false, center: true, 'data-confirm': "Really update #{f.object.owner}?"
|
@@ -5,7 +5,7 @@
|
|
5
5
|
- if organization.persisted?
|
6
6
|
- if can?(:index, Effective::Membership)
|
7
7
|
= tab 'Membership' do
|
8
|
-
= render 'admin/
|
8
|
+
= render 'admin/memberships/form', owner: organization
|
9
9
|
|
10
10
|
= tab 'Representatives' do
|
11
11
|
= render_datatable(Admin::EffectiveRepresentativesDatatable.new(organization: organization), inline: true, namespace: :admin)
|
@@ -18,10 +18,6 @@
|
|
18
18
|
= tab 'Fee Payments' do
|
19
19
|
= render_inline_datatable(Admin::EffectiveFeePaymentsDatatable.new(organization: organization))
|
20
20
|
|
21
|
-
- if can?(:index, Effective::MembershipHistory)
|
22
|
-
= tab 'History' do
|
23
|
-
= render_datatable(Admin::EffectiveMembershipHistoriesDatatable.new(owner: organization))
|
24
|
-
|
25
21
|
- if can?(:index, Effective::Order)
|
26
22
|
= tab 'Orders' do
|
27
23
|
= render_datatable(Admin::EffectiveOrdersDatatable.new(user: organization))
|
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.
|
4
|
+
version: 0.4.7
|
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
|
+
date: 2022-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|