Merge pull request #8172 from turbo124/v5-develop

Implement next_run calculation for scheduled tasks
This commit is contained in:
David Bomba 2023-01-18 07:47:00 +11:00 committed by GitHub
commit 1a4338b904
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 450 additions and 38 deletions

View File

@ -26,7 +26,9 @@ class SchedulerFactory
$scheduler->is_paused = false; $scheduler->is_paused = false;
$scheduler->is_deleted = false; $scheduler->is_deleted = false;
$scheduler->template = ''; $scheduler->template = '';
$scheduler->next_run = now()->format('Y-m-d');
$scheduler->next_run_client = now()->format('Y-m-d');
return $scheduler; return $scheduler;
} }
} }

View File

@ -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.
* *
@ -33,12 +37,27 @@ class StoreSchedulerRequest extends Request
'name' => ['bail', 'required', Rule::unique('schedulers')->where('company_id', auth()->user()->company()->id)], 'name' => ['bail', 'required', Rule::unique('schedulers')->where('company_id', auth()->user()->company()->id)],
'is_paused' => 'bail|sometimes|boolean', 'is_paused' => 'bail|sometimes|boolean',
'frequency_id' => 'bail|required|integer|digits_between:1,12', 'frequency_id' => 'bail|required|integer|digits_between:1,12',
'next_run' => 'bail|required|date:Y-m-d', 'next_run' => 'bail|required|date:Y-m-d|after_or_equal:today',
'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()
{
$input = $this->all();
if (array_key_exists('next_run', $input) && is_string($input['next_run']))
$this->merge(['next_run_client' => $input['next_run']]);
return $input;
}
} }

View File

@ -32,7 +32,8 @@ class UpdateSchedulerRequest extends Request
'name' => ['bail', 'sometimes', Rule::unique('schedulers')->where('company_id', auth()->user()->company()->id)->ignore($this->task_scheduler->id)], 'name' => ['bail', 'sometimes', Rule::unique('schedulers')->where('company_id', auth()->user()->company()->id)->ignore($this->task_scheduler->id)],
'is_paused' => 'bail|sometimes|boolean', 'is_paused' => 'bail|sometimes|boolean',
'frequency_id' => 'bail|required|integer|digits_between:1,12', 'frequency_id' => 'bail|required|integer|digits_between:1,12',
'next_run' => 'bail|required|date:Y-m-d', 'next_run' => 'bail|required|date:Y-m-d|after_or_equal:today',
'next_run_client' => 'bail|sometimes|date:Y-m-d',
'template' => 'bail|required|string', 'template' => 'bail|required|string',
'parameters' => 'bail|array', 'parameters' => 'bail|array',
]; ];
@ -40,4 +41,17 @@ class UpdateSchedulerRequest extends Request
return $rules; return $rules;
} }
public function prepareForValidation()
{
$input = $this->all();
if (array_key_exists('next_run', $input) && is_string($input['next_run']))
$this->merge(['next_run_client' => $input['next_run']]);
return $input;
}
} }

View 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';
}
}

View File

@ -649,6 +649,24 @@ class Company extends BaseModel
return $data; return $data;
} }
public function timezone_offset()
{
$offset = 0;
$entity_send_time = $this->getSetting('entity_send_time');
if ($entity_send_time == 0) {
return 0;
}
$timezone = $this->timezone();
$offset -= $timezone->utc_offset;
$offset += ($entity_send_time * 3600);
return $offset;
}
public function translate_entity() public function translate_entity()
{ {
return ctrans('texts.company'); return ctrans('texts.company');
@ -666,4 +684,5 @@ class Company extends BaseModel
return $item->id == $this->getSetting('date_format_id'); return $item->id == $this->getSetting('date_format_id');
})->first()->format; })->first()->format;
} }
} }

View File

