effective_products 0.3.19 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9359afd6341adfc7785cfdab0bb854383be7056444cee9e9c96c3498700e37f3
4
- data.tar.gz: 8337933483ebd05733c5a0f40d4992efd63aa016ea5c223a0fda99bcfe0952ad
3
+ metadata.gz: ae9800b96a6f375ca67ce8dc0f46f0324a33958404debfc3e1fd0d9143db9bbe
4
+ data.tar.gz: 7160df9d3c521738108b6051ca5c7c1b0274668667351a380597104829fb1ce9
5
5
  SHA512:
6
- metadata.gz: b37be8fdb808e28a4ce8e9f721708de8fe94b6f9e78f4355ff32aec0adb14db19d208f3e568dcb168c290cb5ac97ce40e5edf4b9409e4a38f55e6293e881a1f9
7
- data.tar.gz: d84aa1252cdc276af293caa02e606b81a9d02115683cb2437419f8f1459a68a524be81869ccf121bd650e74b453628df7f8969cbb2b525d396c52c6386263b51
6
+ metadata.gz: 25c627e59ff932a4fc4be7b5001f9e65bce0c237cdbcd64350f39759a72b87e55f07517e5e3ab118acbb195fa36fc27c65bec615e7bb8e74dccdaaa631318b92
7
+ data.tar.gz: 0c9edae9f2ddeee94927abbd1788e9bae6f19e131e3acba02b664765970d8be20479005bc1386c45f5e1bd60440466a9d84aa1c90bfc475cbb939e2fce585b46
@@ -5,5 +5,6 @@ module Admin
5
5
 
6
6
  include Effective::CrudController
7
7
 
8
+ submit :mark_paid, 'Save and Mark Paid', redirect: :index
8
9
  end
9
10
  end
@@ -5,12 +5,6 @@ module Admin
5
5
 
6
6
  include Effective::CrudController
7
7
 
8
- # Admin can go straight to submitted
9
- submit :mark_as_submitted, 'Save'
10
8
  submit :mark_paid, 'Save and Mark Paid', redirect: :index
11
-
12
- on :mark_as_submitted, redirect: :index
13
- on :mark_as_issued, redirect: :index
14
-
15
9
  end
16
10
  end
@@ -1,20 +1,26 @@
1
1
  module Admin
2
2
  class EffectiveRingsDatatable < Effective::Datatable
3
3
  filters do
4
- scope :ready_to_issue
4
+ scope :submitted
5
5
  scope :issued
6
6
  scope :all
7
7
  end
8
8
 
9
9
  datatable do
10
- order :updated_at
10
+ order :submitted_at
11
11
 
12
12
  col :updated_at, visible: false
13
- col :created_at, visible: false
13
+ col :created_at, as: :date, visible: false
14
14
  col :id, visible: false
15
15
 
16
- col :created_at, as: :date
17
- col :owner, search: :string
16
+ col :status
17
+
18
+ col :submitted_at, as: :date
19
+ col :purchased_at, as: :date, visible: false
20
+ col :issued_at, as: :date, visible: false
21
+
22
+ col :owner, label: 'User', search: :string
23
+ col :parent
18
24
 
19
25
  col(:first_name) { |ring| ring.owner.first_name }
20
26
  col(:last_name) { |ring| ring.owner.last_name }
@@ -25,11 +31,22 @@ module Admin
25
31
  ring.owner.try(:membership).try(:number)
26
32
  end
27
33
 
28
- col :shipping_address, label: 'Address'
34
+ col(:shipping_address, visible: true) { |ring| ring.owner.try(:shipping_address).try(:to_html) }
35
+ col(:address1, visible: false) { |ring| ring.owner.try(:shipping_address).try(:address1) }
36
+ col(:address2, visible: false) { |ring| ring.owner.try(:shipping_address).try(:address2) }
37
+ col(:city, visible: false) { |ring| ring.owner.try(:shipping_address).try(:city) }
38
+ col(:state_code, visible: false, label: 'Prov') { |ring| ring.owner.try(:shipping_address).try(:state_code) }
39
+ col(:postal_code, visible: false, label: 'Postal') { |ring| ring.owner.try(:shipping_address).try(:postal_code) }
40
+ col(:country_code, visible: false, label: 'Country') { |ring| ring.owner.try(:shipping_address).try(:country_code) }
29
41
 
30
42
  col :size
31
43
  col :metal
32
- col :issued_at
44
+
45
+ col :purchased_order, search: :string, visible: false
46
+ col :price, as: :price, visible: false
47
+ col :tax_exempt, visible: false
48
+ col :qb_item_name, visible: false
49
+
33
50
 
34
51
  actions_col
35
52
  end
@@ -1,44 +1,28 @@
1
1
  module Admin
2
2
  class EffectiveStampsDatatable < Effective::Datatable
3
3
  filters do
4
- scope :ready_to_issue
5
- scope :pending
4
+ scope :submitted
6
5
  scope :issued
7
6
  scope :all
8
7
  end
9
8
 
10
9
  datatable do
