effective_orders 2.2.4 → 3.0.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.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +124 -84
  4. data/app/assets/javascripts/effective_orders/customers.js.coffee +39 -0
  5. data/app/assets/javascripts/effective_orders/providers/{stripe_charges.js.coffee → stripe.js.coffee} +15 -13
  6. data/app/assets/javascripts/effective_orders/subscriptions.js.coffee +73 -0
  7. data/app/assets/stylesheets/effective_orders.scss +2 -1
  8. data/app/assets/stylesheets/effective_orders/_order.scss +16 -8
  9. data/app/assets/stylesheets/effective_orders/_subscriptions.scss +14 -0
  10. data/app/controllers/admin/customers_controller.rb +11 -8
  11. data/app/controllers/admin/order_items_controller.rb +4 -8
  12. data/app/controllers/admin/orders_controller.rb +133 -87
  13. data/app/controllers/effective/carts_controller.rb +18 -8
  14. data/app/controllers/effective/concerns/purchase.rb +39 -0
  15. data/app/controllers/effective/customers_controller.rb +43 -0
  16. data/app/controllers/effective/orders_controller.rb +73 -119
  17. data/app/controllers/effective/providers/app_checkout.rb +3 -1
  18. data/app/controllers/effective/providers/ccbill.rb +4 -6
  19. data/app/controllers/effective/providers/cheque.rb +20 -11
  20. data/app/controllers/effective/providers/free.rb +33 -0
  21. data/app/controllers/effective/providers/mark_as_paid.rb +33 -0
  22. data/app/controllers/effective/providers/moneris.rb +9 -17
  23. data/app/controllers/effective/providers/paypal.rb +4 -6
  24. data/app/controllers/effective/providers/pretend.rb +4 -4
  25. data/app/controllers/effective/providers/refund.rb +39 -0
  26. data/app/controllers/effective/providers/stripe.rb +19 -40
  27. data/app/controllers/effective/providers/stripe_connect.rb +2 -6
  28. data/app/controllers/effective/webhooks_controller.rb +44 -95
  29. data/app/datatables/effective_customers_datatable.rb +21 -29
  30. data/app/datatables/effective_order_items_datatable.rb +77 -79
  31. data/app/datatables/effective_orders_datatable.rb +67 -57
  32. data/app/helpers/effective_carts_helper.rb +17 -14
  33. data/app/helpers/effective_orders_helper.rb +40 -56
  34. data/app/helpers/effective_paypal_helper.rb +3 -3
  35. data/app/helpers/effective_stripe_helper.rb +47 -18
  36. data/app/helpers/effective_subscriptions_helper.rb +79 -0
  37. data/app/mailers/effective/orders_mailer.rb +125 -2
  38. data/app/models/concerns/acts_as_purchasable.rb +23 -33
  39. data/app/models/concerns/acts_as_subscribable.rb +68 -0
  40. data/app/models/concerns/acts_as_subscribable_buyer.rb +22 -0
  41. data/app/models/effective/cart.rb +53 -24
  42. data/app/models/effective/cart_item.rb +6 -12
  43. data/app/models/effective/customer.rb +51 -54
  44. data/app/models/effective/order.rb +160 -147
  45. data/app/models/effective/order_item.rb +18 -21
  46. data/app/models/effective/product.rb +7 -7
  47. data/app/models/effective/providers/ccbill_postback.rb +1 -1
  48. data/app/models/effective/providers/stripe_charge.rb +8 -19
  49. data/app/models/effective/subscripter.rb +230 -0
  50. data/app/models/effective/subscription.rb +27 -76
  51. data/app/models/effective/tax_rate_calculator.rb +10 -7
  52. data/app/views/admin/customers/_actions.html.haml +1 -2
  53. data/app/views/admin/customers/index.html.haml +1 -1
  54. data/app/views/admin/customers/show.html.haml +6 -0
  55. data/app/views/admin/orders/_actions.html.haml +9 -7
  56. data/app/views/admin/orders/_form.html.haml +11 -7
  57. data/app/views/admin/orders/_order_actions.html.haml +2 -1
  58. data/app/views/admin/orders/_order_item_fields.html.haml +1 -1
  59. data/app/views/admin/orders/edit.html.haml +4 -0
  60. data/app/views/admin/orders/index.html.haml +1 -4
  61. data/app/views/admin/orders/new.html.haml +1 -1
  62. data/app/views/admin/orders/show.html.haml +5 -6
  63. data/app/views/effective/carts/_cart.html.haml +2 -2
  64. data/app/views/effective/carts/show.html.haml +2 -2
  65. data/app/views/effective/customers/_customer.html.haml +152 -0
  66. data/app/views/effective/customers/_fields.html.haml +12 -0
  67. data/app/views/effective/customers/_form.html.haml +13 -0
  68. data/app/views/effective/customers/edit.html.haml +3 -0
  69. data/app/views/effective/orders/_checkout_step1.html.haml +8 -15
  70. data/app/views/effective/orders/_checkout_step2.html.haml +34 -21
  71. data/app/views/effective/orders/_order.html.haml +8 -9
  72. data/app/views/effective/orders/_order_actions.html.haml +7 -8
  73. data/app/views/effective/orders/_order_header.html.haml +1 -1
  74. data/app/views/effective/orders/_order_items.html.haml +11 -5
  75. data/app/views/effective/orders/_order_note.html.haml +4 -7
  76. data/app/views/effective/orders/_orders_table.html.haml +26 -26
  77. data/app/views/effective/orders/app_checkout/_form.html.haml +2 -2
  78. data/app/views/effective/orders/ccbill/_form.html.haml +1 -1
  79. data/app/views/effective/orders/cheque/_form.html.haml +3 -1
  80. data/app/views/effective/orders/declined.html.haml +1 -1
  81. data/app/views/effective/orders/{checkout_step1.html.haml → edit.html.haml} +0 -0
  82. data/app/views/effective/orders/free/_form.html.haml +4 -0
  83. data/app/views/effective/orders/index.html.haml +2 -4
  84. data/app/views/effective/orders/mark_as_paid/_form.html.haml +32 -0
  85. data/app/views/effective/orders/moneris/_form.html.haml +6 -6
  86. data/app/views/effective/orders/{checkout_step2.html.haml → new.html.haml} +1 -1
  87. data/app/views/effective/orders/paypal/_form.html.haml +2 -2
  88. data/app/views/effective/orders/pretend/_form.html.haml +2 -2
  89. data/app/views/effective/orders/purchased.html.haml +3 -0
  90. data/app/views/effective/orders/refund/_form.html.haml +32 -0
  91. data/app/views/effective/orders/show.html.haml +4 -1
  92. data/app/views/effective/orders/stripe/_form.html.haml +5 -5
  93. data/app/views/effective/orders_mailer/subscription_canceled.html.haml +9 -0
  94. data/app/views/effective/orders_mailer/subscription_payment_failed.html.haml +9 -0
  95. data/app/views/effective/orders_mailer/subscription_payment_succeeded.html.haml +9 -0
  96. data/app/views/effective/orders_mailer/subscription_trial_expired.html.haml +5 -0
  97. data/app/views/effective/orders_mailer/subscription_trial_expiring.html.haml +7 -0
  98. data/app/views/effective/subscriptions/_fields.html.haml +16 -0
  99. data/app/views/effective/subscriptions/_plan.html.haml +21 -0
  100. data/app/views/layouts/effective_orders_mailer_layout.html.haml +6 -8
  101. data/config/effective_orders.rb +41 -20
  102. data/config/routes.rb +48 -48
  103. data/db/migrate/01_create_effective_orders.rb.erb +19 -5
  104. data/lib/effective_orders.rb +78 -42
  105. data/lib/effective_orders/engine.rb +36 -82
  106. data/lib/effective_orders/version.rb +1 -1
  107. data/lib/generators/effective_orders/install_generator.rb +2 -2
  108. data/lib/generators/templates/effective_orders_mailer_preview.rb +39 -4
  109. data/lib/tasks/effective_orders_tasks.rake +42 -0
  110. data/spec/controllers/carts_controller_spec.rb +1 -1
  111. data/spec/controllers/moneris_orders_controller_spec.rb +4 -4
  112. data/spec/controllers/orders_controller_spec.rb +4 -4
  113. data/spec/controllers/stripe_orders_controller_spec.rb +2 -2
  114. data/spec/controllers/webhooks_controller_spec.rb +1 -1
  115. data/spec/dummy/config/initializers/effective_orders.rb +1 -7
  116. data/spec/dummy/db/schema.rb +1 -0
  117. data/spec/dummy/db/test.sqlite3 +0 -0
  118. data/spec/dummy/log/test.log +3 -0
  119. data/spec/models/acts_as_purchasable_spec.rb +0 -56
  120. data/spec/models/customer_spec.rb +3 -3
  121. data/spec/models/order_spec.rb +2 -2
  122. data/spec/spec_helper.rb +1 -1
  123. data/spec/support/factories.rb +2 -1
  124. metadata +37 -49
  125. data/active_admin/effective_carts.rb +0 -14
  126. data/active_admin/effective_orders.rb +0 -112
  127. data/app/assets/javascripts/effective_orders/providers/stripe_subscriptions.js.coffee +0 -28
  128. data/app/controllers/concerns/acts_as_active_admin_controller.rb +0 -69
  129. data/app/controllers/effective/subscriptions_controller.rb +0 -126
  130. data/app/models/effective/datatables/customers.rb +0 -40
  131. data/app/models/effective/datatables/order_items.rb +0 -101
  132. data/app/models/effective/datatables/orders.rb +0 -91
  133. data/app/models/inputs/price_field.rb +0 -63
  134. data/app/models/inputs/price_form_input.rb +0 -7
  135. data/app/models/inputs/price_formtastic_input.rb +0 -9
  136. data/app/models/inputs/price_input.rb +0 -19
  137. data/app/models/inputs/price_simple_form_input.rb +0 -8
  138. data/app/views/admin/orders/_form_mark_as_paid.html.haml +0 -33
  139. data/app/views/admin/orders/_order_payment_details.html.haml +0 -5
  140. data/app/views/admin/orders/mark_as_paid.html.haml +0 -7
  141. data/app/views/effective/orders/stripe/_subscription_fields.html.haml +0 -7
  142. data/app/views/effective/subscriptions/index.html.haml +0 -22
  143. data/app/views/effective/subscriptions/new.html.haml +0 -9
  144. data/app/views/effective/subscriptions/show.html.haml +0 -49
  145. data/db/upgrade/02_upgrade_effective_orders_from03x.rb.erb +0 -29
  146. data/db/upgrade/03_upgrade_effective_orders_from1x.rb.erb +0 -98
  147. data/db/upgrade/upgrade_price_column_on_table.rb.erb +0 -17
  148. data/lib/generators/effective_orders/upgrade_from03x_generator.rb +0 -31
  149. data/lib/generators/effective_orders/upgrade_from1x_generator.rb +0 -27
  150. data/lib/generators/effective_orders/upgrade_price_column_generator.rb +0 -30
