effective_orders 4.4.6 → 4.5.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: a54d5be2f0c22c7b2b947e3eebda8f746025e23b743adb0b4e54a2525a83782e
4
- data.tar.gz: c245ef36019bc0515c5f2928ae9bee3e32b334b67a1bc9dae88725c424a24952
3
+ metadata.gz: f0bcae4f96f01459844e667c3c9c426a2eac78084e2cfcccb3dc630874554bf8
4
+ data.tar.gz: ca5cc298e9277e80c080d743045f6ff469b50d0ba54ed6c0183d5905f7b10b0e
5
5
  SHA512:
6
- metadata.gz: 2aea14e9db07efae0390ce10fa7dcbd395ce40bb5226b2cb2561dde89fc9dc8d08aa5db64ba91fb63228d9f3db2448451f9f43ae107334234ff42d7e97693eaa
7
- data.tar.gz: fa126fcbe853811ff54979016c71a57712ecb4e5d252fbd4a3280cf09ab67cb290788a1a5c6d648d31766a793aa74621a7c3f2244bf3840f018e428a2dfc55bb
6
+ metadata.gz: 315a63864050c7dacfe06ac17dfd098bfb4d698490cb214a9293b7446b6f35061dfa1e5919b63ce1684588977ecb1258ad07d8e7d4c056b61cb457de0ac13ec2
7
+ data.tar.gz: 910d703ac1b4c71a4f0ae00666ea16511578c7a39f31b56348bdd34069aa82d0c07978db26d7586c3b3a545f0aa2fa242bedd8ee25d7a02ca4baff2756537162
@@ -0,0 +1,77 @@
1
+ this.StripeForm ||= class StripeForm
2
+ constructor: ->
3
+ @form = null
4
+ @paymentIntent = null
5
+
6
+ @data = null
7
+ @stripe = null
8
+ @card = null
9
+
10
+ initialize: ->
11
+ @form = $('form[data-stripe-form]').first()
12
+ return false unless @form.length > 0
13
+
14
+ @paymentIntent = @form.find("input[name$='[payment_intent_id]']").first()
15
+ @data = @form.data('stripe-form')
16
+ @stripe = Stripe(@data.key)
17
+ @card = @stripe.elements().create('card', @style())
18
+
19
+ @mount()
20
+
21
+ style: ->
22
+ style: {
23
+ base: { color: '#32325d', fontSize: '16px', },
24
+ invalid: { color: '#dc3545', iconColor: '#dc3545' }
25
+ }
26
+
27
+ mount: ->
28
+ @card.mount('#stripe-card-element')
29
+
30
+ @card.addEventListener('change', (error) ->
31
+ $('#stripe-card-errors').text(if error.message then error.message else '')
32
+ )
33
+
34
+ @form.on('click', '[type=submit]', (event) => @submit(event))
35
+
36
+ submit: (event) ->
37
+ event.preventDefault()
38
+
39
+ payment = if @shouldUseNewCard() then @useNewCard() else @useExistingCard()
40
+
41
+ $.active = $.active + 1
42
+
43
+ payment.then((result) =>
44
+ if result.error
45
+ @errorPayment(result.error)
46
+ else if result.paymentIntent.status == 'succeeded'
47
+ @submitPayment(result.paymentIntent)
48
+ ).then((result) =>
49
+ $.active = $.active - 1
50
+ )
51
+
52
+ shouldUseNewCard: ->
53
+ @form.get(0).checkValidity() &&
54
+ @paymentIntent.val().length == 0 &&
55
+ (@data.token_required || @form.children('.collapse.show').length > 0)
56
+
57
+ useNewCard: ->
58
+ @stripe.confirmCardPayment(@data.client_secret, {
59
+ payment_method: {
60
+ card: @card,
61
+ billing_details: { email: @data.email }
62
+ },
63
+ setup_future_usage: 'off_session'
64
+ })
65
+
66
+ useExistingCard: ->
67
+ @stripe.confirmCardPayment(@data.client_secret, { payment_method: @data.payment_method })
68
+
69
+ submitPayment: (payment) ->
70
+ @paymentIntent.val(payment['id'])
71
+ @form.submit()
72
+
73
+ errorPayment: (error) ->
74
+ $('#stripe-card-errors').text(error.message)
75
+ EffectiveForm.invalidate(@form);
76
+
77
+ $ -> (new StripeForm()).initialize()
@@ -5,15 +5,15 @@ module ActsAsPurchasable
5
5
  def acts_as_purchasable(*options)
