effective_memberships 0.3.5 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/effective_memberships/applicant-flowchart.excalidraw +2165 -0
  3. data/app/assets/images/effective_memberships/applicant-flowchart.png +0 -0
  4. data/app/assets/stylesheets/effective_memberships/base.scss +0 -1
  5. data/app/controllers/effective/membership_cards_controller.rb +19 -0
  6. data/app/datatables/admin/effective_applicants_datatable.rb +2 -1
  7. data/app/datatables/admin/effective_categories_datatable.rb +0 -1
  8. data/app/datatables/admin/effective_fees_datatable.rb +3 -0
  9. data/app/models/concerns/effective_memberships_applicant.rb +45 -26
  10. data/app/models/concerns/effective_memberships_card.rb +56 -0
  11. data/app/models/concerns/effective_memberships_category.rb +26 -2
  12. data/app/models/concerns/effective_memberships_owner.rb +22 -20
  13. data/app/models/concerns/effective_memberships_registrar.rb +1 -1
  14. data/app/models/effective/applicant_reference.rb +6 -1
  15. data/app/models/effective/fee.rb +8 -43
  16. data/app/models/effective/membership_card.rb +7 -0
  17. data/app/views/admin/applicants/_form.html.haml +1 -1
  18. data/app/views/effective/applicants/_course_amounts.html.haml +1 -1
  19. data/app/views/effective/applicants/_education.html.haml +1 -1
  20. data/app/views/effective/applicants/_experience.html.haml +1 -1
  21. data/app/views/effective/applicants/_stamp.html.haml +36 -0
  22. data/app/views/effective/applicants/stamp.html.haml +28 -0
  23. data/app/views/effective/membership_cards/index.html.haml +16 -0
  24. data/config/routes.rb +7 -0
  25. data/db/seeds.rb +9 -3
  26. data/lib/effective_memberships/version.rb +1 -1
  27. data/lib/effective_memberships.rb +5 -1
  28. metadata +24 -2
@@ -1,5 +1,4 @@
1
1
  .table-courses .form-group { margin-bottom: 0; }
2
2
  .table-courses th,
3
3
  .table-courses td { vertical-align: middle; ;}
4
-
5
4
  .table-courses-course-name { text-align: right; width: 15rem; }
@@ -0,0 +1,19 @@
1
+ module Effective
2
+ class MembershipCardsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+
5
+ include Effective::CrudController
6
+
7
+ resource_scope -> { EffectiveMemberships.MembershipCard }
8
+
9
+ def show
10
+ membership = Effective::Membership.find(params[:id])
11
+ card = resource_scope.new(membership: membership)
12
+
13
+ EffectiveResources.authorize!(self, :show, card)
14
+
15
+ send_data(card.to_pdf, filename: card.filename, type: card.content_type, disposition: 'attachment')
16
+ end
17
+
18
+ end
19
+ end
@@ -1,9 +1,10 @@
1
1
  module Admin
2
2
  class EffectiveApplicantsDatatable < Effective::Datatable
3
3
  filters do
4
- scope :all
4
+ scope :not_draft, label: 'All'
5
5
  scope :in_progress, label: 'Open / Active'
6
6
  scope :done, label: 'Done'
7
+ scope :draft
7
8
  end
8
9
 
9
10
  datatable do
@@ -12,7 +12,6 @@ module Admin
12
12
  col :renewal_fee, as: :price
13
13
  col :late_fee, as: :price
14
14
  col :rich_text_body, label: 'Body'
15
-
16
15
  col :tax_exempt
17
16
  col :qb_item_name, visible: false
18
17
 
@@ -25,6 +25,9 @@ module Admin
25
25
 
26
26
  col :fee_type, search: EffectiveMemberships.fee_types
27
27
  col :price, as: :price
28
+ col :tax_exempt, visible: false
29
+ col :qb_item_name, visible: false
30
+
28
31
  col :purchased?, as: :boolean
29
32
  col :purchased_order, visible: false
30
33
 
@@ -49,6 +49,7 @@ module EffectiveMembershipsApplicant
49
49
  experience: 'Work Experience',
