effective_memberships 0.3.14 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/admin/organizations_controller.rb +19 -0
  3. data/app/controllers/admin/representatives_controller.rb +19 -0
  4. data/app/controllers/effective/applicants_controller.rb +2 -3
  5. data/app/controllers/effective/fee_payments_controller.rb +1 -2
  6. data/app/controllers/effective/organizations_controller.rb +16 -0
  7. data/app/controllers/effective/representatives_controller.rb +19 -0
  8. data/app/datatables/admin/effective_applicants_datatable.rb +10 -5
  9. data/app/datatables/admin/effective_categories_datatable.rb +7 -0
  10. data/app/datatables/admin/effective_fee_payments_datatable.rb +11 -6
  11. data/app/datatables/admin/effective_organizations_datatable.rb +31 -0
  12. data/app/datatables/admin/effective_representatives_datatable.rb +28 -0
  13. data/app/datatables/effective_applicants_datatable.rb +1 -1
  14. data/app/datatables/effective_fee_payments_datatable.rb +5 -4
  15. data/app/datatables/effective_organizations_datatable.rb +18 -0
  16. data/app/datatables/effective_representatives_datatable.rb +40 -0
  17. data/app/helpers/effective_memberships_helper.rb +25 -0
  18. data/app/mailers/effective/memberships_mailer.rb +7 -7
  19. data/app/models/concerns/effective_memberships_applicant.rb +63 -30
  20. data/app/models/concerns/effective_memberships_category.rb +32 -5
  21. data/app/models/concerns/effective_memberships_fee_payment.rb +44 -45
  22. data/app/models/concerns/effective_memberships_organization.rb +94 -0
  23. data/app/models/concerns/effective_memberships_owner.rb +0 -55
  24. data/app/models/concerns/effective_memberships_registrar.rb +2 -2
  25. data/app/models/concerns/effective_memberships_user.rb +70 -0
  26. data/app/models/effective/fee.rb +1 -1
  27. data/app/models/effective/organization.rb +8 -0
  28. data/app/models/effective/representative.rb +56 -0
  29. data/app/views/admin/categories/_form_applicant_eligibility.html.haml +1 -1
  30. data/app/views/admin/categories/_form_applicant_steps.html.haml +29 -24
  31. data/app/views/admin/categories/_form_category.html.haml +3 -0
  32. data/app/views/admin/categories/_form_renewals.html.haml +0 -2
  33. data/app/views/admin/organizations/_fields.html.haml +6 -0
  34. data/app/views/admin/organizations/_form.html.haml +31 -0
  35. data/app/views/admin/organizations/_form_organization.html.haml +23 -0
  36. data/app/views/admin/representatives/_form.html.haml +38 -0
  37. data/app/views/{effective/applicants/_demographics_fields.html.haml → admin/representatives/_user_fields.html.haml} +2 -6
  38. data/app/views/effective/applicants/_dashboard.html.haml +24 -5
  39. data/app/views/effective/applicants/_demographics.html.haml +1 -1
  40. data/app/views/effective/applicants/_missing_info.html.haml +7 -3
  41. data/app/views/effective/applicants/_organization.html.haml +9 -0
  42. data/app/views/effective/applicants/_select_organization.html.haml +21 -0
  43. data/app/views/effective/applicants/_summary.html.haml +17 -9
  44. data/app/views/effective/applicants/billing.html.haml +2 -2
  45. data/app/views/effective/applicants/demographics.html.haml +7 -6
  46. data/app/views/effective/applicants/education.html.haml +2 -2
  47. data/app/views/effective/applicants/organization.html.haml +19 -0
  48. data/app/views/effective/applicants/references.html.haml +1 -1
  49. data/app/views/effective/applicants/select.html.haml +11 -1
  50. data/app/views/effective/applicants/stamp.html.haml +2 -2
  51. data/app/views/effective/applicants/start.html.haml +17 -11
  52. data/app/views/effective/applicants/submitted.html.haml +5 -5
  53. data/app/views/effective/applicants/summary.html.haml +1 -1
  54. data/app/views/effective/fee_payments/_demographics.html.haml +1 -1
  55. data/app/views/effective/fee_payments/_organization.html.haml +9 -0
  56. data/app/views/effective/fee_payments/_summary.html.haml +39 -1
  57. data/app/views/effective/fee_payments/billing.html.haml +2 -2
  58. data/app/views/effective/fee_payments/demographics.html.haml +2 -2
  59. data/app/views/effective/fee_payments/organization.html.haml +18 -0
  60. data/app/views/effective/fee_payments/start.html.haml +20 -17
  61. data/app/views/effective/fee_payments/submitted.html.haml +10 -3
  62. data/app/views/effective/fees/_dashboard.html.haml +20 -8
  63. data/app/views/effective/memberships/_dashboard.html.haml +16 -5
  64. data/app/views/effective/organizations/_dashboard.html.haml +10 -0
  65. data/app/views/effective/organizations/_form.html.haml +8 -0
  66. data/app/views/effective/organizations/_form_organization.html.haml +11 -0
  67. data/app/views/effective/representatives/_form.html.haml +33 -0
  68. data/app/views/effective/{fee_payments/_demographics_fields.html.haml → representatives/_user_fields.html.haml} +2 -6
  69. data/app/views/organizations/_demographics.html.haml +45 -0
  70. data/app/views/organizations/_fields_demographics.html.haml +29 -0
  71. data/app/views/users/_demographics.html.haml +50 -0
  72. data/app/views/users/_fields_demographics.html.haml +29 -0
  73. data/config/effective_memberships.rb +3 -0
  74. data/config/routes.rb +9 -0
  75. data/db/migrate/01_create_effective_memberships.rb.erb +57 -10
  76. data/db/seeds.rb +18 -0
  77. data/lib/effective_memberships/engine.rb +3 -0
  78. data/lib/effective_memberships/version.rb +1 -1
  79. data/lib/effective_memberships.rb +6 -2
  80. metadata +33 -20
  81. data/app/views/effective/applicants/_demographics_owner.html.haml +0 -20
  82. data/app/views/effective/fee_payments/_demographics_owner.html.haml +0 -20
