op_cart 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a055877b518c695c504b0910b9ee3b53d7dee695
4
- data.tar.gz: b09e9b447b40d0185ef69a7f108a2807798ae29e
3
+ metadata.gz: 695ceaa47d75df3df79ef2d8049909b2cd605662
4
+ data.tar.gz: edfc90597c37f748372219b032568a26d17012c0
5
5
  SHA512:
6
- metadata.gz: de05c032008bf45018a3e243bfa6dea54f4dae090fcce0213625b60c8bcffa1f661af8a1a983674cd41373c00e7ba7a43930db10dad57d5cb01b7a733164a7da
7
- data.tar.gz: 8fe5ab19e078945cfe0b34b1ddbd062a26718a9390f3b71058ef4489fcfd4005e1e41ed7e4f2b324b4c7b5ff8469e39688c76c4d79d6f23ed27c00d6f705f486
6
+ metadata.gz: b9f7d545228109490cb3a503023943b4ae6a5dcf196eca748609af70a633fb4c229251570e7b723a9fea78f1eb369c713ac0c31cdf51b98f78eb89e094bba267
7
+ data.tar.gz: 88aa09d43bea2327481b99d933ac087a8093c2e857a22e0b0bf2bb6a253df0208565d43ac1958a6c556e320212230df1e35856c22f7a2383d343a824293a9a6a
@@ -105,7 +105,7 @@ module OpCart
105
105
 
106
106
  def add_shipping_address
107
107
  @order.shipping_address = @shipping_address = ShippingAddress.new(
108
- shipping_address_params.merge user_id: @user.try(:id)
108
+ shipping_address_params.merge user: @user
109
109
  )
110
110
  end
111
111
  end
@@ -1,6 +1,7 @@
1
1
  module OpCart
2
2
  class Order < ActiveRecord::Base
3
3
  has_many :line_items
4
+ has_many :subscriptions
4
5
  belongs_to :shipping_address
5
6
  belongs_to :user
6
7
 
@@ -19,6 +20,7 @@ module OpCart
19
20
  before_validation :set_total
20
21
  before_validation -> { self.status = :pending }, unless: :status?
21
22
  before_save :charge_customer, if: -> { self.status == 'pending' }
23
+ before_create :create_subscriptions
22
24
 
23
25
  private
24
26
 
@@ -40,10 +42,9 @@ module OpCart
40
42
  end
41
43
 
42
44
  def charge_customer
43
- customer = Customer.find_or_create_by user: user
44
45
  if processor_token.present?
45
46
  customer.update_card processor_token
46
- processor_token = nil
47
+ self.processor_token = nil
47
48
  end
48
49
 
49
50
  self.processor_response = Stripe::Charge.create(
@@ -53,6 +54,7 @@ module OpCart
53
54
  ).to_hash
54
55
  self.status = :paid if processor_response['captured']
55
56
  rescue Stripe::InvalidRequestError, Stripe::CardError => e
57
+ self.processor_token = nil
56
58
  if e.try(:code) == 'card_declined'
57
59
  self.status = :payment_declined
58
60
  end
@@ -68,5 +70,17 @@ module OpCart
68
70
  self.errors.add :card_error, (message || e.message)
69
71
  false
70
72
  end
73
+
74
+ def create_subscriptions
75
+ line_items.each do |li|
76
+ if li.sellable.is_a? Plan
77
+ subscriptions.new customer: customer, plan: li.sellable, quantity: li.quantity
78
+ end
79
+ end
80
+ end
81
+
82
+ def customer
83
+ @customer ||= Customer.find_or_create_by user: user
84
+ end
71
85
  end
72
86
  end