50
50
  references: 'References',
51
51
  files: 'Attach Files',
52
+ stamp: 'Professional Stamp',
52
53
  declarations: 'Declarations',
53
54
  summary: 'Review',
54
55
  billing: 'Billing Address',
@@ -93,10 +94,14 @@ module EffectiveMembershipsApplicant
93
94
  has_many :applicant_references, -> { order(:id) }, class_name: 'Effective::ApplicantReference', as: :applicant, inverse_of: :applicant, dependent: :destroy
94
95
  accepts_nested_attributes_for :applicant_references, reject_if: :all_blank, allow_destroy: true
95
96
 
96
- has_many :fees, -> { order(:id) }, as: :parent, inverse_of: :parent, class_name: 'Effective::Fee', dependent: :nullify
97
+ has_many :stamps, -> { order(:id) }, class_name: 'Effective::Stamp', as: :applicant, inverse_of: :applicant, dependent: :destroy
98
+ accepts_nested_attributes_for :stamps, reject_if: :all_blank, allow_destroy: true
99
+
100
+ # Effective Namespace polymorphic
101
+ has_many :fees, -> { order(:id) }, class_name: 'Effective::Fee', as: :parent, inverse_of: :parent, dependent: :destroy
97
102
  accepts_nested_attributes_for :fees, reject_if: :all_blank, allow_destroy: true
98
103
 
99
- has_many :orders, -> { order(:id) }, as: :parent, inverse_of: :parent, class_name: 'Effective::Order', dependent: :nullify
104
+ has_many :orders, -> { order(:id) }, class_name: 'Effective::Order', as: :parent, inverse_of: :parent, dependent: :destroy
100
105
  accepts_nested_attributes_for :orders
101
106
 
102
107
  effective_resource do
@@ -138,6 +143,8 @@ module EffectiveMembershipsApplicant
138
143
  scope :in_progress, -> { where.not(status: [:approved, :declined]) }
139
144
  scope :done, -> { where(status: [:approved, :declined]) }
140
145
 
146
+ scope :not_draft, -> { where.not(status: :draft) }
147
+
141
148
  # Set Apply to Join or Reclassification
142
149
  before_validation(if: -> { new_record? && owner.present? }) do
143
150
  self.applicant_type ||= (owner.membership.blank? ? 'Apply to Join' : 'Apply to Reclassify')
@@ -274,6 +281,9 @@ module EffectiveMembershipsApplicant
274
281
 
275
282
  applicant_steps = Array(category&.applicant_wizard_steps)
276
283
 
284
+ # Special logic for stamp step
285
+ applicant_steps.delete(:stamp) unless apply_to_join?
286
+
277
287
  wizard_steps.select do |step|
278
288
  required_steps.include?(step) || category.blank? || applicant_steps.include?(step)
279
289
  end
@@ -282,29 +292,30 @@ module EffectiveMembershipsApplicant
282
292
 
283
293
  # All Fees and Orders
284
294
  def submit_fees
285
- fees.select { |fee| fee.applicant_submit_fee? }
286
- end
287
-
288
- def submit_order
289
- orders.find { |order| order.purchasables.any?(&:applicant_submit_fee?) }
290
- end
291
-
292
- def submit_fee_qb_item_name
293
- 'Applicant'
294
- end
295
+ # Find or build submit fee
296
+ fee = fees.first || fees.build(owner: owner, fee_type: 'Applicant')
297
+
298
+ unless fee.purchased?
299
+ fee.assign_attributes(
300
+ category: category,
301
+ price: category.applicant_fee,
302
+ tax_exempt: category.applicant_fee_tax_exempt,
303
+ qb_item_name: category.applicant_fee_qb_item_name
304
+ )
305
+ end
295
306
 
296
- def find_or_build_submit_fees
297
- return submit_fees if submit_fees.present?
307
+ # Update stamp price
308
+ stamp = stamps.first
298
309
 