6
6
  @acts_as_purchasable = options || []
7
7
 
8
- if table_exists?
9
- instance = new()
10
- raise 'must respond_to price' unless instance.respond_to?(:price)
11
- raise 'must respond_to purchased_order_id' unless instance.respond_to?(:purchased_order_id)
12
-
13
- if defined?(EffectiveQbSync)
14
- raise 'must respond to qb_item_name' unless instance.respond_to?(:qb_item_name)
15
- end
16
- end
8
+ # if table_exists?
9
+ # instance = new()
10
+ # raise 'must respond_to price' unless instance.respond_to?(:price)
11
+ # raise 'must respond_to purchased_order_id' unless instance.respond_to?(:purchased_order_id)
12
+
13
+ # if defined?(EffectiveQbSync)
14
+ # raise 'must respond to qb_item_name' unless instance.respond_to?(:qb_item_name)
15
+ # end
16
+ # end
17
17
 
18
18
  include ::ActsAsPurchasable
19
19
  end
@@ -7,9 +7,11 @@ module ActsAsSubscribable
7
7
  def acts_as_subscribable(*options)
8
8
  @acts_as_subscribable = options || []
9
9
 
10
- instance = new()
11
- raise 'must respond to trialing_until' unless instance.respond_to?(:trialing_until)
12
- raise 'must respond to subscription_status' unless instance.respond_to?(:subscription_status)
10
+ # if table_exists?
11
+ # instance = new()
12
+ # raise 'must respond to trialing_until' unless instance.respond_to?(:trialing_until) || !EffectiveOrders.trial?
13
+ # raise 'must respond to subscription_status' unless instance.respond_to?(:subscription_status)
14
+ # end
13
15
 
14
16
  include ::ActsAsSubscribable
15
17
  (ActsAsSubscribable.descendants ||= []) << self
@@ -20,7 +22,7 @@ module ActsAsSubscribable
20
22
  has_one :subscription, as: :subscribable, class_name: 'Effective::Subscription', inverse_of: :subscribable
21
23
  has_one :customer, through: :subscription, class_name: 'Effective::Customer'
22
24
 
23
- before_validation(if: -> { trialing_until.blank? && EffectiveOrders.trial? }) do
25
+ before_validation(if: -> { EffectiveOrders.trial? && trialing_until.blank? }) do
24
26
  self.trialing_until = (Time.zone.now + EffectiveOrders.trial.fetch(:length)).beginning_of_day
25
27
  end
26
28
 
@@ -28,7 +30,10 @@ module ActsAsSubscribable
28
30
  raise :abort unless (subscripter.destroy! rescue false)
29
31
  end
30
32
 
31
- validates :trialing_until, presence: true, if: -> { EffectiveOrders.trial? }
33
+ if EffectiveOrders.trial?
34
+ validates :trialing_until, presence: true
35
+ end
36
+
32
37
  validates :subscription_status, inclusion: { allow_nil: true, in: EffectiveOrders::STATUSES.keys }
33
38
 
34
39
  scope :trialing, -> { where(subscription_status: nil).where('trialing_until > ?', Time.zone.now) }
@@ -51,6 +51,13 @@ module Effective
51
51
  end
52
52
  end
53
53
 
54
+ def invoices
55
+ @invoices ||= if stripe_customer_id.present?
56
+ Rails.logger.info "[STRIPE] list invoices: #{stripe_customer_id}"
57
+ ::Stripe::Invoice.list(customer: stripe_customer_id) rescue nil
58
+ end
59
+ end
60
+
54
61
  def upcoming_invoice
55
62
  @upcoming_invoice ||= if stripe_customer_id.present?
56
63
  Rails.logger.info "[STRIPE] get upcoming invoice: #{stripe_customer_id}"
@@ -28,6 +28,9 @@ module Effective
28
28
  attr_accessor :send_mark_as_paid_email_to_buyer # Set by Admin::Orders#mark_as_paid
29
29
  attr_accessor :skip_buyer_validations # Set by Admin::Orders#create
30
30
 
31
+ # If we want to use orders in a has_many way
32
+ belongs_to :parent, polymorphic: true, optional: true
33
+
31
34
  belongs_to :user, validate: false # This is the buyer/user of the order. We validate it below.
32
35
  has_many :order_items, -> { order(:id) }, inverse_of: :order, class_name: 'Effective::OrderItem', dependent: :delete_all
33
36
 
@@ -337,13 +340,14 @@ module Effective
337
340
 
