1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-12 22:22:32 +01:00

Refresh and remove accounts

This commit is contained in:
David Bomba 2022-08-11 14:19:35 +10:00
parent f7eb506e0d
commit 6f9baa1c37
10 changed files with 129 additions and 29 deletions

View File

@ -0,0 +1,41 @@
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class YodleeApiException extends Exception
{
/**
* Report the exception.
*
* @return void
*/
public function report()
{
//
}
/**
* Render the exception into an HTTP response.
*
* @param Request $request
* @return Response
*/
public function render($request)
{
// $msg = 'Unable to refund the transaction';
$msg = ctrans('texts.error');
if ($this->getMessage() && strlen($this->getMessage()) >= 1) {
$msg = $this->getMessage();
}
return response()->json([
'message' => $msg,
], 400);
}
}

View File

@ -71,7 +71,7 @@ class AccountTransformer implements AccountTransformerInterface
$data = []; $data = [];
if(!property_exists($yodlee_account, 'account')) if(!property_exists($yodlee_account, 'account'))
return []; return $data;
foreach($yodlee_account->account as $account) foreach($yodlee_account->account as $account)
{ {
@ -93,7 +93,7 @@ class AccountTransformer implements AccountTransformerInterface
'provider_account_id' => $account->providerAccountId, 'provider_account_id' => $account->providerAccountId,
'provider_id' => $account->providerId, 'provider_id' => $account->providerId,
'provider_name' => $account->providerName, 'provider_name' => $account->providerName,
'nickname' => $account?->nickname, 'nickname' => property_exists($account, 'nickname') ? $account->nickname : '',
'current_balance' => property_exists($account, 'currentBalance') ? $account->currentBalance->amount : 0, 'current_balance' => property_exists($account, 'currentBalance') ? $account->currentBalance->amount : 0,
'account_currency' => property_exists($account, 'currency') ? $account->currentBalance->currency : '', 'account_currency' => property_exists($account, 'currency') ? $account->currentBalance->currency : '',
]; ];

View File

@ -120,7 +120,7 @@ class IncomeTransformer implements BankRevenueInterface
$data = []; $data = [];
if(!property_exists($transaction, 'transaction')) if(!property_exists($transaction, 'transaction'))
return []; return $data;
foreach($transaction->transaction as $transaction) foreach($transaction->transaction as $transaction)
{ {

View File

@ -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()) if($response->failed())
throw new YodleeApiException($response->body()); throw new YodleeApiException($response->body());
} }
public function getTransactions($params = []) public function getTransactions($params = [])
{ {
$token = $this->getAccessToken(); $token = $this->getAccessToken();

View File

@ -14,6 +14,7 @@ namespace App\Http\Controllers\Bank;
use App\Helpers\Bank\Yodlee\Yodlee; use App\Helpers\Bank\Yodlee\Yodlee;
use App\Http\Controllers\BaseController; use App\Http\Controllers\BaseController;
use App\Http\Requests\Yodlee\YodleeAuthRequest; use App\Http\Requests\Yodlee\YodleeAuthRequest;
use App\Models\BankIntegration;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class YodleeController extends BaseController class YodleeController extends BaseController
@ -50,9 +51,6 @@ class YodleeController extends BaseController
$yodlee = new Yodlee($token); $yodlee = new Yodlee($token);
$yodlee->setTestMode(); $yodlee->setTestMode();
if(!is_string($token))
dd($token);
$data = [ $data = [
'access_token' => $yodlee->getAccessToken(), 'access_token' => $yodlee->getAccessToken(),
'fasttrack_url' => $yodlee->getFastTrackUrl(), '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();
}
} }

View File

@ -426,8 +426,8 @@ class BankIntegrationController extends BaseController
* *
* *
* @OA\Post( * @OA\Post(
* path="/api/v1/bank_integrations/remote_accounts", * path="/api/v1/bank_integrations/refresh_accounts",
* operationId="getRemoteAccounts", * operationId="getRefreshAccounts",
* tags={"bank_integrations"}, * tags={"bank_integrations"},
* summary="Gets the list of accounts from the remote server", * summary="Gets the list of accounts from the remote server",
* description="Adds an bank_integration to a company", * 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 // 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 // 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); return response()->json(['message' => 'Not yet authenticated with Bank Integration service'], 400);
$yodlee = new Yodlee($bank_account_id); $yodlee = new Yodlee($bank_account_id);
$yodlee->setTestMode();
$accounts = $yodlee->getAccounts(); $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) public function getTransactions(AdminBankIntegrationRequest $request)
{ {
//handle API failures we have only accounts for success //handle API failures we have only accounts for success
@ -498,7 +547,6 @@ class BankIntegrationController extends BaseController
$transactions = (new BankService(auth()->user()->company()))->match(); $transactions = (new BankService(auth()->user()->company()))->match();
return response()->json($transactions, 200, [], JSON_PRETTY_PRINT); return response()->json($transactions, 200, [], JSON_PRETTY_PRINT);
} }

View File

@ -11,8 +11,11 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\SoftDeletes;
class BankIntegration extends BaseModel class BankIntegration extends BaseModel
{ {
use SoftDeletes;
protected $fillable = [ protected $fillable = [
]; ];

View File

@ -47,7 +47,7 @@ class BankIntegrationTransformer extends EntityTransformer
{ {
return [ return [
'id' => (string) $this->encodePrimaryKey($bank_integration->id), '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, 'provider_id' => (int) $bank_integration->provider_id ?: 0,
'bank_account_id' => (int) $bank_integration->bank_account_id ?: 0, 'bank_account_id' => (int) $bank_integration->bank_account_id ?: 0,
'bank_account_name' => (string) $bank_integration->bank_account_name ?: '', 'bank_account_name' => (string) $bank_integration->bank_account_name ?: '',
@ -57,6 +57,10 @@ class BankIntegrationTransformer extends EntityTransformer
'balance' => (float)$bank_integration->balance ?: 0, 'balance' => (float)$bank_integration->balance ?: 0,
'currency' => (string)$bank_integration->currency ?: '', 'currency' => (string)$bank_integration->currency ?: '',
'nickname' => (string)$bank_integration->nickname ?: '', '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,
]; ];
} }

View File

@ -20,7 +20,7 @@ return new class extends Migration
$table->unsignedInteger('company_id'); $table->unsignedInteger('company_id');
$table->unsignedInteger('user_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('provider_id'); //id of the bank
$table->bigInteger('bank_account_id'); //id $table->bigInteger('bank_account_id'); //id
$table->text('bank_account_name')->nullable(); //accountName $table->text('bank_account_name')->nullable(); //accountName

View File

@ -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::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::put('accounts/{account}', [AccountController::class, 'update'])->name('account.update');
Route::resource('bank_integrations', BankIntegrationController::class); // name = (clients. index / create / show / update / destroy / edit 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/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::post('check_subdomain', [SubdomainController::class, 'index'])->name('check_subdomain');
Route::get('ping', [PingController::class, 'index'])->name('ping'); Route::get('ping', [PingController::class, 'index'])->name('ping');
Route::get('health_check', [PingController::class, 'health'])->name('health_check'); Route::get('health_check', [PingController::class, 'health'])->name('health_check');