effective_resources 1.9.16 → 1.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2aae5d9ac90fa652dad2f7a60995282a9347dbfbbfdb0b497d1c46db42d7fe4
4
- data.tar.gz: 9d19f8cc152193da25ab30c7a4bc43187f9e52fb4eb309c0751df134f2a76dbc
3
+ metadata.gz: 0bc703e350cb8ca2e07dd5d9f0413f88bd15e98bab5d113e2696397e00af0732
4
+ data.tar.gz: d40aa7078d8ce692b7c5c7991b5c5ed2c06de95b0bf3602c5253b2b19affe6e6
5
5
  SHA512:
6
- metadata.gz: 2f33925a5ae6b5eda2076f6a27607af422e02412db62b55d0b6175a77cff200c18450611c314680b54c7843b59bdc498b508b760c03221e47da2a6e62f59efb1
7
- data.tar.gz: 71e9ab7dd0e61db615b043455459dad0de6b4e199f14ed39a0eb88ac16558d8b33d55bb9e0b95a2412dd4fa630ef277b198636078825ddb66d5c6db68c6b9fd3
6
+ metadata.gz: 1f5a322f0390678c9fc5834003621d73a42ab538cb3c904d942b68d44a57acb81cd5ad4601b722f8f8795e64930074ad4281a8f26baea4d798edc0b182eaa48b
7
+ data.tar.gz: efcd8d06e4889a5adce7a747eb207a0abfb920ae4f46981fd4de82ddeace22eb9ff2364fe1482c99ccff71d94d0d3393e986fd10fd2c6aa74059459ac583f06a
@@ -69,6 +69,13 @@ module Effective
69
69
  @page_title ||= resource_wizard_step_title(resource, step)
70
70
  end
71
71
 
72
+ def ready_checkout
73
+ return unless step == :checkout
74
+ return unless resource.class.try(:acts_as_purchasable_wizard?)
75
+
76
+ resource.ready!
77
+ end
78
+
72
79
  end
73
80
  end
74
81
  end
@@ -25,6 +25,8 @@ module Effective
25
25
 
26
26
  before_action :assign_current_step
27
27
  before_action :assign_page_title
28
+
29
+ before_action :ready_checkout
28
30
  end
29
31
 
30
32
  helper_method :resource
@@ -14,8 +14,8 @@ module EffectiveResourcesWizardHelper
14
14
  return sidebar unless block_given?
15
15
 
16
16
  content_tag(:div, class: 'row') do
17
- content_tag(:div, class: 'col-3') { sidebar } +
18
- content_tag(:div, class: 'col-9') { yield }
17
+ content_tag(:div, class: 'col-lg-3') { sidebar } +
18
+ content_tag(:div, class: 'col-lg-9') { yield }
19
19
  end
20
20
  end
21
21
 
@@ -28,10 +28,10 @@ module EffectiveResourcesWizardHelper
28
28
  disabled = !resource.can_visit_step?(nav_step)
29
29
 
30
30
  label = [index, title].compact.join('. ')
31
- klass = ['list-group-item', ('active' if current), ('disabled' if disabled && !current)].compact.join(' ')
31
+ klass = ['list-group-item', 'list-group-item-action', ('active' if current), ('disabled' if disabled && !current)].compact.join(' ')
32
32
 
33
33
  if (current || disabled)
34
- content_tag(:li, label, class: klass)
34
+ content_tag(:a, label, class: klass)
35
35
  else
36
36
  link_to(label, wizard_path(nav_step), class: klass)
37
37
  end
