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)
|
||||
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
|
||||
render :show, status: :created, location: @subscription
|
||||
|
@ -8,4 +8,10 @@ class PaymentSchedule < ApplicationRecord
|
||||
belongs_to :coupon
|
||||
belongs_to :invoicing_profile
|
||||
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
|
||||
|
@ -20,7 +20,7 @@ class Subscription < ApplicationRecord
|
||||
|
||||
# @param invoice if true then only the subscription is payed, without 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?
|
||||
|
||||
set_expiration_date
|
||||
@ -33,16 +33,30 @@ class Subscription < ApplicationRecord
|
||||
# debit 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
|
||||
invoc.wallet_amount = @wallet_amount_debit
|
||||
invoc.wallet_transaction_id = wallet_transaction.id
|
||||
payment.wallet_amount = @wallet_amount_debit
|
||||
payment.wallet_transaction_id = wallet_transaction.id
|
||||
end
|
||||
invoc.save
|
||||
payment.save
|
||||
end
|
||||
true
|
||||
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)
|
||||
coupon_id = nil
|
||||
total = plan.amount
|
||||
|
@ -199,8 +199,8 @@ class PDF::Invoice < Prawn::Document
|
||||
elsif cp.type == 'amount_off'
|
||||
# refunds of invoices with cash coupons: we need to ventilate coupons on paid items
|
||||
if invoice.is_a?(Avoir)
|
||||
paid_items = invoice.invoice.invoice_items.select{ |ii| ii.amount.positive? }.length
|
||||
refund_items = 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
|
||||
|
||||
discount = ((invoice.coupon.amount_off / paid_items) * refund_items) / 100.00
|
||||
else
|
||||
|
@ -41,4 +41,17 @@ class PaymentScheduleService
|
||||
end
|
||||
{ payment_schedule: ps, items: items }
|
||||
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
|
||||
|
@ -9,11 +9,11 @@ class Subscriptions::Subscribe
|
||||
@operator_profile_id = operator_profile_id
|
||||
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?
|
||||
|
||||
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
|
||||
|
||||
def extend_subscription(subscription, new_expiration_date, free_days)
|
||||
|
@ -73,4 +73,32 @@ class StripeWorker
|
||||
)
|
||||
plan.update_columns(stp_price_id: price.id)
|
||||
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
|
||||
|
@ -16,7 +16,7 @@ class CreatePaymentSchedules < ActiveRecord::Migration[5.2]
|
||||
t.string :footprint
|
||||
t.string :environment
|
||||
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
|
||||
end
|
||||
|
@ -1513,7 +1513,7 @@ CREATE TABLE public.payment_schedules (
|
||||
footprint character varying,
|
||||
environment character varying,
|
||||
invoicing_profile_id bigint,
|
||||
operator_profile_id_id bigint,
|
||||
operator_profile_id bigint,
|
||||
created_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);
|
||||
|
||||
|
||||
--
|
||||
-- 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: -
|
||||
--
|
||||
@ -5442,14 +5450,6 @@ ALTER TABLE ONLY public.projects_themes
|
||||
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: -
|
||||
--
|
||||
|
Loading…
x
Reference in New Issue
Block a user