11
- order :purchased_at
10
+ order :submitted_at
12
11
 
13
12
  col :updated_at, visible: false
13
+ col :created_at, as: :date, visible: false
14
14
  col :id, visible: false
15
15
 
16
- col :registered_at, as: :date do |stamp|
17
- stamp.applicant.try(:registered_at).try(:strftime, '%F')
18
- end
19
-
20
- col :purchased_at, as: :date, visible: false do |stamp|
21
- stamp.purchased_order.try(:purchased_at).try(:strftime, '%F')
22
- end
16
+ col :status
23
17
 
24
- col :created_at, as: :date, visible: false
25
- col :created_by
26
- col :status, visible: false
27
- col :owner, search: :string
18
+ col :submitted_at, as: :date
19
+ col :purchased_at, as: :date, visible: false
20
+ col :issued_at, as: :date, visible: false
28
21
 
29
- col(:applicant, search: :string) do |stamp|
30
- if stamp.applicant.present?
31
- link_to(stamp.applicant, effective_memberships.edit_admin_applicant_path(stamp.applicant)) + ' ' + badges(stamp.applicant.status)
32
- end
33
- end
22
+ col :owner, label: 'User', search: :string
23
+ col :parent
34
24
 
35
- col(:stamp_wizard, search: :string) do |stamp|
36
- if stamp.stamp_wizard.present?
37
- stamp.stamp_wizard.to_s + ' ' + badges(stamp.stamp_wizard.status)
38
- end
39
- end
40
-
41
- col(:email, visible: false) { |stamp| mail_to stamp.owner.email }
25
+ col(:email, visible: false) { |stamp| mail_to(stamp.owner.email) }
42
26
  col(:phone, visible: false) { |stamp| stamp.owner.phone }
43
27
 
44
28
  col :member_number, label: 'Member #' do |stamp|
@@ -50,26 +34,19 @@ module Admin
50
34
 
51
35
  col :category, search: EffectiveProducts.stamp_categories
52
36
 
53
- if current_user.respond_to?(:shipping_address)
54
- col :user_shipping_address, label: "Shipping Address" do |stamp|
55
- stamp.owner.try(:shipping_address).try(:to_html)
56
- end
57
-
58
- col(:address1, visible: false) { |stamp| stamp&.owner.shipping_address.try(:address1) }
59
- col(:address2, visible: false) { |stamp| stamp&.owner.shipping_address.try(:address2) }
60
- col(:city, visible: false) { |stamp| stamp&.owner.shipping_address.try(:city) }
61
- col(:state_code, visible: false, label: 'Prov') { |stamp| stamp&.owner.shipping_address.try(:state_code) }
62
- col(:postal_code, visible: false, label: 'Postal') { |stamp| stamp&.owner.shipping_address.try(:postal_code) }
63
- col(:country_code, visible: false, label: 'Country') { |stamp| stamp&.owner.shipping_address.try(:country_code) }
64
- end
37
+ col(:shipping_address, visible: true) { |stamp| stamp.owner.try(:shipping_address).try(:to_html) }
38
+ col(:address1, visible: false) { |stamp| stamp.owner.try(:shipping_address).try(:address1) }
39
+ col(:address2, visible: false) { |stamp| stamp.owner.try(:shipping_address).try(:address2) }
40
+ col(:city, visible: false) { |stamp| stamp.owner.try(:shipping_address).try(:city) }
41
+ col(:state_code, visible: false, label: 'Prov') { |stamp| stamp.owner.try(:shipping_address).try(:state_code) }
42
+ col(:postal_code, visible: false, label: 'Postal') { |stamp| stamp.owner.try(:shipping_address).try(:postal_code) }
43
+ col(:country_code, visible: false, label: 'Country') { |stamp| stamp.owner.try(:shipping_address).try(:country_code) }
65
44
 
66
45
  col :purchased_order, search: :string, visible: false
67
46
  col :price, as: :price, visible: false
68
47
  col :tax_exempt, visible: false
69
48
  col :qb_item_name, visible: false
70
49
 
71
- col :issued_at, as: :date
72
-
73
50
  actions_col
74
51
  end
75
52
 
@@ -44,7 +44,7 @@ module EffectiveProductsRingWizard
44
44
  accepts_nested_attributes_for :owner
45
45
 
46
46
  # Effective Namespace
47
- has_many :rings, -> { order(:id) }, class_name: 'Effective::Ring', inverse_of: :ring_wizard, dependent: :destroy
47
+ has_many :rings, -> { order(:id) }, class_name: 'Effective::Ring', as: :parent, dependent: :destroy
48
48
  accepts_nested_attributes_for :rings, reject_if: :all_blank, allow_destroy: true
49
49
 
50
50
  effective_resource do
@@ -74,7 +74,7 @@ module EffectiveProductsRingWizard
74
74
 
75
75
  # Ring Step
76
76
  validate(if: -> { current_step == :ring }) do
77
- self.errors.add(:rings, "can't be blank") unless present_rings.present?
77
+ errors.add(:rings, "can't be blank") unless present_rings.present?
78
78
  end
