diff --git a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php index 0b66428e7c0f..4eae43c59d23 100644 --- a/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php +++ b/app/Http/Requests/TaskScheduler/StoreSchedulerRequest.php @@ -12,10 +12,14 @@ namespace App\Http\Requests\TaskScheduler; use App\Http\Requests\Request; +use App\Http\ValidationRules\Scheduler\ValidClientIds; +use App\Models\Client; +use App\Utils\Traits\MakesHash; use Illuminate\Validation\Rule; class StoreSchedulerRequest extends Request { + use MakesHash; /** * Determine if the user is authorized to make this request. * @@ -37,13 +41,13 @@ class StoreSchedulerRequest extends Request 'next_run_client' => 'bail|sometimes|date:Y-m-d', 'template' => 'bail|required|string', 'parameters' => 'bail|array', + 'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()], ]; return $rules; } - public function prepareForValidation() { diff --git a/app/Http/ValidationRules/Scheduler/ValidClientIds.php b/app/Http/ValidationRules/Scheduler/ValidClientIds.php new file mode 100644 index 000000000000..cedd7bba0cc8 --- /dev/null +++ b/app/Http/ValidationRules/Scheduler/ValidClientIds.php @@ -0,0 +1,43 @@ +user()->company()->id)->whereIn('id', $this->transformKeys($value))->count() == count($value); + + } + + /** + * @return string + */ + public function message() + { + return 'Invalid client ids'; + } +} diff --git a/app/Models/Company.php b/app/Models/Company.php index b612690fd4e8..33f3f01046d7 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -649,24 +649,6 @@ class Company extends BaseModel return $data; } - public function translate_entity() - { - return ctrans('texts.company'); - } - - public function date_format() - { - $date_formats = Cache::get('date_formats'); - - if (! $date_formats) { - $this->buildCache(true); - } - - return $date_formats->filter(function ($item) { - return $item->id == $this->getSetting('date_format_id'); - })->first()->format; - } - public function timezone_offset() { $offset = 0; @@ -685,4 +667,22 @@ class Company extends BaseModel return $offset; } + public function translate_entity() + { + return ctrans('texts.company'); + } + + public function date_format() + { + $date_formats = Cache::get('date_formats'); + + if (! $date_formats) { + $this->buildCache(true); + } + + return $date_formats->filter(function ($item) { + return $item->id == $this->getSetting('date_format_id'); + })->first()->format; + } + } diff --git a/app/Models/Scheduler.php b/app/Models/Scheduler.php index bdc7eaaa497e..cc82ebb551ef 100644 --- a/app/Models/Scheduler.php +++ b/app/Models/Scheduler.php @@ -67,7 +67,7 @@ class Scheduler extends BaseModel return new SchedulerService($this); } - public function company(): \Illuminate\Database\Eloquent\Relations\BelongsTo + public function company() { return $this->belongsTo(Company::class); } diff --git a/app/Services/Scheduler/SchedulerService.php b/app/Services/Scheduler/SchedulerService.php index 6074572bf5a4..40de48ef3e6c 100644 --- a/app/Services/Scheduler/SchedulerService.php +++ b/app/Services/Scheduler/SchedulerService.php @@ -57,7 +57,7 @@ class SchedulerService //work out the date range $statement_properties = $this->calculateStatementProperties(); - $pdf = $_client->service()->statement($statement_properties,true); + $_client->service()->statement($statement_properties,true); }); diff --git a/tests/Feature/Scheduler/SchedulerTest.php b/tests/Feature/Scheduler/SchedulerTest.php index ffd2099c6a10..055e7f0d943b 100644 --- a/tests/Feature/Scheduler/SchedulerTest.php +++ b/tests/Feature/Scheduler/SchedulerTest.php @@ -11,8 +11,8 @@ namespace Tests\Feature\Scheduler; -use App\Export\CSV\ClientExport; use App\Factory\SchedulerFactory; +use App\Models\Client; use App\Models\RecurringInvoice; use App\Models\Scheduler; use App\Services\Scheduler\SchedulerService; @@ -22,12 +22,17 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithoutEvents; use Illuminate\Routing\Middleware\ThrottleRequests; +use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Session; use Illuminate\Validation\ValidationException; use Tests\MockAccountData; use Tests\MockUnitData; use Tests\TestCase; +/** + * @test + * @covers App\Services\Scheduler\SchedulerService + */ class SchedulerTest extends TestCase { use MakesHash; @@ -50,7 +55,141 @@ class SchedulerTest extends TestCase ThrottleRequests::class ); - $this->withoutExceptionHandling(); + } + + public function testClientsValidationInScheduledTask() + { + + $c = Client::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'number' => rand(1000,100000), + 'name' => 'A fancy client' + ]); + + $c2 = Client::factory()->create([ + 'company_id' => $this->company->id, + 'user_id' => $this->user->id, + 'number' => rand(1000,100000), + 'name' => 'A fancy client' + ]); + + $data = [ + 'name' => 'A test statement scheduler', + 'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY, + 'next_run' => now()->format('Y-m-d'), + 'template' => 'client_statement', + 'parameters' => [ + 'date_range' => 'previous_month', + 'show_payments_table' => true, + 'show_aging_table' => true, + 'status' => 'paid', + 'clients' => [ + $c2->hashed_id, + $c->hashed_id + ], + ], + ]; + + $response = false; + + try{ + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/task_schedulers', $data); + + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + } + + $response->assertStatus(200); + + + $data = [ + 'name' => 'A single Client', + 'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY, + 'next_run' => now()->format('Y-m-d'), + 'template' => 'client_statement', + 'parameters' => [ + 'date_range' => 'previous_month', + 'show_payments_table' => true, + 'show_aging_table' => true, + 'status' => 'paid', + 'clients' => [ + $c2->hashed_id, + ], + ], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/task_schedulers', $data); + + $response->assertStatus(200); + + + $data = [ + 'name' => 'An invalid Client', + 'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY, + 'next_run' => now()->format('Y-m-d'), + 'template' => 'client_statement', + 'parameters' => [ + 'date_range' => 'previous_month', + 'show_payments_table' => true, + 'show_aging_table' => true, + 'status' => 'paid', + 'clients' => [ + 'xx33434', + ], + ], + ]; + + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + ])->postJson('/api/v1/task_schedulers', $data); + + $response->assertStatus(422); + + + } + + + public function testCalculateNextRun() + { + + $scheduler = SchedulerFactory::create($this->company->id, $this->user->id); + + $data = [ + 'name' => 'A test statement scheduler', + 'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY, + 'next_run' => "2023-01-01", + 'template' => 'client_statement', + 'parameters' => [ + 'date_range' => 'previous_month', + 'show_payments_table' => true, + 'show_aging_table' => true, + 'status' => 'paid', + 'clients' => [], + ], + ]; + + $scheduler->fill($data); + $scheduler->save(); + + $service_object = new SchedulerService($scheduler); + + $reflectionMethod = new \ReflectionMethod(SchedulerService::class, 'calculateNextRun'); + $reflectionMethod->setAccessible(true); + $method = $reflectionMethod->invoke(new SchedulerService($scheduler)); + + $scheduler->fresh(); + + $this->assertEquals("2023-02-01", $scheduler->next_run->format('Y-m-d')); + } public function testCalculateStartAndEndDates() @@ -77,24 +216,16 @@ class SchedulerTest extends TestCase $service_object = new SchedulerService($scheduler); - // $reflection = new \ReflectionClass(get_class($service_object)); - // $method = $reflection->getMethod('calculateStatementProperties'); - // $method->setAccessible(true); - // $method->invokeArgs($service_object, []); - $reflectionMethod = new \ReflectionMethod(SchedulerService::class, 'calculateStartAndEndDates'); $reflectionMethod->setAccessible(true); - $method = $reflectionMethod->invoke(new SchedulerService($scheduler)); // 'baz' + $method = $reflectionMethod->invoke(new SchedulerService($scheduler)); $this->assertIsArray($method); $this->assertEquals('previous_month', $scheduler->parameters['date_range']); - + $this->assertEqualsCanonicalizing(['2022-12-01','2022-12-31'], $method); - - // $this->assertEquals('paid', $method['status']); - } public function testCalculateStatementProperties()