@@ -16,6 +16,10 @@ module EffectiveMembershipsCategory
16
16
  module ClassMethods
17
17
  def effective_memberships_category?; true; end
18
18
 
19
+ def category_types
20
+ ['Individual', 'Organization']
21
+ end
22
+
19
23
  def categories
20
24
  []
21
25
  end
@@ -35,6 +39,8 @@ module EffectiveMembershipsCategory
35
39
  has_many :membership_categories, class_name: 'Effective::MembershipCategory', as: :category
36
40
 
37
41
  effective_resource do
42
+ category_type :string
43
+
38
44
  title :string
39
45
  category :string
40
46
  position :integer
@@ -110,17 +116,18 @@ module EffectiveMembershipsCategory
110
116
  scope :create_bad_standing, -> { where(create_bad_standing: true) }
111
117
 
112
118
  validates :title, presence: true, uniqueness: true
113
-
119
+ validates :category_type, presence: true
114
120
  validates :position, presence: true
115
121
 
116
- after_initialize(if: -> { new_record? }) do
117
- self.applicant_wizard_steps = EffectiveMemberships.Applicant.all_wizard_steps
118
- self.applicant_review_wizard_steps = EffectiveMemberships.ApplicantReview.all_wizard_steps
119
- self.fee_payment_wizard_steps = EffectiveMemberships.FeePayment.all_wizard_steps
122
+ before_validation do
123
+ self.applicant_wizard_steps = EffectiveMemberships.Applicant.all_wizard_steps if applicant_wizard_steps.blank?
124
+ self.applicant_review_wizard_steps = EffectiveMemberships.ApplicantReview.all_wizard_steps if applicant_review_wizard_steps.blank?
125
+ self.fee_payment_wizard_steps = EffectiveMemberships.FeePayment.all_wizard_steps if fee_payment_wizard_steps.blank?
120
126
  end
121
127
 