299
- fees.build(
300
- owner: owner,
301
- fee_type: 'Applicant',
302
- category: category,
303
- price: category.applicant_fee,
304
- qb_item_name: submit_fee_qb_item_name()
305
- )
310
+ if stamp.present? && !stamp.purchased?
311
+ stamp.assign_attributes(
312
+ price: category.stamp_fee,
313
+ tax_exempt: category.stamp_fee_tax_exempt,
314
+ qb_item_name: category.stamp_fee_qb_item_name
315
+ )
316
+ end
306
317
 
307
- submit_fees
318
+ (fees + stamps)
308
319
  end
309
320
 
310
321
  # Draft -> Submitted requirements
@@ -314,7 +325,9 @@ module EffectiveMembershipsApplicant
314
325
 
315
326
  wizard_steps[:checkout] ||= Time.zone.now
316
327
  wizard_steps[:submitted] = Time.zone.now
328
+
317
329
  submitted!
330
+ stamps.each { |stamp| stamp.submit! }
318
331
 
319
332
  after_commit do
320
333
  applicant_references.each { |reference| reference.notify! if reference.submitted? }
@@ -409,10 +422,6 @@ module EffectiveMembershipsApplicant
409
422
  # Reset the progress so far. They have to click through screens again.
410
423
  assign_attributes(wizard_steps: wizard_steps.slice(:start, :select))
411
424
 
412
- # Delete any fees and orders. Keep all other data.
413
- submit_fees.each { |fee| fee.mark_for_destruction }
414
- submit_order.mark_for_destruction if submit_order
415
-
416
425
  save!
417
426
  end
418
427
 
@@ -462,6 +471,16 @@ module EffectiveMembershipsApplicant
462
471
  category&.min_applicant_files.to_i
463
472
  end
464
473
 
474
+ # Stamps step
475
+ def stamp
476
+ stamps.first || stamps.build(
477
+ owner: owner,
478
+ name: owner.to_s,
479
+ shipping_address: (owner.try(:shipping_address) || owner.try(:billing_address)),
480
+ price: 0
481
+ )
482
+ end
483
+
465
484
  # The submit! method used to be here
466
485
  # But it needs to be inside the included do block
467
486
  # So see above. Sorry.
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ # EffectiveMembershipsCard
4
+ # Mark your card model with include EffectiveMembershipsCard to get all the includes
5
+
6
+ module EffectiveMembershipsCard
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ def effective_memberships_card?; true; end
11
+ end
12
+
13
+ included do
14
+ include ActiveModel::Model
15
+
16
+ attr_accessor :membership
17
+ validates :membership, presence: true
18
+ end
19
+
20
+ # Instance Methods
21
+ def owner
22
+ membership&.owner
23
+ end
24
+
25
+ def content_type
26
+ 'application/pdf'
27
+ end
28
+
29
+ def filename
30
+ "#{self.class.name.split('::').first.downcase}-membership-card-#{Time.zone.now.strftime('%F')}.pdf"
31
+ end
32
+
33
+ def to_pdf
34
+ raise('is invalid') unless valid?
35
+
36
+ return pdf.render() if pdf.respond_to?(:render) # Prawn
37
+ return pdf.to_pdf() if pdf.respond_to?(:to_pdf) # CombinePdf
38
+
39
+ pdf
40
+ end
41
+
42
+ def pdf
43
+ @pdf ||= build_pdf()
44
+ end
45
+
46
+ private
47
+
48
+ def build_pdf()
49
+ raise('to be implemented')
50
+
51
+ # pdf = Prawn::Document.new
52
+ # pdf.text("Membership Card for #{membership.owner} Number #{membership.number}")
53
+ # pdf
54
+ end
55
+
56
+ end
@@ -110,6 +110,7 @@ module EffectiveMembershipsCategory
110
110
  scope :create_bad_standing, -> { where(create_bad_standing: true) }
111
111
 
112
112
  validates :title, presence: true, uniqueness: true
113
+
113
114
  validates :position, presence: true
114
115
 
115
116
  after_initialize(if: -> { new_record? }) do
@@ -138,6 +139,9 @@ module EffectiveMembershipsCategory
138
139
  validates :prorated_oct, presence: true, numericality: { greater_than_or_equal_to: 0 }