@@ -1,6 +1,6 @@
1
1
  module Effective
2
2
  class TaxRateCalculator
3
- attr_reader :order
3
+ attr_reader :order, :country_code, :state_code
4
4
 
5
5
  RATES = {
6
6
  'CA' => { # Canada
@@ -20,15 +20,18 @@ module Effective
20
20
  }
21
21
  }
22
22
 
23
- def initialize(order:)
23
+ def initialize(order: nil, country_code: nil, state_code: nil)
24
24
  @order = order
25
+ @country_code = country_code
26
+ @state_code = state_code
27
+
28
+ raise 'expected an order, or a country and state code' unless (order || country_code)
29
+ raise 'expected an order OR a country and state code. Not both.' if (order && country_code)
25
30
  end
26
31
 
27
32
  def tax_rate
28
- return nil unless order.billing_address.try(:country_code).present?
29
-
30
- country = order.billing_address.country_code
31
- state = order.billing_address.state_code
33
+ country = country_code || (order.billing_address.country_code if order.billing_address.present?)
34
+ state = state_code || (order.billing_address.state_code if order.billing_address.present?)
32
35
 
33
36
  rate = RATES[country]
34
37
  return rate if rate.kind_of?(Numeric)
@@ -38,7 +41,7 @@ module Effective
38
41
  end