79
79
 
80
80
  # All Fees and Orders
@@ -83,14 +83,14 @@ module EffectiveProductsRingWizard
83
83
  end
84
84
 
85
85
  def after_submit_purchased!
86
- # Nothing to do yet
86
+ rings.each { |ring| ring.submit! }
87
87
  end
88
88
 
89
89
  end
90
90
 
91
91
  # Instance Methods
92
92
  def to_s
93
- 'ring payment'
93
+ (persisted? || destroyed?) ? "#{model_name.human} ##{id_was}" : model_name.human
94
94
  end
95
95
 
96
96
  def in_progress?
@@ -106,13 +106,7 @@ module EffectiveProductsRingWizard
106
106
  end
107
107
 
108
108
  def build_ring
109
- ring = rings.build(owner: owner)
110
-
111
- if (address = owner.try(:shipping_address) || owner.try(:billing_address)).present?
112
- ring.shipping_address = address
113
- end
114
-
115
- ring
109
+ rings.build(owner: owner)
116
110
  end
117
111
 
118
112
  def assign_pricing
@@ -44,7 +44,7 @@ module EffectiveProductsStampWizard
44
44
  accepts_nested_attributes_for :owner
45
45
 
46
46
  # Effective Namespace
47
- has_many :stamps, -> { order(:id) }, class_name: 'Effective::Stamp', inverse_of: :stamp_wizard, dependent: :destroy
47
+ has_many :stamps, -> { order(:id) }, class_name: 'Effective::Stamp', as: :parent, dependent: :destroy
48
48
  accepts_nested_attributes_for :stamps, reject_if: :all_blank, allow_destroy: true
49
49
 
50
50
  effective_resource do
@@ -69,12 +69,16 @@ module EffectiveProductsStampWizard
69
69
 
70
70
  scope :for, -> (user) { where(owner: user) }
71
71
 
72
+ before_validation(if: -> { current_step == :stamp && stamp.present? }) do
73
+ assign_pricing unless stamp.purchased?
74
+ end
75
+
72
76
  # All Steps validations
73
77
  validates :owner, presence: true
74
78
 
75
79
  # Stamp Step
76
80
  validate(if: -> { current_step == :stamp }) do
77
- self.errors.add(:stamps, "can't be blank") unless present_stamps.present?
81
+ errors.add(:stamps, "can't be blank") unless present_stamps.present?
78
82
  end
79
83
 
80
84
  # All Fees and Orders
@@ -92,6 +96,10 @@ module EffectiveProductsStampWizard
92
96
  (persisted? || destroyed?) ? "#{model_name.human} ##{id_was}" : model_name.human
93
97
  end
94
98
 
99
+ def stamp_categories
100
+ EffectiveProducts.stamp_categories
101
+ end
102
+
95
103
  def in_progress?
96
104
  draft?
97
105
  end
@@ -105,13 +113,7 @@ module EffectiveProductsStampWizard
105
113
  end
106
114
 
107
115
  def build_stamp
108
- stamp = stamps.build(owner: owner)
109
-
110
- if (address = owner.try(:shipping_address) || owner.try(:billing_address)).present?
111
- stamp.shipping_address = address
112
- end
113
-
114
- stamp
116
+ stamps.build(owner: owner, name: owner.to_s.presence)
115
117
  end
116
118
 
117
119
  def assign_pricing
@@ -124,17 +126,6 @@ module EffectiveProductsStampWizard
124
126
  # stamp.assign_attributes(price: price, qb_item_name: qb_item_name, tax_exempt: tax_exempt)
125
127
  end
126
128
 
127
- # After the configure Stamp step
128
- def stamp!
129
- assign_pricing() if stamp.present?
130
- raise('expected stamp to have a price') if stamp.price.blank?
131
- save!
132
- end
133
-
134
- def stamp_categories
135
- EffectiveProducts.stamp_categories
136
- end
137
-
138
129
  private
139
130
 
140
131
  def present_stamps
@@ -9,22 +9,35 @@ module Effective
9
9
  METALS = ['14k Yellow Gold', 'Sterling Silver', 'Titanium']
10
10
 
11
11
  acts_as_purchasable
12
- acts_as_addressable :shipping
12
+
13
+ acts_as_statused(
14
+ :draft, # Built in an application
15
+ :submitted, # Submitted by a ring wizard
16
+ :issued # Issued by an admin
17
+ )
13
18
 
14
19
  log_changes if respond_to?(:log_changes)
15
20
 
16
21
  # This ring is charged to an owner
17
22
  belongs_to :owner, polymorphic: true
23
+ accepts_nested_attributes_for :owner, reject_if: :all_blank
18
24
 
19
- # Through the ring_wizard
20
- belongs_to :ring_wizard, polymorphic: true, optional: true
25
+ # This could be a RingWizard, or Blank (admin created)
26
+ belongs_to :parent, polymorphic: true, optional: true
21
27
 
22
28
  effective_resource do
23
29
  size :integer
24
30
  metal :string
25
31
 
