effective_products 0.0.3 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/admin/stamps_controller.rb +11 -0
  3. data/app/controllers/effective/ring_wizards_controller.rb +0 -21
  4. data/app/controllers/effective/stamp_wizards_controller.rb +10 -0
  5. data/app/datatables/admin/effective_stamps_datatable.rb +52 -0
  6. data/app/datatables/effective_stamp_wizards_datatable.rb +36 -0
  7. data/app/helpers/effective_products_helper.rb +0 -1
  8. data/app/models/concerns/effective_products_ring_wizard.rb +20 -29
  9. data/app/models/concerns/effective_products_stamp_wizard.rb +139 -0
  10. data/app/models/effective/ring.rb +0 -12
  11. data/app/models/effective/stamp.rb +114 -0
  12. data/app/models/effective/stamp_wizard.rb +7 -0
  13. data/app/views/admin/stamps/_form.html.haml +12 -0
  14. data/app/views/admin/stamps/_stamp.html.haml +53 -0
  15. data/app/views/effective/ring_wizards/_dashboard.html.haml +1 -1
  16. data/app/views/effective/ring_wizards/_ring.html.haml +34 -27
  17. data/app/views/effective/ring_wizards/_ring_wizard.html.haml +1 -6
  18. data/app/views/effective/ring_wizards/submitted.html.haml +1 -0
  19. data/app/views/effective/stamp_wizards/_content.html.haml +10 -0
  20. data/app/views/effective/stamp_wizards/_dashboard.html.haml +27 -0
  21. data/app/views/effective/stamp_wizards/_layout.html.haml +3 -0
  22. data/app/views/effective/stamp_wizards/_orders.html.haml +4 -0
  23. data/app/views/effective/stamp_wizards/_stamp.html.haml +45 -0
  24. data/app/views/effective/stamp_wizards/_stamp_fields.html.haml +45 -0
  25. data/app/views/effective/stamp_wizards/_stamp_wizard.html.haml +3 -0
  26. data/app/views/effective/stamp_wizards/_summary.html.haml +31 -0
  27. data/app/views/effective/stamp_wizards/billing.html.haml +15 -0
  28. data/app/views/effective/stamp_wizards/checkout.html.haml +6 -0
  29. data/app/views/effective/stamp_wizards/stamp.html.haml +18 -0
  30. data/app/views/effective/stamp_wizards/start.html.haml +16 -0
  31. data/app/views/effective/stamp_wizards/submitted.html.haml +16 -0
  32. data/app/views/effective/stamp_wizards/summary.html.haml +8 -0
  33. data/app/views/effective/stamps/_fields.html.haml +11 -0
  34. data/config/routes.rb +8 -0
  35. data/db/migrate/01_create_effective_products.rb.erb +55 -0
  36. data/lib/effective_products/engine.rb +1 -0
  37. data/lib/effective_products/version.rb +1 -1
  38. metadata +26 -3
  39. data/app/views/effective/rings/_fields.html.haml +0 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd6de56034ed84b15b02ab52785db58b37b0839e67a0db8cf31b77da8f4db148
4
- data.tar.gz: e7a59c34d1c681a582c7c7c510ad9cc8c8f911e7bfbe339864678bca3f4db4d7
3
+ metadata.gz: 36f1b24a9da60c9e39f6d27fd085283bd0f5b061f80c14a53f7a4a59edb1d31a
4
+ data.tar.gz: 713caaaaa536356ede62d6d207166a8861190bb3d8ea41c16296637f49033c84
5
5
  SHA512:
6
- metadata.gz: 4383a40c636b788b989b22a8dedbc8d7afac6be72313ec737d3fe3ea1457365054194f99739651e3d61cacfa5a412e3aaa0d7068c39bfa3d41819446a226119f
7
- data.tar.gz: b33a258e854dfdd4211edfb7143105d1c6af606cd8274886c548e65e414919a0d41e651cbd07e8399e497e2b06e9137f695cc053e43acf4509b663b01149f1de
6
+ metadata.gz: 8bc5e5606f1fe01fde2bc06429ba9f4813a0f6115cfafaa7fa657aaee71c4440f61a00bf523446a4b82af4e2513bf5593c19801030f50e1d7f82aafd87bddead
7
+ data.tar.gz: aa6f08d926456c04c97f34b7ad4d53b26e021339a98c3e54781ce3475056771b22ec46063d6daf0a47af990362c7e1d84213bc5392c07725673e71f3cf44db7c
@@ -0,0 +1,11 @@
1
+ module Admin
2
+ class StampsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_products) }
5
+
6
+ include Effective::CrudController
7
+
8
+ submit :mark_paid, 'Save and Mark Paid'
9
+
10
+ end
11
+ end
@@ -6,26 +6,5 @@ module Effective
6
6
 
7
7
  resource_scope -> { EffectiveProducts.RingWizard.deep.where(owner: current_user) }
8
8
 
9
- # Allow only 1 in-progress application at a time
10
- before_action(only: [:new, :show], unless: -> { resource&.done? }) do
11
- existing = resource_scope.in_progress.where.not(id: resource).first
12
-
13
- if existing.present?
14
- flash[:success] = "You have been redirected to your existing in progress payment"
15
- redirect_to effective_products.ring_wizard_build_path(existing, existing.next_step)
16
- end
17
- end
18
-
19
- after_save do
20
- flash.now[:success] = ''
21
- end
22
-
23
- private
24
-
25
- def permitted_params
26
- model = (params.key?(:effective_ring_wizard) ? :effective_ring_wizard : :ring_wizard)
27
- params.require(model).permit!.except(:status, :status_steps, :wizard_steps, :submitted_at)
28
- end
29
-
30
9
  end
31
10
  end
@@ -0,0 +1,10 @@
1
+ module Effective
2
+ class StampWizardsController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+
5
+ include Effective::WizardController
6
+
7
+ resource_scope -> { EffectiveProducts.StampWizard.deep.where(owner: current_user) }
8
+
9
+ end
10
+ end
@@ -0,0 +1,52 @@
1
+ module Admin
2
+ class EffectiveStampsDatatable < Effective::Datatable
3
+ filters do
4
+ scope :ready_to_issue
5
+ scope :issued
6
+ scope :all
7
+ end
8
+
9
+ datatable do
10
+ order :updated_at
11
+
12
+ col :updated_at, visible: false
13
+ col :created_at, visible: false
14
+ col :id, visible: false
15
+
16
+ col :created_at, as: :date
17
+ col :owner, search: :string
18
+
19
+ col :applicant, visible: false
20
+ col :stamp_wizard, visible: false
21
+
22
+ col(:email) { |stamp| stamp.owner.email }
23
+ col(:phone) { |stamp| stamp.owner.phone }
24
+
25
+ col :member_number, label: 'Member #' do |stamp|
26
+ stamp.owner.try(:membership).try(:number)
27
+ end
28
+
29
+ col :name
30
+ col :name_confirmation, visible: false
31
+
32
+ col :category, visible: false
33
+
34
+ col :shipping_address, label: 'Address'
35
+
36
+ col :purchased_order, visible: false
37
+ col :price, visible: false
38
+ col :tax_exempt, visible: false
39
+ col :qb_item_name, visible: false
40
+
41
+ col :status, visible: false
42
+
43
+ col :issued_at
44
+
45
+ actions_col
46
+ end
47
+
48
+ collection do
49
+ Effective::Stamp.deep.all
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,36 @@
1
+ # Dashboard Stamp Payments
2
+ class EffectiveStampWizardsDatatable < Effective::Datatable
3
+ datatable do
4
+ order :created_at
5
+
6
+ col :token, visible: false
7
+ col :created_at, visible: false
8
+
9
+ col(:submitted_at, label: 'Submitted on') do |resource|
10
+ resource.submitted_at&.strftime('%F') || 'Incomplete'
11
+ end
12
+
13
+ col :owner, visible: false, search: :ststamp
14
+ col :status, visible: false
15
+ col :orders, action: :show
16
+
17
+ col(:issued_at, label: 'Issued on') do |resource|
18
+ resource.stamp.issued_at&.strftime('%F') || '-'
19
+ end
20
+
21
+ actions_col(actions: []) do |resource|
22
+ if resource.draft?
23
+ dropdown_link_to('Continue', effective_products.stamp_wizard_build_path(resource, reource.next_step), 'data-turbolinks' => false)
24
+ dropdown_link_to('Delete', effective_products.stamp_wizard_path(resource), 'data-confirm': "Really delete #{resource}?", 'data-method': :delete)
25
+ else
26
+ dropdown_link_to('Show', effective_products.stamp_wizard_path(resource))
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ collection do
33
+ EffectiveProducts.StampWizard.deep.done.where(owner: current_user)
34
+ end
35
+
36
+ end
@@ -1,3 +1,2 @@
1
1
  module EffectiveProductsHelper
2
-
3
2
  end
@@ -15,14 +15,6 @@ module EffectiveProductsRingWizard
15
15
 
16
16
  module ClassMethods
17
17
  def effective_products_ring_wizard?; true; end
18
-
19
- def all_wizard_steps
20
- const_get(:WIZARD_STEPS).keys
21
- end
22
-
23
- def required_wizard_steps
24
- [:start, :billing, :checkout, :submitted]
25
- end
26
18
  end
27
19
 
28
20
  included do
@@ -83,7 +75,7 @@ module EffectiveProductsRingWizard
83
75
  # All Steps validations
84
76
  validates :owner, presence: true
85
77
 
86
- # Tickets Step
78
+ # Ring Step
87
79
  validate(if: -> { current_step == :ring }) do
88
80
  self.errors.add(:rings, "can't be blank") unless present_rings.present?
89
81
  end
@@ -117,14 +109,7 @@ module EffectiveProductsRingWizard
117
109
  end
118
110
 
119
111
  def build_ring
120
- ring = rings.build(
121
- owner: owner,
122
- first_name: owner.try(:first_name),
123
- last_name: owner.try(:last_name),
124
- email: owner.try(:email),
125
- phone: owner.try(:phone)
126
- )
127
-
112
+ ring = rings.build(owner: owner)
128
113
  address = owner.try(:shipping_address) || owner.try(:billing_address)
129
114
 
130
115
  if address.present?
@@ -135,23 +120,29 @@ module EffectiveProductsRingWizard
135
120
  end
136
121
 
137
122
  def assign_pricing
138
- price = case ring.metal
139
- when '14k Yellow Gold' then 450_00
140
- when 'Sterling Silver' then 175_00
141
- when 'Titanium' then 50_00
142
- else
143
- raise "unexpected ring metal: #{ring.metal || 'none'}"
144
- end
145
-
146
- qb_item_name = "Chemist's Ring"
147
- tax_exempt = false
148
-
149
- ring.assign_attributes(price: price, qb_item_name: qb_item_name, tax_exempt: tax_exempt)
123
+ raise('to be implemented by including class')
124
+
125
+ # raise('expected a persisted ring') unless ring&.persisted?
126
+
127
+ # price = case ring.metal
128
+ # when '14k Yellow Gold' then 450_00
129
+ # when 'Sterling Silver' then 175_00
130
+ # when 'Titanium' then 50_00
131
+ # else
132
+ # raise "unexpected ring metal: #{ring.metal || 'none'}"
133
+ # end
134
+
135
+ # qb_item_name = "Professional Ring"
136
+ # tax_exempt = false
137
+
138
+ # ring.assign_attributes(price: price, qb_item_name: qb_item_name, tax_exempt: tax_exempt)
150
139
  end
151
140
 
152
141
  # After the configure Ring step
153
142
  def ring!
154
143
  assign_pricing() if ring.present?
144
+ raise('expected ring to have a price') if ring.price.blank?
145
+
155
146
  save!
156
147
  end
157
148
 
@@ -0,0 +1,139 @@
1
+ # frozen_string_literal: true
2
+
3
+ # EffectiveProductsStampWizard
4
+ #
5
+ # Mark your owner model with effective_products_stamp_wizard to get all the includes
6
+
7
+ module EffectiveProductsStampWizard
8
+ extend ActiveSupport::Concern
9
+
10
+ module Base
11
+ def effective_products_stamp_wizard
12
+ include ::EffectiveProductsStampWizard
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def effective_products_stamp_wizard?; true; end
18
+ end
19
+
20
+ included do
21
+ acts_as_purchasable_parent
22
+ acts_as_tokened
23
+
24
+ acts_as_statused(
25
+ :draft, # Just Started
26
+ :submitted # All done
27
+ )
28
+
29
+ acts_as_wizard(
30
+ start: 'Start',
31
+ stamp: 'Select Stamp',
32
+ summary: 'Review',
33
+ billing: 'Billing Address',
34
+ checkout: 'Checkout',
35
+ submitted: 'Submitted'
36
+ )
37
+
38
+ acts_as_purchasable_wizard
39
+
40
+ log_changes(except: :wizard_steps) if respond_to?(:log_changes)
41
+
42
+ # Application Namespace
43
+ belongs_to :owner, polymorphic: true
44
+ accepts_nested_attributes_for :owner
45
+
46
+ # Effective Namespace
47
+ has_many :stamps, -> { order(:id) }, class_name: 'Effective::Stamp', inverse_of: :stamp_wizard, dependent: :destroy
48
+ accepts_nested_attributes_for :stamps, reject_if: :all_blank, allow_destroy: true
49
+
50
+ has_many :orders, -> { order(:id) }, as: :parent, class_name: 'Effective::Order', dependent: :nullify
51
+ accepts_nested_attributes_for :orders
52
+
53
+ effective_resource do
54
+ # Acts as Statused
55
+ status :string, permitted: false
56
+ status_steps :text, permitted: false
57
+
58
+ # Dates
59
+ submitted_at :datetime
60
+
61
+ # Acts as Wizard
62
+ wizard_steps :text, permitted: false
63
+
64
+ timestamps
65
+ end
66
+
67
+ scope :deep, -> { includes(:owner, :orders, :stamps) }
68
+ scope :sorted, -> { order(:id) }
69
+
70
+ scope :in_progress, -> { where.not(status: [:submitted]) }
71
+ scope :done, -> { where(status: [:submitted]) }
72
+
73
+ scope :for, -> (user) { where(owner: user) }
74
+
75
+ # All Steps validations
76
+ validates :owner, presence: true
77
+
78
+ # Stamp Step
79
+ validate(if: -> { current_step == :stamp }) do
80
+ self.errors.add(:stamps, "can't be blank") unless present_stamps.present?
81
+ end
82
+
83
+ # All Fees and Orders
84
+ def submit_fees
85
+ stamps
86
+ end
87
+
88
+ def after_submit_purchased!
89
+ stamps.each { |stamp| stamp.submit! }
90
+ end
91
+
92
+ end
93
+
94
+ # Instance Methods
95
+ def to_s
96
+ 'stamp payment'
97
+ end
98
+
99
+ def in_progress?
100
+ draft?
101
+ end
102
+
103
+ def done?
104
+ submitted?
105
+ end
106
+
107
+ def stamp
108
+ stamps.first
109
+ end
110
+
111
+ def build_stamp
112
+ address = owner.try(:shipping_address) || owner.try(:billing_address)
113
+ stamps.build(owner: owner, shipping_address: address)
114
+ end
115
+
116
+ def assign_pricing
117
+ raise('to be implemented by including class')
118
+
119
+ # price = (stamp.physical? ? 100_00 : 50_00)
120
+ # qb_item_name = "Professional Stamp"
121
+ # tax_exempt = false
122
+
123
+ # stamp.assign_attributes(price: price, qb_item_name: qb_item_name, tax_exempt: tax_exempt)
124
+ end
125
+
126
+ # After the configure Stamp step
127
+ def stamp!
128
+ assign_pricing() if stamp.present?
129
+ raise('expected stamp to have a price') if stamp.price.blank?
130
+ save!
131
+ end
132
+
133
+ private
134
+
135
+ def present_stamps
136
+ stamps.reject(&:marked_for_destruction?)
137
+ end
138
+
139
+ end
@@ -53,17 +53,5 @@ module Effective
53
53
  issued_at.present?
54
54
  end
55
55
 
56
- # This is the Admin Save and Mark Paid action
57
- def mark_paid!
58
- raise('expected a blank ring payment') if ring_wizard.present?
59
-
60
- save!
61
-
62
- order = Effective::Order.new(items: self, user: owner)
63
- order.purchase!(skip_buyer_validations: true, email: false)
64
-
65
- true
66
- end
67
-
68
56
  end
69
57
  end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Effective
4
+ class Stamp < ActiveRecord::Base
5
+ acts_as_purchasable
6
+ acts_as_addressable :shipping
7
+
8
+ acts_as_statused(
9
+ :draft, # Built in an application
10
+ :submitted, # Submitted by an applicant or stamp wizard
11
+ :issued # Issued by an admin
12
+ )
13
+
14
+ #CATEGORIES = ['Physical', 'Digital-only']
15
+ CATEGORIES = ['Physical']
16
+
17
+ log_changes if respond_to?(:log_changes)
18
+
19
+ # This stamp is charged to an owner
20
+ belongs_to :owner, polymorphic: true
21
+
22
+ # Sometimes a stamp is built through an applicant
23
+ belongs_to :applicant, polymorphic: true, optional: true
24
+
25
+ # Other times through the stamp_wizard
26
+ belongs_to :stamp_wizard, polymorphic: true, optional: true
27
+
28
+ effective_resource do
29
+ name :string
30
+ name_confirmation :string
31
+
32
+ category :string
33
+
34
+ # Admin issues stamps
35
+ issued_at :datetime # Present when issued by an admin
36
+
37
+ # Acts as Statused
38
+ status :string
39
+ status_steps :text
40
+
41
+ # Acts as Purchasable
42
+ price :integer
43
+ qb_item_name :string
44
+ tax_exempt :boolean
45
+
46
+ timestamps
47
+ end
48
+
49
+ scope :deep, -> { includes(:owner) }
50
+
51
+ scope :with_approved_applicants, -> { where(applicant_id: EffectiveMemberships.Applicant.approved) }
52
+ scope :with_stamp_wizards, -> { where(applicant_id: nil).where.not(stamp_wizard_id: nil) }
53
+
54
+ scope :ready_to_issue, -> {
55
+ with_approved_applicants.or(with_stamp_wizards).purchased.where.not(issued_at: nil)
56
+ }
57
+
58
+ validates :category, presence: true, inclusion: { in: CATEGORIES }
59
+ validates :name, presence: true
60
+ validates :name_confirmation, presence: true
61
+
62
+ validate(if: -> { name.present? && name_confirmation.present? }) do
63
+ self.errors.add(:name_confirmation, "doesn't match name") unless name == name_confirmation
64
+ end
65
+
66
+ validate(if: -> { physical? }) do
67
+ self.errors.add(:shipping_address, "can't be blank when physical stamp") unless shipping_address.present?
68
+ end
69
+
70
+ def to_s
71
+ ['Professional Stamp', *name.presence].join(' ')
72
+ end
73
+
74
+ def issued?
75
+ issued_at.present?
76
+ end
77
+
78
+ def mark_as_issued!
79
+ issued!
80
+ end
81
+
82
+ def physical?
83
+ category == 'Physical'
84
+ end
85
+
86
+ def created_by_admin?
87
+ stamp_wizard_id.blank? && applicant_id.blank?
88
+ end
89
+
90
+ # Called by an application when submitted
91
+ # Called by a stamp wizard when submitted
92
+ def submit!
93
+ raise('expected a purchased order') unless purchased?
94
+ submitted!
95
+ end
96
+
97
+ # This is the Admin Save and Mark Paid action
98
+ def mark_paid!
99
+ raise('expected an user with a membership category') unless owner && owner.try(:membership).present?
100
+
101
+ category = owner.membership.categories.first
102
+
103
+ assign_attributes(
104
+ price: category.stamp_fee,
105
+ tax_exempt: category.stamp_fee_tax_exempt,
106
+ qb_item_name: category.stamp_fee_qb_item_name
107
+ )
108
+
109
+ save!
110
+ Effective::Order.new(items: self, user: owner).mark_as_purchased!
111
+ end
112
+
113
+ end
114
+ end
@@ -0,0 +1,7 @@
1
+ module Effective
2
+ class StampWizard < ActiveRecord::Base
3
+ self.table_name = EffectiveProducts.stamp_wizards_table_name.to_s
4
+
5
+ effective_products_stamp_wizard
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ = effective_form_with(model: [:admin, stamp], engine: true) do |f|
2
+ - if f.object.new_record?
3
+ = f.select :owner, { 'Users' => current_user.class.members.sorted }, polymorphic: true
4
+ - else
5
+ = f.static_field :owner
6
+
7
+ = render 'effective/stamps/fields', f: f, stamp: f.object
8
+
9
+ - if f.object.new_record?
10
+ = f.submit 'Save and Mark Paid'
11
+ - else
12
+ = f.submit 'Save'
@@ -0,0 +1,53 @@
1
+ %table.table
2
+ %tbody
3
+ %tr
4
+ %th Owner
5
+ %td
6
+ - url = (edit_polymorphic_path(stamp.owner) rescue "/admin/users/#{stamp.owner.to_param}/edit")
7
+ = link_to(stamp.owner, url)
8
+
9
+ %tr
10
+ %th Purchased Order
11
+ %td
12
+ - if stamp.purchased_order.present?
13
+ = link_to(stamp.purchased_order, effective_orders.admin_order_path(stamp.purchased_order))
14
+
15
+ %tr
16
+ %th Contact
17
+ %td
18
+ - owner = stamp.owner
19
+
20
+ = owner.to_s
21
+
22
+ - if owner.try(:email).present?
23
+ %br
24
+ = mail_to(owner.email)
25
+
26
+ - if owner.try(:phone).present?
27
+ %br
28
+ = owner.phone
29
+
30
+ - if owner.try(:membership).try(:number).present?
31
+ %br
32
+ Member Number #{owner.membership.number}
33
+
34
+ %tr
35
+ %th
36
+ %td= stamp.physical? ? 'Physical' : 'Digital Only'
37
+
38
+ - if stamp.shipping_address.present?
39
+ %tr
40
+ %th Address
41
+ %td= stamp.shipping_address.to_html
42
+
43
+ %tr
44
+ %th Name on Stamp
45
+ %td= stamp.name
46
+
47
+ %tr
48
+ %th Name Confirmation
49
+ %td= stamp.name_confirmation
50
+
51
+ %tr
52
+ %th Issued At
53
+ %td= stamp.issued_at&.strftime('%F') || 'Not Issued'
@@ -11,7 +11,7 @@
11
11
  Please
12
12
  = link_to("Continue payment for #{existing}", effective_products.ring_wizard_build_path(existing, existing.next_step), 'data-turbolinks' => false, class: 'btn btn-primary')
13
13
  or you can
14
- = link_to('Abandon registration', effective_products.ring_wizard_path(existing), 'data-confirm': "Really delete #{existing}?", 'data-method': :delete, class: 'btn btn-danger')
14
+ = link_to('Abandon payment', effective_products.ring_wizard_path(existing), 'data-confirm': "Really delete #{existing}?", 'data-method': :delete, class: 'btn btn-danger')
15
15
  to start over.
16
16
 
17
17
  %hr
@@ -1,33 +1,40 @@
1
- = card('Ring') do
2
- - ring = ring_wizard.ring
3
- - owner = ring_wizard.owner
1
+ .card
2
+ .card-body
3
+ .row
4
+ .col-sm
5
+ %h5.card-title= ring_wizard.wizard_step_title(:ring)
6
+ .col-sm-auto.text-right
7
+ = link_to('Edit', wizard_path(:ring)) if edit_effective_wizard?
4
8
 
5
- %table.table.table-sm
6
- %tbody
7
- %tr
8
- %th Owner
9
- %td
10
- = owner.to_s
11
- - if owner.try(:email).present?
12
- %br
13
- = mail_to(owner.email)
9
+ - ring = ring_wizard.ring
10
+ - owner = ring_wizard.owner
14
11
 
15
- - if owner.try(:phone).present?
16
- %br
17
- = owner.phone
12
+ %table.table.table-sm
13
+ %tbody
14
+ %tr
15
+ %th Owner
16
+ %td
17
+ = owner.to_s
18
+ - if owner.try(:email).present?
19
+ %br
20
+ = mail_to(owner.email)
18
21
 
19
- - if owner.try(:membership).try(:number).present?
20
- %br
21
- Member Number #{owner.membership.number}
22
+ - if owner.try(:phone).present?
23
+ %br
24
+ = owner.phone
22
25
 
23
- %tr
24
- %th Address
25
- %td= ring.shipping_address.to_html
26
+ - if owner.try(:membership).try(:number).present?
27
+ %br
28
+ Member Number #{owner.membership.number}
26
29
 
27
- %tr
28
- %th Metal
29
- %td= ring.metal
30
+ %tr
31
+ %th Address
32
+ %td= ring.shipping_address.to_html
30
33
 
31
- %tr
32
- %th Size
33
- %td Size #{ring.size}
34
+ %tr
35
+ %th Metal
36
+ %td= ring.metal
37
+
38
+ %tr
39
+ %th Size
40
+ %td Size #{ring.size}
@@ -1,8 +1,3 @@
1
1
  .effective-ring-payment
2
- - blacklist = ring_wizard.class.required_wizard_steps + [:summary]
3
- - steps = ring_wizard.required_steps - blacklist
4
-
5
- = render "effective/ring_wizards/summary", ring_wizard: ring_wizard
6
-
7
- - steps.select { |step| ring_wizard.has_completed_step?(step) }.each do |partial|
2
+ - ring_wizard.render_steps.each do |partial|
8
3
  = render "effective/ring_wizards/#{partial}", ring_wizard: ring_wizard, step: partial
@@ -9,6 +9,7 @@
9
9
 
10
10
  = link_to "Return to Dashboard", root_path, class: 'btn btn-lg btn-primary mb-4'
11
11
 
12
+ = render 'effective/ring_wizards/summary', ring_wizard: resource
12
13
  = render 'effective/ring_wizards/ring_wizard', ring_wizard: resource
13
14
  = render 'effective/ring_wizards/orders', ring_wizard: resource
14
15
 
@@ -0,0 +1,10 @@
1
+ - all_steps_content = resource.try(:rich_text_all_steps_content)
2
+ - step_content = resource.try("rich_text_#{step}_content")
3
+
4
+ - if all_steps_content.present?
5
+ .card.mb-4
6
+ .card-body= all_steps_content
7
+
8
+ - if step_content.present?
9
+ .card.mb-4
10
+ .card-body= step_content
@@ -0,0 +1,27 @@
1
+ -# In progress payments
2
+ - existing = EffectiveProducts.StampWizard.in_progress.for(current_user).first
3
+ - datatable = EffectiveResources.best('EffectiveStampWizardsDatatable').new(self, namespace: :effective)
4
+
5
+ - if existing.present?
6
+ %h2 In Progress Stamp Payments
7
+
8
+ %p Your payment for Professional Stamp is incomplete
9
+
10
+ %p
11
+ Please
12
+ = link_to("Continue payment for #{existing}", effective_products.stamp_wizard_build_path(existing, existing.next_step), 'data-turbolinks' => false, class: 'btn btn-primary')
13
+ or you can
14
+ = link_to('Abandon payment', effective_products.stamp_wizard_path(existing), 'data-confirm': "Really delete #{existing}?", 'data-method': :delete, class: 'btn btn-danger')
15
+ to start over.
16
+
17
+ %hr
18
+
19
+ %h2 Stamp Payments
20
+
21
+ - if datatable.present?
22
+ = render_simple_datatable(datatable)
23
+ - else
24
+ %p You have no past stamp payments. When you do, we'll show them here.
25
+
26
+ - if existing.blank?
27
+ %p= link_to 'Order a Professional Stamp', effective_products.new_stamp_wizard_path, class: 'btn btn-primary'
@@ -0,0 +1,3 @@
1
+ .row
2
+ .col-lg-3.mb-3= render_wizard_sidebar(resource)
3
+ .col-lg-9= yield
@@ -0,0 +1,4 @@
1
+ - if stamp_wizard.submit_order&.purchased?
2
+ .card.mb-4
3
+ .card-body
4
+ = render(stamp_wizard.submit_order)
@@ -0,0 +1,45 @@
1
+ .card
2
+ .card-body
3
+ .row
4
+ .col-sm
5
+ %h5.card-title= stamp_wizard.wizard_step_title(:stamp)
6
+ .col-sm-auto.text-right
7
+ = link_to('Edit', wizard_path(:stamp)) if edit_effective_wizard?
8
+
9
+ - stamp = stamp_wizard.stamp
10
+ - owner = stamp_wizard.owner
11
+
12
+ %table.table.table-sm
13
+ %tbody
14
+ %tr
15
+ %th Owner
16
+ %td
17
+ = owner.to_s
18
+ - if owner.try(:email).present?
19
+ %br
20
+ = mail_to(owner.email)
21
+
22
+ - if owner.try(:phone).present?
23
+ %br
24
+ = owner.phone
25
+
26
+ - if owner.try(:membership).try(:number).present?
27
+ %br
28
+ Member Number #{owner.membership.number}
29
+
30
+ %tr
31
+ %th Category
32
+ %td= stamp.category
33
+
34
+ - if stamp.shipping_address.present?
35
+ %tr
36
+ %th Address
37
+ %td= stamp.shipping_address.to_html
38
+
39
+ %tr
40
+ %th Name
41
+ %td= stamp.name
42
+
43
+ %tr
44
+ %th Name Confirmation
45
+ %td= stamp.name_confirmation
@@ -0,0 +1,45 @@
1
+ %h2 Contact Information
2
+
3
+ - owner = f.object.owner
4
+
5
+ %p
6
+ = owner.to_s
7
+
8
+ - if owner.try(:email).present?
9
+ %br
10
+ = mail_to(owner.email)
11
+
12
+ - if owner.try(:phone).present?
13
+ %br
14
+ = owner.phone
15
+
16
+ - if owner.try(:membership).try(:number).present?
17
+ %br
18
+ Member Number #{owner.membership.number}
19
+
20
+ %h2 Display Name
21
+ %p Please enter and confirm your name as it should appear on the Professional Stamp.
22
+
23
+ = f.text_field :name
24
+ = f.text_field :name_confirmation, hint: 'must match name'
25
+
26
+ %h2 Stamp Information
27
+
28
+ %table.table
29
+ %thead
30
+ %th Stamp
31
+ %th.order_price Cost
32
+ %tbody
33
+ %tr
34
+ %td Physical
35
+ %td.order_price $50.00 + GST
36
+ %tr
37
+ %td Digital-only
38
+ %td.order_price $25.00 + GST
39
+
40
+ %p Please select a stamp:
41
+
42
+ = f.select :category, Effective::Stamp::CATEGORIES
43
+
44
+ = f.show_if :category, 'Physical' do
45
+ = effective_address_fields(f, :shipping)
@@ -0,0 +1,3 @@
1
+ .effective-stamp-payment
2
+ - stamp_wizard.render_steps.each do |partial|
3
+ = render "effective/stamp_wizards/#{partial}", stamp_wizard: stamp_wizard, step: partial
@@ -0,0 +1,31 @@
1
+ = card('Stamp Payment') do
2
+ - stamp = stamp_wizard.stamp
3
+
4
+ %table.table.table-sm
5
+ %tbody
6
+ - if request.path.start_with?('/admin')
7
+ %tr
8
+ %th Owner
9
+ %td
10
+ - url = (polymorphic_admin_path(stamp_wizard.owner) rescue "/admin/users/#{stamp_wizard.owner.to_param}/edit")
11
+ = link_to(stamp_wizard.owner, url)
12
+ - else
13
+ %tr
14
+ %th Owner
15
+ %td= stamp_wizard.owner
16
+
17
+ - if stamp_wizard.orders.present?
18
+ %tr
19
+ %th Order
20
+ %td
21
+ - stamp_wizard.orders.each do |order|
22
+ = link_to(order, effective_orders.order_path(order))
23
+
24
+ - if stamp_wizard.was_submitted?
25
+ %tr
26
+ %th Submitted
27
+ %td= stamp_wizard.submitted_at.strftime('%F')
28
+
29
+ %tr
30
+ %th Issued
31
+ %td= stamp.issued_at&.strftime('%F') || 'Not Issued'
@@ -0,0 +1,15 @@
1
+ = render 'layout' do
2
+ = render 'effective/stamp_wizards/content', resource: resource
3
+
4
+ - raise('expected owner to respond to billing_address') unless resource.owner.respond_to?(:billing_address)
5
+
6
+ = card('Billing Address') do
7
+ %p Please enter your billing address
8
+
9
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
10
+ = f.hidden_field :id
11
+
12
+ = f.fields_for(:owner, f.object.owner) do |fu|
13
+ = effective_address_fields(fu, :billing)
14
+
15
+ = f.save 'Save and Continue'
@@ -0,0 +1,6 @@
1
+ = render 'layout' do
2
+ = render 'effective/stamp_wizards/content', resource: resource
3
+
4
+ .card
5
+ .card-body
6
+ = render_checkout_step2(resource.submit_order, purchased_url: wizard_path(:submitted), deferred_url: wizard_path(:checkout), declined_url: wizard_path(:checkout))
@@ -0,0 +1,18 @@
1
+ = render 'layout' do
2
+ = render 'effective/stamp_wizards/content', resource: resource
3
+
4
+ .card
5
+ .card-body
6
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
7
+ = f.hidden_field :id
8
+
9
+ = f.fields_for :stamps, (f.object.stamp || f.object.build_stamp) do |fr|
10
+ = fr.hidden_field :stamp_wizard_id
11
+ = fr.hidden_field :stamp_wizard_type
12
+
13
+ = fr.hidden_field :owner_id
14
+ = fr.hidden_field :owner_type
15
+
16
+ = render('effective/stamp_wizards/stamp_fields', f: fr)
17
+
18
+ = f.save 'Save and Continue'
@@ -0,0 +1,16 @@
1
+ = render 'layout' do
2
+ = render 'effective/stamp_wizards/content', resource: resource
3
+
4
+ .card
5
+ .card-body
6
+ %p Welcome #{current_user}!
7
+
8
+ %p You are about to purchase a 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.hidden_field :owner_type
14
+ = f.hidden_field :owner_id
15
+
16
+ = f.save 'Save and Continue'
@@ -0,0 +1,16 @@
1
+ = render 'layout' do
2
+ = render 'effective/stamp_wizards/content', resource: resource
3
+
4
+ - raise('expected a submitted resource') unless resource.was_submitted?
5
+ - raise('expected a purchased resource submit_order') unless resource.submit_order&.purchased?
6
+
7
+ .alert.alert-warning.mb-4
8
+ Successfully paid on #{resource.submit_order.purchased_at.strftime('%F')}.
9
+
10
+ = link_to "Return to Dashboard", root_path, class: 'btn btn-lg btn-primary mb-4'
11
+
12
+ = render 'effective/stamp_wizards/summary', stamp_wizard: resource
13
+ = render 'effective/stamp_wizards/stamp_wizard', stamp_wizard: resource
14
+ = render 'effective/stamp_wizards/orders', stamp_wizard: resource
15
+
16
+ = link_to 'Return to Dashboard', root_path, class: 'btn btn-lg btn-primary'
@@ -0,0 +1,8 @@
1
+ = render 'layout' do
2
+ = render 'effective/stamp_wizards/content', resource: resource
3
+
4
+ = render 'effective/stamp_wizards/stamp_wizard', stamp_wizard: resource
5
+
6
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
7
+ = f.hidden_field :id
8
+ = f.submit 'Save and Continue', class: 'btn btn-primary'
@@ -0,0 +1,11 @@
1
+ = f.text_field :name
2
+ = f.text_field :name_confirmation, hint: 'must match name'
3
+
4
+ %h2 Stamp Information
5
+
6
+ %p Please select a stamp and enter a shipping address.
7
+
8
+ = f.select :category, Effective::Stamp::CATEGORIES
9
+
10
+ = f.show_if :category, 'Physical' do
11
+ = effective_address_fields(f, :shipping)
data/config/routes.rb CHANGED
@@ -10,6 +10,10 @@ EffectiveProducts::Engine.routes.draw do
10
10
  resources :ring_wizards, name: :ring_wizard, only: [:new, :show, :destroy] do
11
11
  resources :build, controller: :ring_wizards, only: [:show, :update]
12
12
  end
13
+
14
+ resources :stamp_wizards, name: :stamp_wizard, only: [:new, :show, :destroy] do
15
+ resources :build, controller: :stamp_wizards, only: [:show, :update]
16
+ end
13
17
  end
14
18
 
15
19
  namespace :admin do
@@ -18,6 +22,10 @@ EffectiveProducts::Engine.routes.draw do
18
22
  resources :rings, only: [:index, :show] do
19
23
  post :mark_as_issued, on: :member
20
24
  end
25
+
26
+ resources :stamps do
27
+ post :mark_as_issued, on: :member
28
+ end
21
29
  end
22
30
 
23
31
  end
@@ -48,5 +48,60 @@ class CreateEffectiveProducts < ActiveRecord::Migration[6.1]
48
48
  add_index :ring_wizards, :status
49
49
  add_index :ring_wizards, :token
50
50
 
51
+ create_table :stamps do |t|
52
+ t.integer :owner_id
53
+ t.string :owner_type
54
+
55
+ t.integer :stamp_wizard_id
56
+ t.string :stamp_wizard_type
57
+
58
+ t.integer :applicant_id
59
+ t.string :applicant_type
60
+
61
+ t.string :status
62
+ t.text :status_steps
63
+
64
+ t.string :category
65
+ t.string :name
66
+ t.string :name_confirmation
67
+
68
+ t.datetime :issued_at
69
+
70
+ # Acts as purchasable
71
+ t.integer :purchased_order_id
72
+ t.integer :price
73
+ t.boolean :tax_exempt, default: false
74
+ t.string :qb_item_name
75
+
76
+ t.timestamps
77
+ end
78
+
79
+ create_table :stamp_wizards do |t|
80
+ t.string :token
81
+
82
+ t.integer :owner_id
83
+ t.string :owner_type
84
+
85
+ t.integer :user_id
86
+ t.string :user_type
87
+
88
+ # Acts as Statused
89
+ t.string :status
90
+ t.text :status_steps
91
+
92
+ # Acts as Wizard
93
+ t.text :wizard_steps
94
+
95
+ # Dates
96
+ t.datetime :submitted_at
97
+
98
+ t.datetime :updated_at
99
+ t.datetime :created_at
100
+ end
101
+
102
+ add_index :stamp_wizards, [:owner_id, :owner_type]
103
+ add_index :stamp_wizards, :status
104
+ add_index :stamp_wizards, :token
105
+
51
106
  end