39
42
 
40
43
  def unknown_tax_rate
41
- order.skip_buyer_validations? ? nil : 0
44
+ (order && order.skip_buyer_validations?) ? nil : 0
42
45
  end
43
46
 
44
47
  end
@@ -1,2 +1 @@
1
- - if customer.stripe_customer_id.present?
2
- = link_to 'Manage', "https://manage.stripe.com/customers/#{customer.stripe_customer_id}"
1
+ = link_to 'Manage', "https://dashboard.stripe.com/#{'test/' if Rails.env.development?}customers/#{customer.stripe_customer_id}"
@@ -1,7 +1,7 @@
1
1
  %h1.effective-admin-heading= @page_title
2
2
 
3
3
  %p.text-right.effective-admin-actions
4
- = link_to 'Stripe Dashboard: Customers', 'https://manage.stripe.com/customers', :class => 'btn btn-primary'
4
+ = link_to 'Stripe Customers', "https://dashboard.stripe.com/#{'test/' if Rails.env.development?}customers", class: 'btn btn-primary'
5
5
 
6
6
  - if @datatable.present?
7
7
  = render_datatable @datatable
@@ -0,0 +1,6 @@
1
+ %h1.effective-admin-heading= @page_title
2
+
3
+ %p.text-right.effective-admin-actions
4
+ = link_to 'Stripe Customer', "https://dashboard.stripe.com/#{'test/' if Rails.env.development?}customers/#{@customer.stripe_customer_id}", class: 'btn btn-primary'
5
+
6
+ = render 'effective/customers/customer', customer: @customer
@@ -1,9 +1,11 @@
1
- = link_to (datatable.try(:admin_namespace?) ? effective_orders.admin_order_path(order) : effective_orders.order_path(order)), title: 'View' do
2
- %span.glyphicon.glyphicon-eye-open
1
+ - if datatable.admin_namespace?
2
+ - if order.purchased? == false
3
+ = link_to effective_orders.admin_order_path(order), title: 'Checkout' do
4
+ %span.glyphicon.glyphicon-usd
3
5
 