32
+ submitted_at :datetime
26
33
  issued_at :datetime # Present when issued by an admin
27
34
 
35
+ created_by_admin :boolean
36
+
37
+ # Acts as Statused
38
+ status :string
39
+ status_steps :text
40
+
28
41
  # Acts as Purchasable
29
42
  price :integer
30
43
  qb_item_name :string
@@ -33,31 +46,42 @@ module Effective
33
46
  timestamps
34
47
  end
35
48
 
36
- scope :deep, -> { includes(:addresses, owner: [:membership]) }
49
+ scope :deep, -> { includes(:purchased_order, :parent, owner: [:addresses, :membership]) }
50
+ scope :ready_to_issue, -> { submitted }
51
+ scope :not_issued, -> { where.not(status: :issued) }
52
+ scope :created_by_admin, -> { where(created_by_admin: true) }
37
53
 
38
- scope :ready_to_issue, -> { purchased.where(issued_at: nil) }
39
- scope :issued, -> { where.not(issued_at: nil) }
54
+ validates :parent, presence: true, unless: -> { created_by_admin? }
40
55
 
41
56
  validates :metal, presence: true, inclusion: { in: METALS }
42
-
43
57
  validates :size, presence: true
44
58
  validates :size, inclusion: { in: TITANIUM_SIZES }, if: -> { metal == 'Titanium' }
45
59
  validates :size, inclusion: { in: SIZES }, if: -> { metal != 'Titanium' }
46
60
 
61
+ validate(if: -> { owner.present? }) do
62
+ errors.add(:owner, "must have a shipping address") unless owner.try(:shipping_address).present?
63
+ end
64
+
47
65
  def to_s
48
- ["Chemist's Ring", (" - #{metal} size #{size}" if metal.present? && size.present?)].compact.join
66
+ [
67
+ model_name.human,
68
+ ("#{metal} size #{size}" if metal.present? && size.present?)
69
+ ].compact.join(' - ')
49
70
  end
50
71
 
51
- def mark_as_issued!
52
- update!(issued_at: Time.zone.now)
72
+ # Called by a ring wizard when submitted
73
+ def submit!
74
+ submitted!
53
75
  end
54
76
 
55
- def submitted?
56
- purchased?
77
+ # Admin action
78
+ def mark_as_submitted!
79
+ submitted!
57
80
  end
58
81
 
59
- def issued?
60
- issued_at.present?
82
+ # Admin action
83
+ def mark_as_issued!
84
+ issued!
61
85
  end
62
86
 
63
87
  end
@@ -5,9 +5,6 @@ module Effective
5
5
  self.table_name = (EffectiveProducts.stamps_table_name || :stamps).to_s
6
6
 
7
7
  acts_as_purchasable
8
- acts_as_addressable :shipping
9
-
10
- attr_accessor :admin_action
11
8
 