139
140
  validates :prorated_nov, presence: true, numericality: { greater_than_or_equal_to: 0 }
140
141
  validates :prorated_dec, presence: true, numericality: { greater_than_or_equal_to: 0 }
142
+
143
+ validates :qb_item_name, presence: true
144
+ validates :tax_exempt, inclusion: { in: [true, false] }
141
145
  end
142
146
  end
143
147
 
@@ -176,7 +180,7 @@ module EffectiveMembershipsCategory
176
180
  end
177
181
 
178
182
  def applicant_wizard_steps_collection
179
- wizard_steps = EffectiveMemberships.Applicant.all_wizard_steps
183
+ wizard_steps = EffectiveMemberships.Applicant.wizard_steps_hash
180
184
  required_steps = EffectiveMemberships.Applicant.required_wizard_steps
181
185
 
182
186
  wizard_steps.map do |step, title|
@@ -185,7 +189,7 @@ module EffectiveMembershipsCategory
185
189
  end
186
190
 
187
191
  def fee_payment_wizard_steps_collection
188
- wizard_steps = EffectiveMemberships.FeePayment.all_wizard_steps
192
+ wizard_steps = EffectiveMemberships.FeePayment.wizard_steps_hash
189
193
  required_steps = EffectiveMemberships.FeePayment.required_wizard_steps
190
194
 
191
195
  wizard_steps.map do |step, title|
@@ -193,4 +197,24 @@ module EffectiveMembershipsCategory
193
197
  end
194
198
  end
195
199
 
200
+ def applicant_fee_qb_item_name
201
+ 'Applicant'
202
+ end
203
+
204
+ def applicant_fee_tax_exempt
205
+ tax_exempt
206
+ end
207
+
208
+ def stamp_fee
209
+ 0
210
+ end
211
+
212
+ def stamp_fee_qb_item_name
213
+ qb_item_name
214
+ end
215
+
216
+ def stamp_fee_tax_exempt
217
+ tax_exempt
218
+ end
219
+
196
220
  end
@@ -137,11 +137,6 @@ module EffectiveMembershipsOwner
137
137
  end
138
138
 
139
139
  # Instance Methods
140
- def additional_fee_attributes(fee)
141
- raise('expected an Effective::Fee') unless fee.kind_of?(Effective::Fee)
142
- {}
143
- end
144
-
145
140
  def build_prorated_fee(date: nil)
146
141
  raise('must have an existing membership') unless membership.present?
147
142
 
@@ -156,8 +151,10 @@ module EffectiveMembershipsOwner
156
151
  fee.assign_attributes(
157
152
  fee_type: 'Prorated',
158
153
  category: category,
154
+ period: period,
159
155
  price: price,
160
- period: period
156
+ tax_exempt: category.tax_exempt,
157
+ qb_item_name: category.qb_item_name
161
158
  )
162
159
 
163
160
  fee
@@ -178,16 +175,17 @@ module EffectiveMembershipsOwner
178
175
  fee.assign_attributes(
179
176
  fee_type: 'Discount',
180
177
  category: category,
178
+ period: period,
181
179
  price: price,
182
- period: period
180
+ tax_exempt: category.tax_exempt,
181
+ qb_item_name: category.qb_item_name
183
182
  )
184
183
 
185
184
  fee
186
185
  end
187
186
 
188
- def build_title_fee(period:, title:, fee_type: nil, category: nil, price: nil, qb_item_name: nil, tax_exempt: nil)
189
- fee_type ||= 'Renewal'
190
-
187
+ # Only thing optional is category, late_on and bad_standing_on
188
+ def build_title_fee(title:, fee_type:, period:, price:, tax_exempt:, qb_item_name:, category: nil)
191
189
  fee = fees.find do |fee|
192
190
  fee.fee_type == fee_type && fee.period == period && fee.title == title &&
193
191
  (category.blank? || fee.category_id == category.id && fee.category_type == category.class.name)
@@ -197,24 +195,21 @@ module EffectiveMembershipsOwner
197
195
 
198
196
  # Build the title fee
199
197
  fee ||= fees.build()
200
- price ||= (category.renewal_fee.to_i if category.present? && fee_type == 'Renewal')
201
198
 
202
199
  fee.assign_attributes(
203
- fee_type: fee_type,
204
200
  title: title,
201
+ fee_type: fee_type,
205
202
  category: category,
206
- price: price,
207
203
  period: period,
208
- qb_item_name: qb_item_name,
204
+ price: price,
209
205
  tax_exempt: tax_exempt,
210
- late_on: nil,
211
- bad_standing_on: nil
206
+ qb_item_name: qb_item_name
212
207
  )
213
208
 
214
209
  fee
215
210
  end
216
211
 
217
- def build_renewal_fee(category:, period:, late_on:, bad_standing_on:)
212
+ def build_renewal_fee(category:, period:, late_on: nil, bad_standing_on: nil)
218
213
  raise('must have an existing membership') unless membership.present?
219
214
 
220
215
  fee = fees.find { |fee| fee.fee_type == 'Renewal' && fee.period == period && fee.category_id == category.id && fee.category_type == category.class.name }
@@ -223,13 +218,18 @@ module EffectiveMembershipsOwner
223
218
  # Build the renewal fee
224
219
  fee ||= fees.build()
225
220
 
221
+ late_on ||= EffectiveMemberships.Registrar.late_fee_date(period: period)
222
+ bad_standing_on ||= EffectiveMemberships.Registrar.bad_standing_date(period: period)
223
+
226
224
  fee.assign_attributes(
227
225
  fee_type: 'Renewal',
228
226
  category: category,
229
- price: category.renewal_fee.to_i,
230
227
  period: period,
228
+ price: category.renewal_fee.to_i,
229
+ tax_exempt: category.tax_exempt,
230
+ qb_item_name: category.qb_item_name,
231
231
  late_on: late_on,
232
- bad_standing_on: bad_standing_on
232
+ bad_standing_on: bad_standing_on,
233
233
  )
234
234
 
235
235
  fee
@@ -252,8 +252,10 @@ module EffectiveMembershipsOwner
252
252
  fee.assign_attributes(
253
253
  fee_type: 'Late',
254
254
  category: category,
255
- price: category.late_fee.to_i,
256
255
  period: period,
256
+ price: category.late_fee.to_i,
257
+ tax_exempt: category.tax_exempt,
258
+ qb_item_name: category.qb_item_name
257
259
  )
258
260
 
259
261
  fee
@@ -219,7 +219,7 @@ module EffectiveMembershipsRegistrar
219
219
 
220
220
  if owner.outstanding_fee_payment_fees.present?
221
221
  order = Effective::Order.new(items: owner.outstanding_fee_payment_fees, user: owner)
222
- order.purchase!(skip_buyer_validations: true, email: false)
222
+ order.mark_as_purchased!
223
223
  end
224
224
 
225
225
  owner.update_membership_status!
@@ -2,7 +2,12 @@ module Effective
2
2
  class ApplicantReference < ActiveRecord::Base
3
3
  acts_as_tokened
4
4
  acts_as_addressable :reference
5
- acts_as_statused :submitted, :completed
5
+
6
+ acts_as_statused(
7
+ :submitted, # Was submitted by the applicant
8
+ :completed # Was completed by the reference.
9
+ )
10
+
6
11
  log_changes(to: :applicant) if respond_to?(:log_changes)
7
12
 
8
13
  belongs_to :applicant, polymorphic: true
@@ -14,11 +14,11 @@ module Effective
14
14
  belongs_to :category, polymorphic: true, optional: true
15
15
 
16
16
  effective_resource do
17
- fee_type :string
17
+ fee_type :string
18
18
 
19
- title :string
19
+ title :string
20
20
 
21
- period :date
21
+ period :date
22
22
 
23
23
  late_on :date
24
24
  bad_standing_on :date
@@ -33,32 +33,22 @@ module Effective
33
33
  scope :sorted, -> { order(:id) }
34
34
  scope :deep, -> { includes(:owner, :parent, :category) }
