mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-29 18:52:22 +01:00
WIP: create subscription on stripe
This commit is contained in:
parent
45800034c0
commit
78847bdb4b
@ -20,7 +20,9 @@ class API::SubscriptionsController < API::ApiController
|
|||||||
|
|
||||||
@subscription = Subscription.new(subscription_params)
|
@subscription = Subscription.new(subscription_params)
|
||||||
is_subscribe = Subscriptions::Subscribe.new(current_user.invoicing_profile.id, user_id)
|
is_subscribe = Subscriptions::Subscribe.new(current_user.invoicing_profile.id, user_id)
|
||||||
.pay_and_save(@subscription, coupon: coupon_params[:coupon_code], invoice: true)
|
.pay_and_save(@subscription, coupon: coupon_params[:coupon_code],
|
||||||
|
invoice: true,
|
||||||
|
schedule: params[:subcription][:payment_schedule])
|
||||||
|
|
||||||
if is_subscribe
|
if is_subscribe
|
||||||
render :show, status: :created, location: @subscription
|
render :show, status: :created, location: @subscription
|
||||||
|
@ -8,4 +8,10 @@ class PaymentSchedule < ApplicationRecord
|
|||||||
belongs_to :coupon
|
belongs_to :coupon
|
||||||
belongs_to :invoicing_profile
|
belongs_to :invoicing_profile
|
||||||
belongs_to :operator_profile, foreign_key: :operator_profile_id, class_name: 'InvoicingProfile'
|
belongs_to :operator_profile, foreign_key: :operator_profile_id, class_name: 'InvoicingProfile'
|
||||||
|
|
||||||
|
after_create :create_stripe_subscription
|
||||||
|
|
||||||
|
def create_stripe_subscription
|
||||||
|
StripeWorker.perform_async(:create_stripe_subscription, id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -20,7 +20,7 @@ class Subscription < ApplicationRecord
|
|||||||
|
|
||||||
# @param invoice if true then only the subscription is payed, without reservation
|
# @param invoice if true then only the subscription is payed, without reservation
|
||||||
# if false then the subscription is payed with reservation
|
# if false then the subscription is payed with reservation
|
||||||
def save_with_payment(operator_profile_id, invoice = true, coupon_code = nil, payment_intent_id = nil)
|
def save_with_payment(operator_profile_id, invoice = true, coupon_code = nil, payment_intent_id = nil, schedule = nil)
|
||||||
return false unless valid?
|
return false unless valid?
|
||||||
|
|
||||||
set_expiration_date
|
set_expiration_date
|
||||||
@ -33,16 +33,30 @@ class Subscription < ApplicationRecord
|
|||||||
# debit wallet
|
# debit wallet
|
||||||
wallet_transaction = debit_user_wallet
|
wallet_transaction = debit_user_wallet
|
||||||
|
|
||||||
invoc = generate_invoice(operator_profile_id, coupon_code, payment_intent_id)
|
payment = if schedule
|
||||||
|
generate_schedule(operator_profile_id, coupon_code, payment_intent_id)
|
||||||
|
else
|
||||||
|
generate_invoice(operator_profile_id, coupon_code, payment_intent_id)
|
||||||
|
end
|
||||||
|
|
||||||
if wallet_transaction
|
if wallet_transaction
|
||||||
invoc.wallet_amount = @wallet_amount_debit
|
payment.wallet_amount = @wallet_amount_debit
|
||||||
invoc.wallet_transaction_id = wallet_transaction.id
|
payment.wallet_transaction_id = wallet_transaction.id
|
||||||
end
|
end
|
||||||
invoc.save
|
payment.save
|
||||||
end
|
end
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate_schedule(operator_profile_id, coupon_code = nil, payment_intent_id = nil)
|
||||||
|
operator = InvoicingProfile.find(operator_profile_id)&.user
|
||||||
|
method = operator&.admin? || (operator&.manager? && operator != user) ? nil : 'stripe'
|
||||||
|
coupon = Coupon.find_by(code: coupon_code) unless coupon_code.nil?
|
||||||
|
|
||||||
|
schedule = PaymentScheduleService.new.create(self, plan.amount, coupon, operator, method)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
def generate_invoice(operator_profile_id, coupon_code = nil, payment_intent_id = nil)
|
def generate_invoice(operator_profile_id, coupon_code = nil, payment_intent_id = nil)
|
||||||
coupon_id = nil
|
coupon_id = nil
|
||||||
total = plan.amount
|
total = plan.amount
|
||||||
|
@ -199,8 +199,8 @@ class PDF::Invoice < Prawn::Document
|
|||||||
elsif cp.type == 'amount_off'
|
elsif cp.type == 'amount_off'
|
||||||
# refunds of invoices with cash coupons: we need to ventilate coupons on paid items
|
# refunds of invoices with cash coupons: we need to ventilate coupons on paid items
|
||||||
if invoice.is_a?(Avoir)
|
if invoice.is_a?(Avoir)
|
||||||
paid_items = invoice.invoice.invoice_items.select{ |ii| ii.amount.positive? }.length
|
paid_items = invoice.invoice.invoice_items.select { |ii| ii.amount.positive? }.length
|
||||||
refund_items = invoice.invoice_items.select{ |ii| ii.amount.positive? }.length
|
refund_items = invoice.invoice_items.select { |ii| ii.amount.positive? }.length
|
||||||
|
|
||||||
discount = ((invoice.coupon.amount_off / paid_items) * refund_items) / 100.00
|
discount = ((invoice.coupon.amount_off / paid_items) * refund_items) / 100.00
|
||||||
else
|
else
|
||||||
|
@ -41,4 +41,17 @@ class PaymentScheduleService
|
|||||||
end
|
end
|
||||||
{ payment_schedule: ps, items: items }
|
{ payment_schedule: ps, items: items }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create(subscription, total, coupon, operator, payment_method)
|
||||||
|
schedule = compute(subscription.plan, total, coupon)
|
||||||
|
ps = schedule[:payment_schedule]
|
||||||
|
items = schedule[:items]
|
||||||
|
|
||||||
|
ps.scheduled = subscription
|
||||||
|
ps.payment_method = payment_method
|
||||||
|
ps.operator_profile_id = operator
|
||||||
|
items.each do |item|
|
||||||
|
item.payment_schedule = ps
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -9,11 +9,11 @@ class Subscriptions::Subscribe
|
|||||||
@operator_profile_id = operator_profile_id
|
@operator_profile_id = operator_profile_id
|
||||||
end
|
end
|
||||||
|
|
||||||
def pay_and_save(subscription, coupon: nil, invoice: nil, payment_intent_id: nil)
|
def pay_and_save(subscription, coupon: nil, invoice: nil, payment_intent_id: nil, schedule: nil)
|
||||||
return false if user_id.nil?
|
return false if user_id.nil?
|
||||||
|
|
||||||
subscription.statistic_profile_id = StatisticProfile.find_by(user_id: user_id).id
|
subscription.statistic_profile_id = StatisticProfile.find_by(user_id: user_id).id
|
||||||
subscription.save_with_payment(operator_profile_id, invoice, coupon, payment_intent_id)
|
subscription.save_with_payment(operator_profile_id, invoice, coupon, payment_intent_id, schedule)
|
||||||
end
|
end
|
||||||
|
|
||||||
def extend_subscription(subscription, new_expiration_date, free_days)
|
def extend_subscription(subscription, new_expiration_date, free_days)
|
||||||
|
@ -73,4 +73,32 @@ class StripeWorker
|
|||||||
)
|
)
|
||||||
plan.update_columns(stp_price_id: price.id)
|
plan.update_columns(stp_price_id: price.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_stripe_subscription(payment_schedule_id, first_invoice_items)
|
||||||
|
payment_schedule = PaymentSchedule.find(payment_schedule_id)
|
||||||
|
|
||||||
|
items = []
|
||||||
|
first_invoice_items.each do |fii|
|
||||||
|
# TODO, fill this prices with real data
|
||||||
|
price = Stripe::Price.create({
|
||||||
|
unit_amount: 2000,
|
||||||
|
currency: 'eur',
|
||||||
|
recurring: { interval: 'month' },
|
||||||
|
product_data: {
|
||||||
|
name: 'lorem ipsum'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ api_key: Setting.get('stripe_secret_key') })
|
||||||
|
items.push(price: price[:id])
|
||||||
|
end
|
||||||
|
Stripe::Subscription.create({
|
||||||
|
customer: payment_schedule.invoicing_profile.user.stp_customer_id,
|
||||||
|
cancel_at: payment_schedule.scheduled.expiration_date,
|
||||||
|
promotion_code: payment_schedule.coupon&.code,
|
||||||
|
add_invoice_items: items,
|
||||||
|
items: [
|
||||||
|
{ price: payment_schedule.scheduled.plan.stp_price_id }
|
||||||
|
]
|
||||||
|
}, { api_key: Setting.get('stripe_secret_key') })
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -16,7 +16,7 @@ class CreatePaymentSchedules < ActiveRecord::Migration[5.2]
|
|||||||
t.string :footprint
|
t.string :footprint
|
||||||
t.string :environment
|
t.string :environment
|
||||||
t.belongs_to :invoicing_profile, foreign_key: true
|
t.belongs_to :invoicing_profile, foreign_key: true
|
||||||
t.references :operator_profile_id, foreign_key: { to_table: 'invoicing_profiles' }
|
t.references :operator_profile, foreign_key: { to_table: 'invoicing_profiles' }
|
||||||
|
|
||||||
t.timestamps
|
t.timestamps
|
||||||
end
|
end
|
||||||
|
@ -1513,7 +1513,7 @@ CREATE TABLE public.payment_schedules (
|
|||||||
footprint character varying,
|
footprint character varying,
|
||||||
environment character varying,
|
environment character varying,
|
||||||
invoicing_profile_id bigint,
|
invoicing_profile_id bigint,
|
||||||
operator_profile_id_id bigint,
|
operator_profile_id bigint,
|
||||||
created_at timestamp without time zone NOT NULL,
|
created_at timestamp without time zone NOT NULL,
|
||||||
updated_at timestamp without time zone NOT NULL
|
updated_at timestamp without time zone NOT NULL
|
||||||
);
|
);
|
||||||
@ -4554,10 +4554,10 @@ CREATE INDEX index_payment_schedules_on_invoicing_profile_id ON public.payment_s
|
|||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: index_payment_schedules_on_operator_profile_id_id; Type: INDEX; Schema: public; Owner: -
|
-- Name: index_payment_schedules_on_operator_profile_id; Type: INDEX; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE INDEX index_payment_schedules_on_operator_profile_id_id ON public.payment_schedules USING btree (operator_profile_id_id);
|
CREATE INDEX index_payment_schedules_on_operator_profile_id ON public.payment_schedules USING btree (operator_profile_id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -5378,6 +5378,14 @@ ALTER TABLE ONLY public.projects_machines
|
|||||||
ADD CONSTRAINT fk_rails_88b280c24c FOREIGN KEY (machine_id) REFERENCES public.machines(id);
|
ADD CONSTRAINT fk_rails_88b280c24c FOREIGN KEY (machine_id) REFERENCES public.machines(id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: payment_schedules fk_rails_8b73dd8d7d; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.payment_schedules
|
||||||
|
ADD CONSTRAINT fk_rails_8b73dd8d7d FOREIGN KEY (operator_profile_id) REFERENCES public.invoicing_profiles(id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: availability_tags fk_rails_8cb4e921f7; Type: FK CONSTRAINT; Schema: public; Owner: -
|
-- Name: availability_tags fk_rails_8cb4e921f7; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@ -5442,14 +5450,6 @@ ALTER TABLE ONLY public.projects_themes
|
|||||||
ADD CONSTRAINT fk_rails_b021a22658 FOREIGN KEY (theme_id) REFERENCES public.themes(id);
|
ADD CONSTRAINT fk_rails_b021a22658 FOREIGN KEY (theme_id) REFERENCES public.themes(id);
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Name: payment_schedules fk_rails_b38f5b39f6; Type: FK CONSTRAINT; Schema: public; Owner: -
|
|
||||||
--
|
|
||||||
|
|
||||||
ALTER TABLE ONLY public.payment_schedules
|
|
||||||
ADD CONSTRAINT fk_rails_b38f5b39f6 FOREIGN KEY (operator_profile_id_id) REFERENCES public.invoicing_profiles(id);
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: statistic_profiles fk_rails_bba64e5eb9; Type: FK CONSTRAINT; Schema: public; Owner: -
|
-- Name: statistic_profiles fk_rails_bba64e5eb9; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
Loading…
x
Reference in New Issue
Block a user