1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 05:02:36 +01:00

Parsing bank transactions

This commit is contained in:
David Bomba 2022-08-17 11:52:16 +10:00
parent d348d2ce4e
commit 2d6888a6ec
6 changed files with 79 additions and 75 deletions

View File

@ -24,11 +24,11 @@ class Yodlee
private string $api_endpoint = 'https://production.api.yodlee.com/ysl'; private string $api_endpoint = 'https://production.api.yodlee.com/ysl';
// private string $test_api_endpoint = 'https://sandbox.api.yodlee.com/ysl'; private string $dev_api_endpoint = 'https://sandbox.api.yodlee.com/ysl';
private string $test_api_endpoint = 'https://development.api.yodlee.com/ysl'; private string $test_api_endpoint = 'https://development.api.yodlee.com/ysl';
//public string $test_fast_track_url = 'https://fl4.sandbox.yodlee.com/authenticate/restserver/fastlink'; public string $dev_fast_track_url = 'https://fl4.sandbox.yodlee.com/authenticate/restserver/fastlink';
public string $test_fast_track_url = 'https://fl4.preprod.yodlee.com/authenticate/USDevexPreProd3-449/fastlink?channelAppName=usdevexpreprod3'; public string $test_fast_track_url = 'https://fl4.preprod.yodlee.com/authenticate/USDevexPreProd3-449/fastlink?channelAppName=usdevexpreprod3';
@ -55,6 +55,8 @@ class Yodlee
$this->test_mode = config('ninja.yodlee.test_mode'); $this->test_mode = config('ninja.yodlee.test_mode');
config('ninja.yodlee.dev_mode') ? $this->setDevUrl() : null;
} }
public function getFastTrackUrl() public function getFastTrackUrl()
@ -69,6 +71,15 @@ class Yodlee
return $this; return $this;
} }
public function setDevUrl()
{
$this->test_api_endpoint = $this->dev_api_endpoint;
$this->api_endpoint = $this->dev_api_endpoint;
return $this;
}
public function getEndpoint() public function getEndpoint()
{ {
return $this->test_mode ? $this->test_api_endpoint : $this->api_endpoint; return $this->test_mode ? $this->test_api_endpoint : $this->api_endpoint;

View File

@ -30,14 +30,12 @@ class ProcessBankTransactions implements ShouldQueue
private BankIntegration $bank_integration; private BankIntegration $bank_integration;
private ?string $from_date; private string $from_date;
private string $default_date = '2022-01-01';
/** /**
* Create a new job instance. * Create a new job instance.
*/ */
public function __construct(string $bank_integration_account_id, BankIntegration $bank_integration, ?string $from_date) public function __construct(string $bank_integration_account_id, BankIntegration $bank_integration, string $from_date = '2022-01-01')
{ {
$this->bank_integration_account_id = $bank_integration_account_id; $this->bank_integration_account_id = $bank_integration_account_id;
$this->bank_integration = $bank_integration; $this->bank_integration = $bank_integration;
@ -56,9 +54,8 @@ class ProcessBankTransactions implements ShouldQueue
$yodlee = new Yodlee($this->bank_integration_account_id); $yodlee = new Yodlee($this->bank_integration_account_id);
$data = [ $data = [
'baseType' => 'DEBIT', //CREDIT
'top' => 500, 'top' => 500,
'fromDate' => $this->from_date ?: $this->default_date, /// YYYY-MM-DD 'fromDate' => $this->from_date, /// YYYY-MM-DD
'accountId' => $this->bank_integration->bank_account_id, 'accountId' => $this->bank_integration->bank_account_id,
]; ];
@ -68,6 +65,8 @@ class ProcessBankTransactions implements ShouldQueue
$company = $this->bank_integration->company; $company = $this->bank_integration->company;
$user_id = $company->owner()->id; $user_id = $company->owner()->id;
BankTransaction::unguard();
foreach($transactions as $transaction) foreach($transactions as $transaction)
{ {
@ -75,40 +74,13 @@ class ProcessBankTransactions implements ShouldQueue
continue; continue;
$bt = BankTransaction::create( $bt = BankTransaction::create(
$transaction array_merge($transaction,[
); 'company_id' => $company->id,
'user_id' => $user_id,
'bank_integration_id' => $this->bank_integration->id,
])
)->save();
$bt->company_id = $company->id;
$bt->user_id = $user_id;
$bt->base_type = 'DEBIT';
$bt->save();
}
$data = [
'baseType' => 'CREDIT', //CREDIT
'top' => 500,
'fromDate' => $this->from_date ?: $this->default_date, /// YYYY-MM-DD
'accountId' => $this->bank_integration->bank_account_id,
];
//income transactions
$transactions = $yodlee->getTransactions($data);
$bts = BankTransaction::whereIn('transaction_id', array_column($transactions, 'transaction_id'))->where('company_id', $company->id)->withTrashed()->get('transaction_id');
foreach($transactions as $transaction)
{
$bt = BankTransaction::create(
$transaction
);
$bt->company_id = $company->id;
$bt->user_id = $user_id;
$bt->base_type = 'CREDIT';
$bt->save();
} }
BankService::dispatch($company->id, $company->db); BankService::dispatch($company->id, $company->db);

View File

@ -76,36 +76,5 @@ class BankService implements ShouldQueue
}); });
} }
// public function match($transactions): array
// {
// foreach($transactions as $transaction)
// {
// $this->matchIncome($transaction);
// }
// return $transactions;
// }
// private function matchExpense()
// {
// }
// private function matchIncome($transaction)
// {
// $description = str_replace(" ", "", $transaction->description);
// $invoice = $this->invoices->first(function ($value, $key) use ($description){
// return str_contains($value->number, $description);
// });
// if($invoice)
// $transaction['invocie_id'] = $invoice->hashed_id;
// return $transaction;
// }
} }