35
35
 
36
- before_validation(if: -> { owner.present? }) do
37
- additional = owner.additional_fee_attributes(self)
38
- raise('expected a Hash of attributes') unless additional.kind_of?(Hash)
39
- assign_attributes(additional)
40
- end
41
-
42
36
  before_validation(if: -> { owner && owner.membership }) do
43
37
  self.category ||= owner.membership.categories.first if owner.membership.categories.length == 1
44
38
  end
45
39
 
46
40
  before_validation do
47
- self.period ||= default_period()
48
- self.late_on ||= default_late_on()
49
- self.bad_standing_on ||= default_bad_standing_on()
50
-
51
- self.qb_item_name ||= default_qb_item_name()
52
- self.tax_exempt = default_tax_exempt() if tax_exempt.nil?
53
-
41
+ self.period ||= EffectiveMemberships.Registrar.current_period
54
42
  self.title ||= default_title()
55
43
  end
56
44
 
57
45
  validates :fee_type, presence: true
58
- validates :price, presence: true
59
46
 
60
47
  validates :title, presence: true
61
48
  validates :period, presence: true
49
+
50
+ validates :price, presence: true
51
+ validates :tax_exempt, inclusion: { in: [true, false] }
62
52
  validates :qb_item_name, presence: true
63
53
 
64
54
  validate(if: -> { fee_type.present? }) do
@@ -107,33 +97,8 @@ module Effective
107
97
  EffectiveMemberships.custom_fee_types.include?(fee_type)
108
98
  end
109
99
 
110
- def default_period
111
- EffectiveMemberships.Registrar.current_period
112
- end
113
-
114
- def default_late_on
115
- nil
116
- end
117
-
118
- def default_bad_standing_on
119
- nil
120
- end
121
-
122
100
  def default_title
123
- [
124
- period&.strftime('%Y').presence,
125
- category.to_s.presence,
126
- fee_type.presence,
127
- 'Fee'
128
- ].join(' ')
129
- end
130
-
131
- def default_qb_item_name
132
- category&.qb_item_name.presence || "#{fee_type}"
133
- end
134
-
135
- def default_tax_exempt
136
- category.present? ? category.tax_exempt : false
101
+ [period&.strftime('%Y'), category, fee_type, 'Fee'].compact.join(' ')
137
102
  end
138
103
 
139
104
  end
@@ -0,0 +1,7 @@
1
+ module Effective
2
+ class MembershipCard
3
+
4
+ include EffectiveMembershipsCard
5
+
6
+ end
7
+ end
@@ -35,7 +35,7 @@
35
35
 
36
36
  - if applicant.owner.applicants.any? { |other| other.was_submitted? && other.id != applicant.id }
37
37
  = tab 'Other Applications' do
38
- = render_datatable(Admin::EffectiveApplicantsDatatable.new(owner_id: applicant.owner_id, except_id: applicant.id))
38
+ = render_datatable(Admin::EffectiveApplicantsDatatable.new(owner: applicant.owner, except_id: applicant.id))
39
39
 
40
40
  - if applicant.persisted? && applicant.respond_to?(:log_changes_datatable)
41
41
  = tab 'Logs' do
@@ -8,7 +8,7 @@
8
8
 
9
9
 
10
10
  - applicant.applicant_course_areas_collection.each do |area|
11
- - datatable = EffectiveApplicantCoursesDatatable.new(applicant_id: applicant.id, applicant_course_area_id: area.id)
11
+ - datatable = EffectiveApplicantCoursesDatatable.new(applicant: applicant, applicant_course_area_id: area.id)
12
12
 
13
13
  .mb-4
14
14
  %h6= area
@@ -6,7 +6,7 @@
6
6
  .col-sm-auto.text-right
7
7
  = link_to('Edit', wizard_path(:education)) if edit_effective_wizard?
8
8
 
9
- - datatable = EffectiveApplicantEducationsDatatable.new(applicant_id: applicant.id)
9
+ - datatable = EffectiveApplicantEducationsDatatable.new(applicant: applicant)
10
10
  .mb-4= render_simple_datatable(datatable)
