mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
Refactor for determining gateway fees
This commit is contained in:
parent
c8a9997a98
commit
c8770f09ca
@ -467,7 +467,8 @@ class Client extends BaseModel implements HasLocalePreference
|
||||
|
||||
$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));
|
||||
$gateways = $this->company
|
||||
@ -480,32 +481,46 @@ class Client extends BaseModel implements HasLocalePreference
|
||||
$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) {
|
||||
return 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
|
||||
// //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 = [];
|
||||
|
||||
foreach ($valid_gateways as $gateway) {
|
||||
foreach ($gateways as $gateway) {
|
||||
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;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
$languages = Cache::get('languages');
|
||||
|
@ -228,7 +228,7 @@ class CompanyGateway extends BaseModel
|
||||
|
||||
public function getFeesAndLimits()
|
||||
{
|
||||
if (is_null($this->fees_and_limits)) {
|
||||
if (is_null($this->fees_and_limits) || empty($this->fees_and_limits)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -269,6 +269,9 @@ class CompanyGateway extends BaseModel
|
||||
public function calcGatewayFee($amount, $include_taxes = false)
|
||||
{
|
||||
$fees_and_limits = $this->getFeesAndLimits();
|
||||
//dd($fees_and_limits);
|
||||
//
|
||||
// info(var_dump($$fees_and_limits));
|
||||
|
||||
if (! $fees_and_limits) {
|
||||
return 0;
|
||||
|
@ -72,8 +72,8 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
* Authorize a payment method.
|
||||
*
|
||||
* Returns a reusable token for storage for future payments
|
||||
* @param const $payment_method the GatewayType::constant
|
||||
* @return view Return a view for collecting payment method information
|
||||
* @param const $payment_method The GatewayType::constant
|
||||
* @return view Return a view for collecting payment method information
|
||||
*/
|
||||
public function authorize($payment_method)
|
||||
{
|
||||
@ -82,8 +82,8 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
/**
|
||||
* Executes purchase attempt for a given amount.
|
||||
*
|
||||
* @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 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)
|
||||
* @return mixed
|
||||
*/
|
||||
public function purchase($amount, $return_client_response = false)
|
||||
@ -95,7 +95,7 @@ class BaseDriver extends AbstractPaymentDriver
|
||||
*
|
||||
* @param Payment $payment The Payment Object
|
||||
* @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
|
||||
*/
|
||||
public function refund(Payment $payment, $amount, $return_client_response = false)
|
||||
|
@ -47,11 +47,11 @@ class Alipay
|
||||
{
|
||||
return route('client.payments.response', [
|
||||
'company_gateway_id' => $this->stripe->company_gateway->id,
|
||||
'gateway_type_id' => GatewayType::SOFORT,
|
||||
'gateway_type_id' => GatewayType::ALIPAY,
|
||||
'hashed_ids' => implode(',', $data['hashed_ids']),
|
||||
'amount' => $data['amount'],
|
||||
'fee' => $data['fee'],
|
||||
'payment_method_id' => GatewayType::SOFORT,
|
||||
'payment_method_id' => GatewayType::ALIPAY,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ use App\DataMapper\InvoiceItem;
|
||||
use App\Events\Payment\PaymentWasCreated;
|
||||
use App\Factory\PaymentFactory;
|
||||
use App\Models\Client;
|
||||
use App\Models\Credit;
|
||||
use App\Models\Invoice;
|
||||
use App\Models\Payment;
|
||||
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
|
||||
$this->applyCreditPayment();
|
||||
|
||||
info("partial = {$this->invoice->partial}");
|
||||
info("balance = {$this->invoice->balance}");
|
||||
|
||||
/* Determine $amount */
|
||||
if ($this->invoice->partial > 0)
|
||||
$amount = $this->invoice->partial;
|
||||
@ -64,6 +68,8 @@ class AutoBillInvoice extends AbstractService
|
||||
else
|
||||
return $this->finalizePaymentUsingCredits();
|
||||
|
||||
info("balance remains to be paid!!");
|
||||
|
||||
$gateway_token = $this->getGateway($amount);
|
||||
|
||||
/* 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->amount = $amount;
|
||||
$payment->applied = $amount;
|
||||
$payment->client_id = $this->invoice->client_id;
|
||||
$payment->currency_id = $this->invoice->client->getSetting('currency_id');
|
||||
$payment->date = now();
|
||||
@ -113,10 +120,12 @@ class AutoBillInvoice extends AbstractService
|
||||
|
||||
$this->invoice->service()->setStatus(Invoice::STATUS_PAID)->save();
|
||||
|
||||
foreach($this->used_credit as $credit)
|
||||
{
|
||||
$payment->credits()->attach($credit['credit_id'], ['amount' => $credit['amount']]);
|
||||
}
|
||||
foreach($this->used_credit as $credit)
|
||||
{
|
||||
$current_credit = Credit::find($credit['credit_id']);
|
||||
$payment->credits()->attach($current_credit->id, ['amount' => $credit['amount']]);
|
||||
$this->applyPaymentToCredit($current_credit, $credit['amount']);
|
||||
}
|
||||
|
||||
$payment->ledger()
|
||||
->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;
|
||||
@ -226,7 +235,9 @@ class AutoBillInvoice extends AbstractService
|
||||
$credit->line_items = $credit_items;
|
||||
|
||||
$credit = $credit->calc()->getCredit();
|
||||
$credit->save();
|
||||
|
||||
return $credit;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,24 +34,19 @@ class AutoBillInvoiceTest extends TestCase
|
||||
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->paid_to_date, 0);
|
||||
$this->assertEquals($this->client->credit_balance, 10);
|
||||
|
||||
$this->invoice->service()->markSent()->autoBill()->save();
|
||||
|
||||
// info(print_r($this->invoice->payments()->first()->toArray(),1));
|
||||
$this->assertNotNull($this->invoice->payments());
|
||||
$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->paid_to_date, 10);
|
||||
$this->assertEquals($this->client->credit_balance, 0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -36,7 +36,8 @@ class FeesAndLimitsTest extends TestCase
|
||||
$data['fee_tax_rate2'] = '';
|
||||
$data['fee_tax_name3'] = '';
|
||||
$data['fee_tax_rate3'] = 0;
|
||||
|
||||
$data['fee_cap'] = 0;
|
||||
|
||||
$fees_and_limits_array = [];
|
||||
$fees_and_limits_array[] = $data;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user