View File

@ -205,6 +205,7 @@ return [
'client_secret' => env('YODLEE_CLIENT_SECRET', false), 'client_secret' => env('YODLEE_CLIENT_SECRET', false),
'admin_name' => env('YODLEE_LOGIN_ADMIN_NAME', false), 'admin_name' => env('YODLEE_LOGIN_ADMIN_NAME', false),
'test_mode' => env("YODLEE_TEST_MODE", false), 'test_mode' => env("YODLEE_TEST_MODE", false),
'dev_mode' => env("YODLEE_DEV_MODE", false),
'config_name' => env("YODLEE_CONFIG_NAME", false), 'config_name' => env("YODLEE_CONFIG_NAME", false),
], ],
]; ];

View File

@ -59,9 +59,8 @@ return new class extends Migration
$table->decimal('amount', 20, 6); $table->decimal('amount', 20, 6);
$table->string('currency_code'); $table->string('currency_code');
$table->string('account_type'); $table->string('account_type');
$table->string('base_type')->index();
$table->unsignedInteger('category_id'); $table->unsignedInteger('category_id');
$table->string('category_type'); $table->string('category_type')->index();
$table->date('date'); $table->date('date');
$table->unsignedBigInteger('bank_account_id'); $table->unsignedBigInteger('bank_account_id');
$table->text('description'); $table->text('description');

View File

@ -13,12 +13,18 @@
namespace Tests\Feature\Bank; namespace Tests\Feature\Bank;
use App\Helpers\Bank\Yodlee\Yodlee; use App\Helpers\Bank\Yodlee\Yodlee;
use App\Jobs\Bank\ProcessBankTransactions;
use App\Models\BankIntegration;
use App\Models\BankTransaction;
use App\Services\Bank\BankService;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Tests\MockAccountData;
use Tests\TestCase; use Tests\TestCase;
class YodleeApiTest extends TestCase class YodleeApiTest extends TestCase
{ {
use DatabaseTransactions; use DatabaseTransactions;
use MockAccountData;
protected function setUp(): void protected function setUp(): void
{ {
@ -26,9 +32,55 @@ class YodleeApiTest extends TestCase
if(!config('ninja.yodlee.client_id')) if(!config('ninja.yodlee.client_id'))
$this->markTestSkipped('Skip test no Yodlee API credentials found'); $this->markTestSkipped('Skip test no Yodlee API credentials found');
$this->makeTestData();
} }
public function testFunctionalMatching()
{
$yodlee = new Yodlee('sbMem62e1e69547bfb1');
$accounts = $yodlee->getAccounts();
foreach($accounts as $account)
{
if(!BankIntegration::where('bank_account_id', $account['id'])->where('company_id', $this->company->id)->exists())
{
$bank_integration = new BankIntegration();
$bank_integration->company_id = $this->company->id;
$bank_integration->account_id = $this->company->account_id;
$bank_integration->user_id = $this->user->id;
$bank_integration->bank_account_id = $account['id'];
$bank_integration->bank_account_type = $account['account_type'];
$bank_integration->bank_account_name = $account['account_name'];
$bank_integration->bank_account_status = $account['account_status'];
$bank_integration->bank_account_number = $account['account_number'];
$bank_integration->provider_id = $account['provider_id'];
$bank_integration->provider_name = $account['provider_name'];
$bank_integration->nickname = $account['nickname'];
$bank_integration->balance = $account['current_balance'];
$bank_integration->currency = $account['account_currency'];
$bank_integration->save();
ProcessBankTransactions::dispatchSync('sbMem62e1e69547bfb1', $bank_integration);
}
}
$this->assertGreaterThan(1, BankIntegration::count());
$this->assertGreaterThan(1, BankTransaction::count());
BankService::dispatchSync($this->company->id, $this->company->db);
// $transactions = $yodlee->getTransactions();
}
public function testDataMatching() public function testDataMatching()
{ {
@ -472,8 +524,8 @@ class YodleeApiTest extends TestCase
$accounts = $yodlee->getTransactions($data); $accounts = $yodlee->getTransactions($data);
$this->assertIsArray($accounts);
nlog($accounts);
} }
} }