11
11
 
12
12
  - if applicant.applicant_educations_details.present?
@@ -20,7 +20,7 @@
20
20
  %th Total Months
21
21
  %td= applicant.applicant_experiences_months
22
22
 
23
- - datatable = EffectiveApplicantExperiencesDatatable.new(applicant_id: applicant.id)
23
+ - datatable = EffectiveApplicantExperiencesDatatable.new(applicant: applicant)
24
24
  .mb-4= render_simple_datatable(datatable)
25
25
 
26
26
  - if applicant.applicant_experiences_details.present?
@@ -0,0 +1,36 @@
1
+ .card
2
+ .card-body
3
+ .row
4
+ .col-sm
5
+ %h5.card-title= applicant.wizard_step_title(:stamp)
6
+ .col-sm-auto.text-right
7
+ = link_to('Edit', wizard_path(:stamp)) if edit_effective_wizard?
8
+
9
+ - applicant.stamps.each do |stamp|
10
+ %table.table.table-sm
11
+ %tbody
12
+ %tr
13
+ %th Name
14
+ %td= stamp.name
15
+
16
+ %tr
17
+ %th Name Confirmation
18
+ %td= stamp.name_confirmation
19
+
20
+ %tr
21
+ %th Category
22
+ %td= stamp.category
23
+
24
+ - if stamp.shipping_address.present?
25
+ %tr
26
+ %th Shipping Address
27
+ %td= stamp.shipping_address.to_html
28
+
29
+ - if applicant.was_approved?
30
+ %tr
31
+ %th Submitted
32
+ %td= stamp.submitted_at&.strftime('%F') || '-'
33
+
34
+ %tr
35
+ %th Issued
36
+ %td= stamp.issued_at&.strftime('%F') || 'Not Issued'
@@ -0,0 +1,28 @@
1
+ = render 'layout' do
2
+ = render 'effective/applicants/content', resource: resource
3
+
4
+ .card
5
+ .card-body
6
+ %p Should your application be approved, you are eligible to receive a Professional Stamp.
7
+
8
+ %p Please confirm your name as it should appear on any Professional Stamp.
9
+
10
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
11
+ = f.hidden_field :id
12
+
13
+ = f.fields_for(:stamps, f.object.stamp) do |fs|
14
+ = fs.hidden_field :applicant_id
15
+ = fs.hidden_field :applicant_type
16
+
17
+ = fs.hidden_field :owner_id
18
+ = fs.hidden_field :owner_type
19
+
20
+ = fs.hidden_field :price
21
+ = fs.hidden_field :tax_exempt
22
+ = fs.hidden_field :qb_item_name
23
+
24
+ = render 'effective/stamps/fields', f: fs
25
+
26
+ %p Stamps will be processed after approval of this application.
27
+
28
+ = f.save 'Save and Continue'
@@ -0,0 +1,16 @@
1
+ - owners = current_user.effective_memberships_owners
2
+
3
+ - owners.each do |owner|
4
+ - membership = owner.membership
5
+ - card = EffectiveMemberships.MembershipCard.new(membership: membership)
6
+
7
+ - next unless EffectiveResources.authorized?(self, :show, card)
8
+
9
+ = card('Membership Card') do
10
+ %p
11
+ Your membership card for
12
+ = membership.categories.to_sentence
13
+ = membership.owner.to_s
14
+ is available for download:
15
+
16
+ %p= link_to 'Download Membership Card', effective_memberships.membership_card_membership_path(membership, format: :pdf), class: 'btn btn-primary'
data/config/routes.rb CHANGED
@@ -18,6 +18,13 @@ EffectiveMemberships::Engine.routes.draw do
18
18
  end
19
19
 
20
20
  get '/directory', to: 'memberships_directory#index'
21
+
22
+ resources :membership_cards, only: :index
23
+
24
+ resources :memberships, only: [] do
25
+ get :membership_card, on: :member, to: 'membership_cards#show'
26
+ end
27
+
21
28
  end
22
29
 
23
30
  namespace :admin do