122
128
  before_validation do
123
129
  self.position ||= (self.class.pluck(:position).compact.max || -1) + 1
130
+ self.category_type ||= self.class.category_types.first
124
131
  end
125
132
 
126
133
  with_options(if: -> { can_apply? }) do
@@ -155,6 +162,14 @@ module EffectiveMembershipsCategory
155
162
  can_apply_new? || can_apply_existing? || can_apply_restricted?
156
163
  end
157
164
 
165
+ def individual?
166
+ category_type == 'Individual'
167
+ end
168
+
169
+ def organization?
170
+ category_type == 'Organization'
171
+ end
172
+
158
173
  def prorated_fee(date:)
159
174
  send("prorated_#{date.strftime('%b').downcase}").to_i
160
175
  end
@@ -167,6 +182,18 @@ module EffectiveMembershipsCategory
167
182
  Array(self[:can_apply_restricted_ids]) - [nil, '']
168
183
  end
169
184
 
185
+ def optional_applicant_wizard_steps
186
+ applicant_wizard_steps - EffectiveMemberships.Applicant.required_wizard_steps
187
+ end
188
+
189
+ def optional_fee_payment_wizard_steps
190
+ fee_payment_wizard_steps - EffectiveMemberships.FeePayment.required_wizard_steps
191
+ end
192
+
193
+ def optional_applicant_review_wizard_steps
194
+ applicant_review_wizard_steps - EffectiveMemberships.ApplicantReview.required_wizard_steps
195
+ end
196
+
170
197
  def applicant_wizard_steps
171
198
  (Array(self[:applicant_wizard_steps]) - [nil, '']).map(&:to_sym)
172
199
  end
@@ -32,7 +32,8 @@ module EffectiveMembershipsFeePayment
32
32
 