@ -257,13 +257,6 @@ class RecurringInvoice extends BaseModel
} }
} }
/*
As we are firing at UTC+0 if our offset is negative it is technically firing the day before so we always need
to add ON a day - a day = 86400 seconds
*/
// if($offset < 0)
// $offset += 86400;
switch ($this->frequency_id) { switch ($this->frequency_id) {
case self::FREQUENCY_DAILY: case self::FREQUENCY_DAILY:
return Carbon::parse($this->next_send_date_client)->startOfDay()->addDay()->addSeconds($offset); return Carbon::parse($this->next_send_date_client)->startOfDay()->addDay()->addSeconds($offset);

View File

@ -38,7 +38,7 @@ class Scheduler extends BaseModel
'name', 'name',
'frequency_id', 'frequency_id',
'next_run', 'next_run',
'scheduled_run', 'next_run_client',
'template', 'template',
'is_paused', 'is_paused',
'parameters', 'parameters',
@ -46,6 +46,7 @@ class Scheduler extends BaseModel
protected $casts = [ protected $casts = [
'next_run' => 'datetime', 'next_run' => 'datetime',
'next_run_client' => 'datetime',
'created_at' => 'timestamp', 'created_at' => 'timestamp',
'updated_at' => 'timestamp', 'updated_at' => 'timestamp',
'deleted_at' => 'timestamp', 'deleted_at' => 'timestamp',
@ -66,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);
} }

View File

@ -24,8 +24,10 @@ use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Mail\Mailer; use Illuminate\Mail\Mailer;
use Illuminate\Queue\Events\JobProcessing; use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\ParallelTesting;
use Illuminate\Support\Facades\Queue; use Illuminate\Support\Facades\Queue;
use Illuminate\Support\Facades\RateLimiter; use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
@ -102,6 +104,11 @@ class AppServiceProvider extends ServiceProvider
return $this; return $this;
}); });
ParallelTesting::setUpTestDatabase(function ($database, $token) {
Artisan::call('db:seed');
});
} }
/** /**

View File

@ -27,6 +27,7 @@ use App\Utils\Number;
use App\Utils\PhantomJS\Phantom; use App\Utils\PhantomJS\Phantom;
use App\Utils\Traits\Pdf\PdfMaker as PdfMakerTrait; use App\Utils\Traits\Pdf\PdfMaker as PdfMakerTrait;
use Illuminate\Support\Carbon; use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
class Statement class Statement
{ {
@ -117,7 +118,7 @@ class Statement
} }
if (\is_null($this->entity)) { if (\is_null($this->entity)) {
\DB::connection(config('database.default'))->beginTransaction(); DB::connection(config('database.default'))->beginTransaction();
$this->rollback = true; $this->rollback = true;

View File

@ -12,9 +12,11 @@
namespace App\Services\Scheduler; namespace App\Services\Scheduler;
use App\Models\Client; use App\Models\Client;
use App\Models\RecurringInvoice;
use App\Models\Scheduler; use App\Models\Scheduler;
use App\Utils\Traits\MakesDates; use App\Utils\Traits\MakesDates;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use Carbon\Carbon;
class SchedulerService class SchedulerService
{ {
@ -51,18 +53,25 @@ class SchedulerService
->each(function ($_client){ ->each(function ($_client){
$this->client = $_client; $this->client = $_client;
$statement_properties = $this->calculateStatementProperties();
//work out the date range //work out the date range
$pdf = $_client->service()->statement($statement_properties,true); $statement_properties = $this->calculateStatementProperties();
//calculate next run dates; $_client->service()->statement($statement_properties,true);
}); });
//calculate next run dates;
$this->calculateNextRun();
} }
private function calculateStatementProperties() /**
* Hydrates the array needed to generate the statement
*
* @return array The statement options array
*/
private function calculateStatementProperties(): array
{ {
$start_end = $this->calculateStartAndEndDates(); $start_end = $this->calculateStartAndEndDates();
@ -76,7 +85,12 @@ class SchedulerService
} }
private function calculateStartAndEndDates() /**
* Start and end date of the statement
*
* @return array [$start_date, $end_date];
*/
private function calculateStartAndEndDates(): array
{ {
return match ($this->scheduler->parameters['date_range']) { return match ($this->scheduler->parameters['date_range']) {
'this_month' => [now()->firstOfMonth()->format('Y-m-d'), now()->lastOfMonth()->format('Y-m-d')], 'this_month' => [now()->firstOfMonth()->format('Y-m-d'), now()->lastOfMonth()->format('Y-m-d')],
@ -91,6 +105,67 @@ class SchedulerService
} }
/**
* Sets the next run date of the scheduled task
*
*/
private function calculateNextRun()
{
if (! $this->scheduler->next_run) {
return null;
}
$offset = $this->scheduler->company->timezone_offset();
switch ($this->scheduler->frequency_id) {
case RecurringInvoice::FREQUENCY_DAILY:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addDay();
break;
case RecurringInvoice::FREQUENCY_WEEKLY:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addWeek();
break;
case RecurringInvoice::FREQUENCY_TWO_WEEKS:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addWeeks(2);
break;
case RecurringInvoice::FREQUENCY_FOUR_WEEKS:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addWeeks(4);
break;
case RecurringInvoice::FREQUENCY_MONTHLY:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addMonthNoOverflow();
break;
case RecurringInvoice::FREQUENCY_TWO_MONTHS:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addMonthsNoOverflow(2);
break;
case RecurringInvoice::FREQUENCY_THREE_MONTHS:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addMonthsNoOverflow(3);
break;
case RecurringInvoice::FREQUENCY_FOUR_MONTHS:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addMonthsNoOverflow(4);
break;
case RecurringInvoice::FREQUENCY_SIX_MONTHS:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addMonthsNoOverflow(6);
break;
case RecurringInvoice::FREQUENCY_ANNUALLY:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addYear();
break;
case RecurringInvoice::FREQUENCY_TWO_YEARS:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addYears(2);
break;
case RecurringInvoice::FREQUENCY_THREE_YEARS:
$next_run = Carbon::parse($this->scheduler->next_run)->startOfDay()->addYears(3);
break;
default:
$next_run = null;
}
$this->scheduler->next_run_client = $next_run ?: null;
$this->scheduler->next_run = $next_run ? $next_run->copy()->addSeconds($offset) : null;
$this->scheduler->save();
}
//handle when the scheduler has been paused.
} }

