From 6f9baa1c37796f6a3394531cccd79d55c9aac8da Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 11 Aug 2022 14:19:35 +1000 Subject: [PATCH] Refresh and remove accounts --- app/Exceptions/YodleeApiException.php | 41 +++++++++++++ .../Yodlee/Transformer/AccountTransformer.php | 4 +- .../Yodlee/Transformer/IncomeTransformer.php | 2 +- app/Helpers/Bank/Yodlee/Yodlee.php | 18 ++++++ .../Controllers/Bank/YodleeController.php | 19 +----- .../Controllers/BankIntegrationController.php | 58 +++++++++++++++++-- app/Models/BankIntegration.php | 3 + .../BankIntegrationTransformer.php | 6 +- .../2022_08_05_023357_bank_integration.php | 2 +- routes/api.php | 5 +- 10 files changed, 129 insertions(+), 29 deletions(-) create mode 100644 app/Exceptions/YodleeApiException.php diff --git a/app/Exceptions/YodleeApiException.php b/app/Exceptions/YodleeApiException.php new file mode 100644 index 0000000000..c5c4458e5e --- /dev/null +++ b/app/Exceptions/YodleeApiException.php @@ -0,0 +1,41 @@ +getMessage() && strlen($this->getMessage()) >= 1) { + $msg = $this->getMessage(); + } + + return response()->json([ + 'message' => $msg, + ], 400); + } +} diff --git a/app/Helpers/Bank/Yodlee/Transformer/AccountTransformer.php b/app/Helpers/Bank/Yodlee/Transformer/AccountTransformer.php index c8a4359aee..1f045a58f8 100644 --- a/app/Helpers/Bank/Yodlee/Transformer/AccountTransformer.php +++ b/app/Helpers/Bank/Yodlee/Transformer/AccountTransformer.php @@ -71,7 +71,7 @@ class AccountTransformer implements AccountTransformerInterface $data = []; if(!property_exists($yodlee_account, 'account')) - return []; + return $data; foreach($yodlee_account->account as $account) { @@ -93,7 +93,7 @@ class AccountTransformer implements AccountTransformerInterface 'provider_account_id' => $account->providerAccountId, 'provider_id' => $account->providerId, 'provider_name' => $account->providerName, - 'nickname' => $account?->nickname, + 'nickname' => property_exists($account, 'nickname') ? $account->nickname : '', 'current_balance' => property_exists($account, 'currentBalance') ? $account->currentBalance->amount : 0, 'account_currency' => property_exists($account, 'currency') ? $account->currentBalance->currency : '', ]; diff --git a/app/Helpers/Bank/Yodlee/Transformer/IncomeTransformer.php b/app/Helpers/Bank/Yodlee/Transformer/IncomeTransformer.php index 8fde691498..fd9f207a48 100644 --- a/app/Helpers/Bank/Yodlee/Transformer/IncomeTransformer.php +++ b/app/Helpers/Bank/Yodlee/Transformer/IncomeTransformer.php @@ -120,7 +120,7 @@ class IncomeTransformer implements BankRevenueInterface $data = []; if(!property_exists($transaction, 'transaction')) - return []; + return $data; foreach($transaction->transaction as $transaction) { diff --git a/app/Helpers/Bank/Yodlee/Yodlee.php b/app/Helpers/Bank/Yodlee/Yodlee.php index 59d42602dd..24826b04dd 100644 --- a/app/Helpers/Bank/Yodlee/Yodlee.php +++ b/app/Helpers/Bank/Yodlee/Yodlee.php @@ -153,12 +153,30 @@ class Yodlee } + if($response->failed()) + throw new YodleeApiException($response->body()); + + } + + public function deleteAccount($account_id) + { + + $token = $this->getAccessToken(); + + $response = Http::withHeaders($this->getHeaders(["Authorization" => "Bearer {$token}"]))->delete($this->getEndpoint(). "/accounts/{$account_id}", []); + + if($response->successful()){ + + return true; + + } if($response->failed()) throw new YodleeApiException($response->body()); } + public function getTransactions($params = []) { $token = $this->getAccessToken(); diff --git a/app/Http/Controllers/Bank/YodleeController.php b/app/Http/Controllers/Bank/YodleeController.php index 704476e736..1de1e6e13c 100644 --- a/app/Http/Controllers/Bank/YodleeController.php +++ b/app/Http/Controllers/Bank/YodleeController.php @@ -14,6 +14,7 @@ namespace App\Http\Controllers\Bank; use App\Helpers\Bank\Yodlee\Yodlee; use App\Http\Controllers\BaseController; use App\Http\Requests\Yodlee\YodleeAuthRequest; +use App\Models\BankIntegration; use Illuminate\Http\Request; class YodleeController extends BaseController @@ -50,9 +51,6 @@ class YodleeController extends BaseController $yodlee = new Yodlee($token); $yodlee->setTestMode(); - if(!is_string($token)) - dd($token); - $data = [ 'access_token' => $yodlee->getAccessToken(), 'fasttrack_url' => $yodlee->getFastTrackUrl(), @@ -66,18 +64,5 @@ class YodleeController extends BaseController } - public function refreshAccounts(YodleeAdminRequest $request) - { - - $token = auth()->user()->account->bank_integration_account_id; - - if(!$token) - return response()->json(['message' => 'No bank integrations are present. Please add a bank account. '],400); - - $yodlee = new Yodlee($token); - $yodlee->setTestMode(); - - $yodlee->getAccounts(); - } - + } diff --git a/app/Http/Controllers/BankIntegrationController.php b/app/Http/Controllers/BankIntegrationController.php index 725bd2275a..3d2d3c6183 100644 --- a/app/Http/Controllers/BankIntegrationController.php +++ b/app/Http/Controllers/BankIntegrationController.php @@ -426,8 +426,8 @@ class BankIntegrationController extends BaseController * * * @OA\Post( - * path="/api/v1/bank_integrations/remote_accounts", - * operationId="getRemoteAccounts", + * path="/api/v1/bank_integrations/refresh_accounts", + * operationId="getRefreshAccounts", * tags={"bank_integrations"}, * summary="Gets the list of accounts from the remote server", * description="Adds an bank_integration to a company", @@ -456,7 +456,7 @@ class BankIntegrationController extends BaseController * ), * ) */ - public function remoteAccounts(AdminBankIntegrationRequest $request) + public function refreshAccounts(AdminBankIntegrationRequest $request) { // As yodlee is the first integration we don't need to perform switches yet, however // if we add additional providers we can reuse this class @@ -467,12 +467,61 @@ class BankIntegrationController extends BaseController return response()->json(['message' => 'Not yet authenticated with Bank Integration service'], 400); $yodlee = new Yodlee($bank_account_id); + $yodlee->setTestMode(); $accounts = $yodlee->getAccounts(); - return response()->json($accounts, 200); + foreach($accounts as $account) + { + + if(!BankIntegration::where('bank_account_id', $account['id'])->where('company_id', auth()->user()->company()->id)->exists()) + { + $bank_integration = new BankIntegration(); + $bank_integration->company_id = auth()->user()->company()->id; + $bank_integration->account_id = auth()->user()->account_id; + $bank_integration->user_id = auth()->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(); + } + } + + + return response()->json(BankIntegration::query()->company(), 200); } + public function removeAccount(AdminBankIntegrationRequest $request, $acc_id) + { + + $bank_account_id = auth()->user()->account->bank_integration_account_id; + + if(!$bank_account_id) + return response()->json(['message' => 'Not yet authenticated with Bank Integration service'], 400); + + $company_id = auth()->user()->company()->id; + + $bi = BankIntegration::withTrashed()->where('bank_account_id', $acc_id)->where('company_id', $company_id)->firstOrFail(); + + $yodlee = new Yodlee($bank_account_id); + $yodlee->setTestMode(); + $res = $yodlee->deleteAccount($acc_id); + + $this->bank_integration_repo->delete($bi); + + return $this->itemResponse($bi->fresh()); + + } + + public function getTransactions(AdminBankIntegrationRequest $request) { //handle API failures we have only accounts for success @@ -498,7 +547,6 @@ class BankIntegrationController extends BaseController $transactions = (new BankService(auth()->user()->company()))->match(); - return response()->json($transactions, 200, [], JSON_PRETTY_PRINT); } diff --git a/app/Models/BankIntegration.php b/app/Models/BankIntegration.php index 9f8d4c74f0..8791169803 100644 --- a/app/Models/BankIntegration.php +++ b/app/Models/BankIntegration.php @@ -11,8 +11,11 @@ namespace App\Models; +use Illuminate\Database\Eloquent\SoftDeletes; + class BankIntegration extends BaseModel { + use SoftDeletes; protected $fillable = [ ]; diff --git a/app/Transformers/BankIntegrationTransformer.php b/app/Transformers/BankIntegrationTransformer.php index a33cce27d2..6845e41a55 100644 --- a/app/Transformers/BankIntegrationTransformer.php +++ b/app/Transformers/BankIntegrationTransformer.php @@ -47,7 +47,7 @@ class BankIntegrationTransformer extends EntityTransformer { return [ 'id' => (string) $this->encodePrimaryKey($bank_integration->id), - 'provider_bank_name' => (string)$bank_integration->provider_bank_name ?: '', + 'provider_name' => (string)$bank_integration->provider_name ?: '', 'provider_id' => (int) $bank_integration->provider_id ?: 0, 'bank_account_id' => (int) $bank_integration->bank_account_id ?: 0, 'bank_account_name' => (string) $bank_integration->bank_account_name ?: '', @@ -57,6 +57,10 @@ class BankIntegrationTransformer extends EntityTransformer 'balance' => (float)$bank_integration->balance ?: 0, 'currency' => (string)$bank_integration->currency ?: '', 'nickname' => (string)$bank_integration->nickname ?: '', + 'is_deleted' => (bool) $bank_integration->is_deleted, + 'created_at' => (int) $bank_integration->created_at, + 'updated_at' => (int) $bank_integration->updated_at, + 'archived_at' => (int) $bank_integration->deleted_at, ]; } diff --git a/database/migrations/2022_08_05_023357_bank_integration.php b/database/migrations/2022_08_05_023357_bank_integration.php index f39de10f83..00833aad91 100644 --- a/database/migrations/2022_08_05_023357_bank_integration.php +++ b/database/migrations/2022_08_05_023357_bank_integration.php @@ -20,7 +20,7 @@ return new class extends Migration $table->unsignedInteger('company_id'); $table->unsignedInteger('user_id'); - $table->text('provider_bank_name'); //providerName ie Chase + $table->text('provider_name'); //providerName ie Chase $table->bigInteger('provider_id'); //id of the bank $table->bigInteger('bank_account_id'); //id $table->text('bank_account_name')->nullable(); //accountName diff --git a/routes/api.php b/routes/api.php index 962f6d8a48..abd18b0025 100644 --- a/routes/api.php +++ b/routes/api.php @@ -107,9 +107,10 @@ Route::group(['middleware' => ['throttle:10,1','api_secret_check','email_db']], Route::group(['middleware' => ['throttle:300,1', 'api_db', 'token_auth', 'locale'], 'prefix' => 'api/v1', 'as' => 'api.'], function () { Route::put('accounts/{account}', [AccountController::class, 'update'])->name('account.update'); Route::resource('bank_integrations', BankIntegrationController::class); // name = (clients. index / create / show / update / destroy / edit - Route::post('bank_integrations/remote_accounts', [BankIntegrationController::class, 'remoteAccounts'])->name('bank_integrations.remote_accounts'); + Route::post('bank_integrations/refresh_accounts', [BankIntegrationController::class, 'refreshAccounts'])->name('bank_integrations.refresh_accounts'); Route::post('bank_integrations/transactions', [BankIntegrationController::class, 'getTransactions'])->name('bank_integrations.transactions'); - + Route::post('bank_integrations/remove_account/{acc_id}', [BankIntegrationController::class, 'removeAccount'])->name('bank_integrations.remove_account'); + Route::post('check_subdomain', [SubdomainController::class, 'index'])->name('check_subdomain'); Route::get('ping', [PingController::class, 'index'])->name('ping'); Route::get('health_check', [PingController::class, 'health'])->name('health_check');