Find old EUA to get tx_days for new agreement
The end user agreement ID isn't stored with the bank integration, but it *is* returned as part of the error for an expired account which works perfectly for the case of renewing an expired requisition. When `tx_days` isn't set in the request (i.e. it's a renewal) we instead extract the EUA ID from the account error after getting the integration, then once we have the EUA we're able to restore the old tx_days setting. Since the BankIntegration query is used in both endpoints, this moves it to a method with `firstOrFail()` rather than `first()` which also allows for a cleanup of the integration saving code with try/catch/finally to make it a little clearer which values apply to both new+existing cases.
This commit is contained in:
parent
d87d4580be
commit
fb47c29c91
|
|
@ -60,7 +60,30 @@ class Nordigen
|
|||
return $this->client->institution->getInstitutions();
|
||||
}
|
||||
|
||||
// requisition-section
|
||||
/**
|
||||
* Get end user agreement details by ID.
|
||||
*
|
||||
* @return array{
|
||||
* id: string,
|
||||
* created: string,
|
||||
* institution_id: string,
|
||||
* max_historical_days: int,
|
||||
* access_valid_for_days: int,
|
||||
* access_scope: string[],
|
||||
* accepted: string
|
||||
* } Agreement details
|
||||
*/
|
||||
public function getAgreement(string $euaId): array {
|
||||
$eua = $this->client->endUserAgreement->getEndUserAgreement($euaId);
|
||||
|
||||
return $eua;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Bank Requisition
|
||||
*
|
||||
* @param array{id: string} $institution
|
||||
*/
|
||||
public function createRequisition(
|
||||
string $redirect,
|
||||
array $institution,
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ use App\Http\Requests\Nordigen\ConfirmNordigenBankIntegrationRequest;
|
|||
use App\Http\Requests\Nordigen\ConnectNordigenBankIntegrationRequest;
|
||||
use App\Jobs\Bank\ProcessBankTransactionsNordigen;
|
||||
use App\Models\BankIntegration;
|
||||
use App\Models\Company;
|
||||
use App\Utils\Ninja;
|
||||
use Cache;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
use Nordigen\NordigenPHP\Exceptions\NordigenExceptions\NordigenException;
|
||||
|
|
@ -76,6 +78,21 @@ class NordigenController extends BaseController
|
|||
return $institution['id'] == $data['institution_id'];
|
||||
}))[0];
|
||||
|
||||
// Renewals have an Institution ID, but bypass the history selection screen
|
||||
// and thus lack the history setting, so we can find the Agreement ID here.
|
||||
if (!isset($data['tx_days'])) {
|
||||
// Query the integration so we get the correct Account ID
|
||||
$integration = $this->findIntegrationBy('institution', $institution, $company);
|
||||
|
||||
// Extract the EUA ID from the expired account error
|
||||
$match = '/End User Agreement \(EUA\) ([0-9a-f-]+) has expired/';
|
||||
$nordigenAccount = $nordigen->getAccount($integration->nordigen_account_id);
|
||||
$euaId = preg_replace($match, '${1}', $nordigenAccount['error']);
|
||||
|
||||
// Fetch the old agreement and maintain its history setting
|
||||
$data['tx_days'] = $nordigen->getAgreement($euaId)['max_historical_days'];
|
||||
}
|
||||
|
||||
// redirect to requisition flow
|
||||
try {
|
||||
$requisition = $nordigen->createRequisition(
|
||||
|
|
@ -156,18 +173,19 @@ class NordigenController extends BaseController
|
|||
// connect new accounts
|
||||
$bank_integration_ids = [];
|
||||
foreach ($requisition["accounts"] as $nordigenAccountId) {
|
||||
|
||||
$nordigen_account = $nordigen->getAccount($nordigenAccountId);
|
||||
|
||||
if (isset($nordigen_account['error'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$existing_bank_integration = BankIntegration::withTrashed()->where('nordigen_account_id', $nordigen_account['id'])->where('company_id', $company->id)->where('is_deleted', 0)->first();
|
||||
|
||||
if (!$existing_bank_integration) {
|
||||
try {
|
||||
$bank_integration = $this->findIntegrationBy('account', $nordigen_account, $company);
|
||||
|
||||
$bank_integration->deleted_at = null;
|
||||
} catch (ModelNotFoundException $e) {
|
||||
$bank_integration = new BankIntegration();
|
||||
|
||||
$bank_integration->integration_type = BankIntegration::INTEGRATION_TYPE_NORDIGEN;
|
||||
$bank_integration->company_id = $company->id;
|
||||
$bank_integration->account_id = $company->account_id;
|
||||
|
|
@ -175,42 +193,31 @@ class NordigenController extends BaseController
|
|||
$bank_integration->nordigen_account_id = $nordigen_account['id'];
|
||||
$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->nordigen_institution_id = $nordigen_account['provider_id'];
|
||||
$bank_integration->provider_name = $nordigen_account['provider_name'];
|
||||
$bank_integration->nickname = $nordigen_account['nickname'];
|
||||
$bank_integration->balance = $nordigen_account['current_balance'];
|
||||
$bank_integration->currency = $nordigen_account['account_currency'];
|
||||
$bank_integration->disabled_upstream = false;
|
||||
} finally {
|
||||
$bank_integration->auto_sync = true;
|
||||
$bank_integration->disabled_upstream = false;
|
||||
$bank_integration->balance = $nordigen_account['current_balance'];
|
||||
$bank_integration->bank_account_status = $nordigen_account['account_status'];
|
||||
$bank_integration->from_date = now()->subDays($nordigen_account['provider_history']);
|
||||
|
||||
$bank_integration->save();
|
||||
|
||||
array_push($bank_integration_ids, $bank_integration->id);
|
||||
|
||||
} else {
|
||||
|
||||
// resetting metadata for account status
|
||||
$existing_bank_integration->balance = $nordigen_account['current_balance'];
|
||||
$existing_bank_integration->bank_account_status = $nordigen_account['account_status'];
|
||||
$existing_bank_integration->disabled_upstream = false;
|
||||
$existing_bank_integration->auto_sync = true;
|
||||
$existing_bank_integration->from_date = now()->subDays($nordigen_account['provider_history']);
|
||||
$existing_bank_integration->deleted_at = null;
|
||||
|
||||
$existing_bank_integration->save();
|
||||
|
||||
array_push($bank_integration_ids, $existing_bank_integration->id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// perform update in background
|
||||
$company->account->bank_integrations->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)->where('auto_sync', true)->each(function ($bank_integration) {
|
||||
ProcessBankTransactionsNordigen::dispatch($bank_integration);
|
||||
});
|
||||
$company->account->bank_integrations
|
||||
->where("integration_type", BankIntegration::INTEGRATION_TYPE_NORDIGEN)
|
||||
->where('auto_sync', true)
|
||||
->each(function ($bank_integration) {
|
||||
ProcessBankTransactionsNordigen::dispatch($bank_integration);
|
||||
});
|
||||
|
||||
// prevent rerun of this method with same ref
|
||||
Cache::delete($data["ref"]);
|
||||
|
|
@ -242,6 +249,24 @@ class NordigenController extends BaseController
|
|||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first available Bank Integration from its Nordigen account or institution.
|
||||
*
|
||||
* @param 'account'|'institution' $key
|
||||
* @param array{id: string} $accountOrInstitution
|
||||
*/
|
||||
private function findIntegrationBy(
|
||||
string $key,
|
||||
array $accountOrInstitution,
|
||||
Company $company,
|
||||
): BankIntegration {
|
||||
return BankIntegration::withTrashed()
|
||||
->where("nordigen_{$key}_id", $accountOrInstitution['id'])
|
||||
->where('company_id', $company->id)
|
||||
->where('is_deleted', 0)
|
||||
->firstOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of available banking institutions from Nordigen
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue