1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-09-20 00:11:35 +02:00

dev-workaround for storing accountId + updates to transaction jobs + local fonts

This commit is contained in:
paulwer 2023-12-11 09:15:41 +01:00
parent 6200a8e3d3
commit cd4dbb897f
8 changed files with 119 additions and 92 deletions

View File

@ -49,7 +49,6 @@ class NordigenController extends BaseController
'institutions' => $nordigen->getInstitutions(),
'company' => $company,
'account' => $company->account,
'redirect' => config('ninja.app_url') . '/nordigen/connect',
];
return view('bank.nordigen.connect', $data);
@ -187,12 +186,13 @@ class NordigenController extends BaseController
$bank_integration->company_id = $company->id;
$bank_integration->account_id = $company->account_id;
$bank_integration->user_id = $company->owner()->id;
$bank_integration->bank_account_id = $nordigen_account['id'];
// $bank_integration->bank_account_id = $nordigen_account['id']; // TODO
$bank_integration->bank_account_type = $nordigen_account['account_type'];
$bank_integration->bank_account_name = $nordigen_account['account_name'];
$bank_integration->bank_account_status = $nordigen_account['account_status'];
$bank_integration->bank_account_number = $nordigen_account['account_number'];
$bank_integration->provider_id = $nordigen_account['provider_id'];
// $bank_integration->provider_id = $nordigen_account['provider_id']; // TODO
$bank_integration->nordigen_meta = (string) $nordigen_account['id'] . "," . $nordigen_account['provider_id']; // TODO: maybe move to bank_account_id and provider_id
$bank_integration->provider_name = $nordigen_account['provider_name'];
$bank_integration->nickname = $nordigen_account['nickname'];
$bank_integration->balance = $nordigen_account['current_balance'];

View File

@ -206,17 +206,19 @@ class BankIntegrationController extends BaseController
return response()->json(BankIntegration::query()->company(), 200);
// Processing transactions for each bank account
$user_account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_YODLEE)->each(function ($bank_integration) use ($user_account) {
if (!$user->account->bank_integration_yodlee_account_id)
$user_account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_YODLEE)->each(function ($bank_integration) use ($user_account) {
ProcessBankTransactionsYodlee::dispatch($user_account, $bank_integration);
ProcessBankTransactionsYodlee::dispatch($user_account, $bank_integration);
});
});
$user_account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->each(function ($bank_integration) use ($user_account) {
if (!$user->account->bank_integration_nordigen_secret_id || !$user->account->bank_integration_nordigen_secret_key)
$user_account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->each(function ($bank_integration) use ($user_account) {
ProcessBankTransactionsNordigen::dispatch($user_account, $bank_integration);
ProcessBankTransactionsNordigen::dispatch($user_account, $bank_integration);
});
});
Cache::put("throttle_polling:{$user_account->key}", true, 300);
@ -225,9 +227,8 @@ class BankIntegrationController extends BaseController
private function refreshAccountsYodlee(User $user)
{
if (!$user->account->bank_integration_yodlee_account_id) {
return response()->json(['message' => 'Not yet authenticated with Bank Integration service'], 400);
}
if (!$user->account->bank_integration_yodlee_account_id)
return;
$yodlee = new Yodlee($user->account->bank_integration_yodlee_account_id);
@ -263,36 +264,26 @@ class BankIntegrationController extends BaseController
private function refreshAccountsNordigen(User $user)
{
if (!$user->account->bank_integration_nordigen_secret_id || !$user->account->bank_integration_nordigen_secret_key)
return response()->json(['message' => 'Not yet authenticated with Bank Integration service'], 400);
return;
$nordigen = new Nordigen($user->account->bank_integration_nordigen_secret_id, $user->account->bank_integration_nordigen_secret_key);
$accounts = $nordigen->getAccounts(); // TODO?!
BankIntegration::withTrashed()->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->each(function (BankIntegration $bank_integration) use ($nordigen, $user) {
$account = $nordigen->getAccount(explode(',', $bank_integration->nordigen_meta)[0]);
foreach ($accounts as $account) {
if ($bi = BankIntegration::withTrashed()->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('bank_account_id', $account['id'])->where('company_id', $user->company()->id)->first()) {
$bi->balance = $account['current_balance'];
$bi->currency = $account['account_currency'];
$bi->save();
} else {
$bank_integration = new BankIntegration();
$bank_integration->company_id = $user->company()->id;
$bank_integration->account_id = $user->account_id;
$bank_integration->user_id = $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'];
if (!$account) {
$bank_integration->disabled_upstream = true;
$bank_integration->save();
return;
}
}
$bank_integration->bank_account_status = $account['account_status'];
$bank_integration->balance = $account['current_balance'];
$bank_integration->currency = $account['account_currency'];
$bank_integration->save();
});
}
/**
@ -314,8 +305,7 @@ class BankIntegrationController extends BaseController
if ($bank_integration->integration_type == BankIntegration::INTEGRATION_TYPE_YODLEE)
$this->removeAccountYodlee($account, $bank_integration);
else if ($bank_integration->integration_type == BankIntegration::INTEGRATION_TYPE_NORDIGEN)
$this->removeAccountNordigen($account, $bank_integration);
// we dont remove Accounts from nordigen, because they could be used within other companies
$this->bank_integration_repo->delete($bank_integration);
@ -332,16 +322,6 @@ class BankIntegrationController extends BaseController
$yodlee->deleteAccount($bank_integration->bank_account_id);
}
private function removeAccountNordigen(Account $account, BankIntegration $bank_integration)
{
if (!$account->bank_integration_nordigen_secret_id || !$account->bank_integration_nordigen_secret_key)
return response()->json(['message' => 'Not yet authenticated with Bank Integration service'], 400);
$nordigen = new Nordigen($account->bank_integration_nordigen_secret_id, $account->bank_integration_nordigen_secret_key);
$nordigen->deleteAccount($bank_integration->bank_account_id);
}
/**
* Return the remote list of accounts stored on the third party provider
* and update our local cache.

View File

@ -51,10 +51,7 @@ class ConnectNordigenBankIntegrationRequest extends Request
if (!array_key_exists('redirect', $input)) {
$context = $this->getTokenContent();
if ($context && array_key_exists('is_react', $context))
$input["redirect"] = $context["is_react"] ? config("ninja.react_url") : config("ninja.app_url");
else
$input["redirect"] = config("ninja.app_url");
$input["redirect"] = isset($context['is_react']) && $context['is_react'] ? config('ninja.react_url') : config('ninja.app_url');
$this->replace($input);

View File

@ -17,6 +17,7 @@ use App\Models\Account;
use App\Models\BankIntegration;
use App\Models\BankTransaction;
use App\Models\Company;
use App\Notifications\Ninja\GenericNinjaAdminNotification;
use App\Services\Bank\BankMatchingService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
@ -39,6 +40,8 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
private int $skip = 0;
public Company $company;
public Nordigen $nordigen;
public $nordigen_account;
/**
* Create a new job instance.
@ -53,6 +56,8 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
if ($this->bank_integration->integration_type != BankIntegration::INTEGRATION_TYPE_NORDIGEN)
throw new \Exception("Invalid BankIntegration Type");
$this->nordigen = new Nordigen($this->account->bank_integration_nordigen_secret_id, $this->account->bank_integration_nordigen_secret_key);
}
/**
@ -69,12 +74,39 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
//Loop through everything until we are up to date
$this->from_date = $this->from_date ?: '2021-01-01';
// UPDATE ACCOUNT
try {
$this->updateAccount();
} catch (\Exception $e) {
nlog("{$this->account->bank_integration_nordigen_secret_id} - exited abnormally => " . $e->getMessage());
$content = [
"Processing transactions for account: {$this->bank_integration->account->key} failed",
"Exception Details => ",
$e->getMessage(),
];
$this->bank_integration->company->notification(new GenericNinjaAdminNotification($content))->ninja();
return;
}
if (!$this->nordigen_account)
return;
// UPDATE TRANSACTIONS
do {
try {
$this->processTransactions();
} catch (\Exception $e) {
nlog("{$this->account->bank_integration_nordigen_secret_id} - exited abnormally => " . $e->getMessage());
$content = [
"Processing transactions for account: {$this->bank_integration->account->key} failed",
"Exception Details => ",
$e->getMessage(),
];
$this->bank_integration->company->notification(new GenericNinjaAdminNotification($content))->ninja();
return;
}
@ -85,13 +117,12 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
}
private function processTransactions()
private function updateAccount()
{
$nordigen = new Nordigen($this->account->bank_integration_nordigen_secret_id, $this->account->bank_integration_nordigen_secret_key); // TODO: maybe implement credentials
$bank_account_id = explode(',', $this->bank_integration->nordigen_meta)[0]; // maybe replace it later with bank_account_id
if (!$nordigen->isAccountActive($this->bank_integration->bank_account_id)) {
if (!$this->nordigen->isAccountActive($bank_account_id)) {
$this->bank_integration->disabled_upstream = true;
$this->bank_integration->save();
$this->stop_loop = false;
@ -99,8 +130,21 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
return;
}
$this->nordigen_account = $this->nordigen->getAccount($bank_account_id);
$this->bank_integration->bank_account_status = $this->nordigen_account['account_status'];
$this->bank_integration->balance = $this->nordigen_account['current_balance'];
$this->bank_integration->currency = $this->nordigen_account['account_currency'];
$this->bank_integration->save();
}
private function processTransactions()
{
//Get transaction count object
$transactions = $nordigen->getTransactions($this->bank_integration->bank_account_id, $this->from_date);
$transactions = $this->nordigen->getTransactions($this->nordigen_account["id"], $this->from_date);
//Get int count
$count = sizeof($transactions);
@ -108,7 +152,7 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
//if no transactions, update the from_date and move on
if (count($transactions) == 0) {
$this->bank_integration->from_date = now()->subDays(2);
$this->bank_integration->from_date = now()->subDays(5);
$this->bank_integration->disabled_upstream = false;
$this->bank_integration->save();
$this->stop_loop = false;
@ -133,7 +177,7 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
continue;
//this should be much faster to insert than using ::create()
$bt = \DB::table('bank_transactions')->insert(
\DB::table('bank_transactions')->insert(
array_merge($transaction, [
'company_id' => $this->company->id,
'user_id' => $user_id,
@ -146,14 +190,18 @@ class ProcessBankTransactionsNordigen implements ShouldQueue
}
$this->skip = $this->skip + 500;
// $this->skip = $this->skip + 500;
if ($count < 500) {
$this->stop_loop = false;
$this->bank_integration->from_date = now()->subDays(2);
$this->bank_integration->save();
// if ($count < 500) {
// $this->stop_loop = false;
// $this->bank_integration->from_date = now()->subDays(5);
// $this->bank_integration->save();
}
// }
$this->stop_loop = false;
$this->bank_integration->from_date = now()->subDays(5);
$this->bank_integration->save();
}
}

View File

@ -30,6 +30,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @property float $balance
* @property int|null $currency
* @property string $nickname
* @property string $nordigen_meta // TODO: maybe move to bank_account_id and provider_id
* @property string|null $from_date
* @property bool $is_deleted
* @property int|null $created_at

48
composer.lock generated
View File

@ -2617,16 +2617,16 @@
},
{
"name": "google/apiclient-services",
"version": "v0.326.1",
"version": "v0.327.0",
"source": {
"type": "git",
"url": "https://github.com/googleapis/google-api-php-client-services.git",
"reference": "4e89c28c499f87eb517679e13356469896a119c6"
"reference": "51a11d4ff70dd9f60334525e71bf4cf592e6d282"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/4e89c28c499f87eb517679e13356469896a119c6",
"reference": "4e89c28c499f87eb517679e13356469896a119c6",
"url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/51a11d4ff70dd9f60334525e71bf4cf592e6d282",
"reference": "51a11d4ff70dd9f60334525e71bf4cf592e6d282",
"shasum": ""
},
"require": {
@ -2655,9 +2655,9 @@
],
"support": {
"issues": "https://github.com/googleapis/google-api-php-client-services/issues",
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.326.1"
"source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.327.0"
},
"time": "2023-12-04T01:18:18+00:00"
"time": "2023-12-11T00:52:16+00:00"
},
{
"name": "google/auth",
@ -6831,16 +6831,16 @@
},
{
"name": "nikic/php-parser",
"version": "v4.17.1",
"version": "v4.18.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d"
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
"reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999",
"reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999",
"shasum": ""
},
"require": {
@ -6881,9 +6881,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1"
"source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0"
},
"time": "2023-08-13T19:53:39+00:00"
"time": "2023-12-10T21:03:43+00:00"
},
{
"name": "nordigen/nordigen-php",
@ -15318,16 +15318,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.41.0",
"version": "v3.41.1",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "7d8d18e19095a939b8a3b8046f57108feaad6134"
"reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7d8d18e19095a939b8a3b8046f57108feaad6134",
"reference": "7d8d18e19095a939b8a3b8046f57108feaad6134",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/8b6ae8dcbaf23f09680643ab832a4a3a260265f6",
"reference": "8b6ae8dcbaf23f09680643ab832a4a3a260265f6",
"shasum": ""
},
"require": {
@ -15397,7 +15397,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.41.0"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.41.1"
},
"funding": [
{
@ -15405,7 +15405,7 @@
"type": "github"
}
],
"time": "2023-12-08T22:54:33+00:00"
"time": "2023-12-10T19:59:27+00:00"
},
{
"name": "hamcrest/hamcrest-php",
@ -16184,16 +16184,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "10.1.9",
"version": "10.1.10",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "a56a9ab2f680246adcf3db43f38ddf1765774735"
"reference": "599109c8ca6bae97b23482d557d2874c25a65e59"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/a56a9ab2f680246adcf3db43f38ddf1765774735",
"reference": "a56a9ab2f680246adcf3db43f38ddf1765774735",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/599109c8ca6bae97b23482d557d2874c25a65e59",
"reference": "599109c8ca6bae97b23482d557d2874c25a65e59",
"shasum": ""
},
"require": {
@ -16250,7 +16250,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.9"
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.10"
},
"funding": [
{
@ -16258,7 +16258,7 @@
"type": "github"
}
],
"time": "2023-11-23T12:23:20+00:00"
"time": "2023-12-11T06:28:43+00:00"
},
{
"name": "phpunit/php-file-iterator",

View File

@ -16,6 +16,7 @@ return new class extends Migration {
{
Schema::table('bank_integrations', function (Blueprint $table) {
$table->string('integration_type')->nullable();
$table->string('nordigen_meta')->nullable(); // accountId,institutionId @todo: maybe replace with the following below
// $table->string('provider_id'); // migrate to string, because nordigen provides a string like: SANDBOXFINANCE_SFIN0000
// $table->string('bank_account_id'); // migrate to string, because nordigen uses uuid() strings
});

View File

@ -22,8 +22,8 @@
// Pass your redirect link after user has been authorized in institution
const config = {
// Text that will be displayed on the left side under the logo. Text is limited to 100 characters, and rest will be truncated.
text: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean mavdvd",
// Text that will be displayed on the left side under the logo. Text is limited to 100 characters, and rest will be truncated. @turbo124 replace with a translated version like ctrans()
text: "{{ $account && !$account->isPaid() ? 'Invoice Ninja' : (isset($company) && !is_null($company) ? $company->name : '') }} will gain access for your selected bank account. After selecting your institution you are redirected to theire front-page to complete the request with your account credentials.",
// Logo URL that will be shown below the modal form.
logoUrl: "{{ $account && !$account->isPaid() ? asset('images/invoiceninja-black-logo-2.png') : (isset($company) && !is_null($company) ? $company->present()->logo() : '') }}",
// Will display country list with corresponding institutions. When `countryFilter` is set to `false`, only list of institutions will be shown.
@ -32,7 +32,7 @@
styles: {
// Primary
// Link to google font
fontFamily: '/assets/fonts/Roboto-Regular.ttf',
fontFamily: new URL("assets/fonts/Roboto-Regular.ttf", window.location.origin).href,
fontSize: '15',
backgroundColor: '#F2F2F2',
textColor: '#222',
@ -58,7 +58,7 @@
const institutionId = institution.getAttribute('data-institution');
const url = new URL(window.location.href);
url.searchParams.set('institution_id', institutionId);
window.location.href = url.href;
w.location.href = url.href;
});
});