mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2026-03-03 02:57:01 +00:00
Improvements for Gateways that are preferentially sorted
This commit is contained in:
@@ -22,8 +22,8 @@ use App\Jobs\Util\ApplePayDomain;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use App\Factory\CompanyGatewayFactory;
|
||||
use App\Filters\CompanyGatewayFilters;
|
||||
use App\Repositories\CompanyRepository;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use App\Repositories\CompanyGatewayRepository;
|
||||
use App\Transformers\CompanyGatewayTransformer;
|
||||
use App\PaymentDrivers\Stripe\Jobs\StripeWebhook;
|
||||
use App\PaymentDrivers\CheckoutCom\CheckoutSetupWebhook;
|
||||
@@ -63,9 +63,9 @@ class CompanyGatewayController extends BaseController
|
||||
|
||||
/**
|
||||
* CompanyGatewayController constructor.
|
||||
* @param CompanyRepository $company_repo
|
||||
* @param CompanyGatewayRepository $company_repo
|
||||
*/
|
||||
public function __construct(CompanyRepository $company_repo)
|
||||
public function __construct(CompanyGatewayRepository $company_repo)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
@@ -210,10 +210,14 @@ class CompanyGatewayController extends BaseController
|
||||
/** @var \App\Models\User $user */
|
||||
$user = auth()->user();
|
||||
|
||||
$company = $user->company();
|
||||
|
||||
$company_gateway = CompanyGatewayFactory::create($user->company()->id, $user->id);
|
||||
$company_gateway->fill($request->all());
|
||||
$company_gateway->save();
|
||||
|
||||
$this->company_repo->addGatewayToCompanyGatewayIds($company_gateway);
|
||||
|
||||
/*Always ensure at least one fees and limits object is set per gateway*/
|
||||
$gateway_types = $company_gateway->driver(new Client())->getAvailableMethods();
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
* @property bool $is_deleted
|
||||
* @property string $config
|
||||
* @property object $settings
|
||||
* @property mixed $fees_and_limits
|
||||
* @property array|object|mixed $fees_and_limits
|
||||
* @property string|null $custom_value1
|
||||
* @property string|null $custom_value2
|
||||
* @property string|null $custom_value3
|
||||
|
||||
94
app/Repositories/CompanyGatewayRepository.php
Normal file
94
app/Repositories/CompanyGatewayRepository.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2025. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Utils\Ninja;
|
||||
use App\Models\Company;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Repositories\BaseRepository;
|
||||
|
||||
/**
|
||||
* CompanyGatewayRepository.
|
||||
*/
|
||||
class CompanyGatewayRepository extends BaseRepository
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function archive($company_gateway): CompanyGateway
|
||||
{
|
||||
|
||||
parent::archive($company_gateway);
|
||||
|
||||
$this->removeGatewayFromCompanyGatewayIds($company_gateway);
|
||||
|
||||
return $company_gateway;
|
||||
}
|
||||
|
||||
public function delete($company_gateway): CompanyGateway
|
||||
{
|
||||
parent::delete($company_gateway);
|
||||
|
||||
$this->removeGatewayFromCompanyGatewayIds($company_gateway);
|
||||
|
||||
return $company_gateway;
|
||||
}
|
||||
|
||||
public function restore($company_gateway): CompanyGateway
|
||||
{
|
||||
parent::restore($company_gateway);
|
||||
|
||||
$this->addGatewayToCompanyGatewayIds($company_gateway);
|
||||
|
||||
return $company_gateway;
|
||||
}
|
||||
|
||||
public function addGatewayToCompanyGatewayIds(CompanyGateway $company_gateway)
|
||||
{
|
||||
$company_gateway_ids = $company_gateway->company->getSetting('company_gateway_ids');
|
||||
|
||||
if(strlen($company_gateway_ids ?? '') > 2){
|
||||
$transformed_ids = collect($this->transformKeys(explode(',', $company_gateway_ids)))
|
||||
->push($company_gateway->hashed_id)
|
||||
->implode(",");
|
||||
|
||||
$company = $company_gateway->company;
|
||||
$settings = $company->settings;
|
||||
$settings->company_gateway_ids = $transformed_ids;
|
||||
$company->settings = $settings;
|
||||
$company->save();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function removeGatewayFromCompanyGatewayIds(CompanyGateway $company_gateway)
|
||||
{
|
||||
$company_gateway_ids = $company_gateway->company->getSetting('company_gateway_ids');
|
||||
|
||||
if(strpos($company_gateway_ids, $company_gateway->hashed_id) !== false){
|
||||
$transformed_ids = collect($this->transformKeys(explode(',', $company_gateway_ids)))
|
||||
->filter(function ($id) use ($company_gateway){
|
||||
return $id !== $company_gateway->hashed_id;
|
||||
})
|
||||
->implode(",");
|
||||
|
||||
$company = $company_gateway->company;
|
||||
$settings = $company->settings;
|
||||
$settings->company_gateway_ids = $transformed_ids;
|
||||
$company->settings = $settings;
|
||||
$company->save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -33,9 +33,12 @@ use App\Events\Invoice\InvoiceWasPaid;
|
||||
use App\Repositories\CreditRepository;
|
||||
use App\Repositories\PaymentRepository;
|
||||
use App\Events\Payment\PaymentWasCreated;
|
||||
use App\Utils\Traits\MakesHash;
|
||||
|
||||
class AutoBillInvoice extends AbstractService
|
||||
{
|
||||
use MakesHash;
|
||||
|
||||
private Client $client;
|
||||
|
||||
private array $used_credit = [];
|
||||
@@ -45,9 +48,7 @@ class AutoBillInvoice extends AbstractService
|
||||
|
||||
public function __construct(private Invoice $invoice, protected string $db)
|
||||
{
|
||||
|
||||
$this->client = $this->invoice->client;
|
||||
|
||||
}
|
||||
|
||||
public function run()
|
||||
@@ -55,7 +56,6 @@ class AutoBillInvoice extends AbstractService
|
||||
MultiDB::setDb($this->db);
|
||||
|
||||
/* @var \App\Modesl\Client $client */
|
||||
|
||||
$is_partial = false;
|
||||
|
||||
/* Is the invoice payable? */
|
||||
@@ -444,14 +444,32 @@ class AutoBillInvoice extends AbstractService
|
||||
*/
|
||||
public function getGateway($amount)
|
||||
{
|
||||
$company_gateway_ids = $this->client->getSetting('company_gateway_ids');
|
||||
|
||||
$transformed_ids = false;
|
||||
|
||||
//gateways are disabled!
|
||||
if($company_gateway_ids == "0") {
|
||||
return false;
|
||||
}
|
||||
elseif(strlen($company_gateway_ids ?? '') > 2){
|
||||
|
||||
// If the client has a special gateway configuration, we need to ensure we only use the ones that are enabled!
|
||||
$transformed_ids = $this->transformKeys(explode(',', $company_gateway_ids));
|
||||
}
|
||||
|
||||
//get all client gateway tokens and set the is_default one to the first record
|
||||
$gateway_tokens = \App\Models\ClientGatewayToken::query()
|
||||
->where('client_id', $this->client->id)
|
||||
->where('is_deleted', 0)
|
||||
->whereHas('gateway', function ($query) {
|
||||
->whereHas('gateway', function ($query) use ($transformed_ids) {
|
||||
$query->where('is_deleted', 0)
|
||||
->where('deleted_at', null);
|
||||
})->orderBy('is_default', 'DESC')
|
||||
->where('deleted_at', null)
|
||||
->when($transformed_ids, function ($q) use ($transformed_ids) {
|
||||
$q->whereIn('id', $transformed_ids);
|
||||
});
|
||||
})
|
||||
->orderBy('is_default', 'DESC')
|
||||
->get();
|
||||
|
||||
$filtered_gateways = $gateway_tokens->filter(function ($gateway_token) use ($amount) {
|
||||
|
||||
@@ -45,6 +45,44 @@ class CompanyGatewayApiTest extends TestCase
|
||||
Model::reguard();
|
||||
}
|
||||
|
||||
public function testCompanyGatewayIdsUpdateWhenAddingNewGateway()
|
||||
{
|
||||
$settings = $this->company->settings;
|
||||
$settings->company_gateway_ids = "Xe0Vjm5ybx,Xe00Aw9Lex,Xe0RpmK3Gb";
|
||||
$this->company->settings = $settings;
|
||||
$this->company->save();
|
||||
|
||||
$this->assertEquals("Xe0Vjm5ybx,Xe00Aw9Lex,Xe0RpmK3Gb", $this->company->getSetting('company_gateway_ids'));
|
||||
|
||||
$data = [
|
||||
'config' => 'random config',
|
||||
'gateway_key' => '3b6621f970ab18887c4f6dca78d3f8bb',
|
||||
];
|
||||
|
||||
/* POST */
|
||||
$response = $this->withHeaders([
|
||||
'X-API-SECRET' => config('ninja.api_secret'),
|
||||
'X-API-TOKEN' => $this->token,
|
||||
])->post('/api/v1/company_gateways', $data);
|
||||
|
||||
$cg = $response->json();
|
||||
|
||||
$cg_id = $cg['data']['id'];
|
||||
|
||||
$this->assertNotNull($cg_id);
|
||||
|
||||
$response->assertStatus(200);
|
||||
|
||||
$company = $this->company->fresh();
|
||||
|
||||
$settings = $company->settings;
|
||||
|
||||
$this->assertCount(4, explode(',', $company->getSetting('company_gateway_ids')));
|
||||
|
||||
$this->assertStringContainsString($cg_id, $company->getSetting('company_gateway_ids'));
|
||||
|
||||
}
|
||||
|
||||
public function testBulkActions()
|
||||
{
|
||||
$cg = CompanyGatewayFactory::create($this->company->id, $this->user->id);
|
||||
|
||||
@@ -12,12 +12,10 @@
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Jobs\Invoice\CheckGatewayFee;
|
||||
use App\Models\CompanyGateway;
|
||||
use App\Models\GatewayType;
|
||||
use App\Models\Invoice;
|
||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\MockAccountData;
|
||||
use Tests\TestCase;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user