Refactor for determining gateway fees

This commit is contained in:
David Bomba 2020-10-12 15:10:34 +11:00
parent c8a9997a98
commit c8770f09ca
7 changed files with 84 additions and 40 deletions

View File

@ -467,7 +467,8 @@ class Client extends BaseModel implements HasLocalePreference
$company_gateways = $this->getSetting('company_gateway_ids'); $company_gateways = $this->getSetting('company_gateway_ids');
if ($company_gateways || $company_gateways == '0') { //we need to check for "0" here as we disable a payment gateway for a client with the number "0" //we need to check for "0" here as we disable a payment gateway for a client with the number "0"
if ($company_gateways || $company_gateways == '0') {
$transformed_ids = $this->transformKeys(explode(',', $company_gateways)); $transformed_ids = $this->transformKeys(explode(',', $company_gateways));
$gateways = $this->company $gateways = $this->company
@ -480,32 +481,46 @@ class Client extends BaseModel implements HasLocalePreference
$gateways = $this->company->company_gateways->where('is_deleted', false); $gateways = $this->company->company_gateways->where('is_deleted', false);
} }
$valid_gateways = $gateways->filter(function ($method) use ($amount) {
if (isset($method->fees_and_limits)) {
//sometimes the key value of the fees and limits object are not static,
//we have to harvest the key value as follows
$properties = array_keys(get_object_vars($method->fees_and_limits));
$fees_and_limits = $method->fees_and_limits->{$properties[0]};
} else {
return true;
}
if ((property_exists($fees_and_limits, 'min_limit')) && $fees_and_limits->min_limit !== null && $fees_and_limits->min_limit != -1 && $amount < $fees_and_limits->min_limit) {
return false;
}
if ((property_exists($fees_and_limits, 'max_limit')) && $fees_and_limits->max_limit !== null && $fees_and_limits->max_limit != -1 && $amount > $fees_and_limits->max_limit) { // $valid_gateways = $gateways->filter(function ($method) use ($amount) {
return false; // if (isset($method->fees_and_limits)) {
} // //sometimes the key value of the fees and limits object are not static,
// //we have to harvest the key value as follows
// //Update!!! apparently we use the gateway_type_id
// $properties = array_keys(get_object_vars($method->fees_and_limits));
// $fees_and_limits = $method->fees_and_limits->{$properties[0]}; //need to iterate over the $properties array as there may be many fees_and_limits
// } else {
// return true;
// }
// if ((property_exists($fees_and_limits, 'min_limit')) && $fees_and_limits->min_limit !== null && $fees_and_limits->min_limit != -1 && $amount < $fees_and_limits->min_limit) {
// return false;
// }
// if ((property_exists($fees_and_limits, 'max_limit')) && $fees_and_limits->max_limit !== null && $fees_and_limits->max_limit != -1 && $amount > $fees_and_limits->max_limit) {
// return false;
// }
// return true;
// })->all();
return true;
})->all();
$payment_methods = []; $payment_methods = [];
foreach ($valid_gateways as $gateway) { foreach ($gateways as $gateway) {
foreach ($gateway->driver($this)->gatewayTypes() as $type) { foreach ($gateway->driver($this)->gatewayTypes() as $type) {
$payment_methods[] = [$gateway->id => $type];
if(property_exists($gateway, 'fees_and_limits') property_exists($gateway->fees_and_limits, $type)){
$fees_and_limits_for_payment_type = $gateway->fees_and_limits->{$type};
}
else
continue;
if($this->validGatewayForAmount($fees_and_limits_for_payment_type, $amount))
$payment_methods[] = [$gateway->id => $type];
} }
} }
@ -533,6 +548,25 @@ class Client extends BaseModel implements HasLocalePreference
return $payment_urls; return $payment_urls;
} }
private function validateFeesAndLimits($fees_and_limits_for_payment_type, $amount) :bool
{
if (isset($fees_and_limits_for_payment_type)) {
$fees_and_limits = $fees_and_limits_for_payment_type;
} else {
return true;
}
if ((property_exists($fees_and_limits, 'min_limit')) && $fees_and_limits->min_limit !== null && $fees_and_limits->min_limit != -1 && $amount < $fees_and_limits->min_limit) {
return false;
}
if ((property_exists($fees_and_limits, 'max_limit')) && $fees_and_limits->max_limit !== null && $fees_and_limits->max_limit != -1 && $amount > $fees_and_limits->max_limit) {
return false;
}
return true;
}
public function preferredLocale() public function preferredLocale()
{ {
$languages = Cache::get('languages'); $languages = Cache::get('languages');

View File

@ -228,7 +228,7 @@ class CompanyGateway extends BaseModel
public function getFeesAndLimits() public function getFeesAndLimits()
{ {
if (is_null($this->fees_and_limits)) { if (is_null($this->fees_and_limits) || empty($this->fees_and_limits)) {
return false; return false;
} }
@ -269,6 +269,9 @@ class CompanyGateway extends BaseModel
public function calcGatewayFee($amount, $include_taxes = false) public function calcGatewayFee($amount, $include_taxes = false)
{ {
$fees_and_limits = $this->getFeesAndLimits(); $fees_and_limits = $this->getFeesAndLimits();
//dd($fees_and_limits);
//
// info(var_dump($$fees_and_limits));
if (! $fees_and_limits) { if (! $fees_and_limits) {
return 0; return 0;

View File

@ -72,8 +72,8 @@ class BaseDriver extends AbstractPaymentDriver
* Authorize a payment method. * Authorize a payment method.
* *
* Returns a reusable token for storage for future payments * Returns a reusable token for storage for future payments
* @param const $payment_method the GatewayType::constant * @param const $payment_method The GatewayType::constant
* @return view Return a view for collecting payment method information * @return view Return a view for collecting payment method information
*/ */
public function authorize($payment_method) public function authorize($payment_method)
{ {
@ -82,8 +82,8 @@ class BaseDriver extends AbstractPaymentDriver
/** /**
* Executes purchase attempt for a given amount. * Executes purchase attempt for a given amount.
* *
* @param float $amount The amount to be collected * @param float $amount The amount to be collected
* @param bool $return_client_response Whether the method needs to return a response (otherwise we assume an unattended payment) * @param bool $return_client_response Whether the method needs to return a response (otherwise we assume an unattended payment)
* @return mixed * @return mixed
*/ */
public function purchase($amount, $return_client_response = false) public function purchase($amount, $return_client_response = false)
@ -95,7 +95,7 @@ class BaseDriver extends AbstractPaymentDriver
* *
* @param Payment $payment The Payment Object * @param Payment $payment The Payment Object
* @param float $amount The amount to be refunded * @param float $amount The amount to be refunded
* @param bool $return_client_response Whether the method needs to return a response (otherwise we assume an unattended payment) * @param bool $return_client_response Whether the method needs to return a response (otherwise we assume an unattended payment)
* @return mixed * @return mixed
*/ */
public function refund(Payment $payment, $amount, $return_client_response = false) public function refund(Payment $payment, $amount, $return_client_response = false)

View File

@ -47,11 +47,11 @@ class Alipay
{ {
return route('client.payments.response', [ return route('client.payments.response', [
'company_gateway_id' => $this->stripe->company_gateway->id, 'company_gateway_id' => $this->stripe->company_gateway->id,
'gateway_type_id' => GatewayType::SOFORT, 'gateway_type_id' => GatewayType::ALIPAY,
'hashed_ids' => implode(',', $data['hashed_ids']), 'hashed_ids' => implode(',', $data['hashed_ids']),
'amount' => $data['amount'], 'amount' => $data['amount'],
'fee' => $data['fee'], 'fee' => $data['fee'],
'payment_method_id' => GatewayType::SOFORT, 'payment_method_id' => GatewayType::ALIPAY,
]); ]);
} }

View File

@ -15,6 +15,7 @@ use App\DataMapper\InvoiceItem;
use App\Events\Payment\PaymentWasCreated; use App\Events\Payment\PaymentWasCreated;
use App\Factory\PaymentFactory; use App\Factory\PaymentFactory;
use App\Models\Client; use App\Models\Client;
use App\Models\Credit;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Payment; use App\Models\Payment;
use App\Models\PaymentHash; use App\Models\PaymentHash;
@ -56,6 +57,9 @@ class AutoBillInvoice extends AbstractService
//if the credits cover the payments, we stop here, build the payment with credits and exit early //if the credits cover the payments, we stop here, build the payment with credits and exit early
$this->applyCreditPayment(); $this->applyCreditPayment();
info("partial = {$this->invoice->partial}");
info("balance = {$this->invoice->balance}");
/* Determine $amount */ /* Determine $amount */
if ($this->invoice->partial > 0) if ($this->invoice->partial > 0)
$amount = $this->invoice->partial; $amount = $this->invoice->partial;
@ -64,6 +68,8 @@ class AutoBillInvoice extends AbstractService
else else
return $this->finalizePaymentUsingCredits(); return $this->finalizePaymentUsingCredits();
info("balance remains to be paid!!");
$gateway_token = $this->getGateway($amount); $gateway_token = $this->getGateway($amount);
/* Bail out if no payment methods available */ /* Bail out if no payment methods available */
@ -103,6 +109,7 @@ class AutoBillInvoice extends AbstractService
$payment = PaymentFactory::create($this->invoice->company_id, $this->invoice->user_id); $payment = PaymentFactory::create($this->invoice->company_id, $this->invoice->user_id);
$payment->amount = $amount; $payment->amount = $amount;
$payment->applied = $amount;
$payment->client_id = $this->invoice->client_id; $payment->client_id = $this->invoice->client_id;
$payment->currency_id = $this->invoice->client->getSetting('currency_id'); $payment->currency_id = $this->invoice->client->getSetting('currency_id');
$payment->date = now(); $payment->date = now();
@ -113,10 +120,12 @@ class AutoBillInvoice extends AbstractService
$this->invoice->service()->setStatus(Invoice::STATUS_PAID)->save(); $this->invoice->service()->setStatus(Invoice::STATUS_PAID)->save();
foreach($this->used_credit as $credit) foreach($this->used_credit as $credit)
{ {
$payment->credits()->attach($credit['credit_id'], ['amount' => $credit['amount']]); $current_credit = Credit::find($credit['credit_id']);
} $payment->credits()->attach($current_credit->id, ['amount' => $credit['amount']]);
$this->applyPaymentToCredit($current_credit, $credit['amount']);
}
$payment->ledger() $payment->ledger()
->updatePaymentBalance($amount * -1) ->updatePaymentBalance($amount * -1)
@ -210,7 +219,7 @@ class AutoBillInvoice extends AbstractService
private function applyPaymentToCredit($credit, $amount) private function applyPaymentToCredit($credit, $amount) :Credit
{ {
$credit_item = new InvoiceItem; $credit_item = new InvoiceItem;
@ -226,7 +235,9 @@ class AutoBillInvoice extends AbstractService
$credit->line_items = $credit_items; $credit->line_items = $credit_items;
$credit = $credit->calc()->getCredit(); $credit = $credit->calc()->getCredit();
$credit->save();
return $credit;
} }
/** /**

View File

@ -34,24 +34,19 @@ class AutoBillInvoiceTest extends TestCase
public function testAutoBillFunctionality() public function testAutoBillFunctionality()
{ {
// info("client balance = {$this->client->balance}");
// info("invoice balance = {$this->invoice->balance}");
$this->assertEquals($this->client->balance, 10); $this->assertEquals($this->client->balance, 10);
$this->assertEquals($this->client->paid_to_date, 0); $this->assertEquals($this->client->paid_to_date, 0);
$this->assertEquals($this->client->credit_balance, 10); $this->assertEquals($this->client->credit_balance, 10);
$this->invoice->service()->markSent()->autoBill()->save(); $this->invoice->service()->markSent()->autoBill()->save();
// info(print_r($this->invoice->payments()->first()->toArray(),1));
$this->assertNotNull($this->invoice->payments()); $this->assertNotNull($this->invoice->payments());
$this->assertEquals(10, $this->invoice->payments()->sum('payments.amount')); $this->assertEquals(10, $this->invoice->payments()->sum('payments.amount'));
//info(print_r($this->invoice->payments()->get(),1));
$this->assertEquals($this->client->balance, 0); $this->assertEquals($this->client->balance, 0);
$this->assertEquals($this->client->paid_to_date, 10); $this->assertEquals($this->client->paid_to_date, 10);
$this->assertEquals($this->client->credit_balance, 0); $this->assertEquals($this->client->credit_balance, 0);
} }
} }

View File

@ -36,7 +36,8 @@ class FeesAndLimitsTest extends TestCase
$data['fee_tax_rate2'] = ''; $data['fee_tax_rate2'] = '';
$data['fee_tax_name3'] = ''; $data['fee_tax_name3'] = '';
$data['fee_tax_rate3'] = 0; $data['fee_tax_rate3'] = 0;
$data['fee_cap'] = 0;
$fees_and_limits_array = []; $fees_and_limits_array = [];
$fees_and_limits_array[] = $data; $fees_and_limits_array[] = $data;