effective_orders 1.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 (146) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +856 -0
  4. data/Rakefile +24 -0
  5. data/app/assets/images/effective_orders/stripe_connect.png +0 -0
  6. data/app/assets/javascripts/effective_orders/shipping_address_toggle.js.coffee +30 -0
  7. data/app/assets/javascripts/effective_orders/stripe_charges.js.coffee +26 -0
  8. data/app/assets/javascripts/effective_orders/stripe_subscriptions.js.coffee +28 -0
  9. data/app/assets/javascripts/effective_orders.js +2 -0
  10. data/app/assets/stylesheets/effective_orders/_order.scss +30 -0
  11. data/app/assets/stylesheets/effective_orders.css.scss +1 -0
  12. data/app/controllers/admin/customers_controller.rb +15 -0
  13. data/app/controllers/admin/orders_controller.rb +22 -0
  14. data/app/controllers/effective/carts_controller.rb +70 -0
  15. data/app/controllers/effective/orders_controller.rb +191 -0
  16. data/app/controllers/effective/providers/moneris.rb +94 -0
  17. data/app/controllers/effective/providers/paypal.rb +29 -0
  18. data/app/controllers/effective/providers/stripe.rb +125 -0
  19. data/app/controllers/effective/providers/stripe_connect.rb +47 -0
  20. data/app/controllers/effective/subscriptions_controller.rb +123 -0
  21. data/app/controllers/effective/webhooks_controller.rb +86 -0
  22. data/app/helpers/effective_carts_helper.rb +90 -0
  23. data/app/helpers/effective_orders_helper.rb +108 -0
  24. data/app/helpers/effective_paypal_helper.rb +37 -0
  25. data/app/helpers/effective_stripe_helper.rb +63 -0
  26. data/app/mailers/effective/orders_mailer.rb +64 -0
  27. data/app/models/concerns/acts_as_purchasable.rb +134 -0
  28. data/app/models/effective/access_denied.rb +17 -0
  29. data/app/models/effective/cart.rb +65 -0
  30. data/app/models/effective/cart_item.rb +40 -0
  31. data/app/models/effective/customer.rb +61 -0
  32. data/app/models/effective/datatables/customers.rb +45 -0
  33. data/app/models/effective/datatables/orders.rb +53 -0
  34. data/app/models/effective/order.rb +247 -0
  35. data/app/models/effective/order_item.rb +69 -0
  36. data/app/models/effective/stripe_charge.rb +35 -0
  37. data/app/models/effective/subscription.rb +95 -0
  38. data/app/models/inputs/price_field.rb +63 -0
  39. data/app/models/inputs/price_form_input.rb +7 -0
  40. data/app/models/inputs/price_formtastic_input.rb +9 -0
  41. data/app/models/inputs/price_input.rb +19 -0
  42. data/app/models/inputs/price_simple_form_input.rb +8 -0
  43. data/app/models/validators/effective/sold_out_validator.rb +7 -0
  44. data/app/views/active_admin/effective_orders/orders/_show.html.haml +70 -0
  45. data/app/views/admin/customers/_actions.html.haml +2 -0
  46. data/app/views/admin/customers/index.html.haml +10 -0
  47. data/app/views/admin/orders/index.html.haml +7 -0
  48. data/app/views/admin/orders/show.html.haml +11 -0
  49. data/app/views/effective/carts/_cart.html.haml +33 -0
  50. data/app/views/effective/carts/show.html.haml +18 -0
  51. data/app/views/effective/orders/_checkout_step_1.html.haml +39 -0
  52. data/app/views/effective/orders/_checkout_step_2.html.haml +18 -0
  53. data/app/views/effective/orders/_my_purchases.html.haml +15 -0
  54. data/app/views/effective/orders/_order.html.haml +4 -0
  55. data/app/views/effective/orders/_order_header.html.haml +21 -0
  56. data/app/views/effective/orders/_order_items.html.haml +39 -0
  57. data/app/views/effective/orders/_order_payment_details.html.haml +11 -0
  58. data/app/views/effective/orders/_order_shipping.html.haml +19 -0
  59. data/app/views/effective/orders/_order_user_fields.html.haml +10 -0
  60. data/app/views/effective/orders/checkout.html.haml +3 -0
  61. data/app/views/effective/orders/declined.html.haml +10 -0
  62. data/app/views/effective/orders/moneris/_form.html.haml +34 -0
  63. data/app/views/effective/orders/my_purchases.html.haml +6 -0
  64. data/app/views/effective/orders/my_sales.html.haml +28 -0
  65. data/app/views/effective/orders/new.html.haml +4 -0
  66. data/app/views/effective/orders/paypal/_form.html.haml +5 -0
  67. data/app/views/effective/orders/purchased.html.haml +10 -0
  68. data/app/views/effective/orders/show.html.haml +17 -0
  69. data/app/views/effective/orders/stripe/_form.html.haml +8 -0
  70. data/app/views/effective/orders/stripe/_subscription_fields.html.haml +7 -0
  71. data/app/views/effective/orders_mailer/order_receipt_to_admin.html.haml +8 -0
  72. data/app/views/effective/orders_mailer/order_receipt_to_buyer.html.haml +8 -0
  73. data/app/views/effective/orders_mailer/order_receipt_to_seller.html.haml +30 -0
  74. data/app/views/effective/subscriptions/index.html.haml +16 -0
  75. data/app/views/effective/subscriptions/new.html.haml +10 -0
  76. data/app/views/effective/subscriptions/show.html.haml +49 -0
  77. data/config/routes.rb +57 -0
  78. data/db/migrate/01_create_effective_orders.rb.erb +91 -0
  79. data/db/upgrade/02_upgrade_effective_orders_from03x.rb.erb +29 -0
  80. data/db/upgrade/upgrade_price_column_on_table.rb.erb +17 -0
  81. data/lib/effective_orders/engine.rb +52 -0
  82. data/lib/effective_orders/version.rb +3 -0
  83. data/lib/effective_orders.rb +76 -0
  84. data/lib/generators/effective_orders/install_generator.rb +38 -0
  85. data/lib/generators/effective_orders/upgrade_from03x_generator.rb +34 -0
  86. data/lib/generators/effective_orders/upgrade_price_column_generator.rb +34 -0
  87. data/lib/generators/templates/README +1 -0
  88. data/lib/generators/templates/effective_orders.rb +210 -0
  89. data/spec/controllers/carts_controller_spec.rb +143 -0
  90. data/spec/controllers/moneris_orders_controller_spec.rb +245 -0
  91. data/spec/controllers/orders_controller_spec.rb +418 -0
  92. data/spec/controllers/stripe_orders_controller_spec.rb +127 -0
  93. data/spec/controllers/webhooks_controller_spec.rb +79 -0
  94. data/spec/dummy/README.rdoc +8 -0
  95. data/spec/dummy/Rakefile +6 -0
  96. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  97. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  98. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  99. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  100. data/spec/dummy/app/models/product.rb +17 -0
  101. data/spec/dummy/app/models/product_with_float_price.rb +17 -0
  102. data/spec/dummy/app/models/user.rb +28 -0
  103. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  104. data/spec/dummy/bin/bundle +3 -0
  105. data/spec/dummy/bin/rails +4 -0
  106. data/spec/dummy/bin/rake +4 -0
  107. data/spec/dummy/config/application.rb +31 -0
  108. data/spec/dummy/config/boot.rb +5 -0
  109. data/spec/dummy/config/database.yml +25 -0
  110. data/spec/dummy/config/environment.rb +5 -0
  111. data/spec/dummy/config/environments/development.rb +37 -0
  112. data/spec/dummy/config/environments/production.rb +83 -0
  113. data/spec/dummy/config/environments/test.rb +39 -0
  114. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  115. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  116. data/spec/dummy/config/initializers/devise.rb +254 -0
  117. data/spec/dummy/config/initializers/effective_addresses.rb +15 -0
  118. data/spec/dummy/config/initializers/effective_orders.rb +22 -0
  119. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  120. data/spec/dummy/config/initializers/inflections.rb +16 -0
  121. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  122. data/spec/dummy/config/initializers/session_store.rb +3 -0
  123. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  124. data/spec/dummy/config/locales/en.yml +23 -0
  125. data/spec/dummy/config/routes.rb +3 -0
  126. data/spec/dummy/config/secrets.yml +22 -0
  127. data/spec/dummy/config.ru +4 -0
  128. data/spec/dummy/db/schema.rb +142 -0
  129. data/spec/dummy/db/test.sqlite3 +0 -0
  130. data/spec/dummy/log/development.log +487 -0
  131. data/spec/dummy/log/test.log +347 -0
  132. data/spec/dummy/public/404.html +67 -0
  133. data/spec/dummy/public/422.html +67 -0
  134. data/spec/dummy/public/500.html +66 -0
  135. data/spec/dummy/public/favicon.ico +0 -0
  136. data/spec/helpers/effective_orders_helper_spec.rb +21 -0
  137. data/spec/models/acts_as_purchasable_spec.rb +107 -0
  138. data/spec/models/customer_spec.rb +71 -0
  139. data/spec/models/factories_spec.rb +13 -0
  140. data/spec/models/order_item_spec.rb +35 -0
  141. data/spec/models/order_spec.rb +323 -0
  142. data/spec/models/stripe_charge_spec.rb +39 -0
  143. data/spec/models/subscription_spec.rb +103 -0
  144. data/spec/spec_helper.rb +44 -0
  145. data/spec/support/factories.rb +118 -0
  146. metadata +387 -0
@@ -0,0 +1,33 @@
1
+ .effective-order
2
+ %table.table
3
+ %thead
4
+ %tr
5
+ %th.quantity Quantity
6
+ %th.item Item
7
+ %th.price Price
8
+ %tbody
9
+ - cart.cart_items.each do |item|
10
+ %tr
11
+ %td.quantity
12
+ = item.quantity
13
+ %td.item
14
+ = item.title.html_safe
15
+ = ' - '
16
+ = link_to_remove_from_cart(item)
17
+ %td.price
18
+ = price_to_currency(item.subtotal)
19
+ - if cart.empty?
20
+ %tr
21
+ %td.quantity
22
+ %td.item There are no items in your shopping cart
23
+ %td.price
24
+ %tfoot
25
+ %tr
26
+ %th{:colspan => 2} Subtotal
27
+ %td.price= price_to_currency(cart.subtotal)
28
+ %tr
29
+ %th{:colspan => 2} Tax
30
+ %td.price= price_to_currency(cart.tax)
31
+ %tr
32
+ %th{:colspan => 2} Total Due
33
+ %td.price= price_to_currency(cart.total)
@@ -0,0 +1,18 @@
1
+ %h2 Shopping Cart
2
+
3
+ - if @cart.empty?
4
+ %p Your cart is empty.
5
+
6
+ %hr
7
+ = link_to 'Home', root_url, :class => 'btn btn-primary'
8
+ = link_to 'Order History', effective_orders.my_purchases_path, :class => 'btn btn-default'
9
+
10
+ - else
11
+ %p Your cart has #{@cart.cart_items.length} items.
12
+
13
+ = render_cart(@cart)
14
+
15
+ %hr
16
+ = link_to_checkout :class => 'btn btn-primary pull-right'
17
+ = link_to_empty_cart
18
+ = link_to 'Order History', effective_orders.my_purchases_path, :class => 'btn btn-default', :rel => :nofollow
@@ -0,0 +1,39 @@
1
+ .effective-order
2
+ = simple_form_for(order, (EffectiveOrders.simple_form_options || {}).merge(:url => effective_orders.orders_path)) do |f|
3
+ = render :partial => 'order_items', :locals => {:order => order, :form => f}
4
+
5
+ - if order.errors[:order_items].present?
6
+ %p.inline-errors= order.errors[:order_items].first
7
+
8
+ - 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))
10
+
11
+ - if EffectiveOrders.collect_user_fields.present? && (f.object.user rescue nil).present?
12
+ %h3 User Information
13
+ = render :partial => 'effective/orders/order_user_fields', :locals => {:form => f, :user => f.object.user }
14
+
15
+ - num_addresses = [EffectiveOrders.require_billing_address, EffectiveOrders.require_shipping_address].count(true)
16
+
17
+ - if num_addresses > 0
18
+ .row
19
+ - if EffectiveOrders.require_billing_address
20
+ %div{:class => "col-sm-#{12 / num_addresses}"}
21
+ %h3 Billing Address
22
+ = effective_address_fields(f, :billing_address)
23
+ - if order.save_billing_address != nil
24
+ = f.input :save_billing_address, :as => :boolean, :label => 'Save as my default Billing Address'
25
+
26
+ - if EffectiveOrders.require_shipping_address
27
+ %div{:class => "col-sm-#{12 / num_addresses}"}
28
+ %h3 Shipping Address
29
+ - if EffectiveOrders.require_billing_address && EffectiveOrders.require_shipping_address
30
+ .shipping_address_fields{:style => (f.object.shipping_address_same_as_billing? && (f.object.errors[:shipping_address] || []).blank?) ? 'display: none;' : 'display: block;'}
31
+ = effective_address_fields(f, :shipping_address)
32
+ - if order.save_shipping_address != nil
33
+ = f.input :save_shipping_address, :as => :boolean, :label => 'Save as my default Shipping Address'
34
+
35
+ = f.input :shipping_address_same_as_billing, :as => :boolean, :label => 'My Shipping address is the same as my Billing address'
36
+
37
+ %hr
38
+ = link_to_current_cart :label => 'Change Items', :class => 'btn btn-default'
39
+ = f.submit 'Continue to Checkout Confirmation', :class => 'btn btn-primary pull-right', :rel => :nofollow, 'data-disable-with' => 'Continuing...'
@@ -0,0 +1,18 @@
1
+ = render order
2
+
3
+ - if EffectiveOrders.moneris_enabled
4
+ = render :partial => '/effective/orders/moneris/form', :locals => {:order => order, :purchased_redirect_url => purchased_redirect_url, :declined_redirect_url => declined_redirect_url}
5
+
6
+ - if EffectiveOrders.paypal_enabled
7
+ = render :partial => '/effective/orders/paypal/form', :locals => {:order => order}
8
+
9
+ - if EffectiveOrders.stripe_enabled
10
+ = render :partial => '/effective/orders/stripe/form', :locals => {:order => order}
11
+
12
+ - if true || EffectiveOrders.allow_pretend_purchase_in_production
13
+ = link_to 'Process Order', effective_orders.pretend_purchase_path(order, :purchased_redirect_url => purchased_redirect_url, :declined_redirect_url => declined_redirect_url), :class => 'btn btn-primary'
14
+ %p payment information is not required to process this order at this time.
15
+ %p * credit card details are not currently required to process this order
16
+ - elsif Rails.env.development?
17
+ = link_to 'Process Order (development only)', effective_orders.pretend_purchase_path(order, :purchased_redirect_url => purchased_redirect_url, :declined_redirect_url => declined_redirect_url), :class => 'btn btn-primary'
18
+
@@ -0,0 +1,15 @@
1
+ %table.table
2
+ %thead
3
+ %tr
4
+ %th Order
5
+ %th Date of Purchase
6
+ %th Description
7
+ %tbody
8
+ - orders.each do |order|
9
+ %tr
10
+ %td= link_to "##{order.to_param}", order_path.gsub(':id', order.to_param)
11
+ %td= order.purchased_at.strftime("%Y-%m-%d %H:%M")
12
+ %td= order_summary(order)
13
+
14
+ - unless orders.present?
15
+ %p You have no purchased orders
@@ -0,0 +1,4 @@
1
+ .effective-order
2
+ = render :partial => 'effective/orders/order_header', :locals => {:order => order}
3
+ = render :partial => 'effective/orders/order_shipping', :locals => {:order => order}
4
+ = render :partial => 'effective/orders/order_items', :locals => {:order => order}
@@ -0,0 +1,21 @@
1
+ %h3 Acme Industries Inc.
2
+ .row
3
+ .col-sm-6
4
+ %p= mail_to EffectiveOrders.mailer[:admin_email] || 'info@acmeindustries.com'
5
+ %p
6
+ 1234 Fake Street
7
+ %br
8
+ Edmonton, AB, T5H 4A5
9
+ %br
10
+ %small Customize me by overriding '/app/views/effective/orders/_order_header.html.haml'
11
+
12
+ .col-sm-6
13
+ - if order.purchased?
14
+ %p Receipt: ##{order.to_param}
15
+ - elsif order.persisted?
16
+ %p Order: ##{order.to_param}
17
+
18
+ - if order.purchased?
19
+ %p Purchased at: #{order.purchased_at.strftime("%Y-%m-%d %H:%M")}
20
+ - else
21
+ %p Date: #{Time.zone.now.strftime("%Y-%m-%d %H:%M")}
@@ -0,0 +1,39 @@
1
+ .effective-order
2
+ %table.table
3
+ - include_download_column = order.purchased? && order.order_items.any? { |order_item| order_item.purchased_download_url.present? rescue false }
4
+ %thead
5
+ %tr
6
+ %th.quantity Quantity
7
+ %th.item Item
8
+ - if include_download_column
9
+ %th.download Download
10
+ %th.price Price
11
+ %tbody
12
+ - order.order_items.each do |item|
13
+ %tr
14
+ %td.quantity
15
+ = item.quantity
16
+ %td.item
17
+ = item.title.html_safe
18
+ - if order.new_record? && item.purchasable.kind_of?(Effective::Subscription)
19
+ = render :partial => 'effective/orders/stripe/subscription_fields', :locals => {:form => form, :subscription => item.purchasable }
20
+
21
+ - if include_download_column
22
+ %td.download
23
+ - if item.purchased? && (item.purchased_download_url rescue nil).present?
24
+ = link_to 'download', item.purchased_download_url
25
+ - else
26
+ = '-'
27
+ %td.price
28
+ = price_to_currency(item.subtotal)
29
+ %tfoot
30
+ %tr
31
+ %th{:colspan => (include_download_column ? 3 : 2)} Subtotal
32
+ %td.price= price_to_currency(order.subtotal)
33
+ %tr
34
+ %th{:colspan => (include_download_column ? 3 : 2)} Tax
35
+ %td.price= price_to_currency(order.tax)
36
+ %tr
37
+ %th{:colspan => (include_download_column ? 3 : 2)} Total Due
38
+ %td.price= price_to_currency(order.total)
39
+
@@ -0,0 +1,11 @@
1
+ %h4 Payment Details
2
+
3
+ %p This order was purchased with the following details:
4
+ %br
5
+
6
+ %table.table
7
+ %tbody
8
+ - order.payment.each do |k, v|
9
+ %tr
10
+ %td= k
11
+ %td= v
@@ -0,0 +1,19 @@
1
+ %table.table
2
+ %thead
3
+ %tr
4
+ %th= "#{order.purchased? ? 'Sold To' : 'Bill To'}"
5
+ - if EffectiveOrders.require_shipping_address && order.shipping_address.present?
6
+ %th Ship To
7
+ %tbody
8
+ %tr
9
+ %td
10
+ - if order.user.to_s != order.user.email
11
+ = "#{order.user.to_s} (#{mail_to order.user.email})".html_safe
12
+ - else
13
+ = mail_to order.user.email
14
+ %br
15
+ - if order.billing_address.present?
16
+ = render :partial => 'effective/addresses/address', :locals => {:address => order.billing_address}
17
+ - if EffectiveOrders.require_shipping_address && order.shipping_address.present?
18
+ %td
19
+ = render :partial => 'effective/addresses/address', :locals => {:address => order.shipping_address}
@@ -0,0 +1,10 @@
1
+ = form.simple_fields_for :user, user do |fa|
2
+ - if (EffectiveOrders.collect_user_fields || []).include?(:salutation) && fa.object.respond_to?(:salutation)
3
+ - if defined?(fa.object.class::SALUTATIONS)
4
+ = fa.input :salutation, :as => :select, :collection => fa.object.class::SALUTATIONS, :include_blank => false, :required => true
5
+ - else
6
+ = fa.input :salutation, :required => true, :placeholder => 'Salutation'
7
+
8
+ - (EffectiveOrders.collect_user_fields || []).reject { |x| x == :salutation }.each do |field|
9
+ - if fa.object.respond_to?(field)
10
+ = fa.input field, :required => true, :placeholder => field.to_s.humanize
@@ -0,0 +1,3 @@
1
+ %h2 Checkout
2
+
3
+ = render_checkout(@order)
@@ -0,0 +1,10 @@
1
+ %h2 Unable to Purchase
2
+ %p There was an error purchasing an order.
3
+
4
+ = render @order
5
+
6
+ %p Your cart has been restored.
7
+
8
+ %hr
9
+ = link_to 'Home', root_url, :class => 'btn btn-primary'
10
+ = link_to_current_cart :class => 'btn btn-default'
@@ -0,0 +1,34 @@
1
+ = form_tag(EffectiveOrders.moneris[:hpp_url], :method => 'post') do
2
+ = hidden_field_tag(:ps_store_id, EffectiveOrders.moneris[:ps_store_id])
3
+ = hidden_field_tag(:hpp_key, EffectiveOrders.moneris[:hpp_key])
4
+ = hidden_field_tag(:lang, 'en-ca')
5
+ = hidden_field_tag(:rvar_authenticity_token, form_authenticity_token)
6
+
7
+ - if purchased_redirect_url.present?
8
+ = hidden_field_tag(:rvar_purchased_redirect_url, purchased_redirect_url)
9
+
10
+ - if declined_redirect_url.present?
11
+ = hidden_field_tag(:rvar_declined_redirect_url, declined_redirect_url)
12
+
13
+ = hidden_field_tag(:email, order.user.try(:email))
14
+ = hidden_field_tag(:cust_id, order.user.to_param)
15
+ = hidden_field_tag(:order_id, "#{order.to_param.to_i + EffectiveOrders.moneris[:order_nudge].to_i}")
16
+ = hidden_field_tag(:gst, '%.2f' % (order.tax / 100.0))
17
+ = hidden_field_tag(:charge_total, '%.2f' % (order.total / 100.0))
18
+
19
+ - order.order_items.each_with_index do |item, x|
20
+ = hidden_field_tag("id#{x}", x)
21
+ = hidden_field_tag("description#{x}", item.title)
22
+ = hidden_field_tag("quantity#{x}", item.quantity)
23
+ = hidden_field_tag("price#{x}", '%.2f' % (item.price / 100.0))
24
+ = hidden_field_tag("subtotal#{x}", '%.2f' % (item.subtotal / 100.0))
25
+
26
+ - if order.billing_address.present?
27
+ - address = order.billing_address
28
+ = hidden_field_tag(:bill_address_one, address.address1)
29
+ = hidden_field_tag(:bill_city, address.city)
30
+ = hidden_field_tag(:bill_state_or_province, address.state)
31
+ = hidden_field_tag(:bill_postal_code, address.postal_code)
32
+ = hidden_field_tag(:bill_country, address.country)
33
+
34
+ %p= submit_tag 'Checkout with Moneris', :class => 'btn btn-primary'
@@ -0,0 +1,6 @@
1
+ %h2 Order History
2
+
3
+ = render_order_history(@orders)
4
+
5
+ %hr
6
+ = link_to 'Home', root_url, :class => 'btn btn-primary'
@@ -0,0 +1,28 @@
1
+ %h2 My Sales
2
+
3
+ %table.table
4
+ %thead
5
+ %tr
6
+ %th Product
7
+ %th Order
8
+ %th Buyer
9
+ %th Date of Sale
10
+ %th Description
11
+ %tbody
12
+ - (@order_items || {}).group_by(&:purchasable).each do |purchasable, order_items|
13
+ - order_items.each_with_index do |order_item, x|
14
+ %tr
15
+ - if x == 0
16
+ %td{:rowspan => order_items.size}
17
+ = link_to purchasable.title, acts_as_purchasable_path(purchasable)
18
+
19
+ %td= "##{order_item.order.to_param}"
20
+ %td= order_item.order.try(:user).try(:to_s)
21
+ %td= order_item.order.purchased_at.strftime("%Y-%m-%d %H:%M")
22
+ %td= order_item_summary(order_item)
23
+
24
+ - unless @order_items.present?
25
+ %p You have no sales
26
+
27
+ %hr
28
+ = link_to 'Home', root_url, :class => 'btn btn-primary'
@@ -0,0 +1,4 @@
1
+ %h2 Checkout
2
+
3
+ = render_checkout(@order)
4
+
@@ -0,0 +1,5 @@
1
+ = form_tag(EffectiveOrders.paypal[:paypal_url], :method => 'post') do
2
+ = hidden_field_tag :cmd, '_s-xclick'
3
+ = hidden_field_tag :encrypted, paypal_encrypted_payload(order)
4
+
5
+ %p= submit_tag 'Checkout with PayPal', :class => 'btn btn-primary'
@@ -0,0 +1,10 @@
1
+ %h2 Thank You
2
+
3
+ %p You have successfully purchased the following:
4
+
5
+ %a.btn.btn-default.pull-right{'data-role' => 'print-button', :class => 'print-button', :onClick => "window.print(); false;"} Print
6
+
7
+ = render @order
8
+
9
+ %hr
10
+ = link_to 'Home', root_url, :class => 'btn btn-primary'
@@ -0,0 +1,17 @@
1
+ - if @order.purchased?
2
+ %h2 Receipt
3
+ - else
4
+ %h2 Order
5
+ %hr
6
+
7
+ %a.btn.btn-default.pull-right{'data-role' => 'print-button', :class => 'print-button', :onClick => "window.print(); false;"} Print
8
+
9
+ = render @order
10
+
11
+ %hr
12
+ = link_to 'Back', :back, :class => 'btn btn-primary'
13
+ - if @order.purchased?
14
+ = '-'
15
+ = link_to 'Resend Receipt', effective_orders.resend_buyer_receipt_path(@order), 'data-confirm' => 'This action will email you a copy of the original email receipt. Send receipt now?', :class => 'btn btn-default'
16
+
17
+
@@ -0,0 +1,8 @@
1
+ = javascript_include_tag "https://checkout.stripe.com/checkout.js"
2
+
3
+ #effective-orders-new-charge-form{:data => {'stripe-publishable-key' => EffectiveOrders.stripe[:publishable_key], 'site-title' => EffectiveOrders.stripe[:site_title], 'site-image' => EffectiveOrders.stripe[:site_image], 'user-email' => current_user.try(:email), 'amount' => order.total, 'description' => "#{order.num_items} items (#{price_to_currency(order.total)})"}}
4
+ = simple_form_for(@stripe_charge || Effective::StripeCharge.new(order), (EffectiveOrders.simple_form_options || {}).merge(:url => effective_orders.stripe_charges_path)) do |f|
5
+ = f.input :effective_order_id, :as => :hidden
6
+ = f.input :token, :as => :hidden
7
+ = f.submit 'Continue to Payment', :class => 'btn btn-primary'
8
+
@@ -0,0 +1,7 @@
1
+ .effective-stripe-subscription
2
+ = form.simple_fields_for :order_items, subscription do |fa|
3
+ = fa.input_field :class, :as => :hidden
4
+ - if subscription.stripe_coupon_id.blank? || subscription.errors[:stripe_coupon_id].present?
5
+ = fa.input :stripe_coupon_id, :label => 'Coupon Code'.html_safe, :placeholder => 'Enter Coupon Code'
6
+ - else
7
+ = fa.input :stripe_coupon_id, :as => :hidden, :label => 'Coupon Code'.html_safe, :placeholder => 'Enter Coupon Code'
@@ -0,0 +1,8 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %meta{:content => 'text/html; charset=UTF-8', 'http-equiv' => "Content-Type"}
5
+ %body
6
+ %p An order has been successfully purchased:
7
+
8
+ = render @order
@@ -0,0 +1,8 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %meta{:content => 'text/html; charset=UTF-8', 'http-equiv' => "Content-Type"}
5
+ %body
6
+ %p Your order has been successfully purchased:
7
+
8
+ = render @order
@@ -0,0 +1,30 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %meta{:content => 'text/html; charset=UTF-8', 'http-equiv' => "Content-Type"}
5
+ %body
6
+ %p= @subject
7
+
8
+ %table.table
9
+ %thead
10
+ %tr
11
+ %th Item
12
+ %th Price
13
+ %tbody
14
+ - @order_items.each do |item|
15
+ %tr
16
+ %td
17
+ - if item.quantity > 1
18
+ = "#{item.quantity}x "
19
+ = item.title
20
+ %td= price_to_currency(item.subtotal)
21
+ %tfoot
22
+ %tr
23
+ %th Subtotal
24
+ %td= price_to_currency(@order_items.sum(&:subtotal))
25
+ %tr
26
+ %th Tax
27
+ %td= price_to_currency(@order_items.sum(&:tax))
28
+ %tr
29
+ %th Total
30
+ %td= price_to_currency(@order_items.sum(&:total))
@@ -0,0 +1,16 @@
1
+ %h2 My Subscriptions
2
+
3
+ - if @subscriptions.present?
4
+ %p You have the following subscriptions:
5
+ %ul
6
+ - @subscriptions.each do |subscription|
7
+ %li
8
+ = subscription.title.html_safe
9
+ = '('
10
+ = link_to 'details', effective_orders.subscription_path(subscription.stripe_plan_id)
11
+ = '-'
12
+ = link_to 'unsubscribe', effective_orders.subscription_path(subscription.stripe_plan_id), :data => {:method => :delete, :confirm => 'This will cancel your subscription. Are you sure? This cannot be undone.'}
13
+ = ')'
14
+ - else
15
+ %p You have no subscriptions
16
+ %p= link_to 'New Subscription', effective_orders.new_subscription_path
@@ -0,0 +1,10 @@
1
+ %h2 New Subscription
2
+
3
+ - if @plans.present?
4
+ = simple_form_for(@subscription, (EffectiveOrders.simple_form_options || {}).merge(:url => effective_orders.subscriptions_path, :method => :post)) do |f|
5
+ = f.input :stripe_plan_id, :as => :select, :collection => stripe_plans_collection(@plans), :include_blank => false, :label => 'Plan'
6
+ = f.input :stripe_coupon_id, :placeholder => 'Coupon Code', :label => 'Coupon'
7
+ = f.submit 'Add to Cart', :class => 'btn btn-primary'
8
+ - else
9
+ %p No available Subscriptions
10
+ %p= link_to 'Home', root_url
@@ -0,0 +1,49 @@
1
+ %h2
2
+ = @plan.name
3
+ Subscription
4
+ details
5
+
6
+ %p= stripe_plan_description(@plan)
7
+
8
+ %table.table
9
+ %tbody
10
+ %tr
11
+ %th Started
12
+ %td= Time.zone.at(@stripe_subscription.start).strftime("%d-%b-%Y")
13
+ - if @stripe_subscription.discount.present?
14
+ %tr
15
+ %th Coupon
16
+ %td= stripe_coupon_description(@stripe_subscription.discount.coupon)
17
+ %tr
18
+ %th Status
19
+ %td= @stripe_subscription.status
20
+ %tr
21
+ %th Current Period Start
22
+ %td= Time.zone.at(@stripe_subscription.current_period_start).strftime("%d-%b-%Y")
23
+ %tr
24
+ %th Current Period End
25
+ %td= Time.zone.at(@stripe_subscription.current_period_end).strftime("%d-%b-%Y")
26
+
27
+ %h3= "#{@plan.interval.chomp('ly')}ly Invoices"
28
+
29
+ %table.table
30
+ %thead
31
+ %tr
32
+ %th Date
33
+ %th Id
34
+ %th Period
35
+ %th Charge
36
+ %tbody
37
+ - @invoices.each do |invoice|
38
+ %tr
39
+ %td= Time.zone.at(invoice.date).strftime("%d-%b-%Y")
40
+ %td= invoice.id
41
+ %td
42
+ = Time.zone.at(invoice.lines.first.period.start).strftime("%d-%b-%Y")
43
+ to
44
+ = Time.zone.at(invoice.lines.first.period.end).strftime("%d-%b-%Y")
45
+ %td= price_to_currency(invoice.total)
46
+
47
+ %h3 Cancel Subscription
48
+
49
+ = link_to 'Unsubscribe', effective_orders.subscription_path(@plan.id), :data => {:method => :delete, :confirm => 'This will cancel your subscription. Are you sure? This cannot be undone.'}
data/config/routes.rb ADDED
@@ -0,0 +1,57 @@
1
+ Rails.application.routes.draw do
2
+ mount EffectiveOrders::Engine => '/', :as => 'effective_orders'
3
+ end
4
+
5
+ EffectiveOrders::Engine.routes.draw do
6
+ scope :module => 'effective' do
7
+
8
+ match 'orders/:id/purchased', :to => 'orders#purchased', :as => 'order_purchased', :via => :get
9
+ match 'orders/:id/declined', :to => 'orders#declined', :as => 'order_declined', :via => :get
10
+ match 'orders/:id/resend_buyer_receipt', :to => 'orders#resend_buyer_receipt', :via => :get, :as => 'resend_buyer_receipt'
11
+ match 'orders/my_purchases', :to => 'orders#my_purchases', :as => 'my_purchases', :via => :get
12
+
13
+ if EffectiveOrders.paypal_enabled
14
+ match 'orders/paypal_postback', :to => 'orders#paypal_postback', :as => 'paypal_postback', :via => :post
15
+ end
16
+
17
+ if EffectiveOrders.moneris_enabled
18
+ match 'orders/moneris_postback', :to => 'orders#moneris_postback', :as => 'moneris_postback', :via => :post
19
+ end
20
+
21
+ if EffectiveOrders.stripe_enabled
22
+ match 'orders/stripe_charge', :to => 'orders#stripe_charge', :as => 'stripe_charges', :via => :post
23
+ end
24
+
25
+ if EffectiveOrders.stripe_subscriptions_enabled
26
+ resources :subscriptions, :only => [:index, :show, :new, :create, :destroy]
27
+ end
28
+
29
+ if EffectiveOrders.stripe_connect_enabled
30
+ match 'orders/stripe_connect_redirect_uri', :to => 'orders#stripe_connect_redirect_uri', :as => 'stripe_connect_redirect_uri', :via => :get
31
+ match 'orders/my_sales', :to => 'orders#my_sales', :as => 'my_sales', :via => :get
32
+ end
33
+
34
+ if Rails.env.development? || EffectiveOrders.allow_pretend_purchase_in_production
35
+ match 'orders/:id/pretend_purchase', :to => 'orders#pretend_purchase', :as => 'pretend_purchase', :via => [:get, :post]
36
+ end
37
+
38
+ # This must be below the other routes defined above.
39
+ resources :orders, :only => [:new, :create, :show, :index]
40
+
41
+ match 'cart', :to => 'carts#show', :as => 'cart', :via => :get
42
+ match 'cart', :to => 'carts#destroy', :via => :delete
43
+
44
+ # If you Tweak this route, please update EffectiveOrdersHelper too
45
+ match 'cart/:purchasable_type/:purchasable_id', :to => 'carts#add_to_cart', :via => [:get, :post], :as => 'add_to_cart'
46
+ match 'cart/:id', :to => 'carts#remove_from_cart', :via => [:delete], :as => 'remove_from_cart'
47
+
48
+ match 'webhooks/stripe', :to => 'webhooks#stripe', :via => [:post, :put]
49
+ end
50
+
51
+ if defined?(EffectiveDatatables)
52
+ namespace :admin do
53
+ resources :customers, :only => [:index]
54
+ resources :orders, :only => [:index, :show]
55
+ end
56
+ end
57
+ end