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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e5b6f09a47c7b274a7719fa302b98201fc0bcdfe574c290d217ad7b1720646b
4
- data.tar.gz: 43a42af2d316ac1ba9279dbf366ef343532e808f1b21c444b8945ea78f61536a
3
+ metadata.gz: 3a59918a13a42cc9da99200ecfa61ed9b45ae8881ca7e9c0d4e2fd0117605003
4
+ data.tar.gz: b1955f238384bbb8cfc4836ad06357b1b815c47c23a9e8ac11303e858feb8379
5
5
  SHA512:
6
- metadata.gz: f9e710cb88c81069d68cebad01b05d6db0fe4c7cbf0feca67d28836f03518bd1deb57ec0d41ba5bc3624128bc2d528932e5aaba48f638da49c69144873e6adf7
7
- data.tar.gz: fa0176f7fa8e24ca28073ae54678c33b99ccde6e65ae2d107ad77301423fac0fcec3a6ee46a348de77a67be99fad6311643e1444b8e266e1593032570ecd6204
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
- datatable do
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 :title
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.all
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.beginning_of_year : date.advance(years: 1).beginning_of_year
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
- def period_end_on(date:)
254
- period(date: date).end_of_year
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.create_renewal_fees(period).find_each do |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.create_late_fees(period).find_each do |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}?"
@@ -2,5 +2,3 @@
2
2
 
3
3
  - if categories.present?
4
4
  = f.select :category, categories, required: true
5
-
6
- = f.text_field :title
@@ -5,7 +5,7 @@
5
5
  - if organization.persisted?
6
6
  - if can?(:index, Effective::Membership)
7
7
  = tab 'Membership' do
8
- = render 'admin/registrar_actions/form', owner: organization
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))
@@ -3,9 +3,7 @@
3
3
  .col-sm-6
4
4
  %h2 Demographics
5
5
  = render 'admin/organizations/fields', f: f
6
-
7
- %h2 Billing Address
8
- = effective_address_fields(f, :billing)
6
+ = render 'organizations/fields_demographics', f: f
9
7
 
10
8
  .col-sm-6
11
9
  %h2 Membership
@@ -1,3 +1,3 @@
1
1
  module EffectiveMemberships
2
- VERSION = '0.4.4'
2
+ VERSION = '0.4.7'
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.4.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-03-30 00:00:00.000000000 Z
11
+ date: 2022-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails