effective_products 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/admin/stamps_controller.rb +9 -0
- data/app/controllers/effective/stamp_wizards_controller.rb +10 -0
- data/app/datatables/admin/effective_stamps_datatable.rb +43 -0
- data/app/datatables/effective_stamp_wizards_datatable.rb +36 -0
- data/app/models/concerns/effective_products_ring_wizard.rb +19 -13
- data/app/models/concerns/effective_products_stamp_wizard.rb +139 -0
- data/app/models/effective/stamp.rb +69 -0
- data/app/models/effective/stamp_wizard.rb +7 -0
- data/app/views/admin/stamps/_stamp.html.haml +53 -0
- data/app/views/effective/ring_wizards/_dashboard.html.haml +1 -1
- data/app/views/effective/stamp_wizards/_content.html.haml +10 -0
- data/app/views/effective/stamp_wizards/_dashboard.html.haml +27 -0
- data/app/views/effective/stamp_wizards/_layout.html.haml +3 -0
- data/app/views/effective/stamp_wizards/_orders.html.haml +4 -0
- data/app/views/effective/stamp_wizards/_stamp.html.haml +45 -0
- data/app/views/effective/stamp_wizards/_stamp_fields.html.haml +45 -0
- data/app/views/effective/stamp_wizards/_stamp_wizard.html.haml +3 -0
- data/app/views/effective/stamp_wizards/_summary.html.haml +31 -0
- data/app/views/effective/stamp_wizards/billing.html.haml +15 -0
- data/app/views/effective/stamp_wizards/checkout.html.haml +6 -0
- data/app/views/effective/stamp_wizards/stamp.html.haml +18 -0
- data/app/views/effective/stamp_wizards/start.html.haml +16 -0
- data/app/views/effective/stamp_wizards/submitted.html.haml +16 -0
- data/app/views/effective/stamp_wizards/summary.html.haml +8 -0
- data/config/routes.rb +8 -0
- data/db/migrate/01_create_effective_products.rb.erb +49 -0
- data/lib/effective_products/engine.rb +1 -0
- data/lib/effective_products/version.rb +1 -1
- metadata +23 -2
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe191a8c318148da7f4d5c91a4e8248ad1e46ed79a226fd8549873fbeeac7e58
|
4
|
+
data.tar.gz: e0481a234925beb15a4bde2656f931cfc98466224d4fdaa7cdf0be3e4a85879e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39a16cb225c1dd2f0c575af9eec56d5b8865f928d2acc2cb0990aec35dfd36b1d9af8acb474a3ac53dee78772224520fd3e35949447bbf1d5079c38a904511bb
|
7
|
+
data.tar.gz: a9f3006715674b41ce72da94d2936a87d456a45f08920cc4765ecc5596d69ffa6502a42aeed557c3ca1dd2061e76214d897bb3e91308e8bb5e2ede6790ec5781
|
@@ -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,43 @@
|
|
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(:first_name) { |stamp| stamp.owner.first_name }
|
20
|
+
col(:last_name) { |stamp| stamp.owner.last_name }
|
21
|
+
col(:email) { |stamp| stamp.owner.email }
|
22
|
+
col(:phone) { |stamp| stamp.owner.phone }
|
23
|
+
|
24
|
+
col :member_number, label: 'Member #' do |stamp|
|
25
|
+
stamp.owner.try(:membership).try(:number)
|
26
|
+
end
|
27
|
+
|
28
|
+
col :category
|
29
|
+
col :name
|
30
|
+
col :name_confirmation
|
31
|
+
|
32
|
+
col :shipping_address, label: 'Address'
|
33
|
+
|
34
|
+
col :issued_at
|
35
|
+
|
36
|
+
actions_col
|
37
|
+
end
|
38
|
+
|
39
|
+
collection do
|
40
|
+
Effective::Stamp.deep.all
|
41
|
+
end
|
42
|
+
end
|
43
|
+
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
|
@@ -75,7 +75,7 @@ module EffectiveProductsRingWizard
|
|
75
75
|
# All Steps validations
|
76
76
|
validates :owner, presence: true
|
77
77
|
|
78
|
-
#
|
78
|
+
# Ring Step
|
79
79
|
validate(if: -> { current_step == :ring }) do
|
80
80
|
self.errors.add(:rings, "can't be blank") unless present_rings.present?
|
81
81
|
end
|
@@ -120,23 +120,29 @@ module EffectiveProductsRingWizard
|
|
120
120
|
end
|
121
121
|
|
122
122
|
def assign_pricing
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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)
|
135
139
|
end
|
136
140
|
|
137
141
|
# After the configure Ring step
|
138
142
|
def ring!
|
139
143
|
assign_pricing() if ring.present?
|
144
|
+
raise('expected ring to have a price') if ring.price.blank?
|
145
|
+
|
140
146
|
save!
|
141
147
|
end
|
142
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
|
+
# Nothing to do yet
|
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
|
@@ -0,0 +1,69 @@
|
|
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
|
+
#CATEGORIES = ['Physical', 'Digital-only']
|
9
|
+
CATEGORIES = ['Physical']
|
10
|
+
|
11
|
+
log_changes if respond_to?(:log_changes)
|
12
|
+
|
13
|
+
# This ring is charged to an owner
|
14
|
+
belongs_to :owner, polymorphic: true
|
15
|
+
|
16
|
+
# Through the stamp_wizard
|
17
|
+
belongs_to :stamp_wizard, polymorphic: true, optional: true
|
18
|
+
|
19
|
+
effective_resource do
|
20
|
+
name :string
|
21
|
+
name_confirmation :string
|
22
|
+
|
23
|
+
category :string
|
24
|
+
|
25
|
+
# Admin issues stamps
|
26
|
+
issued_at :datetime # Present when issued by an admin
|
27
|
+
|
28
|
+
# Acts as Purchasable
|
29
|
+
price :integer
|
30
|
+
qb_item_name :string
|
31
|
+
tax_exempt :boolean
|
32
|
+
|
33
|
+
timestamps
|
34
|
+
end
|
35
|
+
|
36
|
+
scope :deep, -> { includes(:owner) }
|
37
|
+
scope :ready_to_issue, -> { purchased.where(issued_at: nil) }
|
38
|
+
scope :issued, -> { where.not(issued_at: nil) }
|
39
|
+
|
40
|
+
validates :category, presence: true, inclusion: { in: CATEGORIES }
|
41
|
+
validates :name, presence: true
|
42
|
+
validates :name_confirmation, presence: true
|
43
|
+
|
44
|
+
validate(if: -> { name.present? && name_confirmation.present? }) do
|
45
|
+
self.errors.add(:name_confirmation, "doesn't match name") unless name == name_confirmation
|
46
|
+
end
|
47
|
+
|
48
|
+
validate(if: -> { physical? }) do
|
49
|
+
self.errors.add(:shipping_address, "can't be blank when physical stamp") unless shipping_address.present?
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
['Professional Stamp', *name.presence].join(' ')
|
54
|
+
end
|
55
|
+
|
56
|
+
def mark_as_issued!
|
57
|
+
update!(issued_at: Time.zone.now)
|
58
|
+
end
|
59
|
+
|
60
|
+
def issued?
|
61
|
+
issued_at.present?
|
62
|
+
end
|
63
|
+
|
64
|
+
def physical?
|
65
|
+
category == 'Physical'
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -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
|
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
|
@@ -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,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,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'
|
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, only: [:index, :show] do
|
27
|
+
post :mark_as_issued, on: :member
|
28
|
+
end
|
21
29
|
end
|
22
30
|
|
23
31
|
end
|
@@ -48,5 +48,54 @@ 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.string :category
|
59
|
+
t.string :name
|
60
|
+
t.string :name_confirmation
|
61
|
+
|
62
|
+
t.datetime :issued_at
|
63
|
+
|
64
|
+
# Acts as purchasable
|
65
|
+
t.integer :purchased_order_id
|
66
|
+
t.integer :price
|
67
|
+
t.boolean :tax_exempt, default: false
|
68
|
+
t.string :qb_item_name
|
69
|
+
|
70
|
+
t.timestamps
|
71
|
+
end
|
72
|
+
|
73
|
+
create_table :stamp_wizards do |t|
|
74
|
+
t.string :token
|
75
|
+
|
76
|
+
t.integer :owner_id
|
77
|
+
t.string :owner_type
|
78
|
+
|
79
|
+
t.integer :user_id
|
80
|
+
t.string :user_type
|
81
|
+
|
82
|
+
# Acts as Statused
|
83
|
+
t.string :status
|
84
|
+
t.text :status_steps
|
85
|
+
|
86
|
+
# Acts as Wizard
|
87
|
+
t.text :wizard_steps
|
88
|
+
|
89
|
+
# Dates
|
90
|
+
t.datetime :submitted_at
|
91
|
+
|
92
|
+
t.datetime :updated_at
|
93
|
+
t.datetime :created_at
|
94
|
+
end
|
95
|
+
|
96
|
+
add_index :stamp_wizards, [:owner_id, :owner_type]
|
97
|
+
add_index :stamp_wizards, :status
|
98
|
+
add_index :stamp_wizards, :token
|
99
|
+
|
51
100
|
end
|
52
101
|
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
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_products
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
@@ -222,14 +222,22 @@ 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/_stamp.html.haml
|
233
241
|
- app/views/effective/ring_wizards/_content.html.haml
|
234
242
|
- app/views/effective/ring_wizards/_dashboard.html.haml
|
235
243
|
- app/views/effective/ring_wizards/_layout.html.haml
|
@@ -244,7 +252,20 @@ files:
|
|
244
252
|
- app/views/effective/ring_wizards/start.html.haml
|
245
253
|
- app/views/effective/ring_wizards/submitted.html.haml
|
246
254
|
- app/views/effective/ring_wizards/summary.html.haml
|
247
|
-
- app/views/effective/
|
255
|
+
- app/views/effective/stamp_wizards/_content.html.haml
|
256
|
+
- app/views/effective/stamp_wizards/_dashboard.html.haml
|
257
|
+
- app/views/effective/stamp_wizards/_layout.html.haml
|
258
|
+
- app/views/effective/stamp_wizards/_orders.html.haml
|
259
|
+
- app/views/effective/stamp_wizards/_stamp.html.haml
|
260
|
+
- app/views/effective/stamp_wizards/_stamp_fields.html.haml
|
261
|
+
- app/views/effective/stamp_wizards/_stamp_wizard.html.haml
|
262
|
+
- app/views/effective/stamp_wizards/_summary.html.haml
|
263
|
+
- app/views/effective/stamp_wizards/billing.html.haml
|
264
|
+
- app/views/effective/stamp_wizards/checkout.html.haml
|
265
|
+
- app/views/effective/stamp_wizards/stamp.html.haml
|
266
|
+
- app/views/effective/stamp_wizards/start.html.haml
|
267
|
+
- app/views/effective/stamp_wizards/submitted.html.haml
|
268
|
+
- app/views/effective/stamp_wizards/summary.html.haml
|
248
269
|
- config/effective_products.rb
|
249
270
|
- config/routes.rb
|
250
271
|
- 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
|