52
107
  end
@@ -11,6 +11,7 @@ module EffectiveProducts
11
11
  initializer 'effective_products.active_record' do |app|
12
12
  ActiveSupport.on_load :active_record do
13
13
  ActiveRecord::Base.extend(EffectiveProductsRingWizard::Base)
14
+ ActiveRecord::Base.extend(EffectiveProductsStampWizard::Base)
14
15
  end
15
16
  end
16
17
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveProducts
2
- VERSION = '0.0.3'.freeze
2
+ VERSION = '0.0.7'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_products
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.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-01-28 00:00:00.000000000 Z
11
+ date: 2022-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -222,14 +222,23 @@ files:
222
222
  - app/assets/stylesheets/effective_products.scss
223
223
  - app/assets/stylesheets/effective_products/base.scss
224
224
  - app/controllers/admin/rings_controller.rb
225
+ - app/controllers/admin/stamps_controller.rb
225
226
  - app/controllers/effective/ring_wizards_controller.rb
227
+ - app/controllers/effective/stamp_wizards_controller.rb
226
228
  - app/datatables/admin/effective_rings_datatable.rb
229
+ - app/datatables/admin/effective_stamps_datatable.rb
227
230
  - app/datatables/effective_ring_wizards_datatable.rb
231
+ - app/datatables/effective_stamp_wizards_datatable.rb
228
232
  - app/helpers/effective_products_helper.rb
229
233
  - app/models/concerns/effective_products_ring_wizard.rb
234
+ - app/models/concerns/effective_products_stamp_wizard.rb
230
235
  - app/models/effective/ring.rb
231
236
  - app/models/effective/ring_wizard.rb
237
+ - app/models/effective/stamp.rb
238
+ - app/models/effective/stamp_wizard.rb
232
239
  - app/views/admin/rings/_ring.html.haml
240
+ - app/views/admin/stamps/_form.html.haml
241
+ - app/views/admin/stamps/_stamp.html.haml
233
242
  - app/views/effective/ring_wizards/_content.html.haml
234
243
  - app/views/effective/ring_wizards/_dashboard.html.haml
235
244
  - app/views/effective/ring_wizards/_layout.html.haml
@@ -244,7 +253,21 @@ files:
244
253
  - app/views/effective/ring_wizards/start.html.haml
245
254
  - app/views/effective/ring_wizards/submitted.html.haml
246
255
  - app/views/effective/ring_wizards/summary.html.haml
247
- - app/views/effective/rings/_fields.html.haml
256
+ - app/views/effective/stamp_wizards/_content.html.haml
257
+ - app/views/effective/stamp_wizards/_dashboard.html.haml
258
+ - app/views/effective/stamp_wizards/_layout.html.haml
259
+ - app/views/effective/stamp_wizards/_orders.html.haml
260
+ - app/views/effective/stamp_wizards/_stamp.html.haml
261
+ - app/views/effective/stamp_wizards/_stamp_fields.html.haml
262
+ - app/views/effective/stamp_wizards/_stamp_wizard.html.haml
263
+ - app/views/effective/stamp_wizards/_summary.html.haml
264
+ - app/views/effective/stamp_wizards/billing.html.haml
265
+ - app/views/effective/stamp_wizards/checkout.html.haml
266
+ - app/views/effective/stamp_wizards/stamp.html.haml
267
+ - app/views/effective/stamp_wizards/start.html.haml
268
+ - app/views/effective/stamp_wizards/submitted.html.haml
269
+ - app/views/effective/stamp_wizards/summary.html.haml
270
+ - app/views/effective/stamps/_fields.html.haml
248
271
  - config/effective_products.rb
249
272
  - config/routes.rb
250
273
  - db/migrate/01_create_effective_products.rb.erb
@@ -1,39 +0,0 @@
1
- %h2 Contact Information
2
-
3
- = f.text_field :first_name
4
- = f.text_field :last_name
5
- = f.email_field :email
6
- = f.phone_field :phone
7
- = f.static_field :member_number, value: f.object.owner&.membership&.number || 'None'
8
-
9
- = effective_address_fields(f, :shipping)
10
-
11
- %h2 Ring Information
12
-
13
- %table.table
14
- %thead
15
- %th Ring Size
16
- %th Composition
17
- %th.order_price Cost
18
- %tbody
19
- %tr
20
- %td 3-8
21
- %td 14k Yellow Gold
22
- %td.order_price $425.00 + GST
23
- %tr
24
- %td 3-8
25
- %td Sterling Silver
26
- %td.order_price $175.00 + GST
27
- %tr
28
- %td 3-13
29
- %td Titanium
30
- %td.order_price $50.00 + GST
31
-
32
- %ul
33
- %li 14k Yellow Gold and Sterling Silver rings are available in sizes 3 - 8.
34
- %li Titanium rings are available in sizes 3 - 13.
35
-
36
- %p Please select a ring metal and size:
37
-
38
- = f.select :metal, Effective::Ring::METALS
39
- = f.select :size, Effective::Ring::TITANIUM_SIZES