mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-01-18 07:52:23 +01:00
improves how pay_zen transactions are matched with payment_schedule_items, improves rrule of pay_zen subscriptions
This commit is contained in:
parent
a946399ec5
commit
f77ba72758
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
- fix a bug: user was not able to reserve at the same time of an event with pre-registration invalidated
|
- fix a bug: user was not able to reserve at the same time of an event with pre-registration invalidated
|
||||||
- fix a bug: avoids crash if invoicing_profile has no address associated to it
|
- fix a bug: avoids crash if invoicing_profile has no address associated to it
|
||||||
|
- improvement: improves how pay_zen transactions are matched with payment_schedule_items
|
||||||
|
- improvement: improves rrule of pay_zen subscriptions
|
||||||
|
|
||||||
## v6.3.4 2023 November 23
|
## v6.3.4 2023 November 23
|
||||||
|
|
||||||
|
@ -21,14 +21,15 @@ class PayZen::Service < Payment::Service
|
|||||||
amount: payzen_amount(first_item.details['recurring'].to_i),
|
amount: payzen_amount(first_item.details['recurring'].to_i),
|
||||||
effect_date: first_item.due_date.iso8601,
|
effect_date: first_item.due_date.iso8601,
|
||||||
payment_method_token: token_id,
|
payment_method_token: token_id,
|
||||||
rrule: rrule(payment_schedule),
|
rrule: rrule(payment_schedule, first_item.due_date),
|
||||||
order_id: order_id
|
order_id: order_id
|
||||||
}
|
}
|
||||||
initial_amount = first_item.amount
|
initial_amount = first_item.amount
|
||||||
initial_amount -= payment_schedule.wallet_amount if payment_schedule.wallet_amount
|
initial_amount -= payment_schedule.wallet_amount if payment_schedule.wallet_amount
|
||||||
if initial_amount.zero?
|
if initial_amount.zero?
|
||||||
params[:effect_date] = (first_item.due_date + 1.month).iso8601
|
effect_date = first_item.due_date + 1.month
|
||||||
params[:rrule] = rrule(payment_schedule, -1)
|
params[:effect_date] = effect_date.iso8601
|
||||||
|
params[:rrule] = rrule(payment_schedule, effect_date, -1)
|
||||||
else
|
else
|
||||||
params[:initial_amount] = payzen_amount(initial_amount)
|
params[:initial_amount] = payzen_amount(initial_amount)
|
||||||
params[:initial_amount_number] = 1
|
params[:initial_amount_number] = 1
|
||||||
@ -92,8 +93,8 @@ class PayZen::Service < Payment::Service
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
pz_order = payment_schedule_item.payment_schedule.gateway_order.retrieve
|
pz_order = payment_schedule_item.payment_schedule.gateway_order.retrieve
|
||||||
transaction = pz_order['answer']['transactions'].last
|
transaction = find_transaction_by_payment_schedule_item(pz_order['answer']['transactions'], payment_schedule_item)
|
||||||
return unless transaction_matches?(transaction, payment_schedule_item)
|
return unless transaction
|
||||||
|
|
||||||
case transaction['status']
|
case transaction['status']
|
||||||
when 'PAID'
|
when 'PAID'
|
||||||
@ -127,28 +128,35 @@ class PayZen::Service < Payment::Service
|
|||||||
amount
|
amount
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
def rrule(payment_schedule, first_date, offset = 0)
|
||||||
|
count = payment_schedule.payment_schedule_items.count + offset
|
||||||
|
|
||||||
def rrule(payment_schedule, offset = 0)
|
by_month_day_part = case first_date.day
|
||||||
count = payment_schedule.payment_schedule_items.count
|
when 31
|
||||||
"RRULE:FREQ=MONTHLY;COUNT=#{count + offset}"
|
"BYMONTHDAY=28,29,30,31;BYSETPOS=-1"
|
||||||
end
|
when 30
|
||||||
|
"BYMONTHDAY=28,29,30;BYSETPOS=-1"
|
||||||
# check if the given transaction matches the given PaymentScheduleItem
|
when 29
|
||||||
def transaction_matches?(transaction, payment_schedule_item)
|
"BYMONTHDAY=28,29;BYSETPOS=-1"
|
||||||
transaction_date = Time.zone.parse(transaction['creationDate']).to_date
|
else
|
||||||
|
"BYMONTHDAY=#{first_date.day}"
|
||||||
amount = payment_schedule_item.amount
|
|
||||||
if payment_schedule_item == payment_schedule_item.payment_schedule.ordered_items.first &&
|
|
||||||
payment_schedule_item.payment_schedule.wallet_amount
|
|
||||||
amount -= payment_schedule_item.payment_schedule.wallet_amount
|
|
||||||
end
|
end
|
||||||
|
|
||||||
transaction['amount'] == amount &&
|
"RRULE:FREQ=MONTHLY;#{by_month_day_part};COUNT=#{count}"
|
||||||
transaction_date >= payment_schedule_item.due_date.to_date &&
|
|
||||||
transaction_date <= payment_schedule_item.due_date.to_date + 7.days
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_transaction_by_payment_schedule_item(transactions, payment_schedule_item)
|
||||||
|
due_date = payment_schedule_item.due_date.to_date
|
||||||
|
|
||||||
|
transactions.find do |tr|
|
||||||
|
expected_capture_date = Time.zone.parse(tr["transactionDetails"]["paymentMethodDetails"]["expectedCaptureDate"]).to_date
|
||||||
|
|
||||||
|
(tr["operationType"] == "DEBIT") && (expected_capture_date.between?(due_date - 1.day, due_date + 1.day))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
# @see https://payzen.io/en-EN/payment-file/ips/list-of-supported-currencies.html
|
# @see https://payzen.io/en-EN/payment-file/ips/list-of-supported-currencies.html
|
||||||
def zero_decimal_currencies
|
def zero_decimal_currencies
|
||||||
%w[KHR JPY KRW XOF XPF]
|
%w[KHR JPY KRW XOF XPF]
|
||||||
|
78
test/lib/pay_zen/service_test.rb
Normal file
78
test/lib/pay_zen/service_test.rb
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'test_helper'
|
||||||
|
require 'pay_zen/service'
|
||||||
|
|
||||||
|
class PayZen::ServiceTest < ActiveSupport::TestCase
|
||||||
|
setup do
|
||||||
|
@service = PayZen::Service.new
|
||||||
|
end
|
||||||
|
|
||||||
|
test '#rrule' do
|
||||||
|
ps = payment_schedules(:payment_schedule_12)
|
||||||
|
|
||||||
|
first_due_date = ps.ordered_items.first.due_date
|
||||||
|
|
||||||
|
first_date = first_due_date
|
||||||
|
assert_equal "RRULE:FREQ=MONTHLY;BYMONTHDAY=14;COUNT=12", @service.rrule(ps, first_date)
|
||||||
|
|
||||||
|
assert_equal "RRULE:FREQ=MONTHLY;BYMONTHDAY=14;COUNT=11", @service.rrule(ps, first_date, -1)
|
||||||
|
|
||||||
|
first_date = first_due_date + 3.days
|
||||||
|
assert_equal "RRULE:FREQ=MONTHLY;BYMONTHDAY=17;COUNT=12", @service.rrule(ps, first_date)
|
||||||
|
|
||||||
|
first_due_date = first_due_date.change(month: 7)
|
||||||
|
|
||||||
|
first_date = first_due_date.change(day: 28)
|
||||||
|
assert_equal "RRULE:FREQ=MONTHLY;BYMONTHDAY=28;COUNT=12", @service.rrule(ps, first_date)
|
||||||
|
|
||||||
|
first_date = first_due_date.change(day: 29)
|
||||||
|
assert_equal "RRULE:FREQ=MONTHLY;BYMONTHDAY=28,29;BYSETPOS=-1;COUNT=12", @service.rrule(ps, first_date)
|
||||||
|
|
||||||
|
first_date = first_due_date.change(day: 30)
|
||||||
|
assert_equal "RRULE:FREQ=MONTHLY;BYMONTHDAY=28,29,30;BYSETPOS=-1;COUNT=12", @service.rrule(ps, first_date)
|
||||||
|
|
||||||
|
first_date = first_due_date.change(day: 31)
|
||||||
|
assert_equal "RRULE:FREQ=MONTHLY;BYMONTHDAY=28,29,30,31;BYSETPOS=-1;COUNT=12", @service.rrule(ps, first_date)
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_transaction(operation_type:, expected_capture_date:)
|
||||||
|
{ "operationType" => operation_type, "transactionDetails" => { "paymentMethodDetails" => { "expectedCaptureDate" => expected_capture_date } } }
|
||||||
|
end
|
||||||
|
|
||||||
|
test "#find_transaction_by_payment_schedule_item" do
|
||||||
|
ps = payment_schedules(:payment_schedule_12)
|
||||||
|
|
||||||
|
payment_schedule_item = ps.ordered_items.first
|
||||||
|
|
||||||
|
expected_capture_date = payment_schedule_item.due_date.iso8601
|
||||||
|
transactions = [format_transaction(operation_type: "DEBIT", expected_capture_date: expected_capture_date)]
|
||||||
|
|
||||||
|
assert @service.find_transaction_by_payment_schedule_item(transactions, payment_schedule_item)
|
||||||
|
|
||||||
|
expected_capture_date = (payment_schedule_item.due_date - 1.day).iso8601
|
||||||
|
transactions = [format_transaction(operation_type: "DEBIT", expected_capture_date: expected_capture_date)]
|
||||||
|
|
||||||
|
assert @service.find_transaction_by_payment_schedule_item(transactions, payment_schedule_item)
|
||||||
|
|
||||||
|
expected_capture_date = (payment_schedule_item.due_date + 1.day).iso8601
|
||||||
|
transactions = [format_transaction(operation_type: "DEBIT", expected_capture_date: expected_capture_date)]
|
||||||
|
|
||||||
|
assert @service.find_transaction_by_payment_schedule_item(transactions, payment_schedule_item)
|
||||||
|
|
||||||
|
expected_capture_date = (payment_schedule_item.due_date + 2.days).iso8601
|
||||||
|
transactions = [format_transaction(operation_type: "DEBIT", expected_capture_date: expected_capture_date)]
|
||||||
|
|
||||||
|
assert_nil @service.find_transaction_by_payment_schedule_item(transactions, payment_schedule_item)
|
||||||
|
|
||||||
|
expected_capture_date = (payment_schedule_item.due_date - 2.days).iso8601
|
||||||
|
transactions = [format_transaction(operation_type: "DEBIT", expected_capture_date: expected_capture_date)]
|
||||||
|
|
||||||
|
assert_nil @service.find_transaction_by_payment_schedule_item(transactions, payment_schedule_item)
|
||||||
|
|
||||||
|
expected_capture_date = payment_schedule_item.due_date.iso8601
|
||||||
|
transactions = [format_transaction(operation_type: "CREDIT", expected_capture_date: expected_capture_date)]
|
||||||
|
|
||||||
|
assert_nil @service.find_transaction_by_payment_schedule_item(transactions, payment_schedule_item)
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user