View File

@ -24,7 +24,7 @@ class SchedulerTransformer extends EntityTransformer
'id' => $this->encodePrimaryKey($scheduler->id), 'id' => $this->encodePrimaryKey($scheduler->id),
'name' => (string) $scheduler->name, 'name' => (string) $scheduler->name,
'frequency_id' => (string) $scheduler->frequency_id, 'frequency_id' => (string) $scheduler->frequency_id,
'next_run' => $scheduler->next_run, 'next_run' => $scheduler->next_run_client->format('Y-m-d'),
'template' => (string) $scheduler->template, 'template' => (string) $scheduler->template,
'is_paused' => (bool) $scheduler->is_paused, 'is_paused' => (bool) $scheduler->is_paused,
'is_deleted' => (bool) $scheduler->is_deleted, 'is_deleted' => (bool) $scheduler->is_deleted,

View File

@ -31,6 +31,7 @@ class SchedulerFactory extends Factory
'parameters' => [], 'parameters' => [],
'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY, 'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY,
'next_run' => now()->addSeconds(rand(86400,8640000)), 'next_run' => now()->addSeconds(rand(86400,8640000)),
'next_run_client' => now()->addSeconds(rand(86400,8640000)),
'template' => 'statement_task', 'template' => 'statement_task',
]; ];
} }

View File

