tang 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: afcc7d64662d251041c9106406151ef1c0eb633c4f52648aad4bf065e73d5715
4
- data.tar.gz: 70a3bb4255182c594a89773546518ae1972af6dbd9efe4a48a0e04cd0048568a
3
+ metadata.gz: 3b6a2435aa2257528ac4196b8e9edefe6dc12c928c62d8030890a912d2b31aff
4
+ data.tar.gz: 96ed85b8c852c51acf3c0f36d0c0e88148339c91bdb3393d7828beb44350a39a
5
5
  SHA512:
6
- metadata.gz: 729756368750f8bd9bddc7db310caa1bb0b64d93ad604b9d8718361bf68be13c58cfacc269d225308a35130c50d5ece613e3fb286f855bf10b54afeb8122579a
7
- data.tar.gz: 6efa4353dfa69a47657ed8573b026907922d8dadb37f04efd8af5fd892dc4ec8cd65c789ccba00a67f2a1cdac8b87459f52909e1077ce77eb712e8bb7f16942c
6
+ metadata.gz: adf596987d7840506a8557ad4f031ef3ee2d76dd898f37203120c0999a8569d8e4518d123261667e94e01e1d7fb50ccc6574d5626be5e609a88ebdbb7df4f929
7
+ data.tar.gz: 8fe17103f00686bc4a790d6083a9cb64794ab3b29201e232b5f85472b27edfd711500e2021f144c854e51ff1f601daec7ae44638931a845181c8415fe39b4822
@@ -5,7 +5,7 @@ module Tang
5
5
  def index
6
6
  @invoices = current_customer.invoices.
7
7
  paginate(page: params[:page]).
8
- order(period_start: :desc)
8
+ order(date: :desc)
9
9
  end
10
10
  end
11
11
  end
@@ -19,11 +19,8 @@ module Tang
19
19
  end
20
20
 
21
21
  def import_subscription(stripe_subscription)
22
- customer = Tang.customer_class.find_by(stripe_id: stripe_subscription.customer)
23
- plan = Plan.find_by(stripe_id: stripe_subscription.plan.id)
24
- if customer.present? && plan.present?
25
- subscription = Subscription.from_stripe(stripe_subscription, customer, plan)
26
-
22
+ subscription = Subscription.from_stripe(stripe_subscription)
23
+ if subscription.present?
27
24
  # Handle removed discounts
28
25
  subscription.update(coupon: nil, coupon_start: nil) if stripe_subscription.discount.nil?
29
26
  end
@@ -64,9 +64,8 @@ module Tang
64
64
  my_card.update_from_stripe(stripe_card)
65
65
  end
66
66
 
67
- def update_subscription_end(stripe_sub)
68
- timestamp = stripe_sub.current_period_end.to_s
69
- self.active_until = DateTime.strptime(timestamp, '%s')
67
+ def update_subscription_end(subscription)
68
+ self.active_until = subscription.period_end
70
69
  self.save!
71
70
  end
72
71
 
@@ -76,7 +76,7 @@ module Tang
76
76
  c.duration = stripe_coupon.duration
77
77
  c.duration_in_months = stripe_coupon.duration_in_months
78
78
  c.max_redemptions = stripe_coupon.max_redemptions
79
- c.redeem_by = stripe_coupon.redeem_by
79
+ c.redeem_by = DateTime.strptime(stripe_coupon.redeem_by.to_s, '%s') if stripe_coupon.redeem_by.present?
80
80
  end
81
81
 
82
82
  return coupon
@@ -19,6 +19,10 @@ module Tang
19
19
  self[:period_start] || created_at
20
20
  end
21
21
 
22
+ def period_start=(val)
23
+ self[:period_start] = val
24
+ end
25
+
22
26
  def period_end
23
27
  if subscription.present?
24
28
  self[:period_end] || subscription.plan.period_days_from(period_start)
@@ -27,6 +31,10 @@ module Tang
27
31
  end
28
32
  end
29
33
 
34
+ def period_end=(val)
35
+ self[:period_end] = val
36
+ end
37
+
30
38
  def status
31
39
  if charge.present?
32
40
  'paid'
@@ -41,9 +49,9 @@ module Tang
41
49
  invoice = Invoice.find_or_create_by(stripe_id: stripe_invoice.id) do |i|