12
9
  acts_as_statused(
13
10
  :draft, # Built in an application
@@ -19,12 +16,10 @@ module Effective
19
16
 
20
17
  # This stamp is charged to an owner
21
18
  belongs_to :owner, polymorphic: true
19
+ accepts_nested_attributes_for :owner, reject_if: :all_blank
22
20
 
23
- # Sometimes a stamp is built through an applicant
24
- belongs_to :applicant, polymorphic: true, optional: true
25
-
26
- # Other times through the stamp_wizard
27
- belongs_to :stamp_wizard, polymorphic: true, optional: true
21
+ # This could be a StampWizard, an Applicant, a FeePayment, or Blank (admin created)
22
+ belongs_to :parent, polymorphic: true, optional: true
28
23
 
29
24
  effective_resource do
30
25
  name :string
@@ -32,9 +27,11 @@ module Effective
32
27
 
33
28
  category :string
34
29
 
35
- # Admin issues stamps
30
+ submitted_at :datetime
36
31
  issued_at :datetime # Present when issued by an admin
37
32
 
33
+ created_by_admin :boolean
34
+
38
35
  # Acts as Statused
39
36
  status :string
40
37
  status_steps :text
@@ -47,90 +44,59 @@ module Effective
47
44
  timestamps
48
45
  end
49
46
 
50
- scope :deep, -> { includes(:addresses, :purchased_order, owner: [:membership], applicant: [:category, :user], stamp_wizard: [:user]) }
47
+ scope :deep, -> { includes(:purchased_order, :parent, owner: [:addresses, :membership]) }
48
+ scope :ready_to_issue, -> { submitted }
51
49
  scope :not_issued, -> { where.not(status: :issued) }
50
+ scope :created_by_admin, -> { where(created_by_admin: true) }
52
51
 
53
- scope :with_registered_applicants, -> { where(applicant_id: EffectiveMemberships.Applicant.registered) }
54
- scope :with_unregistered_applicants, -> { where.not(applicant_id: nil).where.not(applicant_id: EffectiveMemberships.Applicant.registered) }
55
-
56
- scope :with_purchased_stamp_wizards, -> { purchased.where.not(stamp_wizard_id: nil) }
57
- scope :with_not_purchased_stamp_wizards, -> { not_purchased.where.not(stamp_wizard_id: nil) }
58
-
59
- scope :created_by_admin, -> { submitted.where(applicant_id: nil, stamp_wizard_id: nil) }
60
-
61
- # Datatable Scopes
62
- scope :ready_to_issue, -> {
63
- with_registered_applicants.or(with_purchased_stamp_wizards).or(created_by_admin).submitted
64
- }
65
-
66
- scope :pending, -> { pending_applicant_registration.or(pending_stamp_request_purchase) }
67
- scope :pending_applicant_registration, -> { not_issued.with_unregistered_applicants }
68
- scope :pending_stamp_request_purchase, -> { not_issued.with_not_purchased_stamp_wizards }
52
+ validates :parent, presence: true, unless: -> { created_by_admin? }
69
53
 
70
54
  validates :name, presence: true
71
55
  validates :name_confirmation, presence: true
72
56
  validates :category, presence: true
73
- validates :shipping_address, presence: true, unless: -> { category == 'Digital-only' }
74
57
 
75
58
  validate(if: -> { name.present? && name_confirmation.present? }) do
76
59
  errors.add(:name_confirmation, "doesn't match name") unless name == name_confirmation
77
60
  end
78
61
 
79
- validate(if: -> { admin_action }) do
80
- errors.add(:owner_id, "must have a membership") unless owner && owner.try(:membership).present?
62
+ validate(if: -> { owner.present? }, unless: -> { category == 'Digital-only' }) do
63
+ errors.add(:owner, "must have a shipping address") unless owner.try(:shipping_address).present?
81
64
  end
82
65
 
83
66
  def to_s
84
- [
85
- model_name.human,
86
- ('Replacement' if stamp_wizard_id_was.present?),
87
- '-',
88
- name.presence,
89
- ("- #{category}" if category.present?)
90
- ].compact.join(' ')
67
+ [model_name.human, name.presence, category.presence].compact.join(' - ')
91
68
  end
92
69
 
70
+ # Called by a stamp wizard, applicant or fee payment when submitted
71
+ def submit!
72
+ submitted!
73
+ end
74
+
75
+ # Admin action
93
76
  def mark_as_submitted!
94
77
  submitted!
95
78
  end
96
79
 
80
+ # Admin action
97
81
  def mark_as_issued!
98
82
  issued!
99
83
  end
100
84
 
101
- def created_by_admin?
102
- stamp_wizard_id.blank? && applicant_id.blank?
103
- end
104
-
105
- # Called by an application when submitted
106
- # Called by a stamp wizard when submitted
107
- def submit!
108
- raise('expected a purchased order') unless (purchased? || applicant&.submit_order&.purchased?)
109
- submitted!
110
- end
111
-
112
85
  # This is the Admin Save and Mark Paid action
113
86
  def mark_paid!
114
- assign_attributes(admin_action: true)
87
+ category = owner&.membership&.category
115
88
 
116
- category = owner&.membership&.categories&.first
89
+ assign_attributes(
90
+ price: (category&.stamp_fee || 0),
91
+ tax_exempt: (category&.stamp_fee_tax_exempt || false),
92
+ qb_item_name: (category&.stamp_fee_qb_item_name || 'Professional Stamp')
93
+ )
117
94
 
118
- if category.present?
119
- assign_attributes(
120
- price: category.stamp_fee,
121
- tax_exempt: category.stamp_fee_tax_exempt,
122
- qb_item_name: category.stamp_fee_qb_item_name
123
- )
124
- end
95
+ submit!
125
96
 
126
- submitted! # Will fail with invalid owner membership anyway
127
-
128
- if category.present?
129
- Effective::Order.new(items: self, user: owner).mark_as_purchased!
130
- end
97
+ Effective::Order.new(items: self, user: owner).mark_as_purchased!
131
98
 
132
99
  true
133
100
  end
134
-
135
101
  end
136
102
  end
@@ -1,48 +1,17 @@
1
- %table.table
2
- %tbody
3
- %tr
4
- %th Owner
5
- %td
6
- - url = (edit_polymorphic_path(ring.owner) rescue "/admin/users/#{ring.owner.to_param}/edit")
7
- = link_to(ring.owner, url)
1
+ = effective_table_with(ring) do |f|
2
+ = f.content_for :owner, label: 'User' do
3
+ - owner = f.object.owner
8
4
 
9
- %tr
10
- %th Purchased Order
11
- %td
12
- - if ring.purchased_order.present?
13
- = link_to(ring.purchased_order, effective_orders.admin_order_path(ring.purchased_order))
5
+ = owner.to_s
14
6
 
15
- %tr
16
- %th Contact
17
- %td
18
- - owner = ring.owner
7
+ - if owner.try(:email).present?
8
+ %br
9
+ = mail_to(owner.email)
19
10
 
20
- = owner.to_s
11
+ - if owner.try(:phone).present?
12
+ %br
13
+ = owner.phone
21
14
 
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 Address
36
- %td= ring.shipping_address.to_html
37
-
38
- %tr
39
- %th Size
40
- %td= ring.size
41
-
42
- %tr
43
- %th Metal
44
- %td= ring.metal
45
-
46
- %tr
47
- %th Issued At
48
- %td= ring.issued_at&.strftime('%F') || 'Not Issued'
15
+ - if owner.try(:membership).try(:number).present?
16
+ %br
17
+ Member Number #{owner.membership.number}
@@ -1,23 +1,23 @@
1
1
  = effective_form_with(model: [:admin, stamp], engine: true) do |f|
2
+ - f.object.owner_type ||= current_user.class.name
3
+ = f.hidden_field :owner_type
4
+
2
5
  - if inline_datatable?
3
6
  = f.hidden_field :owner_id
4
- = f.hidden_field :owner_type
5
-
6
7
  - else
7
- - ajax_url = (effective_resources.users_effective_ajax_index_path unless Rails.env.test?)
8
- - f.object.owner_type ||= current_user.class.name
9
-
10
- = f.hidden_field :owner_type
8
+ - ajax_url = (effective_resources.users_effective_ajax_index_path(scope: :members) unless Rails.env.test?)
11
9
 
12
10
  = f.select :owner_id, current_user.class.all, label: 'User', ajax_url: ajax_url,
13
11
  'data-load-ajax-url': effective_products.new_admin_stamp_path,
14
12
  'data-load-ajax-div': '#effective-stamps-ajax'
15
13
 
14
+ - if f.object.new_record?
15
+ = f.hidden_field :created_by_admin, value: true
16
+
16
17
  #effective-stamps-ajax
17
18
  = render 'effective/stamps/fields', f: f, stamp: f.object
18
19
 
19
- = f.submit do
20
- - if f.object.new_record?
21
- = f.save 'Save and Mark Paid'
22
- - else
23
- = f.save 'Save'
20
+ - if f.object.new_record?
21
+ = f.submit 'Save and Mark Paid'
22
+ - else
23
+ = effective_submit(f)
@@ -1,40 +1,3 @@
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?
8
-
9
- - ring = ring_wizard.ring
10
- - owner = ring_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 Address
32
- %td= ring.shipping_address.to_html
33
-
34
- %tr
35
- %th Metal
36
- %td= ring.metal
37
-
38
- %tr
39
- %th Size
40
- %td Size #{ring.size}
1
+ = wizard_card(ring_wizard) do
2
+ = effective_table_with(ring_wizard.ring) do |f|
3
+ = render('effective/rings/fields', f: f)
@@ -1,57 +1,2 @@
1
-
2
- %h2 Member Information
3
-
4
- - owner = f.object.owner
5
-
6
- %p
7
- = owner.to_s
8
-
9
- - if owner.try(:email).present?
10
- %br
11
- = mail_to(owner.email)
12
-
13
- - if owner.try(:phone).present?
14
- %br
15
- = owner.phone
16
-
17
- - if owner.try(:membership).try(:number).present?
18
- %br
19
- Member Number #{owner.membership.number}
20
-
21
- %h2 Ring Information
22
- %p
23
- The 14k Yellow Gold and Sterling Silver rings will have the association's letters as well as your membership number engraved inside the band.
24
- Titanium rings do not come engraved.
25
-
26
- %p Please choose your desired metal and ring size:
27
-
28
- %table.table
29
- %thead
30
- %th Ring Size
31
- %th Composition
32
- %th.order_price Cost
33
- %tbody
34
- %tr
35
- %td 3-8
36
- %td 14k Yellow Gold
37
- %td.order_price $425.00 + GST
38
- %tr
39
- %td 3-8
40
- %td Sterling Silver
41
- %td.order_price $175.00 + GST
42
- %tr
43
- %td 3-13
44
- %td Titanium
45
- %td.order_price $50.00 + GST
46
-
47
- %ul
48
- %li 14k Yellow Gold and Sterling Silver rings are available in sizes 3 - 8.
49
- %li Titanium rings are available in sizes 3 - 13.
50
-
51
- %p Please select a ring metal and size:
52
-
53
- = f.select :metal, Effective::Ring::METALS
54
- = f.select :size, Effective::Ring::TITANIUM_SIZES
55
-
56
- %h2 Shipping Information
57
- = effective_address_fields(f, :shipping)
1
+ = f.fields_for(:rings, f.object.ring || f.object.build_ring) do |fr|
2
+ = render 'effective/rings/fields', f: fr, parent: resource
@@ -0,0 +1 @@
1
+ -# Ring Requirements
@@ -1,18 +1,12 @@
1
1
  = render 'layout' do
2
2
  = render 'effective/ring_wizards/content', resource: resource
3
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
4
+ = card do
5
+ .mb-2= render('ring_requirements', ring_wizard: resource)
8
6
 
9
- = f.fields_for :rings, (f.object.ring || f.object.build_ring) do |fr|
10
- = fr.hidden_field :ring_wizard_id
11
- = fr.hidden_field :ring_wizard_type
7
+ = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
8
+ = f.hidden_field :id
12
9
 
13
- = fr.hidden_field :owner_id
14
- = fr.hidden_field :owner_type
10
+ = render('effective/ring_wizards/ring_fields', f: f)
15
11
 
16
- = render('effective/ring_wizards/ring_fields', f: fr)
17
-
18
- = f.save 'Save and Continue'
12
+ = f.save 'Save and Continue'
@@ -0,0 +1,12 @@
1
+ = f.hidden_field :parent_id
2
+ = f.hidden_field :parent_type
3
+
4
+ = f.hidden_field :owner_id
5
+ = f.hidden_field :owner_type
6
+
7
+ = f.select :metal, Effective::Ring::METALS
8
+ = f.select :size, Effective::Ring::TITANIUM_SIZES
9
+
10
+ - if f.object.owner.present?
11
+ = f.fields_for(:owner) do |fu|
12
+ = effective_address_fields(fu, :shipping, skip_same_as_billing: true)
@@ -0,0 +1,23 @@
1
+ %table.table.table-sm.table-striped.table-hover
2
+ %tbody
3
+ %tr
4
+ %th Metal
5
+ %td= ring.metal
6
+
7
+ %tr
8
+ %th Size
9
+ %td= ring.size
10
+
11
+ - if ring.owner.try(:shipping_address).present?
12
+ %tr
13
+ %th Shipping Address
14
+ %td= ring.owner.shipping_address.to_html
15
+
16
+ - if ring.was_submitted?
17
+ %tr
18
+ %th Submitted
19
+ %td= ring.submitted_at&.strftime('%F') || '-'
20
+
21
+ %tr
22
+ %th Issued
23
+ %td= ring.issued_at&.strftime('%F') || 'Not Issued'
@@ -0,0 +1,2 @@
1
+ = f.fields_for(:stamps, f.object.stamp || f.object.build_stamp) do |fs|
2
+ = render 'effective/stamps/fields', f: fs, parent: resource
@@ -1 +1 @@
1
- %p Stamp Requirements
1
+ - # Stamp Requirements
@@ -7,13 +7,6 @@
7
7
  = effective_form_with(model: resource, url: wizard_path(step), method: :put) do |f|
8
8
  = f.hidden_field :id
9
9
 
10
- = f.fields_for :stamps, (f.object.stamp || f.object.build_stamp) do |fr|
11
- = fr.hidden_field :stamp_wizard_id
12
- = fr.hidden_field :stamp_wizard_type
13
-
14
- = fr.hidden_field :owner_id
15
- = fr.hidden_field :owner_type
16
-
17
- = render('effective/stamps/fields', f: fr, parent: resource)
10
+ = render('effective/stamp_wizards/stamp_fields', f: f)
18
11
 
19
12
  = f.save 'Save and Continue'
@@ -1,4 +1,9 @@
1
- - f.object.shipping_address ||= (f.object.owner.try(:shipping_address) || f.object.owner.try(:billing_address))
1
+ = f.hidden_field :parent_id
2
+ = f.hidden_field :parent_type
3
+
4
+ = f.hidden_field :owner_id
5
+ = f.hidden_field :owner_type
6
+
2
7
  - f.object.name ||= f.object.owner.to_s
3
8
 
4
9
  = f.text_field :name
@@ -7,4 +12,6 @@
7
12
  - collection = local_assigns[:parent].try(:stamp_categories) || EffectiveProducts.stamp_categories
8
13
  = f.select :category, collection
9
14
 
10
- = effective_address_fields(f, :shipping)
15
+ - if f.object.owner.present?
16
+ = f.fields_for(:owner) do |fu|
17
+ = effective_address_fields(fu, :shipping, skip_same_as_billing: true)
@@ -0,0 +1,27 @@
1
+ %table.table.table-sm.table-striped.table-hover
2
+ %tbody
3
+ %tr
4
+ %th Name
5
+ %td= stamp.name
6
+
7
+ %tr
8
+ %th Name Confirmation
9
+ %td= stamp.name_confirmation
10
+
11
+ %tr
12
+ %th Category
13
+ %td= stamp.category
14
+
15
+ - if stamp.owner.try(:shipping_address).present?
16
+ %tr
17
+ %th Shipping Address
18
+ %td= stamp.owner.shipping_address.to_html
19
+
20
+ - if stamp.was_submitted?
21
+ %tr
22
+ %th Submitted
23
+ %td= stamp.submitted_at&.strftime('%F') || '-'
24
+
25
+ %tr
26
+ %th Issued
27
+ %td= stamp.issued_at&.strftime('%F') || 'Not Issued'
@@ -4,14 +4,22 @@ class CreateEffectiveProducts < ActiveRecord::Migration[6.0]
4
4
  t.integer :owner_id
5
5
  t.string :owner_type
6
6
 
7
- t.integer :ring_wizard_id
8
- t.string :ring_wizard_type
7
+ # This could be a RingWizard, or Blank (admin created)
8
+ t.integer :parent_id
9
+ t.string :parent_type
9
10
 
10
11
  t.integer :size
11
12
  t.string :metal
12
13
 
14
+ t.datetime :submitted_at
13
15
  t.datetime :issued_at
14
16
 
17
+ t.boolean :created_by_admin, default: false
18
+
19
+ # Acts as Statused
20
+ t.string :status
21
+ t.text :status_steps
22
+
15
23
  # Acts as purchasable
16
24
  t.integer :purchased_order_id
17
25
  t.integer :price
@@ -21,15 +29,15 @@ class CreateEffectiveProducts < ActiveRecord::Migration[6.0]
21
29
  t.timestamps
22
30
  end
23
31
 
32
+ add_index :rings, [:owner_id, :owner_type]
33
+ add_index :rings, [:parent_id, :parent_type]
34
+
24
35
  create_table :ring_wizards do |t|
25
36
  t.string :token
26
37
 
27
38
  t.integer :owner_id
28
39
  t.string :owner_type
29
40
 
30
- t.integer :user_id
31
- t.string :user_type
32
-
33
41
  # Acts as Statused
34
42
  t.string :status
35
43
  t.text :status_steps
@@ -52,21 +60,24 @@ class CreateEffectiveProducts < ActiveRecord::Migration[6.0]
52
60
  t.integer :owner_id
53
61
  t.string :owner_type
54
62
 
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
+ # This could be a StampWizard, an Applicant, a FeePayment, or Blank (admin created)
64
+ t.integer :parent_id
65
+ t.string :parent_type
63
66
 
64
- t.string :category
65
67
  t.string :name
66
68
  t.string :name_confirmation
67
69
 
70
+ t.string :category
71
+
72
+ t.datetime :submitted_at
68
73
  t.datetime :issued_at
69
74
 
75
+ t.boolean :created_by_admin, default: false
76
+
77
+ # Acts as Statused
78
+ t.string :status
79
+ t.text :status_steps
80
+
70
81
  # Acts as purchasable
71
82
  t.integer :purchased_order_id
72
83
  t.integer :price
@@ -76,15 +87,15 @@ class CreateEffectiveProducts < ActiveRecord::Migration[6.0]
76
87
  t.timestamps
77
88
  end
78
89
 
90
+ add_index :stamps, [:owner_id, :owner_type]
91
+ add_index :stamps, [:parent_id, :parent_type]
92
+
79
93
  create_table :stamp_wizards do |t|
80
94
  t.string :token
81
95
 
82
96
  t.integer :owner_id
83
97
  t.string :owner_type
84
98
 
85
- t.integer :user_id
86
- t.string :user_type
87
-
88
99
  # Acts as Statused
89
100
  t.string :status
90
101
  t.text :status_steps
@@ -1,3 +1,3 @@
1
1
  module EffectiveProducts
2
- VERSION = '0.3.19'.freeze
2
+ VERSION = '0.4.0'.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.3.19
4
+ version: 0.4.0
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: 2026-06-11 00:00:00.000000000 Z
11
+ date: 2026-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -246,6 +246,7 @@ files:
246
246
  - app/views/effective/ring_wizards/_orders.html.haml
247
247
  - app/views/effective/ring_wizards/_ring.html.haml
248
248
  - app/views/effective/ring_wizards/_ring_fields.html.haml
249
+ - app/views/effective/ring_wizards/_ring_requirements.html.haml
249
250
  - app/views/effective/ring_wizards/_ring_wizard.html.haml
250
251
  - app/views/effective/ring_wizards/_summary.html.haml
251
252
  - app/views/effective/ring_wizards/billing.html.haml
@@ -254,11 +255,14 @@ files:
254
255
  - app/views/effective/ring_wizards/start.html.haml
255
256
  - app/views/effective/ring_wizards/submitted.html.haml
256
257
  - app/views/effective/ring_wizards/summary.html.haml
258
+ - app/views/effective/rings/_fields.html.haml
259
+ - app/views/effective/rings/_ring.html.haml
257
260
  - app/views/effective/stamp_wizards/_content.html.haml
258
261
  - app/views/effective/stamp_wizards/_dashboard.html.haml
259
262
  - app/views/effective/stamp_wizards/_layout.html.haml
260
263
  - app/views/effective/stamp_wizards/_orders.html.haml
261
264
  - app/views/effective/stamp_wizards/_stamp.html.haml
265
+ - app/views/effective/stamp_wizards/_stamp_fields.html.haml
262
266
  - app/views/effective/stamp_wizards/_stamp_requirements.html.haml
263
267
  - app/views/effective/stamp_wizards/_stamp_wizard.html.haml
264
268
  - app/views/effective/stamp_wizards/_summary.html.haml
@@ -269,6 +273,7 @@ files:
269
273
  - app/views/effective/stamp_wizards/submitted.html.haml
270
274
  - app/views/effective/stamp_wizards/summary.html.haml
271
275
  - app/views/effective/stamps/_fields.html.haml
276
+ - app/views/effective/stamps/_stamp.html.haml
272
277
  - config/effective_products.rb
273
278
  - config/locales/effective_products.en.yml
274
279
  - config/routes.rb