mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-21 15:54:22 +01:00
check shopping cart items is valid before pay online
This commit is contained in:
parent
f9bd27ea13
commit
c24aad00c4
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
- Fix a bug: admins are shown in select member for reservation by admin
|
- Fix a bug: admins are shown in select member for reservation by admin
|
||||||
- Fix a bug: unable to show tours in machines and spaces page
|
- Fix a bug: unable to show tours in machines and spaces page
|
||||||
|
- Check shopping cart items is valid before pay online
|
||||||
|
|
||||||
## v5.4.2 2022 June 1
|
## v5.4.2 2022 June 1
|
||||||
|
|
||||||
|
@ -53,6 +53,14 @@ class API::PayzenController < API::PaymentsController
|
|||||||
render json: e, status: :unprocessable_entity
|
render json: e, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def check_cart
|
||||||
|
cart = shopping_cart
|
||||||
|
unless cart.valid?
|
||||||
|
render json: { error: 'unable to pay' }, status: :unprocessable_entity and return
|
||||||
|
end
|
||||||
|
render json: { cart: 'ok' }, status: :ok
|
||||||
|
end
|
||||||
|
|
||||||
def check_hash
|
def check_hash
|
||||||
@result = PayZen::Helper.check_hash(params[:algorithm], params[:hash_key], params[:hash], params[:data])
|
@result = PayZen::Helper.check_hash(params[:algorithm], params[:hash_key], params[:hash], params[:data])
|
||||||
end
|
end
|
||||||
|
@ -19,6 +19,9 @@ class API::StripeController < API::PaymentsController
|
|||||||
res = nil # json of the API answer
|
res = nil # json of the API answer
|
||||||
|
|
||||||
cart = shopping_cart
|
cart = shopping_cart
|
||||||
|
unless cart.valid?
|
||||||
|
render json: { error: 'unable to pay' }, status: :unprocessable_entity and return
|
||||||
|
end
|
||||||
begin
|
begin
|
||||||
amount = debit_amount(cart) # will contains the amount and the details of each invoice lines
|
amount = debit_amount(cart) # will contains the amount and the details of each invoice lines
|
||||||
if params[:payment_method_id].present?
|
if params[:payment_method_id].present?
|
||||||
@ -71,10 +74,7 @@ class API::StripeController < API::PaymentsController
|
|||||||
|
|
||||||
def setup_subscription
|
def setup_subscription
|
||||||
cart = shopping_cart
|
cart = shopping_cart
|
||||||
cart.items.each do |item|
|
raise InvalidSubscriptionError unless cart.valid?
|
||||||
raise InvalidSubscriptionError unless item.valid?(cart.items)
|
|
||||||
raise InvalidSubscriptionError unless item.to_object.errors.empty?
|
|
||||||
end
|
|
||||||
|
|
||||||
service = Stripe::Service.new
|
service = Stripe::Service.new
|
||||||
method = service.attach_method_as_default(
|
method = service.attach_method_as_default(
|
||||||
|
@ -46,4 +46,9 @@ export default class PayzenAPI {
|
|||||||
const res: AxiosResponse<CreateTokenResponse> = await apiClient.post('/api/payzen/update_token', { payment_schedule_id: paymentScheduleId });
|
const res: AxiosResponse<CreateTokenResponse> = await apiClient.post('/api/payzen/update_token', { payment_schedule_id: paymentScheduleId });
|
||||||
return res?.data;
|
return res?.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async checkCart (cart: ShoppingCart, customer: User): Promise<CreatePaymentResponse> {
|
||||||
|
const res: AxiosResponse<CreatePaymentResponse> = await apiClient.post('/api/payzen/check_cart', { cart_items: cart, customer_id: customer.id });
|
||||||
|
return res?.data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,6 +132,7 @@ export const PayzenForm: React.FC<PayzenFormProps> = ({ onSubmit, onSuccess, onE
|
|||||||
try {
|
try {
|
||||||
const { result } = await PayZenKR.current.validateForm();
|
const { result } = await PayZenKR.current.validateForm();
|
||||||
if (result === null) {
|
if (result === null) {
|
||||||
|
await PayzenAPI.checkCart(cart, customer);
|
||||||
await PayZenKR.current.onSubmit(onPaid);
|
await PayZenKR.current.onSubmit(onPaid);
|
||||||
await PayZenKR.current.onError(handleError);
|
await PayZenKR.current.onError(handleError);
|
||||||
await PayZenKR.current.submit();
|
await PayZenKR.current.submit();
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
# A discount coupon applied to the whole shopping cart
|
# A discount coupon applied to the whole shopping cart
|
||||||
class CartItem::Coupon
|
class CartItem::Coupon
|
||||||
|
attr_reader :errors
|
||||||
|
|
||||||
# @param coupon {String|Coupon} may be nil or empty string if no coupons are applied
|
# @param coupon {String|Coupon} may be nil or empty string if no coupons are applied
|
||||||
def initialize(customer, operator, coupon)
|
def initialize(customer, operator, coupon)
|
||||||
@customer = customer
|
@customer = customer
|
||||||
@operator = operator
|
@operator = operator
|
||||||
@coupon = coupon
|
@coupon = coupon
|
||||||
|
@errors = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def coupon
|
def coupon
|
||||||
@ -27,4 +29,15 @@ class CartItem::Coupon
|
|||||||
def type
|
def type
|
||||||
'coupon'
|
'coupon'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def valid?(_all_items)
|
||||||
|
return true if @coupon.nil?
|
||||||
|
|
||||||
|
c = ::Coupon.find_by(code: @coupon)
|
||||||
|
if c.nil? || c.status(@customer.id) != 'active'
|
||||||
|
@errors[:item] = 'coupon is invalid'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# A payment schedule applied to plan in the shopping cart
|
# A payment schedule applied to plan in the shopping cart
|
||||||
class CartItem::PaymentSchedule
|
class CartItem::PaymentSchedule
|
||||||
attr_reader :requested
|
attr_reader :requested, :errors
|
||||||
|
|
||||||
def initialize(plan, coupon, requested, customer, start_at = nil)
|
def initialize(plan, coupon, requested, customer, start_at = nil)
|
||||||
raise TypeError unless coupon.is_a? CartItem::Coupon
|
raise TypeError unless coupon.is_a? CartItem::Coupon
|
||||||
@ -12,6 +12,7 @@ class CartItem::PaymentSchedule
|
|||||||
@requested = requested
|
@requested = requested
|
||||||
@customer = customer
|
@customer = customer
|
||||||
@start_at = start_at
|
@start_at = start_at
|
||||||
|
@errors = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def schedule(total, total_without_coupon)
|
def schedule(total, total_without_coupon)
|
||||||
@ -33,4 +34,12 @@ class CartItem::PaymentSchedule
|
|||||||
def type
|
def type
|
||||||
'subscription'
|
'subscription'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def valid?(_all_items)
|
||||||
|
if @plan&.disabled
|
||||||
|
@errors[:item] = 'plan is disabled'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -37,4 +37,12 @@ class CartItem::PrepaidPack < CartItem::BaseItem
|
|||||||
def type
|
def type
|
||||||
'pack'
|
'pack'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def valid?(_all_items)
|
||||||
|
if @pack.disabled
|
||||||
|
@errors[:item] = 'pack is disabled'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -43,7 +43,26 @@ class CartItem::Reservation < CartItem::BaseItem
|
|||||||
def valid?(all_items)
|
def valid?(all_items)
|
||||||
pending_subscription = all_items.find { |i| i.is_a?(CartItem::Subscription) }
|
pending_subscription = all_items.find { |i| i.is_a?(CartItem::Subscription) }
|
||||||
@slots.each do |slot|
|
@slots.each do |slot|
|
||||||
availability = Availability.find(slot[:availability_id])
|
availability = Availability.find_by(id: slot[:availability_id])
|
||||||
|
if availability.nil?
|
||||||
|
@errors[:slot] = 'slot availability no exist'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if availability.available_type == 'machines'
|
||||||
|
s = Slot.find_by(start_at: slot[:start_at], end_at: slot[:end_at], availability_id: slot[:availability_id], canceled_at: nil)
|
||||||
|
unless s.nil?
|
||||||
|
@errors[:slot] = 'slot has reserved'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
elsif availability.available_type == 'space' && availability.spaces.first.disabled.nil?
|
||||||
|
@errors[:slot] = 'space is disabled'
|
||||||
|
return false
|
||||||
|
elsif availability.completed?
|
||||||
|
@errors[:slot] = 'availability has completed'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
next if availability.plan_ids.empty?
|
next if availability.plan_ids.empty?
|
||||||
next if (@customer.subscribed_plan && availability.plan_ids.include?(@customer.subscribed_plan.id)) ||
|
next if (@customer.subscribed_plan && availability.plan_ids.include?(@customer.subscribed_plan.id)) ||
|
||||||
(pending_subscription && availability.plan_ids.include?(pending_subscription.plan.id)) ||
|
(pending_subscription && availability.plan_ids.include?(pending_subscription.plan.id)) ||
|
||||||
|
@ -41,4 +41,12 @@ class CartItem::Subscription < CartItem::BaseItem
|
|||||||
def type
|
def type
|
||||||
'subscription'
|
'subscription'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def valid?(_all_items)
|
||||||
|
if @plan.disabled
|
||||||
|
@errors[:item] = 'plan is disabled'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -87,6 +87,19 @@ class ShoppingCart
|
|||||||
{ success: success, payment: payment, errors: errors }
|
{ success: success, payment: payment, errors: errors }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def valid?
|
||||||
|
items.each do |item|
|
||||||
|
next if item.valid?(@items)
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return false unless @coupon.valid?([])
|
||||||
|
|
||||||
|
return false unless @payment_schedule.valid?([])
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Save the object associated with the provided item or raise and Rollback if something wrong append.
|
# Save the object associated with the provided item or raise and Rollback if something wrong append.
|
||||||
|
@ -214,6 +214,7 @@ Rails.application.routes.draw do
|
|||||||
post 'payzen/check_hash' => 'payzen#check_hash'
|
post 'payzen/check_hash' => 'payzen#check_hash'
|
||||||
post 'payzen/create_token' => 'payzen#create_token'
|
post 'payzen/create_token' => 'payzen#create_token'
|
||||||
post 'payzen/update_token' => 'payzen#update_token'
|
post 'payzen/update_token' => 'payzen#update_token'
|
||||||
|
post 'payzen/check_cart' => 'payzen#check_cart'
|
||||||
|
|
||||||
# local payments handling
|
# local payments handling
|
||||||
post 'local_payment/confirm_payment' => 'local_payment#confirm_payment'
|
post 'local_payment/confirm_payment' => 'local_payment#confirm_payment'
|
||||||
|
@ -141,7 +141,7 @@ class Reservations::RestrictedTest < ActionDispatch::IntegrationTest
|
|||||||
end
|
end
|
||||||
|
|
||||||
assert_equal 422, response.status
|
assert_equal 422, response.status
|
||||||
assert_match /slot is restricted for subscribers/, response.body
|
assert_match /unable to pay/, response.body
|
||||||
|
|
||||||
assert_equal reservations_count, Reservation.count
|
assert_equal reservations_count, Reservation.count
|
||||||
assert_equal invoices_count, Invoice.count
|
assert_equal invoices_count, Invoice.count
|
||||||
|
Loading…
x
Reference in New Issue
Block a user