op_cart 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/op_cart/order.rb +3 -1
- data/lib/op_cart/engine.rb +6 -0
- data/lib/op_cart/version.rb +1 -1
- metadata +2 -9
- data/app/assets/javascripts/jquery.ziptastic.js +0 -52
- data/app/assets/javascripts/op_cart/application.js +0 -14
- data/app/assets/javascripts/op_cart/orders.js.coffee +0 -95
- data/app/assets/stylesheets/op_cart/application.css +0 -15
- data/app/helpers/op_cart/application_helper.rb +0 -24
- data/app/views/op_cart/orders/new.html.slim +0 -80
- data/app/views/op_cart/orders/show.html.slim +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79460d9add671f55638c9210167b3b10e899a37d
|
4
|
+
data.tar.gz: f8146f320bf1c2a125b5e2096537caf35f4d6e90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a39e432d8b9022466da41141e96dfb0927cebe52a0311c6af20e29890a272b9fa2b51d2c9c7b8fe49a699bea8663fa6882524d80afea2a9e426024ec351bcbc9
|
7
|
+
data.tar.gz: 9c7d2785dad800e8f0eedd88d4ff0ba8f6f252c95b2eab81faa7d082daf14c894a2b131c2bc602fbe325fcecc3f2832b1b9a113b59998415b63ed3c5fcf8fb3d
|
data/app/models/op_cart/order.rb
CHANGED
@@ -30,11 +30,13 @@ module OpCart
|
|
30
30
|
|
31
31
|
# TODO Create shipping address
|
32
32
|
|
33
|
-
Stripe::Charge.create(
|
33
|
+
charge = Stripe::Charge.create(
|
34
34
|
amount: total,
|
35
35
|
currency: "usd",
|
36
36
|
customer: customer.id
|
37
37
|
)
|
38
|
+
#TODO: Mark order as charged
|
39
|
+
# update_attribute :charged, true if charge.captured
|
38
40
|
rescue Stripe::CardError => e
|
39
41
|
# The card has been declined or some other error has occurred
|
40
42
|
self.errors.add e
|
data/lib/op_cart/engine.rb
CHANGED
data/lib/op_cart/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: op_cart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Boehs
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -76,19 +76,12 @@ files:
|
|
76
76
|
- MIT-LICENSE
|
77
77
|
- README.md
|
78
78
|
- Rakefile
|
79
|
-
- app/assets/javascripts/jquery.ziptastic.js
|
80
|
-
- app/assets/javascripts/op_cart/application.js
|
81
|
-
- app/assets/javascripts/op_cart/orders.js.coffee
|
82
|
-
- app/assets/stylesheets/op_cart/application.css
|
83
79
|
- app/controllers/op_cart/application_controller.rb
|
84
80
|
- app/controllers/op_cart/orders_controller.rb
|
85
|
-
- app/helpers/op_cart/application_helper.rb
|
86
81
|
- app/models/op_cart/line_item.rb
|
87
82
|
- app/models/op_cart/order.rb
|
88
83
|
- app/models/op_cart/product.rb
|
89
84
|
- app/models/op_cart/shipping_address.rb
|
90
|
-
- app/views/op_cart/orders/new.html.slim
|
91
|
-
- app/views/op_cart/orders/show.html.slim
|
92
85
|
- config/initializers/stripe.rb
|
93
86
|
- config/locales/op_cart.en.yml
|
94
87
|
- config/routes.rb
|
@@ -1,52 +0,0 @@
|
|
1
|
-
(function( $ ) {
|
2
|
-
var requests = {};
|
3
|
-
var zipValid = {
|
4
|
-
us: /[0-9]{5}(-[0-9]{4})?/
|
5
|
-
};
|
6
|
-
|
7
|
-
$.ziptastic = function(country, zip, callback){
|
8
|
-
// If only zip and callback are given default to US
|
9
|
-
if (arguments.length == 2 && typeof arguments[1] == 'function') {
|
10
|
-
callback = arguments[1];
|
11
|
-
zip = arguments[0];
|
12
|
-
country = 'US';
|
13
|
-
}
|
14
|
-
|
15
|
-
country = country.toUpperCase();
|
16
|
-
// Only make unique requests
|
17
|
-
if(!requests[country]) {
|
18
|
-
requests[country] = {};
|
19
|
-
}
|
20
|
-
if(!requests[country][zip]) {
|
21
|
-
requests[country][zip] = $.getJSON('http://zip.getziptastic.com/v2/' + country + '/' + zip);
|
22
|
-
}
|
23
|
-
|
24
|
-
// Bind to the finished request
|
25
|
-
requests[country][zip].done(function(data) {
|
26
|
-
if (typeof callback == 'function') {
|
27
|
-
callback(data.country, data.state, data.state_short, data.city, zip);
|
28
|
-
}
|
29
|
-
});
|
30
|
-
|
31
|
-
// Allow for binding to the deferred object
|
32
|
-
return requests[country][zip];
|
33
|
-
};
|
34
|
-
|
35
|
-
$.fn.ziptastic = function( options ) {
|
36
|
-
return this.each(function() {
|
37
|
-
var ele = $(this);
|
38
|
-
|
39
|
-
ele.on('keyup', function() {
|
40
|
-
var zip = ele.val();
|
41
|
-
|
42
|
-
// TODO Non-US zip codes?
|
43
|
-
if(zipValid.us.test(zip)) {
|
44
|
-
$.ziptastic(zip, function(country, state, state_short, city) {
|
45
|
-
// Trigger the updated information
|
46
|
-
ele.trigger('zipChange', [country, state, state_short, city, zip]);
|
47
|
-
});
|
48
|
-
}
|
49
|
-
});
|
50
|
-
});
|
51
|
-
};
|
52
|
-
})( jQuery );
|
@@ -1,14 +0,0 @@
|
|
1
|
-
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
-
// listed below.
|
3
|
-
//
|
4
|
-
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
-
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
-
//
|
7
|
-
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
-
// compiled file.
|
9
|
-
//
|
10
|
-
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
-
// about supported directives.
|
12
|
-
//
|
13
|
-
//= require 'jquery.ziptastic'
|
14
|
-
//= require_tree .
|
@@ -1,95 +0,0 @@
|
|
1
|
-
@OpCart =
|
2
|
-
ready: ->
|
3
|
-
if $('body').is '.op_cart-orders-new, .op_cart-orders-create'
|
4
|
-
$number = $ '#credit_card_number'
|
5
|
-
$expiry = $ '#credit_card_expiry'
|
6
|
-
$cvc = $ '#credit_card_cvc'
|
7
|
-
|
8
|
-
if $('#card_form_inputs')
|
9
|
-
$number.payment 'formatCardNumber'
|
10
|
-
$expiry.payment 'formatCardExpiry'
|
11
|
-
$cvc.payment 'formatCardCVC'
|
12
|
-
|
13
|
-
$('#shipping_address_postal_code').change => @updateZipFields()
|
14
|
-
|
15
|
-
@updateZipFields()
|
16
|
-
@updateDisplayedQuantities()
|
17
|
-
@stripeCreateToken()
|
18
|
-
|
19
|
-
load: ->
|
20
|
-
OpCart.ready()
|
21
|
-
|
22
|
-
updateZipFields: ->
|
23
|
-
$locality = $ '#shipping_address_locality'
|
24
|
-
$region = $ '#shipping_address_region'
|
25
|
-
$zip = $ '#shipping_address_postal_code'
|
26
|
-
|
27
|
-
if $zip.val().length == 5
|
28
|
-
$.ziptastic $zip.val(), (country, region, region_short, locality, zip) ->
|
29
|
-
$locality.val locality
|
30
|
-
$region.val region
|
31
|
-
$locality.prop "disabled", false
|
32
|
-
$region.prop "disabled", false
|
33
|
-
|
34
|
-
|
35
|
-
stripeCreateToken: ->
|
36
|
-
$("#new_order").submit (event) ->
|
37
|
-
$form = $(this)
|
38
|
-
$form.find("button").prop "disabled", true
|
39
|
-
|
40
|
-
Stripe.setPublishableKey $form.data("stripe-key")
|
41
|
-
|
42
|
-
expiration = $("#credit_card_expiry").payment "cardExpiryVal"
|
43
|
-
|
44
|
-
Stripe.card.createToken
|
45
|
-
number: $("#credit_card_number").val()
|
46
|
-
cvc: $("#credit_card_cvc").val()
|
47
|
-
exp_month: expiration.month || 0
|
48
|
-
exp_year: expiration.year || 0
|
49
|
-
, OpCart.stripeResponseHandler
|
50
|
-
|
51
|
-
false # Prevent the form from submitting with the default action
|
52
|
-
|
53
|
-
stripeResponseHandler: (status, response) ->
|
54
|
-
$form = $("#new_order")
|
55
|
-
|
56
|
-
if response.error || !$form.get(0).checkValidity()
|
57
|
-
if response.error
|
58
|
-
errorMessage = response.error.message
|
59
|
-
else
|
60
|
-
errorMessage = 'Email or shipping information missing' #TODO: what else is missing?
|
61
|
-
$form.find(".payment-errors").text errorMessage
|
62
|
-
$form.find("button").prop "disabled", false
|
63
|
-
else
|
64
|
-
$('#order_card_token').val response.id
|
65
|
-
$('#order_details').remove()
|
66
|
-
$form.get(0).submit()
|
67
|
-
|
68
|
-
addItemToOrder: (productId, quantity) ->
|
69
|
-
currentQuantity = @lineItemQuantity productId
|
70
|
-
@lineItemQuantity productId, currentQuantity + 1
|
71
|
-
@updateDisplayedQuantity productId
|
72
|
-
|
73
|
-
removeItemFromOrder: (productId) ->
|
74
|
-
@lineItemQuantity productId, 0
|
75
|
-
@updateDisplayedQuantity productId
|
76
|
-
|
77
|
-
updateDisplayedQuantities: ->
|
78
|
-
$('[data-product-id]').each -> OpCart.updateDisplayedQuantity $(@).data('product-id')
|
79
|
-
|
80
|
-
updateDisplayedQuantity: (productId) ->
|
81
|
-
$quantity = $ "#line_item_product_#{productId} .quantity"
|
82
|
-
$quantity.html @lineItemQuantity(productId)
|
83
|
-
|
84
|
-
lineItemQuantity: (productId, quantity) ->
|
85
|
-
$liQuantities = $ '#line_items_quantities_json'
|
86
|
-
liQuantities = JSON.parse $liQuantities.val() || "{}"
|
87
|
-
|
88
|
-
if quantity >= 0
|
89
|
-
liQuantities[productId] = quantity
|
90
|
-
$liQuantities.val JSON.stringify(liQuantities)
|
91
|
-
else
|
92
|
-
liQuantities[productId] || 0
|
93
|
-
|
94
|
-
$ -> OpCart.ready()
|
95
|
-
$(document).on 'page:load', OpCart.load
|
@@ -1,15 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
-
* listed below.
|
4
|
-
*
|
5
|
-
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
-
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
-
*
|
8
|
-
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
-
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
-
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
-
* file per style scope.
|
12
|
-
*
|
13
|
-
*= require_tree .
|
14
|
-
*= require_self
|
15
|
-
*/
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module OpCart
|
2
|
-
module ApplicationHelper
|
3
|
-
# Can search for named routes directly in the main app, omitting
|
4
|
-
# the "main_app." prefix
|
5
|
-
def method_missing method, *args, &block
|
6
|
-
if main_app_url_helper?(method)
|
7
|
-
main_app.send(method, *args)
|
8
|
-
else
|
9
|
-
super
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def respond_to?(method)
|
14
|
-
main_app_url_helper?(method) or super
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def main_app_url_helper?(method)
|
20
|
-
(method.to_s.end_with?('_path') or method.to_s.end_with?('_url')) and
|
21
|
-
main_app.respond_to?(method)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
@@ -1,80 +0,0 @@
|
|
1
|
-
.op-cart_content
|
2
|
-
- if @products.present?
|
3
|
-
.op-cart_new-order
|
4
|
-
.op-cart_purchasable-items
|
5
|
-
h2 Purchasable Items
|
6
|
-
table
|
7
|
-
thead
|
8
|
-
tr
|
9
|
-
th Product Name
|
10
|
-
th Description
|
11
|
-
th Price
|
12
|
-
th
|
13
|
-
tbody
|
14
|
-
- @products.each do |product|
|
15
|
-
tr id="#{dom_id product}" data-product-id=(product.id)
|
16
|
-
td = product.name
|
17
|
-
td = product.description
|
18
|
-
td = number_to_currency product.price / 100
|
19
|
-
td
|
20
|
-
a.op-cart_add href="#" onclick="OpCart.addItemToOrder(#{product.id}, 1); return false" Add to Order
|
21
|
-
|
22
|
-
.op-cart_items-in-order
|
23
|
-
h2 Items in Order
|
24
|
-
table
|
25
|
-
thead
|
26
|
-
tr
|
27
|
-
th Product Name
|
28
|
-
th Price
|
29
|
-
th Qty
|
30
|
-
th
|
31
|
-
tbody
|
32
|
-
- @products.each do |product|
|
33
|
-
tr id="#{dom_id product, 'line_item'}"
|
34
|
-
td = product.name
|
35
|
-
td = number_to_currency product.price / 100
|
36
|
-
td.quantity 0
|
37
|
-
td
|
38
|
-
a.op-cart_remove href="#" onclick="OpCart.removeItemFromOrder(#{product.id}); return false" Remove
|
39
|
-
|
40
|
-
= simple_form_for @order, data: { stripe_key: Rails.configuration.stripe[:publishable_key] } do |f|
|
41
|
-
span.payment-errors
|
42
|
-
.op-cart_your-information
|
43
|
-
h2 Your Information
|
44
|
-
- if signed_in?
|
45
|
-
strong Email:
|
46
|
-
span = current_user.email
|
47
|
-
- else
|
48
|
-
= simple_fields_for :user do |fu|
|
49
|
-
= fu.input :email, autofocus: true, input_html: { autocomplete: 'email' }
|
50
|
-
= fu.input :password
|
51
|
-
|
52
|
-
.op-cart_shipping-address
|
53
|
-
h2 Shipping Address
|
54
|
-
= simple_fields_for :shipping_address do |sa|
|
55
|
-
- focus_name = signed_in? ? true : false
|
56
|
-
= sa.input :full_name, autofocus: focus_name, input_html: { autocomplete: 'name' }
|
57
|
-
= sa.input :street, input_html: { autocomplete: 'street-address' }
|
58
|
-
= sa.input :postal_code, input_html: { autocomplete: 'postal-code' }
|
59
|
-
= sa.input :locality, disabled: true, input_html: { autocomplete: 'city' }
|
60
|
-
= sa.input :region, disabled: true, input_html: { autocomplete: 'state' }
|
61
|
-
|
62
|
-
.op-cart_card-details
|
63
|
-
h2 Card Details
|
64
|
-
- if f.object.card_token.present?
|
65
|
-
span Card information already provided.
|
66
|
-
- else
|
67
|
-
#card_form_inputs
|
68
|
-
= simple_fields_for :credit_card do |c|
|
69
|
-
= c.input :number, input_html: { autocomplete: 'cc-number' }
|
70
|
-
= c.input :expiry, input_html: { autocomplete: 'cc-exp' }
|
71
|
-
= c.input :cvc, input_html: { autocomplete: 'cc-csc' }
|
72
|
-
|
73
|
-
= simple_fields_for :line_items do |li|
|
74
|
-
= li.input :quantities_json, as: :hidden
|
75
|
-
= f.input :card_token, as: :hidden
|
76
|
-
|
77
|
-
.form-actions
|
78
|
-
= f.button :button, "Submit Payment"
|
79
|
-
- else
|
80
|
-
p Add an item to your order to begin.
|
@@ -1,25 +0,0 @@
|
|
1
|
-
.op-cart_content
|
2
|
-
.op-cart_new-order
|
3
|
-
h2 Items in Order
|
4
|
-
ul.op-cart_items-in-order
|
5
|
-
- @order.line_items.each do |line_item|
|
6
|
-
li id="#{dom_id line_item}"
|
7
|
-
p = line_item.sellable.name
|
8
|
-
p.quantity
|
9
|
-
= line_item.quantity
|
10
|
-
| @
|
11
|
-
= number_to_currency line_item.unit_price / 100
|
12
|
-
| =
|
13
|
-
= number_to_currency line_item.total / 100
|
14
|
-
li
|
15
|
-
p Order Total: #{number_to_currency @order.total / 100}
|
16
|
-
|
17
|
-
.op-cart_your-information
|
18
|
-
h2 Your Information
|
19
|
-
= @order.user.email
|
20
|
-
.op-cart_shipping-address
|
21
|
-
h2 Shipping Address
|
22
|
-
- sa = @order.shipping_address
|
23
|
-
p = sa.full_name
|
24
|
-
p = sa.street
|
25
|
-
p = "#{sa.locality}, #{sa.region} #{sa.postal_code}"
|