4
- - if (order.purchased? == false) && (EffectiveOrders.authorized?(controller, :admin, :effective_orders) rescue false)
5
- = link_to effective_orders.mark_as_paid_admin_order_path(order), title: 'Mark as Paid' do
6
- %span.glyphicon.glyphicon-usd
6
+ = link_to effective_orders.edit_admin_order_path(order), title: 'Edit' do
7
+ %span.glyphicon.glyphicon-edit
7
8
 
8
- = link_to effective_orders.admin_order_path(order), title: 'Delete', data: { method: :delete, confirm: 'Are you sure you want to delete? This cannot be undone.' } do
9
- %span.glyphicon.glyphicon-trash
9
+ - else
10
+ = link_to effective_orders.order_path(order), title: 'View' do
11
+ %span.glyphicon.glyphicon-eye-open
@@ -1,11 +1,9 @@
1
- - unless defined?(Cocoon)
2
- Please install #{link_to 'cocoon', 'https://github.com/nathanvda/cocoon'} to see this page.
3
- - else
4
- = simple_form_for [:admin, order], (EffectiveOrders.admin_simple_form_options || {}).merge(url: effective_orders.admin_orders_path) do |f|
1
+ = simple_form_for [:admin, order], (EffectiveOrders.admin_simple_form_options || {}).merge(url: (order.persisted? ? effective_orders.admin_order_path(order) : effective_orders.admin_orders_path)) do |f|
2
+ - if f.object.new_record?
5
3
  = f.association :user,
6
4
  label: 'Buyer',
7
5
  required: true,
8
- as: (defined?(EffectiveFormInputs) ? :effective_select : :select),
6
+ as: :effective_select,
9
7
  collection: @users || User.all.to_a.sort { |user1, user2| user1.to_s <=> user2.to_s }
10
8
 
11
9
  %h2 Order Items
@@ -22,8 +20,14 @@
22
20
  label: 'Yes, send a payment request email to the buyer.',
23
21
  value: (f.object.send_payment_request_to_buyer.nil? ? EffectiveOrders.mailer[:send_payment_request_to_buyer] : f.object.send_payment_request_to_buyer?)
24
22
 
25
- .effective-order-internal-note
23
+ .row
24
+ .col-sm-6.effective-order-note-to-buyer
25
+ %h2 Note to Buyer
26
+ = f.input :note_to_buyer, disabled: f.object.purchased?, label: false,
27
+ hint: (f.object.purchased? ? 'This message was displayed to the buyer during checkout and appears on the receipt.' : 'This message will be displayed to the buyer during checkout and will appear on the receipt.')
28
+
29
+ .col-sm-6.effective-order-internal-note
26
30
  %h2 Internal Note
27
31
  = f.input :note_internal, label: false, hint: 'For internal admin use only. This note will never be displayed to the buyer.'
28
32
 
29
- = render partial: '/admin/orders/order_actions', locals: { order: @order, form: f, f: f }
33
+ = render partial: '/admin/orders/order_actions', locals: { order: @order, form: f, f: f }
@@ -1,4 +1,5 @@
1
1
  %p.text-right
2
2
  = form.button :submit, 'Save', data: { disable_with: 'Saving...' }
3
+ = form.button :submit, 'Save and Continue', data: { disable_with: 'Saving...' }
3
4
  = form.button :submit, 'Save and Add New', data: { disable_with: 'Saving...' }
4
- = link_to 'Cancel', effective_orders.admin_orders_path
5
+ = form.button :submit, 'Save and Duplicate', data: { disable_with: 'Saving...' }
@@ -4,6 +4,6 @@
4
4
  = f.simple_fields_for :purchasable do |purchasable|
5
5
  .col-sm-2= f.input :quantity, input_html: { value: f.object.quantity || 1, min: 1 }