@@ -0,0 +1,129 @@
1
+ # ActsAsPurchasableWizard
2
+ #
3
+
4
+ module ActsAsPurchasableWizard
5
+ extend ActiveSupport::Concern
6
+
7
+ module Base
8
+ def acts_as_purchasable_wizard
9
+ raise('please declare acts_as_wizard first') unless respond_to?(:acts_as_wizard?)
10
+ raise('please declare acts_as_purchasable_parent first') unless respond_to?(:acts_as_purchasable_parent?)
11
+
12
+ unless (const_get(:WIZARD_STEPS).keys & [:billing, :checkout, :submitted]).length == 3
13
+ raise('please include a :billing, :checkout and :submitted step')
14
+ end
15
+
16
+ include ::ActsAsPurchasableWizard
17
+ end
18
+ end
19
+
20
+ included do
21
+ validates :owner, presence: true
22
+
23
+ # Billing Step
24
+ validate(if: -> { current_step == :billing && owner.present? }) do
25
+ self.errors.add(:base, "must have a billing address") unless owner.billing_address.present?
26
+ self.errors.add(:base, "must have an email") unless owner.email.present?
27
+ end
28
+
29
+ after_purchase do |_|
30
+ raise('expected submit_order to be purchased') unless submit_order&.purchased?
31
+ before_submit_purchased!
32
+ submit_purchased!
33
+ after_submit_purchased!
34
+ end
35
+ end
36
+
37
+ # All Fees and Orders
38
+ def submit_fees
39
+ raise('to be implemented by caller')
40
+ end
41
+
42
+ def submit_order
43
+ orders.first
44
+ end
45
+
46
+ def find_or_build_submit_fees
47
+ submit_fees
48
+ end
49
+
50
+ def find_or_build_submit_order
51
+ order = submit_order || orders.build(user: owner)
52
+ fees = submit_fees().reject { |fee| fee.marked_for_destruction? }
53
+
54
+ # Adds fees, but does not overwrite any existing price.
55
+ fees.each do |fee|
56
+ order.add(fee) unless order.purchasables.include?(fee)
57
+ end
58
+
59
+ order.order_items.each do |order_item|
60
+ fee = fees.find { |fee| fee == order_item.purchasable }
61
+ order.remove(order_item) unless fee.present?
62
+ end
63
+
64
+ # From Billing Step
65
+ order.billing_address = owner.billing_address if owner.billing_address.present?
66
+
67
+ # Important to add/remove anything
68
+ order.save!
69
+
70
+ order
71
+ end
72
+
73
+ # Should be indempotent.
74
+ def build_submit_fees_and_order
75
+ return false if was_submitted?
76
+
77
+ fees = find_or_build_submit_fees()
78
+ raise('already has purchased submit fees') if fees.any?(&:purchased?)
79
+
80
+ order = find_or_build_submit_order()
81
+ raise('already has purchased submit order') if order.purchased?
82
+
83
+ true
84
+ end
85
+
86
+ # Owner clicks on the Billing step. Next step is Checkout
87
+ def billing!
88
+ ready! && save!
89
+ end
90
+
91
+ # Ready to check out
92
+ # This is called by the "ready_checkout" before_action in wizard_controller/before_actions.rb
93
+ def ready!
94
+ without_current_step do
95
+ build_submit_fees_and_order
96
+ save!
97
+ end
98
+ end
99
+
100
+ # Called automatically via after_purchase hook above
101
+ def submit_purchased!
102
+ return false if was_submitted?
103
+
104
+ wizard_steps[:checkout] = Time.zone.now
105
+ submit!
106
+ end
107
+
108
+ # A hook to extend
109
+ def before_submit_purchased!
110
+ end
111
+
112
+ def after_submit_purchased!
113
+ end
114
+
115
+ # Draft -> Submitted requirements
116
+ def submit!
117
+ raise('already submitted') if was_submitted?
118
+ raise('expected a purchased order') unless submit_order&.purchased?
119
+
120
+ wizard_steps[:checkout] ||= Time.zone.now
121
+ wizard_steps[:submitted] = Time.zone.now
122
+ submitted!
123
+ end
124
+
125
+ module ClassMethods
126
+ def acts_as_purchasable_wizard?; true; end
127
+ end
128
+
129
+ end
@@ -50,9 +50,13 @@ module ActsAsWizard
50
50
  can_revisit_completed_steps(step)
51
51
  end
52
52
 
53
+ def wizard_step_keys
54
+ self.class.const_get(:WIZARD_STEPS).keys
55
+ end
56
+
53
57
  def required_steps
54
58
  return self.class.test_required_steps if Rails.env.test? && self.class.test_required_steps.present?
55
- self.class.const_get(:WIZARD_STEPS).keys
59
+ wizard_step_keys()
56
60
  end
57
61
 
58
62
  def wizard_step_title(step)
@@ -104,6 +108,16 @@ module ActsAsWizard
104
108
  has_completed_step?(required_steps.last)
105
109
  end
106
110
 
111
+ def without_current_step(&block)
112
+ existing = current_step
113
+
114
+ begin
115
+ self.current_step = nil; yield
116
+ ensure
117
+ self.current_step = existing
118
+ end
119
+ end
120
+
107
121
  private
108
122
 
109
123
  def can_revisit_completed_steps(step)
@@ -0,0 +1,7 @@
1
+ !!!
2
+ %html{style: 'background: #fff;'}
3
+ %head
4
+ %meta{:content => 'text/html; charset=UTF-8', 'http-equiv' => 'Content-Type'}
5
+
6
+ %body{style: 'background: #fff;'}
7
+ = yield
@@ -21,6 +21,8 @@ EffectiveResources.setup do |config|
21
21
  # end
22
22
  config.authorization_method = Proc.new { |controller, action, resource| authorize!(action, resource) }
23
23
 
24
+ # Default Submits
25
+ #
24
26
  # These default submit actions will be added to each controller
25
27
  # and rendered when calling effective_submit(f)
26
28
  # based on the controller, and its `submits` if any.
@@ -28,4 +30,22 @@ EffectiveResources.setup do |config|
28
30
  # Supported values: 'Save', 'Continue', and 'Add New'