33
33
  acts_as_wizard(
34
34
  start: 'Start',
35
- demographics: 'Demographics',
35
+ demographics: 'Demographics', # Individual only. Users fields.
36
+ organization: 'Organization', # Organization only. Organization fields.
36
37
  declarations: 'Declarations',
37
38
  summary: 'Review',
38
39
  billing: 'Billing Address',
@@ -48,23 +49,20 @@ module EffectiveMembershipsFeePayment
48
49
  attr_accessor :declare_code_of_ethics
49
50
  attr_accessor :declare_truth
50
51
 
51
- # Throwaway
52
- attr_accessor :upgrade, :downgrade
53
-
54
52
  # Application Namespace
55
- belongs_to :owner, polymorphic: true
56
- accepts_nested_attributes_for :owner
57
-
58
- belongs_to :user, polymorphic: true, optional: true
53
+ belongs_to :user, polymorphic: true
59
54
  accepts_nested_attributes_for :user
60
55
 
56
+ belongs_to :organization, polymorphic: true, optional: true
57
+ accepts_nested_attributes_for :organization
58
+
61
59
  # Like maybe optionally it makes sense.
62
60
  belongs_to :category, polymorphic: true, optional: true
63
61
 
62
+ # Effective Namespace
64
63
  has_many :fees, -> { order(:id) }, as: :parent, class_name: 'Effective::Fee', dependent: :nullify
65
64
  accepts_nested_attributes_for :fees, reject_if: :all_blank, allow_destroy: true
66
65
 
67
- # Effective Namespace
68
66
  has_many :orders, -> { order(:id) }, as: :parent, class_name: 'Effective::Order', dependent: :nullify
69
67
  accepts_nested_attributes_for :orders
70
68
 
@@ -83,24 +81,32 @@ module EffectiveMembershipsFeePayment
83
81
  timestamps
84
82
  end
85
83
 
86
- scope :deep, -> { includes(:owner, :category, :orders) }
84
+ scope :deep, -> { includes(:user, :organization, :category, :orders) }
87
85
  scope :sorted, -> { order(:id) }
88
86
 
89
87
  scope :in_progress, -> { where.not(status: [:submitted]) }
90
88
  scope :done, -> { where(status: [:submitted]) }
91
89
 
90
+ scope :for, -> (user) {
91
+ raise('expected a effective memberships user') unless user.class.try(:effective_memberships_user?)
92
+ where(user: user).or(where(organization: user.organizations))
93
+ }
94
+
92
95
  before_validation do
93
96
  self.period ||= EffectiveMemberships.Registrar.current_period
94
97
  end
95
98
 
96
- before_validation(if: -> { current_step == :start && owner && owner.membership }) do
97
- self.category ||= owner.membership.categories.first if owner.membership.categories.length == 1
99
+ before_validation(if: -> { new_record? || current_step == :start }) do
100
+ self.organization_type = (EffectiveMemberships.Organization.name if organization_id.present?)
98
101
  end
99
102
 
100
- validates :period, presence: true
103
+ before_validation(if: -> { current_step == :start && user && user.membership }) do
104
+ self.category ||= user.membership.categories.first if user.membership.categories.length == 1
105
+ end
101
106
 
102
107
  # All Steps validations
103
- validates :owner, presence: true
108
+ validates :user, presence: true
109
+ validates :period, presence: true
104
110
 
105
111
  # Declarations Step
106
112
  with_options(if: -> { current_step == :declarations }) do
@@ -121,6 +127,9 @@ module EffectiveMembershipsFeePayment
121
127
 
122
128
  fee_payment_steps = Array(category&.fee_payment_wizard_steps)
123
129
 
130
+ fee_payment_steps.delete(:organization) unless organization?
131
+
132
+
124
133
  wizard_steps.select do |step|
125
134
  required_steps.include?(step) || category.blank? || fee_payment_steps.include?(step)
126
135
  end
@@ -129,10 +138,6 @@ module EffectiveMembershipsFeePayment
129
138
 
130
139
  # All Fees and Orders
131
140
  # Overriding acts_as_purchasable_wizard
132
- def outstanding_fees
133
- owner&.outstanding_fee_payment_fees
134
- end
135
-
136
141
  def submit_fees
137
142
  fees
138
143
  end
@@ -143,7 +148,7 @@ module EffectiveMembershipsFeePayment
143
148
 
144
149
  # We take over the owner's outstanding fees.
145
150
  def find_or_build_submit_fees
146
- Array(outstanding_fees).each { |fee| fees << fee unless fees.include?(fee) }
151
+ Array(owner.outstanding_fee_payment_fees).each { |fee| fees << fee unless fees.include?(fee) }
147
152
  submit_fees
148
153
  end
149
154
 
@@ -157,6 +162,26 @@ module EffectiveMembershipsFeePayment
157
162
  'Fee Payment'
158
163
  end
159
164
 
165
+ def owner
166
+ organization || user
167
+ end
168
+
169
+ def owner_symbol
170
+ organization? ? :organization : :user
171
+ end
172
+
173
+ def build_organization(params = {})
174
+ self.organization = EffectiveMemberships.Organization.new(params)
175
+ end
176
+
177
+ def individual?
178
+ !owner.kind_of?(EffectiveMemberships.Organization)
179
+ end
180
+
181
+ def organization?
182
+ owner.kind_of?(EffectiveMemberships.Organization)
183
+ end
184
+
160
185
  # Instance Methods
161
186
  def in_progress?
162
187
  draft?
@@ -175,30 +200,4 @@ module EffectiveMembershipsFeePayment
175
200
  save!
176
201
  end
177
202
 
178
- # Work with effective_organizations
179
- def organization!
180
- if upgrade_individual_to_organization?
181
- save!
182
- update!(owner: owner.representatives.first.organization)
183
- elsif downgrade_organization_to_individual?
184
- save!
185
- update!(owner: current_user)
186
- else
187
- save!
188
- end
189
- end
190
-
191
- def upgrade_individual_to_organization?
192
- return false unless EffectiveResources.truthy?(upgrade)
193
- return false unless owner.class.respond_to?(:effective_organizations_user?)
194
- owner.representatives.any?(&:new_record?)
195
- end
196
-
197
- def downgrade_organization_to_individual?
198
- return false unless EffectiveResources.truthy?(downgrade)
199
- return false unless owner.class.respond_to?(:effective_organizations_organization?)
200
- return false if current_user.blank?
201
- owner.representatives.any?(&:marked_for_destruction?)
202
- end
203
-
204
203
  end
@@ -0,0 +1,94 @@
1
+ # EffectiveMembershipsOrganization
2
+ #
3
+ # Mark your category model with effective_memberships_organization to get all the includes
4
+
5
+ module EffectiveMembershipsOrganization
6
+ extend ActiveSupport::Concern
7
+
8
+ module Base
9
+ def effective_memberships_organization
10
+ include ::EffectiveMembershipsOrganization
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def effective_memberships_organization?; true; end
16
+
17
+ def categories
18
+ []
19
+ end
20
+ end
21
+
22
+ included do
23
+ effective_memberships_owner
24
+
25
+ acts_as_addressable :billing # effective_addresses
26
+ log_changes(except: [:representatives, :users]) if respond_to?(:log_changes)
27
+
28
+ # rich_text_body
29
+ # has_many_rich_texts
30
+
31
+ # App scoped
32
+ has_many :applicants, -> { order(:id) }, inverse_of: :organization, as: :organization
33
+ has_many :fee_payments, -> { order(:id) }, inverse_of: :organization, as: :organization
34
+
35
+ # Effective scoped
36
+ has_many :representatives, -> { Effective::Representative.sorted },
37
+ class_name: 'Effective::Representative', inverse_of: :organization, dependent: :delete_all
38
+
39
+ accepts_nested_attributes_for :representatives, allow_destroy: true
40
+
41
+ effective_resource do
42
+ title :string
43
+ email :string
44
+
45
+ phone :string
46
+ fax :string
47
+ website :string
48
+
49
+ category :string
50
+
51
+ notes :text
52
+
53
+ roles_mask :integer
54
+ archived :boolean
55
+
56
+ representatives_count :integer # Counter cache
57
+
58
+ timestamps
59
+ end
60
+
61
+ scope :deep, -> { includes(:representatives) }
62
+ scope :sorted, -> { order(:title) }
63
+
64
+ validates :title, presence: true, uniqueness: true
65
+ validates :email, presence: true
66
+ end
67
+
68
+ # Instance Methods
69
+ def to_s
70
+ title.presence || 'organization'
71
+ end
72
+
73
+ def membership_present?
74
+ membership.present? && !membership.marked_for_destruction?
75
+ end
76
+
77
+ def outstanding_fee_payment_fees
78
+ fees.select { |fee| fee.fee_payment_fee? && !fee.purchased? }
79
+ end
80
+
81
+ def representative(user:)
82
+ representatives.find { |rep| rep.user_id == user.id }
83
+ end
84
+
85
+ # Find or build
86
+ def build_representative(user:)
87
+ representative(user: user) || representatives.build(user: user)
88
+ end
89
+
90
+ def users
91
+ representatives.reject(&:marked_for_destruction?).map(&:user)
92
+ end
93
+
94
+ end
@@ -23,10 +23,6 @@ module EffectiveMembershipsOwner
23
23
  included do
24
24
  acts_as_role_restricted unless respond_to?(:acts_as_role_restricted?)
25
25
 
26
- # App scoped
27
- has_many :applicants, -> { order(:id) }, inverse_of: :owner, as: :owner
28
- has_many :fee_payments, -> { order(:id) }, inverse_of: :owner, as: :owner
29
-
30
26
  # Effective scoped
31
27
  has_many :fees, -> { order(:id) }, inverse_of: :owner, as: :owner, class_name: 'Effective::Fee', dependent: :nullify
32
28
  accepts_nested_attributes_for :fees, reject_if: :all_blank, allow_destroy: true
@@ -40,48 +36,9 @@ module EffectiveMembershipsOwner
40
36
  has_many :membership_histories, -> { Effective::MembershipHistory.sorted }, inverse_of: :owner, as: :owner, class_name: 'Effective::MembershipHistory'
41
37
  accepts_nested_attributes_for :membership_histories
42
38
 
43
- effective_resource do
44
- timestamps
45
- end
46
-
47
39
  scope :members, -> { joins(:membership) }
48
40
  end
49
41
 
50
- def effective_memberships_owner
51
- raise('expected singular usage but there are more than one owner') if effective_memberships_owners.length > 1
52
- effective_memberships_owners.first
53
- end
54
-
55
- def effective_memberships_owners
56
- owners = organizations if self.class.respond_to?(:effective_organizations_user?)
57
- owners = users if self.class.respond_to?(:effective_organizations_organization?)
58
-
59
- owners = Array(owners)
60
- .select { |owner| owner.class.respond_to?(:effective_memberships_owner?) }
61
- .reject { |owner| owner.try(:archived?) }
62
-
63
- owners.presence || [self]
64
- end
65
-
66
- # This is the calculated way of determining if an owner is a member or not.
67
- # The correct way to check for membership is: current_user.is?(:member)
68
- def membership_present?
69
- individual_membership_present? || organization_membership_present?
70
- end
71
-
72
- def individual_membership_present?
73
- membership.present? && !membership.marked_for_destruction?
74
- end
75
-
76
- def organization_membership_present?(except: nil)
77
- return false unless self.class.respond_to?(:effective_organizations_user?)
78
-
79
- organizations
80
- .select { |organization| organization.class.respond_to?(:effective_memberships_owner?) }
81
- .reject { |organization| organization.try(:archived?) }
82
- .any? { |organization| organization != except && organization.membership_present? }
83
- end
84
-
85
42
  def assign_member_role
86
43
  membership_present? ? add_role(:member) : remove_role(:member)
87
44
  end
@@ -92,18 +49,6 @@ module EffectiveMembershipsOwner
92
49
  save!
93
50
  end
94
51
 
95
- def outstanding_fee_payment_owners
96
- effective_memberships_owners.select { |owner| !owner.membership_fees_paid? }
97
- end
98
-
99
- def current_fee_payment_owner
100
- outstanding_fee_payment_owners.first || self
101
- end
102
-
103
- def owner_label
104
- self.class.name.split('::').last
105
- end
106
-
107
52
  def membership_fees_paid?
108
53
  outstanding_fee_payment_fees.blank? && membership && membership.fees_paid?
109
54
  end
@@ -305,7 +305,7 @@ module EffectiveMembershipsRegistrar
305
305
  def add_member_role(owner)
306
306
  owner.add_role(:member)
307
307
 
308
- if owner.class.respond_to?(:effective_organizations_organization?)
308
+ if owner.class.respond_to?(:effective_memberships_organization?)
309
309
  organization = owner
310
310
  organization.representatives.each { |representative| representative.user.add_role(:member) }
311
311
  end
@@ -316,7 +316,7 @@ module EffectiveMembershipsRegistrar
316
316
  def remove_member_role(owner)
317
317
  owner.remove_role(:member)
318
318
 
319
- if owner.class.respond_to?(:effective_organizations_organization?)
319
+ if owner.class.respond_to?(:effective_memberships_organization?)
320
320
  organization = owner
321
321
 
322
322
  organization.representatives.each do |representative|
@@ -0,0 +1,70 @@
1
+ # EffectiveMembershipsUser
2
+ #
3
+ # Mark your user model with effective_memberships_user to get all the includes
4
+
5
+ module EffectiveMembershipsUser
6
+ extend ActiveSupport::Concern
7
+
8
+ module Base
9
+ def effective_memberships_user
10
+ include ::EffectiveMembershipsUser
11
+ end
12
+ end
13
+
14
+ module ClassMethods
15
+ def effective_memberships_user?; true; end
16
+ end
17
+
18
+ included do
19
+ effective_memberships_owner
20
+
21
+ # App scoped
22
+ has_many :applicants, -> { order(:id) }, inverse_of: :user, as: :user
23
+ has_many :fee_payments, -> { order(:id) }, inverse_of: :user, as: :user
24
+
25
+ # Effective Scoped
26
+ has_many :representatives, -> { Effective::Representative.sorted },
27
+ class_name: 'Effective::Representative', inverse_of: :user, dependent: :delete_all
28
+
29
+ accepts_nested_attributes_for :representatives, allow_destroy: true
30
+ end
31
+
32
+ # Instance Methods
33
+ def memberships
34
+ Array(membership) + membership_organizations.map(&:membership)
35
+ end
36
+
37
+ def memberships_owners
38
+ Array(is?(:member) ? self : nil) + membership_organizations
39
+ end
40
+
41
+ def membership_present?
42
+ individual_membership_present? || organization_membership_present?
43
+ end
44
+
45
+ def individual_membership_present?
46
+ membership.present? && !membership.marked_for_destruction?
47
+ end
48
+
49
+ def organization_membership_present?(except: nil)
50
+ organizations.reject(&:archived?).any? { |organization| organization != except && organization.membership_present? }
51
+ end
52
+
53
+ def representative(organization:)
54
+ representatives.find { |rep| rep.organization_id == organization.id } if organization
55
+ end
56
+
57
+ # Find or build
58
+ def build_representative(organization:)
59
+ representative(organization: organization) || representatives.build(organization: organization)
60
+ end
61
+
62
+ def organizations
63
+ representatives.reject(&:marked_for_destruction?).map(&:organization)
64
+ end
65
+
66
+ def membership_organizations
67
+ organizations.select { |organization| organization.is?(:member) && !organization.archived? }
68
+ end
69
+
70
+ end
@@ -4,7 +4,7 @@ module Effective
4
4
 
5
5
  log_changes(to: :owner) if respond_to?(:log_changes)
6
6
 
7
- # Every fee is charged to a owner
7
+ # Every fee is charged to a owner: a user or an organization
8
8
  belongs_to :owner, polymorphic: true
9
9
 
10
10
  # This fee may belong to an application, fee payment, or other parent model
@@ -0,0 +1,8 @@
1
+ module Effective
2
+ class Organization < ActiveRecord::Base
3
+ self.table_name = EffectiveMemberships.organizations_table_name.to_s
4
+
5
+ effective_memberships_organization
6
+
7
+ end
8
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Effective
4
+ class Representative < ActiveRecord::Base
5
+ attr_accessor :new_representative_user_action
6
+
7
+ acts_as_role_restricted
8
+
9
+ log_changes(to: :organization) if respond_to?(:log_changes)
10
+
11
+ belongs_to :organization, polymorphic: true, counter_cache: true
12
+ belongs_to :user, polymorphic: true
13
+
14
+ accepts_nested_attributes_for :organization
15
+ accepts_nested_attributes_for :user
16
+
17
+ effective_resource do
18
+ roles_mask :integer
19
+
20
+ timestamps
21
+ end
22
+
23
+ scope :sorted, -> { order(:id) }
24
+ scope :deep, -> { includes(:user, :organization) }
25
+
26
+ before_validation(if: -> { user && user.new_record? }) do
27
+ user.password ||= SecureRandom.base64(12) + '!@#123abcABC-'
28
+ end
29
+
30
+ after_commit(on: [:create, :destroy], if: -> { user.class.respond_to?(:effective_memberships_owner?) }) do
31
+ user.representatives.reload
32
+ user.update_member_role!
33
+ end
34
+
35
+ validates :organization, presence: true
36
+ validates :user, presence: true
37
+
38
+ validates :user_id, if: -> { user_id && user_type && organization_id && organization_type },
39
+ uniqueness: { scope: [:organization_id, :organization_type], message: 'already belongs to this organization' }
40
+
41
+ def to_s
42
+ user.to_s
43
+ end
44
+
45
+ def build_user(attributes = {})
46
+ raise('please assign user_type first') if user_type.blank?
47
+ self.user = user_type.constantize.new(attributes)
48
+ end
49
+
50
+ def build_organization(attributes = {})
51
+ raise('please assign organization_type first') if organization_type.blank?
52
+ self.organization = organization_type.constantize.new(attributes)
53
+ end
54
+
55
+ end
56
+ end
@@ -2,7 +2,7 @@
2
2
  %h3 Eligibility
3
3
  %p Please configure who may apply for this membership category.
4
4
 
5
- = f.check_box :can_apply_new, label: 'Yes, new users may apply to join'
5
+ = f.check_box :can_apply_new, label: 'Yes, new applicants may apply to join'
6
6
  = f.check_box :can_apply_existing, label: 'Yes, existing members of any category may apply to join'
7
7
  = f.check_box :can_apply_restricted, label: 'Only existing members of the following categories may apply to join'
8
8
 
@@ -14,29 +14,34 @@
14
14
 
15
15
  %table.table.table-sm
16
16
  %tbody
17
- %tr
18
- %td= applicant.wizard_step_title(:education)
19
- %td= f.number_field :min_applicant_educations, label: false
20
- %td minimum number of degrees
21
-
22
- %tr
23
- %td= applicant.wizard_step_title(:course_amounts)
24
- %td= f.number_field :min_applicant_courses, label: false
25
- %td minimum number of courses
26
-
27
- %tr
28
- %td= applicant.wizard_step_title(:experience)
29
- %td= f.number_field :min_applicant_experiences_months, label: false
30
- %td minimimum months of work experience
31
-
32
- %tr
33
- %td= applicant.wizard_step_title(:references)
34
- %td= f.number_field :min_applicant_references, label: false
35
- %td minimimum number of references
36
-
37
- %tr
38
- %td= applicant.wizard_step_title(:files)
39
- %td= f.number_field :min_applicant_files, label: false
40
- %td minimimum number of attached files
17
+ - if applicant.wizard_step_keys.include?(:education)
18
+ %tr
19
+ %td= applicant.wizard_step_title(:education)
20
+ %td= f.number_field :min_applicant_educations, label: false
21
+ %td minimum number of degrees
22
+
23
+ - if applicant.wizard_step_keys.include?(:course_amounts)
24
+ %tr
25
+ %td= applicant.wizard_step_title(:course_amounts)
26
+ %td= f.number_field :min_applicant_courses, label: false
27
+ %td minimum number of courses
28
+
29
+ - if applicant.wizard_step_keys.include?(:experience)
30
+ %tr
31
+ %td= applicant.wizard_step_title(:experience)
32
+ %td= f.number_field :min_applicant_experiences_months, label: false
33
+ %td minimimum months of work experience
34
+
35
+ - if applicant.wizard_step_keys.include?(:references)
36
+ %tr
37
+ %td= applicant.wizard_step_title(:references)
38
+ %td= f.number_field :min_applicant_references, label: false
39
+ %td minimimum number of references
40
+
41
+ - if applicant.wizard_step_keys.include?(:files)
42
+ %tr
43
+ %td= applicant.wizard_step_title(:files)
44
+ %td= f.number_field :min_applicant_files, label: false
45
+ %td minimimum number of attached files
41
46
 
42
47
  = f.submit
@@ -1,6 +1,9 @@
1
1
  = effective_form_with(model: [:admin, category], engine: true) do |f|
2
2
  = f.text_field :title
3
3
 
4
+ = f.select :category_type, f.object.class.category_types,
5
+ hint: 'When Organization, the organization will be given membership. Otherwise the individual user'
6
+
4
7
  - if f.object.class.categories.present?
5
8
  = f.select :category, f.object.class.categories
6
9
 
@@ -1,6 +1,4 @@
1
1
  = effective_form_with(model: [:admin, category], engine: true) do |f|
2
- %h2 Renewals
3
-
4
2
  %h3 Renewal Fees
5
3
  = f.check_box :create_renewal_fees, label: 'Yes, renewal fees should be created'
6
4
 
@@ -0,0 +1,6 @@
1
+ - categories = EffectiveMemberships.Organization.categories
2
+
3
+ - if categories.present?
4
+ = f.select :category, categories, required: true
5
+
6
+ = f.text_field :title