@ -47,6 +47,42 @@ class CompanyTest extends TestCase
$this->makeTestData(); $this->makeTestData();
} }
public function testUpdateCompanyPropertyInvoiceTaskHours()
{
$company_update = [
'invoice_task_hours' => true
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->putJson('/api/v1/companies/'.$this->encodePrimaryKey($this->company->id), $company_update)
->assertStatus(200);
$arr = $response->json();
$this->assertTrue($arr['data']['invoice_task_hours']);
$company_update = [
'invoice_task_hours' => false
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->putJson('/api/v1/companies/'.$this->encodePrimaryKey($this->company->id), $company_update)
->assertStatus(200);
$arr = $response->json();
$this->assertFalse($arr['data']['invoice_task_hours']);
}
public function testCompanyList() public function testCompanyList()
{ {
$this->withoutMiddleware(PasswordProtection::class); $this->withoutMiddleware(PasswordProtection::class);

View File

@ -11,21 +11,24 @@
namespace Tests\Feature\Scheduler; namespace Tests\Feature\Scheduler;
use App\Export\CSV\ClientExport; use App\Factory\SchedulerFactory;
use App\Models\Client;
use App\Models\RecurringInvoice; use App\Models\RecurringInvoice;
use App\Models\Scheduler; use App\Services\Scheduler\SchedulerService;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use Carbon\Carbon; use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
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\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\TestCase; use Tests\TestCase;
/**
* @test
* @covers App\Services\Scheduler\SchedulerService
*/
class SchedulerTest extends TestCase class SchedulerTest extends TestCase
{ {
use MakesHash; use MakesHash;
@ -48,9 +51,217 @@ 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()->addDay()->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()
{
$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, 'calculateStartAndEndDates');
$reflectionMethod->setAccessible(true);
$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);
}
public function testCalculateStatementProperties()
{
$scheduler = SchedulerFactory::create($this->company->id, $this->user->id);
$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' => [],
],
];
$scheduler->fill($data);
$scheduler->save();
$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, 'calculateStatementProperties');
$reflectionMethod->setAccessible(true);
$method = $reflectionMethod->invoke(new SchedulerService($scheduler)); // 'baz'
$this->assertIsArray($method);
$this->assertEquals('paid', $method['status']);
}
public function testGetThisMonthRange() public function testGetThisMonthRange()
{ {
@ -82,24 +293,15 @@ class SchedulerTest extends TestCase
}; };
} }
/**
* 'name' => ['bail', 'required', Rule::unique('schedulers')->where('company_id', auth()->user()->company()->id)],
'is_paused' => 'bail|sometimes|boolean',
'frequency_id' => 'bail|required|integer|digits_between:1,12',
'next_run' => 'bail|required|date:Y-m-d',
'template' => 'bail|required|string',
'parameters' => 'bail|array',
*/
public function testClientStatementGeneration() public function testClientStatementGeneration()
{ {
$data = [ $data = [
'name' => 'A test statement scheduler', 'name' => 'A test statement scheduler',
'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY, 'frequency_id' => RecurringInvoice::FREQUENCY_MONTHLY,
'next_run' => '2023-01-14', 'next_run' => now()->format('Y-m-d'),
'template' => 'client_statement', 'template' => 'client_statement',
'parameters' => [ 'parameters' => [
'date_range' => 'last_month', 'date_range' => 'previous_month',
'show_payments_table' => true, 'show_payments_table' => true,
'show_aging_table' => true, 'show_aging_table' => true,
'status' => 'paid', 'status' => 'paid',
@ -190,7 +392,7 @@ class SchedulerTest extends TestCase
'name' => 'A different Name', 'name' => 'A different Name',
'frequency_id' => 5, 'frequency_id' => 5,
'next_run' => now()->addDays(2)->format('Y-m-d'), 'next_run' => now()->addDays(2)->format('Y-m-d'),
'template' =>'statement', 'template' =>'client_statement',
'parameters' => [], 'parameters' => [],
]; ];
@ -209,7 +411,7 @@ class SchedulerTest extends TestCase
'name' => 'A different Name', 'name' => 'A different Name',
'frequency_id' => 5, 'frequency_id' => 5,
'next_run' => now()->addDays(2)->format('Y-m-d'), 'next_run' => now()->addDays(2)->format('Y-m-d'),
'template' =>'statement', 'template' =>'client_statement',
'parameters' => [], 'parameters' => [],
]; ];

View File

@ -11,7 +11,6 @@
namespace Tests\Unit; namespace Tests\Unit;
use App\DataMapper\ClientSettings;
use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Tests\MockAccountData; use Tests\MockAccountData;