29
31
  config.default_submits = ['Save', 'Continue', 'Add New']
30
32
 
33
+ # Email Settings
34
+ #
35
+ # The default mailer settings for all effective gems
36
+ #
37
+ # Configure the parent class responsible to send e-mails.
38
+ # config.parent_mailer = '::ApplicationMailer'
39
+
40
+ # Default deliver method
41
+ # config.deliver_method = :deliver_now
42
+
43
+ # Default layout
44
+ # config.mailer_layout = 'effective_mailer_layout'
45
+
46
+ # Default From
47
+ config.mailer_sender = "no-reply@example.com"
48
+
49
+ # Send Admin correspondence To
50
+ config.mailer_admin = "admin@example.com"
31
51
  end
@@ -38,6 +38,16 @@ module EffectiveGem
38
38
 
39
39
  true
40
40
  end
41
+
42
+ # This is included into every gem
43
+ # The gem may not have a mailer or use effective email templates
44
+ def send_email(email, *args)
45
+ raise('gem does not respond to mailer_class') unless respond_to?(:mailer_class)
46
+ raise('expected args to be an Array') unless args.kind_of?(Array)
47
+
48
+ mailer_class.send(email, *args).send(EffectiveResources.deliver_method)
49
+ end
50
+
41
51
  end
42
52
 
43
53
  end
@@ -28,6 +28,7 @@ module EffectiveResources
28
28
  ActiveRecord::Base.extend(ActsAsSlugged::Base)
29
29
  ActiveRecord::Base.extend(ActsAsStatused::Base)
30
30
  ActiveRecord::Base.extend(ActsAsWizard::Base)
31
+ ActiveRecord::Base.extend(ActsAsPurchasableWizard::Base)
31
32
  ActiveRecord::Base.extend(HasManyRichTexts::Base)
32
33
 
33
34
  ActiveRecord::Base.extend(EffectiveDeviseUser::Base)
@@ -1,3 +1,3 @@
1
1
  module EffectiveResources
2
- VERSION = '1.9.16'.freeze
2
+ VERSION = '1.10.0'.freeze
3
3
  end
@@ -5,7 +5,10 @@ require 'effective_resources/effective_gem'
5
5
  module EffectiveResources
6
6
 
7
7
  def self.config_keys
8
- [:authorization_method, :default_submits]
8
+ [
9
+ :authorization_method, :default_submits,
10
+ :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :parent_mailer
11
+ ]
9
12
  end
10
13
 
11
14
  include EffectiveGem
@@ -31,6 +34,28 @@ module EffectiveResources
31
34
  (['Save', 'Continue', 'Add New'] & Array(config.default_submits)).inject({}) { |h, v| h[v] = true; h }
32
35
  end
33
36
 
37
+ # Email
38
+ def self.deliver_method
39
+ config[:deliver_method] || :deliver_now
40
+ end
41
+
42
+ def self.mailer_layout
43
+ config[:mailer_layout] || 'effective_mailer_layout'
44
+ end
45
+
46
+ def self.mailer_sender
47
+ config[:mailer_sender] || raise('effective resources mailer_sender missing. Add it to config/initializers/effective_resources.rb')
48
+ end
49
+
50
+ def self.mailer_admin
51
+ config[:mailer_admin] || raise('effective resources mailer_admin missing. Add it to config/initializers/effective_resources.rb')
52
+ end
53
+
54
+ def self.parent_mailer_class
55
+ return config[:parent_mailer].constantize if config[:parent_mailer].present?
56
+ '::ApplicationMailer'.safe_constantize || 'ActionMailer::Base'.constantize
57
+ end
58
+
34
59
  # Utilities
35
60
 
36
61
  # This looks up the best class give the name
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.16
4
+ version: 1.10.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: 2022-01-11 00:00:00.000000000 Z
11
+ date: 2022-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -153,6 +153,7 @@ files:
153
153
  - app/helpers/effective_resources_wizard_helper.rb
154
154
  - app/models/concerns/acts_as_archived.rb
155
155
  - app/models/concerns/acts_as_email_form.rb
156
+ - app/models/concerns/acts_as_purchasable_wizard.rb
156
157
  - app/models/concerns/acts_as_slugged.rb
157
158
  - app/models/concerns/acts_as_statused.rb
158
159
  - app/models/concerns/acts_as_tokened.rb
@@ -201,6 +202,7 @@ files:
201
202
  - app/views/effective/resource/_actions.html.haml
202
203
  - app/views/effective/resource/_actions_dropleft.html.haml
203
204
  - app/views/effective/resource/_actions_glyphicons.html.haml
205
+ - app/views/layouts/effective_mailer_layout.html.haml
204
206
  - config/effective_resources.rb
205
207
  - lib/effective_resources.rb
206
208
  - lib/effective_resources/effective_gem.rb