338
341
  assign_attributes(
339
342
  state: EffectiveOrders::PURCHASED,
340
- purchased_at: Time.zone.now,
341
343
  payment: payment_to_h(payment),
342
344
  payment_provider: provider,
343
345
  payment_card: (card.presence || 'none'),
344
346
  skip_buyer_validations: skip_buyer_validations
345
347
  )
346
348
 
349
+ self.purchased_at ||= Time.zone.now
350
+
347
351
  Effective::Order.transaction do
348
352
  begin
349
353
  run_purchasable_callbacks(:before_purchase)
@@ -504,7 +508,7 @@ module Effective
504
508
  end
505
509
 
506
510
  def update_purchasables_purchased_order!
507
- order_items.each { |oi| oi.purchasable.update_column(:purchased_order_id, self.id) }
511
+ order_items.each { |oi| oi.purchasable&.update_column(:purchased_order_id, self.id) }
508
512
  end
509
513
 
510
514
  def run_purchasable_callbacks(name)
@@ -56,6 +56,10 @@ module Effective
56
56
 
57
57
  validates :status, inclusion: { in: EffectiveOrders::STATUSES.keys }
58
58
 
59
+ before_validation do
60
+ self.name ||= EffectiveOrders.stripe_plans.find { |plan| plan[:id] == stripe_plan_id }&[:name] || 'Subscribed Plan'
61
+ end
62
+
59
63
  def to_s
60
64
  name || 'New Subscription'
61
65
  end
@@ -15,7 +15,7 @@
15
15
  %td= sub.quantity
16
16
  %td= sub.interval
17
17
 
18
- - if customer.stripe_customer.invoices.present?
18
+ - if customer.invoices.present?
19
19
  .card.my-4
20
20
  .card-header Invoices
21
21
  .card-body
@@ -26,7 +26,7 @@
26
26
  %th Invoice
27
27
  %th Total
28
28
  %tbody
29
- - customer.stripe_customer.invoices.each do |invoice|
29
+ - customer.invoices.each do |invoice|
30
30
  - date_method = [(:date if invoice.respond_to?(:date)), (:period_start if invoice.respond_to?(:period_start)), :created].compact.first
31
31
  %tr
32
32
  %td= link_to Time.zone.at(invoice.public_send(date_method)).strftime('%F'), invoice.invoice_pdf
@@ -2,6 +2,10 @@ class CreateEffectiveOrders < ActiveRecord::Migration[4.2]
2
2
  def self.up
3
3
  create_table <%= @orders_table_name %> do |t|
4
4
  t.integer :user_id
5
+
6
+ t.integer :parent_id
7
+ t.string :parent_type
8
+
5
9
  t.string :state
6
10
  t.datetime :purchased_at
7
11
 
@@ -183,7 +183,7 @@ module EffectiveOrders
183
183
  Rails.logger.info '[STRIPE] index plans'
184
184
 
185
185
  plans = begin
186
- Stripe::Plan.all
186
+ Stripe::Plan.respond_to?(:all) ? Stripe::Plan.all : Stripe::Plan.list
187
187
  rescue => e
188
188
  raise e if Rails.env.production?
189
189
  Rails.logger.info "[STRIPE ERROR]: #{e.message}"
@@ -192,15 +192,18 @@ module EffectiveOrders
192
192
  end
193
193
 
194
194
  plans = plans.map do |plan|
195
+ description = ("$#{'%0.2f' % (plan.amount / 100.0)}" + ' ' + plan.currency.upcase + '/' + plan.interval.to_s)
196
+
195
197
  {
196
198
  id: plan.id,
197
199
  product_id: plan.product,
198
- name: plan.nickname,
200
+ name: plan.nickname || description,
201
+ description: description,
199
202
  amount: plan.amount,
200
203
  currency: plan.currency,
201
- description: ("$#{'%0.2f' % (plan.amount / 100.0)}" + ' ' + plan.currency.upcase + '/' + plan.interval.to_s),
202
204
  interval: plan.interval,
203
- interval_count: plan.interval_count
205
+ interval_count: plan.interval_count,
206
+ trial_period_days: plan.trial_period_days
204
207
  }
205
208
  end.sort do |x, y|
206
209
  val ||= (x[:interval] <=> y[:interval])
@@ -1,3 +1,3 @@
1
1
  module EffectiveOrders
2
- VERSION = '4.4.6'.freeze
2
+ VERSION = '4.5.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_orders
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.6
4
+ version: 4.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-17 00:00:00.000000000 Z
11
+ date: 2020-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -121,7 +121,7 @@ files:
121
121
  - app/assets/images/effective_orders/stripe.png
122
122
  - app/assets/javascripts/effective_orders.js
123
123
  - app/assets/javascripts/effective_orders/customers.js.coffee
124
- - app/assets/javascripts/effective_orders/providers/stripe.js
124
+ - app/assets/javascripts/effective_orders/providers/stripe.js.coffee
125
125
  - app/assets/javascripts/effective_orders/subscriptions.js.coffee
126
126
  - app/assets/stylesheets/effective_orders.scss
127
127
  - app/assets/stylesheets/effective_orders/_cart.scss
@@ -253,7 +253,7 @@ homepage: https://github.com/code-and-effect/effective_orders
253
253
  licenses:
254
254
  - MIT
255
255
  metadata: {}
256
- post_install_message:
256
+ post_install_message:
257
257
  rdoc_options: []
258
258
  require_paths:
259
259
  - lib
@@ -268,8 +268,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
268
268
  - !ruby/object:Gem::Version
269
269
  version: '0'
270
270
  requirements: []
271
- rubygems_version: 3.0.3
272
- signing_key:
271
+ rubygems_version: 3.1.2
272
+ signing_key:
273
273
  specification_version: 4
274
274
  summary: Quickly build an online store with carts, orders, automatic email receipts
275
275
  and payment collection via Stripe, StripeConnect, PayPal and Moneris.
@@ -1,97 +0,0 @@
1
- class StripeForm {
2
- initialize() {
3
- let $form = $('form[data-stripe-form]').first();
4
- if ($form.length == 0) { return false; }
5
-
6
- this.$form = $form;
7
- this.$paymentIntentId = this.$form.find("input[name$='[payment_intent_id]']").first();
8
-
9
- this.data = $form.data('stripe-form');
10
- this.stripe = Stripe(this.data.key);
11
- this.card = this.stripe.elements().create("card", { style: this.style() });
12
-
13
- this.mount();
14
- }
15
-
16
- mount() {
17
- this.card.mount("#stripe-card-element");
18
-
19
- this.card.addEventListener('change', function ({ error }) {
20
- if (error) {
21
- $('#stripe-card-errors').text(error.message);
22
- } else {
23
- $('#stripe-card-errors').text('');
24
- }
25
- });
26
-
27
- this.$form.on('click', '[type=submit]', (event) => { this.submit(event) });
28
- }
29
-
30
- shouldUseNewCard() {
31
- let $newCardForm = this.$form.children('.collapse.show')
32
-
33
- return (
34
- this.$form.get(0).checkValidity() &&
35
- (this.data.token_required || $newCardForm.length > 0) &&
36
- this.$paymentIntentId.val().length == 0
37
- )
38
- }
39
-
40
- submit(event) {
41
- event.preventDefault();
42
-
43
- let payment = this.shouldUseNewCard() ? this.useNewCard() : this.useExistingCard();
44
-
45
- payment.then((result) => {
46
- if (result.error) {
47
- this.errorPayment(result.error)
48
- } else if (result.paymentIntent.status == 'succeeded') {
49
- this.submitPayment(result.paymentIntent);
50
- }
51
- });
52
- }
53
-
54
- useExistingCard() {
55
- return this.stripe.confirmCardPayment(this.data.client_secret, {
56
- payment_method: this.data.payment_method
57
- });
58
- }
59
-
60
- useNewCard() {
61
- return this.stripe.confirmCardPayment(this.data.client_secret, {
62
- payment_method: {
63
- card: this.card,
64
- billing_details: {
65
- email: this.data.email
66
- }
67
- },
68
- setup_future_usage: 'off_session'
69
- });
70
- }
71
-
72
- errorPayment(error) {
73
- $('#stripe-card-errors').text(error.message);
74
- EffectiveForm.invalidate(this.$form);
75
- }
76
-
77
- submitPayment(payment) {
78
- this.$paymentIntentId.val('' + payment['id']);
79
- this.$form.submit();
80
- }
81
-
82
- style() {
83
- return {
84
- base: {
85
- color: "#32325d",
86
- fontSize: "16px",
87
- },
88
- invalid: {
89
- color: "#dc3545",
90
- iconColor: "#dc3545"
91
- }
92
- };
93
- }
94
-
95
- }
96
-
97
- $(document).ready(function () { new StripeForm().initialize(); });