6
6
  .col-sm-4= purchasable.input :title, input_html: { maxlength: 255 }
7
- .col-sm-2= purchasable.input :price, as: (defined?(EffectiveFormInputs) ? :effective_price : :price)
7
+ .col-sm-2= purchasable.input :price, as: :effective_price
8
8
  .col-sm-2= purchasable.input :tax_exempt, label: 'Tax Exempt', input_html: { title: 'When checked, tax will not be applied to this item' }
9
9
  .col-sm-2.remove-nested-fields= link_to_remove_association('Remove line item', f)
@@ -0,0 +1,4 @@
1
+ %h1.effective-admin-heading= @page_title
2
+
3
+ = render partial: 'effective/orders/order', locals: { order: @order }
4
+ .effective-order= render partial: 'form', locals: { order: @order }
@@ -3,7 +3,4 @@
3
3
  %p.text-right.effective-admin-actions
4
4
  = link_to 'New Order', effective_orders.new_admin_order_path, class: 'btn btn-primary'
5
5
 
6
- - if @datatable.present?
7
- = render_datatable @datatable
8
- - else
9
- %p There are no orders present
6
+ = render_datatable @datatable
@@ -1,3 +1,3 @@
1
1
  %h1.effective-admin-heading= @page_title
2
2
 
3
- = render partial: 'form', locals: { order: @order }
3
+ .effective-order= render partial: 'form', locals: { order: @order }
@@ -1,8 +1,7 @@
1
- %h1.effective-admin-heading= (@order.purchased? ? 'Receipt' : 'Order')
1
+ %h1.effective-admin-heading= @page_title
2
2
 
3
- = render partial: 'effective/orders/order', locals: {order: @order}
4
-
5
- - if (EffectiveOrders.authorized?(controller, :admin, :effective_orders) rescue false)
3
+ - if @order.purchased?
4
+ = render partial: 'effective/orders/order', locals: { order: @order }
6
5
  = render partial: 'admin/orders/form_note_internal', locals: { order: @order }
7
-
8
- = render partial: 'admin/orders/order_payment_details', locals: { order: @order }
6
+ - else
7
+ = render_checkout_step2(@order, namespace: :admin, purchased_url: effective_orders.admin_order_path(@order), declined_url: effective_orders.admin_order_path(@order))
@@ -16,10 +16,10 @@
16
16
  = link_to_remove_from_cart(item)
17
17
  %td.price
18
18
  = price_to_currency(item.price)
19
- - if cart.empty?
19
+ - if cart.blank?
20
20
  %tr
21
21
  %td.quantity
22
- %td.item Your cart is empty.
22
+ %td.item No items in cart.
23
23
  %td.price
24
24
  %tfoot
25
25
  %tr
@@ -1,7 +1,7 @@
1
1
  %h1.effective-heading= @page_title
2
2
 
3
- - if @cart.empty?
4
- %p Your cart is empty.
3
+ - if @cart.blank?
4
+ %p No items in cart.
5
5
  - else
6
6
  %p Your cart has #{@cart.cart_items.length} items.
7
7
 