@@ -0,0 +1,66 @@
1
+ module OpCart
2
+ class Subscription < ActiveRecord::Base
3
+ belongs_to :plan
4
+ belongs_to :order
5
+ belongs_to :customer
6
+
7
+ before_validation -> { self.status = :pending }, unless: :status?
8
+ before_validation -> { self.quantity = 1 }, unless: :quantity?
9
+ before_validation :create_subscription, on: :create
10
+ before_validation :update_subscription, on: :update
11
+
12
+ validates :processor_token, uniqueness: true, presence: true
13
+ validates :status, presence: true
14
+ validates :quantity, numericality: { only_integer: true, greater_than: 0 }
15
+ validates :started_at, presence: true
16
+ validates :plan, :order, :customer, presence: true
17
+
18
+ def processor_object
19
+ @processor_object ||= customer.processor_object.subscriptions.retrieve processor_token
20
+ rescue Stripe::InvalidRequestError => e
21
+ raise e unless e.message.include? 'does not have subscription'
22
+ end
23
+
24
+ private
25
+
26
+ def create_subscription
27
+ subscriptions_attributes = { plan: plan.processor_token, quantity: quantity }
28
+ subscriptions_attributes[:trial_end] = trial_ended_at.to_i if trial_ended_at
29
+ update_local_object customer.processor_object.subscriptions.create(subscriptions_attributes)
30
+ rescue Stripe::InvalidRequestError => e
31
+ if e.param
32
+ self.errors.add e.param, e.message
33
+ else
34
+ self.errors.add :base, e.message
35
+ end
36
+ false
37
+ end
38
+
39
+ def update_subscription
40
+ subscriptions_attributes = {}
41
+ subscriptions_attributes[:quantity] = quantity if quantity_changed?
42
+ subscriptions_attributes[:trial_end] = trial_ended_at.to_i if trial_ended_at_changed?
43
+ subscriptions_attributes[:plan] = plan.processor_token if plan_id_changed?
44
+ update_local_object customer.processor_object.subscriptions.create(subscriptions_attributes)
45
+ rescue Stripe::InvalidRequestError => e
46
+ if e.param
47
+ self.errors.add e.param, e.message
48
+ else
49
+ self.errors.add :base, e.message
50
+ end
51
+ false
52
+ end
53
+
54
+ def update_local_object subscription=processor_object
55
+ self.processor_token = subscription.id
56
+ self.status = subscription.status
57
+ self.quantity = subscription.quantity
58
+ self.started_at = Time.at subscription.start
59
+ self.canceled_at = Time.at subscription.canceled_at if subscription.canceled_at
60
+ self.ended_at = Time.at subscription.ended_at if subscription.ended_at
61
+ self.trial_started_at = Time.at subscription.trial_start if subscription.trial_start
62
+ self.trial_ended_at = Time.at subscription.trial_end if subscription.trial_end
63
+ self.plan = Plan.find_by! processor_token: subscription.plan.id
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,19 @@
1
+ class CreateOpCartSubscriptions < ActiveRecord::Migration
2
+ def change
3
+ create_table :op_cart_subscriptions do |t|
4
+ t.string :processor_token
5
+ t.string :status
6
+ t.integer :quantity
7
+ t.datetime :started_at
8
+ t.datetime :canceled_at
9
+ t.datetime :ended_at
10
+ t.datetime :trial_started_at
11
+ t.datetime :trial_ended_at
12
+ t.references :plan, index: true
13
+ t.references :order, index: true
14
+ t.references :customer, index: true
15
+
16
+ t.timestamps null: false
17
+ end
18
+ end
19
+ end
data/db/seeds.rb CHANGED
@@ -1,3 +1,13 @@
1
+ shipping_address1_attrs = {
2
+ full_name: User.first.name,
3
+ street: '123 N 4th',
4
+ locality: 'New York',
5
+ region: 'New York',
6
+ postal_code: '12345',
7
+ user: User.first,
8
+ }
9
+ shipping_address1 = OpCart::ShippingAddress.where(street: shipping_address1_attrs[:street]).first_or_create! shipping_address1_attrs
10
+
1
11
  product1_attrs = {
2
12
  name: 'Device 3000',
3
13
  description: 'The original Device 3000',
@@ -7,8 +17,7 @@ product1_attrs = {
7
17
  charge_taxes: true,
8
18
  user: User.first,
9
19
  }
10
-
11
- product1 = OpCart::Product.where(sku: product1_attrs[:sku]).first_or_create product1_attrs
20
+ product1 = OpCart::Product.where(sku: product1_attrs[:sku]).first_or_create! product1_attrs
12
21
 
13
22
  product2_attrs = {
14
23
  name: 'Device 9000',
@@ -19,8 +28,7 @@ product2_attrs = {
19
28
  charge_taxes: true,
20
29
  user: User.first,
21
30
  }
22
-
23
- product2 = OpCart::Product.where(sku: product2_attrs[:sku]).first_or_create product2_attrs
31
+ product2 = OpCart::Product.where(sku: product2_attrs[:sku]).first_or_create! product2_attrs
24
32
 
25
33
  rand_plan_no = rand 10**9
26
34
  plan1_attrs = {
@@ -35,8 +43,7 @@ plan1_attrs = {
35
43
  allow_purchases: true,
36
44
  user: User.first,
37
45
  }
38
-
39
- plan1 = OpCart::Plan.where(name: plan1_attrs[:name]).first_or_create plan1_attrs
46
+ plan1 = OpCart::Plan.where(name: plan1_attrs[:name]).first_or_create! plan1_attrs
40
47
 
41
48
  plan_addon1_attrs = {
42
49
  recurring: false,
@@ -44,5 +51,10 @@ plan_addon1_attrs = {
44
51
  plan: plan1,
45
52
  user: User.first,
46
53
  }
54
+ plan_addon1 = OpCart::PlanAddon.first_or_create! plan_addon1_attrs
47
55
 
48
- plan_addon1 = OpCart::PlanAddon.first_or_create plan_addon1_attrs
56
+ token1 = Stripe::Token.create card: { number: '4'+'1'*15, exp_month: 1, exp_year: 2031, cvc: 123 }
57
+ order1 = OpCart::Order.first || OpCart::Order.new(user: User.first, shipping_address: shipping_address1, processor_token: token1.id)
58
+ order1.line_items << OpCart::LineItem.new(sellable: plan1, quantity: 1)
59
+ order1.line_items << OpCart::LineItem.new(sellable: plan_addon1.product, quantity: 1)
60
+ order1.save!
@@ -1,3 +1,3 @@
1
1
  module OpCart
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -0,0 +1,59 @@
1
+  (22.3ms) CREATE TABLE "schema_migrations" ("version" character varying NOT NULL) 
2
+  (2.1ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
3
+ ActiveRecord::SchemaMigration Load (0.4ms) SELECT "schema_migrations".* FROM "schema_migrations"
4
+ Migrating to CreateOpCartProducts (20140829191646)
5
+  (0.3ms) BEGIN
6
+  (30.8ms) CREATE TABLE "op_cart_products" ("id" serial primary key, "name" character varying NOT NULL, "description" text NOT NULL, "sku" character varying, "image_url" character varying, "price" integer NOT NULL, "allow_purchases" boolean DEFAULT 'f', "charge_taxes" boolean DEFAULT 'f', "user_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL) 
7
+  (1.4ms) CREATE INDEX "index_op_cart_products_on_user_id" ON "op_cart_products" ("user_id")
8
+ SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20140829191646"]]
9
+  (7.3ms) COMMIT
10
+ Migrating to CreateOpCartOrders (20140829200318)
11
+  (10.9ms) BEGIN
12
+  (5.5ms) CREATE TABLE "op_cart_orders" ("id" serial primary key, "total" integer NOT NULL, "tax_amount" integer DEFAULT 0, "status" character varying NOT NULL, "processor_response" json NOT NULL, "shipping_address_id" integer NOT NULL, "user_id" integer NOT NULL, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
13
+  (1.5ms) CREATE INDEX "index_op_cart_orders_on_shipping_address_id" ON "op_cart_orders" ("shipping_address_id")
14
+  (1.4ms) CREATE INDEX "index_op_cart_orders_on_user_id" ON "op_cart_orders" ("user_id")
15
+ SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20140829200318"]]
16
+  (0.5ms) COMMIT
17
+ Migrating to CreateOpCartLineItems (20140829201756)
18
+  (0.3ms) BEGIN
19
+ SQL (26.9ms) CREATE EXTENSION IF NOT EXISTS "hstore"
20
+  (4.8ms) CREATE TABLE "op_cart_line_items" ("id" serial primary key, "unit_price" integer NOT NULL, "quantity" integer NOT NULL, "sellable_snapshot" hstore NOT NULL, "sellable_id" integer NOT NULL, "sellable_type" character varying NOT NULL, "order_id" integer NOT NULL, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL) 
21
+  (1.4ms) CREATE INDEX "index_op_cart_line_items_on_sellable_type_and_sellable_id" ON "op_cart_line_items" ("sellable_type", "sellable_id")
22
+  (1.1ms) CREATE INDEX "index_op_cart_line_items_on_order_id" ON "op_cart_line_items" ("order_id")
23
+ SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20140829201756"]]
24
+  (1.7ms) COMMIT
25
+ Migrating to CreateOpCartShippingAddresses (20150125000000)
26
+  (0.4ms) BEGIN
27
+  (4.2ms) CREATE TABLE "op_cart_shipping_addresses" ("id" serial primary key, "full_name" character varying NOT NULL, "street" character varying NOT NULL, "street_2" character varying, "locality" character varying NOT NULL, "region" character varying NOT NULL, "postal_code" character varying NOT NULL, "user_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL) 
28
+  (1.2ms) CREATE INDEX "index_op_cart_shipping_addresses_on_user_id" ON "op_cart_shipping_addresses" ("user_id")
29
+ SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20150125000000"]]
30
+  (0.4ms) COMMIT
31
+ Migrating to CreateOpCartCustomers (20150131000000)
32
+  (0.3ms) BEGIN
33
+  (5.3ms) CREATE TABLE "op_cart_customers" ("id" serial primary key, "processor_token" character varying, "delinquent" boolean DEFAULT 'f', "default_card_id" integer, "user_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
34
+  (0.8ms) CREATE INDEX "index_op_cart_customers_on_default_card_id" ON "op_cart_customers" ("default_card_id")
35
+  (1.1ms) CREATE INDEX "index_op_cart_customers_on_user_id" ON "op_cart_customers" ("user_id")
36
+ SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20150131000000"]]
37
+  (0.3ms) COMMIT
38
+ Migrating to CreateOpCartCards (20150131000001)
39
+  (0.3ms) BEGIN
40
+  (5.1ms) CREATE TABLE "op_cart_cards" ("id" serial primary key, "processor_token" character varying, "fingerprint" character varying, "last4" character varying, "brand" character varying, "exp_month" character varying, "exp_year" character varying, "customer_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
41
+  (1.0ms) CREATE INDEX "index_op_cart_cards_on_processor_token" ON "op_cart_cards" ("processor_token")
42
+  (1.2ms) CREATE INDEX "index_op_cart_cards_on_fingerprint" ON "op_cart_cards" ("fingerprint")
43
+  (1.5ms) CREATE INDEX "index_op_cart_cards_on_customer_id" ON "op_cart_cards" ("customer_id")
44
+ SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ($1) [["version", "20150131000001"]]
45
+  (0.5ms) COMMIT
46
+ Migrating to CreateOpCartPlans (20150201033629)
47
+  (0.4ms) BEGIN
48
+  (6.2ms) CREATE TABLE "op_cart_plans" ("id" serial primary key, "processor_token" character varying, "name" character varying NOT NULL, "description" character varying, "image_url" character varying, "price" integer, "interval_count" integer, "interval" character varying, "trial_period_days" integer, "allow_purchases" boolean DEFAULT 'f', "user_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL) 
49
+  (1.3ms) CREATE INDEX "index_op_cart_plans_on_user_id" ON "op_cart_plans" ("user_id")
50
+  (7.5ms) ALTER TABLE "op_cart_plans" ADD CONSTRAINT "fk_rails_f7712cb323"
51
+ FOREIGN KEY ("user_id")
52
+ REFERENCES "users" ("id")
53
+ 
54
+ PG::UndefinedTable: ERROR: relation "users" does not exist
55
+ : ALTER TABLE "op_cart_plans" ADD CONSTRAINT "fk_rails_f7712cb323"
56
+ FOREIGN KEY ("user_id")
57
+ REFERENCES "users" ("id")
58
+
59
+  (0.2ms) ROLLBACK
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.0
4
+ version: 0.4.1
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-02-04 00:00:00.000000000 Z
11
+ date: 2015-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -87,6 +87,7 @@ files:
87
87
  - app/models/op_cart/plan_addon.rb
88
88
  - app/models/op_cart/product.rb
89
89
  - app/models/op_cart/shipping_address.rb
90
+ - app/models/op_cart/subscription.rb
90
91
  - config/initializers/stripe.rb
91
92
  - config/locales/op_cart.en.yml
92
93
  - config/routes.rb
@@ -98,6 +99,7 @@ files:
98
99
  - db/migrate/20150131000001_create_op_cart_cards.rb
99
100
  - db/migrate/20150201033629_create_op_cart_plans.rb
100
101
  - db/migrate/20150203043805_create_op_cart_plan_addons.rb
102
+ - db/migrate/20150205220423_create_op_cart_subscriptions.rb
101
103
  - db/seeds.rb
102
104
  - lib/op_cart.rb
103
105
  - lib/op_cart/engine.rb
@@ -133,6 +135,7 @@ files:
133
135
  - test/dummy/config/locales/en.yml
134
136
  - test/dummy/config/routes.rb
135
137
  - test/dummy/config/secrets.yml
138
+ - test/dummy/log/development.log
136
139
  - test/dummy/log/test.log
137
140
  - test/dummy/public/404.html
138
141
  - test/dummy/public/422.html
@@ -199,6 +202,7 @@ test_files:
199
202
  - test/dummy/config/routes.rb
200
203
  - test/dummy/config/secrets.yml
201
204
  - test/dummy/config.ru
205
+ - test/dummy/log/development.log
202
206
  - test/dummy/log/test.log
203
207
  - test/dummy/public/404.html
204
208
  - test/dummy/public/422.html