42
50
  i.subscription = subscription
43
51
  i.customer = customer
44
- i.period_start = stripe_invoice.period_start
45
- i.period_end = stripe_invoice.period_end
46
- i.date = stripe_invoice.created # changed from date
52
+ i.period_start = DateTime.strptime(stripe_invoice.period_start.to_s, '%s')
53
+ i.period_end = DateTime.strptime(stripe_invoice.period_end.to_s, '%s')
54
+ i.date = DateTime.strptime(stripe_invoice.created.to_s, '%s') # changed from date
47
55
  i.currency = stripe_invoice.currency
48
56
  i.subtotal = stripe_invoice.subtotal
49
57
  # i.tax_percent = stripe_invoice.tax_percent # removed from api, replaced with tax rates
@@ -57,11 +65,44 @@ module Tang
57
65
  coupon = Coupon.find_by(stripe_id: stripe_invoice.discount.coupon.id)
58
66
  i.coupon = coupon
59
67
  end
60
-
61
68
  end
69
+
70
+ if invoice.update_from_stripe(stripe_invoice)
71
+ invoice.save
72
+ end
73
+
62
74
  return invoice
63
75
  end
64
76
 
77
+ def update_from_stripe(stripe_invoice)
78
+ changed = false
79
+
80
+ stripe_period_start = DateTime.strptime(stripe_invoice.period_start.to_s, '%s')
81
+ if self[:period_start] != stripe_period_start
82
+ self.period_start = stripe_period_start
83
+ changed = true
84
+ end
85
+
86
+ stripe_period_end = DateTime.strptime(stripe_invoice.period_end.to_s, '%s')
87
+ if self[:period_end] != stripe_period_end
88
+ self.period_end = stripe_period_end
89
+ changed = true
90
+ end
91
+
92
+ stripe_created = DateTime.strptime(stripe_invoice.created.to_s, '%s')
93
+ if self.date != stripe_created
94
+ self.date = stripe_created
95
+ changed = true
96
+ end
97
+
98
+ if self.invoice_pdf != stripe_invoice.invoice_pdf
99
+ self.invoice_pdf = stripe_invoice.invoice_pdf
100
+ changed = true
101
+ end
102
+
103
+ return changed
104
+ end
105
+
65
106
  def self.search(query)
66
107
  invoices = Invoice.none
67
108
  if query.present?
@@ -27,10 +27,8 @@ module Tang
27
27
  ii.amount = stripe_invoice_item.amount
28
28
  ii.currency = stripe_invoice_item.currency
29
29
 
30
- period_start = stripe_invoice_item.period.start.to_s
31
- ii.period_start = DateTime.strptime(period_start, '%s')
32
- period_end = stripe_invoice_item.period.end.to_s
33
- ii.period_end = DateTime.strptime(period_end, '%s')
30
+ ii.period_start = DateTime.strptime(stripe_invoice_item.period.start.to_s, '%s')
31
+ ii.period_end = DateTime.strptime(stripe_invoice_item.period.end.to_s, '%s')
34
32
 
35
33
  ii.plan = plan
36
34
  ii.proration = stripe_invoice_item.proration
@@ -48,14 +48,25 @@ module Tang
48
48
 
49
49
  STATUSES = ['trialing', 'active', 'past_due', 'canceled', 'unpaid']
50
50
 
51
- def self.from_stripe(stripe_subscription, customer, plan)
51
+ def self.from_stripe(stripe_subscription)
52
+ customer = Tang.customer_class.find_by(stripe_id: stripe_subscription.customer)
53
+ plan = Plan.find_by(stripe_id: stripe_subscription.plan.id)
54
+ if customer.present? && plan.present?
55
+ subscription = Subscription.build(stripe_subscription, customer, plan)
56
+ subscription.update(coupon: nil, coupon_start: nil) if stripe_subscription.discount.nil?
57
+ return subscription
58
+ end
59
+ return nil
60
+ end
61
+
62
+ def self.build(stripe_subscription, customer, plan)
52
63
  subscription = Subscription.find_or_create_by(stripe_id: stripe_subscription.id) do |s|
53
64
  s.customer = customer
54
65
  s.plan = plan
55
66
  s.application_fee_percent = stripe_subscription.application_fee_percent
56
67
  s.quantity = stripe_subscription.quantity
57
68
  # s.tax_percent = stripe_subscription.tax_percent # removed from api in favor of tax rates
58
- s.trial_end = stripe_subscription.trial_end
69
+ s.trial_end = DateTime.strptime(stripe_subscription.trial_end.to_s, '%s') if stripe_subscription.trial_end.present?
59
70
  s.coupon = Coupon.find_by(stripe_id: stripe_subscription.discount.coupon.id) if stripe_subscription.discount.present?
60
71
  s.status = stripe_subscription.status
61
72
  end
@@ -63,18 +74,19 @@ module Tang
63
74
  end
64
75
 
65
76
  def period_start
66
- invoice = invoices.last
77
+ invoice = invoices.order(:date).last
67
78
  if invoice.present?
68
- return invoice.period_start
79
+ # return invoice.period_start
80
+ return invoice.date
69
81
  end
70
82
  return created_at
71
83
  end
72
84
 
73
85
  def period_end
74
- invoice = invoices.last
75
- if invoice.present?
76
- return invoice.period_end
77
- end
86
+ # invoice = invoices.order(:period_start).last
87
+ # if invoice.present?
88
+ # return invoice.period_end
89
+ # end
78
90
  return plan.period_days_from(period_start)
79
91
  end
80
92
 
@@ -37,7 +37,7 @@ module Tang
37
37
  )
38
38
 
39
39
  # Finalize customer with subscription and payment method
40
- finalize_customer(customer, stripe_sub, stripe_card)
40
+ finalize_customer(customer, subscription, stripe_card)
41
41
 
42
42
  rescue Stripe::StripeError => e
43
43
  subscription.errors[:base] << e.message
@@ -87,11 +87,11 @@ module Tang
87
87
  return stripe_sub
88
88
  end
89
89
 
90
- def self.finalize_customer(customer, stripe_sub, stripe_card)
90
+ def self.finalize_customer(customer, subscription, stripe_card)
91
91
  # Remove temporary coupon
92
92
  customer.subscription_coupon = nil
93
93
  # Save subscription data to customer
94
- customer.update_subscription_end(stripe_sub)
94
+ customer.update_subscription_end(subscription)
95
95
  # Save the payment method
96
96
  customer.update_card_from_stripe(stripe_card)
97
97
  end
@@ -13,6 +13,11 @@ module Tang
13
13
 
14
14
  # update subscription
15
15
  subscription = Subscription.find_by(stripe_id: stripe_invoice.subscription)
16
+ if subscription.nil?
17
+ stripe_subscription = Stripe::Subscription.retrieve(stripe_invoice.subscription)
18
+ subscription = Subscription.from_stripe(stripe_subscription)
19
+ invoice.update(subscription: subscription)
20
+ end
16
21
  if subscription.present?
17
22
  subscription.fail! if !subscription.past_due?
18
23
  end
@@ -1,7 +1,15 @@
1
1
  module Tang
2
2
  class PayInvoice
3
3
  def self.call(stripe_invoice)
4
- # invoice = Invoice.find_by(stripe_id: stripe_invoice.id)
4
+
5
+ # ensure the subscription exists
6
+ stripe_subscription = Stripe::Subscription.retrieve(stripe_invoice.subscription)
7
+ subscription = Subscription.find_by(stripe_id: stripe_invoice.subscription)
8
+ if subscription.nil?
9
+ subscription = Subscription.from_stripe(stripe_subscription)
10
+ end
11
+
12
+ # create the invoice
5
13
  invoice = Invoice.from_stripe(stripe_invoice)
6
14
 
7
15
  # create charge
@@ -11,21 +19,15 @@ module Tang
11
19
  charge = Charge.from_stripe(stripe_charge, invoice)
12
20
  end
13
21
 
14
- # update subscription
15
- stripe_subscription = Stripe::Subscription.retrieve(stripe_invoice.subscription)
16
- subscription = Subscription.find_by(stripe_id: stripe_invoice.subscription)
17
-
18
- if subscription.present?
19
- # update discount
20
- if stripe_subscription.discount.nil?
21
- subscription.update(coupon: nil, coupon_start: nil)
22
- end
23
-
24
- # update customer active until
25
- customer = subscription.customer
26
- customer.update_subscription_end(stripe_subscription)
22
+ # update discount
23
+ if stripe_subscription.discount.nil?
24
+ subscription.update(coupon: nil, coupon_start: nil)
27
25
  end
28
26
 
27
+ # update customer active until
28
+ customer = subscription.customer
29
+ customer.update_subscription_end(subscription)
30
+
29
31
  return charge
30
32
  end
31
33
  end
@@ -3,5 +3,5 @@
3
3
  <%= link_to 'Download PDF', invoice.invoice_pdf, class: 'btn btn-secondary', target: '_blank' %>
4
4
  </div>
5
5
  <h5 class="list-group-item-heading"><%= number_to_currency(invoice.total.to_f / 100.0) %></h5>
6
- <p class="list-group-item-text">Date <%= invoice.period_start.strftime('%b %d, %Y') %></p>
6
+ <p class="list-group-item-text">Date <%= invoice.date.strftime('%b %d, %Y') %></p>
7
7
  </li>
@@ -22,7 +22,7 @@
22
22
  <% end %>
23
23
  </td>
24
24
  <td><%= payment.stripe_id %></td>
25
- <td><%= payment.invoice.customer.email if payment.invoice.present? %></td>
25
+ <td><%= payment.invoice.customer.email if payment.invoice.present? && payment.invoice.customer.present? %></td>
26
26
  <td><%= payment.created.strftime('%Y/%m/%d %H:%M:%S') %></td>
27
27
  </tr>
28
28
  <% end %>
@@ -43,7 +43,7 @@
43
43
  <tbody>
44
44
  <% @plan.subscriptions.where(status: [:trialing, :active, :past_due]).each do |subscription| %>
45
45
  <tr>
46
- <td><%= link_to subscription.customer.email, tang.admin_subscription_path(subscription) %></td>
46
+ <td><%= link_to subscription.customer.email, tang.admin_subscription_path(subscription) if subscription.customer.present? %></td>
47
47
  <td><%= subscription.status %></td>
48
48
  </tr>
49
49
  <% end %>
@@ -15,7 +15,7 @@
15
15
  <tbody>
16
16
  <% @subscriptions.each do |subscription| %>
17
17
  <tr>
18
- <td><%= link_to subscription.customer.email, tang.admin_subscription_path(subscription) %></td>
18
+ <td><%= link_to subscription.customer.email, tang.admin_subscription_path(subscription) if subscription.customer.present? %></td>
19
19
  <td><%= subscription.status %></td>
20
20
  <td>
21
21
  <%= subscription.plan.name %>
@@ -3,6 +3,6 @@ rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
3
3
  rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
4
4
  std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags 'not @wip'"
5
5
  %>
6
- default: <%= std_opts %> features
6
+ default: <%= std_opts %> --publish-quiet features
7
7
  wip: --tags @wip:3 --wip features
8
8
  rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags "not @wip"
@@ -1,3 +1,3 @@
1
1
  module Tang
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -3,7 +3,9 @@
3
3
  "livemode": false,
4
4
  "id": "evt_00000000000000",
5
5
  "type": "invoice.created",
6
+ "status": "paid",
6
7
  "object": "event",
8
+ "api_version": "2020-08-27",
7
9
  "data": {
8
10
  "object": {
9
11
  "created": 1380674206,
@@ -30,7 +32,6 @@
30
32
  "quantity": 1,
31
33
  "plan": {
32
34
  "interval": "month",
33
- "name": "Member's Club",
34
35
  "amount": 100,
35
36
  "currency": "usd",
36
37
  "id": "fkx0AFo",
@@ -38,11 +39,11 @@
38
39
  "livemode": false,
39
40
  "interval_count": 1,
40
41
  "trial_period_days": null,
42
+ "product": "pr_00000000000000",
41
43
  "metadata": {}
42
44
  },
43
45
  "description": null,
44
- "metadata": null,
45
- "subscription": "su_00000000000000"
46
+ "metadata": null
46
47
  }
47
48
  ]
48
49
  },
@@ -66,8 +67,8 @@
66
67
  "subscription": "sub_00000000000000",
67
68
  "metadata": {},
68
69
  "description": null,
69
- "tax": 0,
70
- "invoice_pdf": "pdf_url"
70
+ "invoice_pdf": "https://pay.stripe.com/invoice/acct_00000000000000/invst_00000000000000/pdf",
71
+ "tax": null
71
72
  }
72
73
  }
73
74
  }
@@ -0,0 +1,114 @@
1
+ {
2
+ "created": 1326853478,
3
+ "livemode": false,
4
+ "id": "evt_00000000000000",
5
+ "type": "invoice.payment_succeeded",
6
+ "object": "event",
7
+ "api_version": "2020-08-27",
8
+ "data": {
9
+ "object": {
10
+ "id": "in_00000000000000",
11
+ "object": "invoice",
12
+ "amount_due": 999,
13
+ "application_fee": null,
14
+ "attempt_count": 1,
15
+ "attempted": true,
16
+ "charge": "ch_18EcOcLrgDIZ7iq8TaNlErVv",
17
+ "closed": true,
18
+ "currency": "eur",
19
+ "customer": "cus_00000000000000",
20
+ "created": 1464084258,
21
+ "description": null,
22
+ "discount": null,
23
+ "ending_balance": 0,
24
+ "forgiven": false,
25
+ "lines": {
26
+ "data": [{
27
+ "id": "sub_00000000000000",
28
+ "object": "line_item",
29
+ "amount": 50,
30
+ "currency": "eur",
31
+ "description": null,
32
+ "discountable": true,
33
+ "livemode": true,
34
+ "metadata": {},
35
+ "period": {
36
+ "start": 1500637196,
37
+ "end": 1532173196
38
+ },
39
+ "plan": {
40
+ "id": "platinum",
41
+ "object": "plan",
42
+ "amount": 500,
43
+ "created": 1499943145,
44
+ "currency": "eur",
45
+ "interval": "month",
46
+ "interval_count": 1,
47
+ "livemode": false,
48
+ "metadata": {},
49
+ "name": "New Plan Test",
50
+ "statement_descriptor": null,
51
+ "trial_period_days": null
52
+ },
53
+ "proration": false,
54
+ "quantity": 1,
55
+ "subscription": null,
56
+ "subscription_item": "si_18ZfWyLrgDIZ7iq8fSlSNGIV",
57
+ "type": "subscription"
58
+ },
59
+ {
60
+ "id": "sub_00000000000000",
61
+ "object": "line_item",
62
+ "amount": 50,
63
+ "currency": "eur",
64
+ "description": null,
65
+ "discountable": true,
66
+ "livemode": true,
67
+ "metadata": {},
68
+ "period": {
69
+ "start": 1500637196,
70
+ "end": 1532173196
71
+ },
72
+ "plan": {
73
+ "id": "gold",
74
+ "object": "plan",
75
+ "amount": 300,
76
+ "created": 1499943155,
77
+ "currency": "eur",
78
+ "interval": "month",
79
+ "interval_count": 1,
80
+ "livemode": false,
81
+ "metadata": {},
82
+ "name": "New gold Plan Test",
83
+ "statement_descriptor": null,
84
+ "trial_period_days": null
85
+ },
86
+ "proration": false,
87
+ "quantity": 1,
88
+ "subscription": null,
89
+ "subscription_item": "si_18ZfWyLrgDIZ7iq8fSlSNGIV",
90
+ "type": "subscription"
91
+ }],
92
+ "total_count": 1,
93
+ "object": "list",
94
+ "url": "/v1/invoices/in_18EcOcLrgDIZ7iq8zsDkunZ0/lines"
95
+ },
96
+ "livemode": false,
97
+ "metadata": {},
98
+ "next_payment_attempt": null,
99
+ "paid": true,
100
+ "period_end": 1464084258,
101
+ "period_start": 1464084258,
102
+ "receipt_number": null,
103
+ "starting_balance": 0,
104
+ "statement_descriptor": null,
105
+ "subscription": "sub_00000000000000",
106
+ "subtotal": 999,
107
+ "tax": null,
108
+ "tax_percent": null,
109
+ "total": 999,
110
+ "webhooks_delivered_at": 1464084258,
111
+ "invoice_pdf": "https://pay.stripe.com/invoice/acct_00000000000000/invst_00000000000000/pdf"
112
+ }
113
+ }
114
+ }