mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-01 10:54:36 -04:00
Validation rules for clients in scheduler
This commit is contained in:
parent
2bcccb2215
commit
1b1fc71d0d
@ -12,10 +12,14 @@
|
|||||||
namespace App\Http\Requests\TaskScheduler;
|
namespace App\Http\Requests\TaskScheduler;
|
||||||
|
|
||||||
use App\Http\Requests\Request;
|
use App\Http\Requests\Request;
|
||||||
|
use App\Http\ValidationRules\Scheduler\ValidClientIds;
|
||||||
|
use App\Models\Client;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
class StoreSchedulerRequest extends Request
|
class StoreSchedulerRequest extends Request
|
||||||
{
|
{
|
||||||
|
use MakesHash;
|
||||||
/**
|
/**
|
||||||
* Determine if the user is authorized to make this request.
|
* 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',
|
'next_run_client' => 'bail|sometimes|date:Y-m-d',
|
||||||
'template' => 'bail|required|string',
|
'template' => 'bail|required|string',
|
||||||
'parameters' => 'bail|array',
|
'parameters' => 'bail|array',
|
||||||
|
'parameters.clients' => ['bail','sometimes', 'array', new ValidClientIds()],
|
||||||
];
|
];
|
||||||
|
|
||||||
return $rules;
|
return $rules;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function prepareForValidation()
|
public function prepareForValidation()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
43
app/Http/ValidationRules/Scheduler/ValidClientIds.php
Normal file
43
app/Http/ValidationRules/Scheduler/ValidClientIds.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com).
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2022. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://www.elastic.co/licensing/elastic-license
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Http\ValidationRules\Scheduler;
|
||||||
|
|
||||||
|
use App\Models\Client;
|
||||||
|
use App\Utils\Traits\MakesHash;
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ValidClientIds.
|
||||||
|
*/
|
||||||
|
class ValidClientIds implements Rule
|
||||||
|
{
|
||||||
|
use MakesHash;
|
||||||
|
/**
|
||||||
|
* @param string $attribute
|
||||||
|
* @param mixed $value
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function passes($attribute, $value)
|
||||||
|
{
|
||||||
|
|
||||||
|
return Client::where('company_id', auth()->user()->company()->id)->whereIn('id', $this->transformKeys($value))->count() == count($value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function message()
|
||||||
|
{
|
||||||
|
return 'Invalid client ids';
|
||||||
|
}
|
||||||
|
}
|
@ -649,24 +649,6 @@ class Company extends BaseModel
|
|||||||
return $data;
|
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()
|
public function timezone_offset()
|
||||||
{
|
{
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
@ -685,4 +667,22 @@ class Company extends BaseModel
|
|||||||
return $offset;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ class Scheduler extends BaseModel
|
|||||||
return new SchedulerService($this);
|
return new SchedulerService($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function company(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
public function company()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Company::class);
|
return $this->belongsTo(Company::class);
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ class SchedulerService
|
|||||||
//work out the date range
|
//work out the date range
|
||||||
$statement_properties = $this->calculateStatementProperties();
|
$statement_properties = $this->calculateStatementProperties();
|
||||||
|
|
||||||
$pdf = $_client->service()->statement($statement_properties,true);
|
$_client->service()->statement($statement_properties,true);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
|
|
||||||
namespace Tests\Feature\Scheduler;
|
namespace Tests\Feature\Scheduler;
|
||||||
|
|
||||||
use App\Export\CSV\ClientExport;
|
|
||||||
use App\Factory\SchedulerFactory;
|
use App\Factory\SchedulerFactory;
|
||||||
|
use App\Models\Client;
|
||||||
use App\Models\RecurringInvoice;
|
use App\Models\RecurringInvoice;
|
||||||
use App\Models\Scheduler;
|
use App\Models\Scheduler;
|
||||||
use App\Services\Scheduler\SchedulerService;
|
use App\Services\Scheduler\SchedulerService;
|
||||||
@ -22,12 +22,17 @@ use Illuminate\Database\Eloquent\Model;
|
|||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||||
use Illuminate\Foundation\Testing\WithoutEvents;
|
use Illuminate\Foundation\Testing\WithoutEvents;
|
||||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Tests\MockAccountData;
|
use Tests\MockAccountData;
|
||||||
use Tests\MockUnitData;
|
use Tests\MockUnitData;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @covers App\Services\Scheduler\SchedulerService
|
||||||
|
*/
|
||||||
class SchedulerTest extends TestCase
|
class SchedulerTest extends TestCase
|
||||||
{
|
{
|
||||||
use MakesHash;
|
use MakesHash;
|
||||||
@ -50,7 +55,141 @@ class SchedulerTest extends TestCase
|
|||||||
ThrottleRequests::class
|
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()
|
public function testCalculateStartAndEndDates()
|
||||||
@ -77,24 +216,16 @@ class SchedulerTest extends TestCase
|
|||||||
|
|
||||||
$service_object = new SchedulerService($scheduler);
|
$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 = new \ReflectionMethod(SchedulerService::class, 'calculateStartAndEndDates');
|
||||||
$reflectionMethod->setAccessible(true);
|
$reflectionMethod->setAccessible(true);
|
||||||
$method = $reflectionMethod->invoke(new SchedulerService($scheduler)); // 'baz'
|
$method = $reflectionMethod->invoke(new SchedulerService($scheduler));
|
||||||
|
|
||||||
$this->assertIsArray($method);
|
$this->assertIsArray($method);
|
||||||
|
|
||||||
$this->assertEquals('previous_month', $scheduler->parameters['date_range']);
|
$this->assertEquals('previous_month', $scheduler->parameters['date_range']);
|
||||||
|
|
||||||
$this->assertEqualsCanonicalizing(['2022-12-01','2022-12-31'], $method);
|
$this->assertEqualsCanonicalizing(['2022-12-01','2022-12-31'], $method);
|
||||||
|
|
||||||
|
|
||||||
// $this->assertEquals('paid', $method['status']);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCalculateStatementProperties()
|
public function testCalculateStatementProperties()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user