@@ -0,0 +1,152 @@
1
+ %h3.effective-heading Customer
2
+
3
+ %table.table
4
+ %tbody
5
+ %tr
6
+ %th Id
7
+ %td= customer.stripe_customer.id
8
+ %tr
9
+ %th Email
10
+ %td= customer.stripe_customer.email
11
+ %tr
12
+ %th Card
13
+ %td
14
+ - if customer.stripe_customer.default_source.present?
15
+ - card = customer.stripe_customer.sources.retrieve(customer.stripe_customer.default_source)
16
+ = "**** **** **** #{card.last4} #{card.brand} #{card.exp_month}/#{card.exp_year}"
17
+ - else
18
+ None
19
+
20
+ - if customer.stripe_customer.currency.present?
21
+ %tr
22
+ %th Currency
23
+ %td= customer.stripe_customer.currency.to_s.upcase
24
+
25
+ - if customer.stripe_customer.account_balance.to_i > 0
26
+ %tr
27
+ %th Balance
28
+ %td= price_to_currency(customer.stripe_customer.account_balance.to_i)
29
+
30
+ = yield if block_given?
31
+
32
+ - if customer.stripe_subscription.present?
33
+ %h3.effective-heading Subscription
34
+
35
+ %table.table
36
+ %tbody
37
+ %tr
38
+ %th Status
39
+ %td= customer.stripe_subscription.status.presence || 'unknown'
40
+
41
+ - if customer.stripe_subscription.discount.present?
42
+ %tr
43
+ %th Coupon
44
+ %td= stripe_coupon_description(customer.stripe_subscription.discount.coupon)
45
+
46
+ - if customer.stripe_subscription.start.present?
47
+ %tr
48
+ %th Started
49
+ %td= Time.zone.at(customer.stripe_subscription.start).strftime('%F')
50
+
51
+ - if customer.stripe_subscription.ended_at.present?
52
+ %tr
53
+ %th Ended
54
+ %td= Time.zone.at(customer.stripe_subscription.ended_at).strftime('%F')
55
+
56
+ - if customer.stripe_subscription.canceled_at.present?
57
+ %tr
58
+ %th Cancelled
59
+ %td= Time.zone.at(customer.stripe_subscription.canceled_at).strftime('%F')
60
+
61
+ - if customer.stripe_subscription.current_period_start.present?
62
+ %tr
63
+ %th Current Period Start
64
+ %td= Time.zone.at(customer.stripe_subscription.current_period_start).strftime('%F')
65
+
66
+ - if customer.stripe_subscription.current_period_end.present?
67
+ %tr
68
+ %th Current Period End
69
+ %td= Time.zone.at(customer.stripe_subscription.current_period_end).strftime('%F')
70
+
71
+ - if customer.stripe_subscription.metadata.present? && false
72
+ %tr
73
+ %th Metadata
74
+ %td= tableize_hash(customer.stripe_subscription.metadata.to_h, th: false)
75
+
76
+ - if customer.stripe_subscription.items.present?
77
+ %tr
78
+ %th Plans
79
+ %td= tableize_hash(customer.stripe_subscription.items.inject({}) { |h, item| h[item.plan.name] = item.quantity; h }, th: false)
80
+
81
+ - if customer.subscriptions.present?
82
+ %table.table
83
+ %thead
84
+ %tr
85
+ %th Subscribed
86
+ %th Plan
87
+ %th
88
+ %tbody
89
+ - customer.subscriptions.each do |sub|
90
+ %tr
91
+ %td= sub.subscribable
92
+ %td= sub
93
+ %td= link_to 'change', edit_polymorphic_path(sub.subscribable)
94
+
95
+ - if customer.stripe_subscription.blank?
96
+ %h3.effective-heading Subscription
97
+ %p No current subscriptions
98
+
99
+ - if customer.stripe_customer.invoices.present?
100
+ %h3.effective-heading Invoices
101
+
102
+ %table.table
103
+ %thead
104
+ %tr
105
+ %th Date
106
+ %th Number
107
+ %th Period
108
+ %th Items
109
+ %th Total
110
+ %tbody
111
+ - customer.stripe_customer.invoices.each do |invoice|
112
+ %tr
113
+ %td= Time.zone.at(invoice.date).strftime('%F')
114
+ %td= invoice.id
115
+ %td
116
+ = Time.zone.at(invoice.lines.first.period.start).strftime('%F')
117
+ to
118
+ = Time.zone.at(invoice.lines.first.period.end).strftime('%F')
119
+ %td
120
+ - invoice.lines.each do |line|
121
+ %p #{line.quantity}x #{line.plan.try(:name)} #{line.description}
122
+
123
+ %td= price_to_currency(invoice.total)
124
+
125
+ - if customer.upcoming_invoice.present?
126
+ %p Upcoming Invoice:
127
+
128
+ %table.table
129
+ %tbody
130
+ %tr
131
+ %th Date
132
+ %td= Time.zone.at(customer.upcoming_invoice.date).strftime('%F')
133
+ %tr
134
+ %th Period
135
+ %td
136
+ = Time.zone.at(customer.upcoming_invoice.period_start).strftime('%F')
137
+ to
138
+ = Time.zone.at(customer.upcoming_invoice.period_end).strftime('%F')
139
+ %tr
140
+ %th Items
141
+ %td
142
+ %table.table
143
+ %tbody
144
+ - customer.upcoming_invoice.lines.each do |line|
145
+ %tr
146
+ %td #{line.quantity}x #{line.plan.name}
147
+ %td #{Time.zone.at(line.period.start).strftime('%F')} to #{Time.zone.at(line.period.end).strftime('%F')}
148
+ %td= line.description
149
+ %td= price_to_currency(line.amount)
150
+ %tr
151
+ %th Total
152
+ %td= price_to_currency(customer.upcoming_invoice.total)
@@ -0,0 +1,12 @@
1
+ .effective-orders-customer{ data: { stripe: stripe.to_json, submit: submit.to_json } }
2
+ - if f.object.token_required?
3
+ = f.input :stripe_token, as: :effective_static_control, label: 'Credit Card', required: true,
4
+ value: f.object.customer.payment_status + ' ' + content_tag(:span, '', class: 'active-card')
5
+
6
+ %p= link_to 'Update Card Details', '#', class: 'btn btn-primary btn-change-card'
7
+
8
+ - else
9
+ = f.input :stripe_token, as: :effective_static_control, label: 'Credit Card', required: false,
10
+ value: f.object.customer.payment_status + ' ' + content_tag(:span, f.object.customer.active_card, class: 'active-card')
11
+
12
+ %p= link_to 'Update Card Details', '#', class: 'btn btn-default btn-change-card'
@@ -0,0 +1,13 @@
1
+ = javascript_include_tag 'https://checkout.stripe.com/checkout.js'
2
+
3
+ = simple_form_for(subscripter, (EffectiveOrders.simple_form_options || {}).merge(url: effective_orders.customer_settings_path, method: :put)) do |f|
4
+ = f.input :stripe_token, as: :hidden, input_html: { value: nil }
5
+
6
+ = render(f.object.customer) do
7
+ %h3.effective-heading Card
8
+ = effective_customer_fields(f)
9
+
10
+ .form-actions
11
+ = f.button :submit, 'Save', data: { disable_with: 'Saving...' }
12
+
13
+
@@ -0,0 +1,3 @@
1
+ %h1.effective-heading= @page_title
2
+
3
+ = render 'effective/customers/form', subscripter: @subscripter
@@ -1,15 +1,18 @@
1
1
  .effective-order
2
- = simple_form_for(order, (EffectiveOrders.simple_form_options || {}).merge(url: (order.new_record? ? effective_orders.orders_path : effective_orders.order_path(order)))) do |f|
3
- = render partial: 'effective/orders/order_items', locals: {order: order, form: f}
2
+ = simple_form_for(order, (EffectiveOrders.simple_form_options || {}).merge(url: checkout_step1_form_url(order, namespace))) do |f|
3
+ = render partial: 'effective/orders/order_items', locals: { order: order, form: f }
4
+
5
+ - unless f.object.pending? || (current_cart && current_cart.blank?)
6
+ = link_to 'Change Items', effective_orders.cart_path, rel: :nofollow, class: 'btn btn-default'
4
7
 
5
8
  - if order.errors[:order_items].present?
6
9
  %p.inline-errors= order.errors[:order_items].first
7
10
 
8
11
  - if order.errors[:total].present?
9
- %p.inline-errors= order.errors[:total].first.gsub(EffectiveOrders.minimum_charge.to_i.to_s, price_to_currency(EffectiveOrders.minimum_charge.to_i))
12
+ %p.inline-errors= order.errors[:total].first
10
13
 
11
14
  - if EffectiveOrders.collect_user_fields.present? && (f.object.user rescue nil).present?
12
- = render partial: 'effective/orders/order_user_fields', locals: {form: f, user: f.object.user }
15
+ = render partial: 'effective/orders/order_user_fields', locals: { form: f, user: f.object.user }
13
16
 
14
17
  - num_addresses = [EffectiveOrders.require_billing_address, EffectiveOrders.require_shipping_address].count(true)
15
18
 
@@ -19,15 +22,11 @@
19
22
  %div{class: "col-sm-#{12 / num_addresses}"}
20
23
  %h2 Billing Address
21
24
  = effective_address_fields(f, :billing_address)
22
- - if f.object.user.respond_to?(:billing_address=)
23
- = f.input :save_billing_address, as: :boolean, label: 'Save as my default billing address', required: false
24
25
 
25
26
  - if EffectiveOrders.require_shipping_address
26
27
  %div{class: "col-sm-#{12 / num_addresses}"}
27
28
  %h2 Shipping Address
28
29
  = effective_address_fields(f, :shipping_address)
29
- - if f.object.user.respond_to?(:shipping_address=)
30
- = f.input :save_shipping_address, as: :boolean, label: 'Save as my default shipping address', required: false
31
30
 
32
31
  - if EffectiveOrders.collect_note
33
32
  = render partial: 'effective/orders/order_note_fields', locals: { form: f }
@@ -36,10 +35,4 @@
36
35
  = render partial: 'effective/orders/order_terms_and_conditions_fields', locals: { form: f }
37
36
 
38
37
  %p.text-right
