Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle edge case with Nordigen where account appears active #9362

Merged
merged 4 commits into from Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions app/Helpers/Bank/Nordigen/Nordigen.php
Expand Up @@ -97,11 +97,11 @@ public function getAccount(string $account_id)
return $it->transform($out);

} catch (\Exception $e) {
if (strpos($e->getMessage(), "Invalid Account ID") !== false) {
return false;
}

throw $e;
nlog("Nordigen getAccount() failed => {$account_id} => " . $e->getMessage());

return false;

}
}

Expand Down
4 changes: 4 additions & 0 deletions app/Http/Requests/Project/StoreProjectRequest.php
Expand Up @@ -44,6 +44,7 @@ public function rules()

$rules['name'] = 'required';
$rules['client_id'] = 'required|exists:clients,id,company_id,'.$user->company()->id;
$rules['budgeted_hours'] = 'sometimes|numeric';

if (isset($this->number)) {
$rules['number'] = Rule::unique('projects')->where('company_id', $user->company()->id);
Expand Down Expand Up @@ -74,6 +75,9 @@ public function prepareForValidation()
$input['color'] = '';
}

if(array_key_exists('budgeted_hours', $input) && empty($input['budgeted_hours']))
$input['budgeted_hours'] = 0;

$this->replace($input);
}

Expand Down
6 changes: 6 additions & 0 deletions app/Http/Requests/Project/UpdateProjectRequest.php
Expand Up @@ -45,6 +45,8 @@ public function rules()
$rules['number'] = Rule::unique('projects')->where('company_id', $user->company()->id)->ignore($this->project->id);
}

$rules['budgeted_hours'] = 'sometimes|numeric';

if ($this->file('documents') && is_array($this->file('documents'))) {
$rules['documents.*'] = $this->file_validation;
} elseif ($this->file('documents')) {
Expand Down Expand Up @@ -73,6 +75,10 @@ public function prepareForValidation()
if (array_key_exists('color', $input) && is_null($input['color'])) {
$input['color'] = '';
}

if(array_key_exists('budgeted_hours', $input) && empty($input['budgeted_hours'])) {
$input['budgeted_hours'] = 0;
}

$this->replace($input);
}
Expand Down
13 changes: 8 additions & 5 deletions app/Jobs/Bank/ProcessBankTransactionsNordigen.php
Expand Up @@ -114,23 +114,26 @@ public function handle()

private function updateAccount()
{
if (!$this->nordigen->isAccountActive($this->bank_integration->nordigen_account_id)) {
$is_account_active = $this->nordigen->isAccountActive($this->bank_integration->nordigen_account_id);
$account = $this->nordigen->getAccount($this->bank_integration->nordigen_account_id);

if (!$is_account_active || !$account) {
$this->bank_integration->disabled_upstream = true;
$this->bank_integration->save();
$this->stop_loop = false;

nlog("Nordigen: account inactive: " . $this->bank_integration->nordigen_account_id);
// @turbo124 @todo send email for expired account

$this->nordigen->disabledAccountEmail($this->bank_integration);

return;
}

$this->nordigen_account = $this->nordigen->getAccount($this->bank_integration->nordigen_account_id);
$this->nordigen_account = $account;

$this->bank_integration->disabled_upstream = false;
$this->bank_integration->bank_account_status = $this->nordigen_account['account_status'];
$this->bank_integration->balance = $this->nordigen_account['current_balance'];
$this->bank_integration->bank_account_status = $account['account_status'];
$this->bank_integration->balance = $account['current_balance'];

$this->bank_integration->save();
}
Expand Down
6 changes: 6 additions & 0 deletions app/Transformers/ProjectTransformer.php
Expand Up @@ -49,6 +49,12 @@ public function includeDocuments(Project $project)

public function includeClient(Project $project): \League\Fractal\Resource\Item
{

if (!$project->client) {
nlog("Project {$project->hashed_id} does not have a client attached - this project is in a bad state");
return null;
}

$transformer = new ClientTransformer($this->serializer);

return $this->includeItem($project->client, $transformer, Client::class);
Expand Down
5 changes: 4 additions & 1 deletion lang/en/texts.php
Expand Up @@ -460,7 +460,7 @@
'edit_token' => 'Edit Token',
'delete_token' => 'Delete Token',
'token' => 'Token',
'add_gateway' => 'Add Gateway',
'add_gateway' => 'Add Payment Gateway',
'delete_gateway' => 'Delete Gateway',
'edit_gateway' => 'Edit Gateway',
'updated_gateway' => 'Successfully updated gateway',
Expand Down Expand Up @@ -5251,6 +5251,9 @@
'payment_type_help' => 'The default payment type to be used for payments',
'quote_valid_until_help' => 'The number of days that the quote is valid for',
'expense_payment_type_help' => 'The default expense payment type to be used',
'paylater' => 'Pay in 4',
'payment_provider' => 'Payment Provider',

);

return $lang;
106 changes: 106 additions & 0 deletions tests/Feature/ProjectApiTest.php
Expand Up @@ -29,6 +29,8 @@ class ProjectApiTest extends TestCase
use DatabaseTransactions;
use MockAccountData;

protected $faker;

protected function setUp() :void
{
parent::setUp();
Expand All @@ -42,6 +44,110 @@ protected function setUp() :void
Model::reguard();
}

public function testProjectValidationForBudgetedHoursPut()
{

$data = $this->project->toArray();
$data['budgeted_hours'] = "aa";

$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->putJson("/api/v1/projects/{$this->project->hashed_id}", $data);

$response->assertStatus(422);

}

public function testProjectValidationForBudgetedHoursPutNull()
{

$data = $this->project->toArray();
$data['budgeted_hours'] = null;

$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->putJson("/api/v1/projects/{$this->project->hashed_id}", $data);

$response->assertStatus(200);

}


public function testProjectValidationForBudgetedHoursPutEmpty()
{

$data = $this->project->toArray();
$data['budgeted_hours'] = "";

$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->putJson("/api/v1/projects/{$this->project->hashed_id}", $data);

$response->assertStatus(200);

}


public function testProjectValidationForBudgetedHours()
{

$data = [
'name' => $this->faker->firstName(),
'client_id' => $this->client->hashed_id,
'number' => 'duplicate',
'budgeted_hours' => null
];

$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson('/api/v1/projects', $data);

$response->assertStatus(200);

}

public function testProjectValidationForBudgetedHours2()
{

$data = [
'name' => $this->faker->firstName(),
'client_id' => $this->client->hashed_id,
'number' => 'duplicate',
'budgeted_hours' => "a"
];

$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson('/api/v1/projects', $data);

$response->assertStatus(422);

}

public function testProjectValidationForBudgetedHours3()
{

$data = [
'name' => $this->faker->firstName(),
'client_id' => $this->client->hashed_id,
'number' => 'duplicate',
'budgeted_hours' => ""
];

$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson('/api/v1/projects', $data);

$response->assertStatus(200);

}

public function testProjectGetFilter()
{
$response = $this->withHeaders([
Expand Down
5 changes: 5 additions & 0 deletions tests/MockAccountData.php
Expand Up @@ -72,6 +72,11 @@ trait MockAccountData
use MakesHash;
use GeneratesCounter;

/**
* @var
*/
public $project;

/**
* @var
*/
Expand Down