effective_orders 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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