39
- - unless f.object.pending? || current_cart.try(:empty?)
40
- = link_to_current_cart(label: 'Change Items')
41
-
42
- - if order.total == 0 && EffectiveOrders.allow_free_orders
43
- = f.submit order_checkout_label(:free), class: 'btn btn-primary', rel: :nofollow, data: {'disable_with' => 'Processing...' }
44
- - else
45
- = f.submit 'Save and Continue', class: 'btn btn-primary', rel: :nofollow, data: {'disable_with' => 'Saving...' }
38
+ = f.submit 'Save and Continue', class: 'btn btn-primary', rel: :nofollow, data: { disable_with: 'Saving...' }
@@ -1,33 +1,46 @@
1
- = render(order)
1
+ = render partial: 'effective/orders/order', locals: { order: order }
2
2
 
3
3
  .effective-order.effective-order-purchase-actions
4
- - if EffectiveOrders.allow_pretend_purchase_in_development
5
- - if Rails.env.production? == false
6
- = render partial: '/effective/orders/pretend/form', locals: {order: order, purchased_redirect_url: purchased_redirect_url, declined_redirect_url: declined_redirect_url}
4
+ - if EffectiveOrders.allow_free_orders && order.free?
5
+ = render partial: '/effective/orders/free/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
7
6
 
8
- - if EffectiveOrders.allow_pretend_purchase_in_production
9
- - if Rails.env.production?
10
- = render partial: '/effective/orders/pretend/form', locals: {order: order, purchased_redirect_url: purchased_redirect_url, declined_redirect_url: declined_redirect_url}
7
+ - elsif EffectiveOrders.allow_refunds && order.refund?
8
+ -# Nothing
11
9
 
12
- - if EffectiveOrders.moneris_enabled
13
- = render partial: '/effective/orders/moneris/form', locals: {order: order, purchased_redirect_url: purchased_redirect_url, declined_redirect_url: declined_redirect_url}
10
+ - else
11
+ - if EffectiveOrders.allow_pretend_purchase_in_development && !Rails.env.production?
12
+ = render partial: '/effective/orders/pretend/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
14
13
 
15
- - if EffectiveOrders.paypal_enabled
16
- = render partial: '/effective/orders/paypal/form', locals: {order: order}
14
+ - if EffectiveOrders.allow_pretend_purchase_in_production && Rails.env.production?
15
+ = render partial: '/effective/orders/pretend/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
17
16
 
18
- - if EffectiveOrders.stripe_enabled
19
- = render partial: '/effective/orders/stripe/form', locals: {order: order}
17
+ - if EffectiveOrders.moneris_enabled
18
+ = render partial: '/effective/orders/moneris/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
20
19
 
21
- - if EffectiveOrders.ccbill_enabled
22
- = render partial: '/effective/orders/ccbill/form', locals: {order: order}
20
+ - if EffectiveOrders.paypal_enabled
21
+ = render partial: '/effective/orders/paypal/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
23
22
 
24
- - if EffectiveOrders.app_checkout_enabled
25
- - if (EffectiveOrders.authorized?(controller, :app_checkout, order) rescue false)
26
- = render partial: '/effective/orders/app_checkout/form', locals: {order: order}
23
+ - if EffectiveOrders.stripe_enabled
24
+ = render partial: '/effective/orders/stripe/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
27
25
 
28
- - if EffectiveOrders.cheque_enabled
29
- = render partial: '/effective/orders/cheque/form', locals: {order: order}
26
+ - if EffectiveOrders.ccbill_enabled
27
+ = render partial: '/effective/orders/ccbill/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
30
28
 
31
- - if EffectiveOrders.allow_pretend_purchase_in_production
29
+ - if EffectiveOrders.app_checkout_enabled && EffectiveOrders.authorized?(controller, :app_checkout, order)
30
+ = render partial: '/effective/orders/app_checkout/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
31
+
32
+ - if EffectiveOrders.cheque_enabled && order.user == current_user
33
+ = render partial: '/effective/orders/cheque/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
34
+
35
+ - if EffectiveOrders.allow_pretend_purchase_in_production && Rails.env.production? && EffectiveOrders.allow_pretend_purchase_in_production_message.present?
32
36
  %br
33
37
  %p= EffectiveOrders.allow_pretend_purchase_in_production_message
38
+
39
+ - if EffectiveOrders.authorized?(controller, :admin, :effective_orders) && order.user != current_user
40
+ - if EffectiveOrders.allow_refunds && order.refund?
41
+ .effective-order.effective-order-admin-purchase-actions
42
+ = render partial: '/effective/orders/refund/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
43
+ - elsif EffectiveOrders.mark_as_paid_enabled
44
+ .effective-order.effective-order-admin-purchase-actions
45
+ = render partial: '/effective/orders/mark_as_paid/form', locals: { order: order, purchased_url: purchased_url, declined_url: declined_url }
46
+