Check start/end/days of week in cron and active/deactivate flights accordingly
This commit is contained in:
70
app/Cron/Nightly/SetActiveFlights.php
Normal file
70
app/Cron/Nightly/SetActiveFlights.php
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Cron\Nightly;
|
||||||
|
|
||||||
|
use App\Events\CronNightly;
|
||||||
|
use App\Interfaces\Listener;
|
||||||
|
use App\Models\Enums\Days;
|
||||||
|
use App\Models\Flight;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Figure out what flights need to be active for today
|
||||||
|
* @package App\Cron\Nightly
|
||||||
|
*/
|
||||||
|
class SetActiveFlights extends Listener
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param CronNightly $event
|
||||||
|
*/
|
||||||
|
public function handle(CronNightly $event): void
|
||||||
|
{
|
||||||
|
$this->checkFlights();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look through every single flight, check the start/end dates,
|
||||||
|
* as well of the days of week if this flight is active on this day
|
||||||
|
*
|
||||||
|
* TODO: Option to check the flight active/inactive against departure TZ
|
||||||
|
* TODO: Move to FlightService
|
||||||
|
*/
|
||||||
|
public function checkFlights(): void
|
||||||
|
{
|
||||||
|
$today = Carbon::now('UTC');
|
||||||
|
$flights = Flight::all();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Flight $flight
|
||||||
|
*/
|
||||||
|
foreach($flights as $flight) {
|
||||||
|
|
||||||
|
// dates aren't set, so just save if there were any changes above
|
||||||
|
// and move onto the next one
|
||||||
|
if ($flight->start_date === null || $flight->end_date === null) {
|
||||||
|
if ($flight->days > 0) {
|
||||||
|
$flight->active = Days::isToday($flight->days);
|
||||||
|
}
|
||||||
|
|
||||||
|
$flight->save();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the day of week now first
|
||||||
|
|
||||||
|
// Start/end date is set, so make sure today is valid for it to be alive
|
||||||
|
// and then make sure if days of the week are specified, check that too
|
||||||
|
if ($today->gte($flight->start_date) && $today->lte($flight->end_date)) {
|
||||||
|
if ($flight->days > 0) {
|
||||||
|
$flight->active = Days::isToday($flight->days);
|
||||||
|
} else {
|
||||||
|
$flight->active = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$flight->active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$flight->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Create flights
|
||||||
|
*/
|
||||||
|
|
||||||
use Faker\Generator as Faker;
|
use Faker\Generator as Faker;
|
||||||
|
|
||||||
# Match the list available in tests/data/*.yml
|
$factory->define(App\Models\Flight::class, function (Faker $faker) {
|
||||||
|
|
||||||
$airlinesAvailable = [1];
|
|
||||||
|
|
||||||
$factory->define(App\Models\Flight::class, function (Faker $faker) use ($airlinesAvailable) {
|
|
||||||
return [
|
return [
|
||||||
'id' => null,
|
'id' => null,
|
||||||
'airline_id' => function () {
|
'airline_id' => function () {
|
||||||
@@ -26,13 +25,15 @@ $factory->define(App\Models\Flight::class, function (Faker $faker) use ($airline
|
|||||||
},
|
},
|
||||||
'distance' => $faker->numberBetween(0, 3000),
|
'distance' => $faker->numberBetween(0, 3000),
|
||||||
'route' => null,
|
'route' => null,
|
||||||
'days' => 0,
|
|
||||||
'level' => 0,
|
'level' => 0,
|
||||||
'dpt_time' => $faker->time(),
|
'dpt_time' => $faker->time(),
|
||||||
'arr_time' => $faker->time(),
|
'arr_time' => $faker->time(),
|
||||||
'flight_time' => $faker->numberBetween(60, 360),
|
'flight_time' => $faker->numberBetween(60, 360),
|
||||||
'has_bid' => false,
|
'has_bid' => false,
|
||||||
'active' => true,
|
'active' => true,
|
||||||
|
'days' => 0,
|
||||||
|
'start_date' => null,
|
||||||
|
'end_date' => null,
|
||||||
'created_at' => $faker->dateTimeBetween('-1 week', 'now'),
|
'created_at' => $faker->dateTimeBetween('-1 week', 'now'),
|
||||||
'updated_at' => function (array $flight) {
|
'updated_at' => function (array $flight) {
|
||||||
return $flight['created_at'];
|
return $flight['created_at'];
|
||||||
|
|||||||
@@ -39,6 +39,19 @@ class Days extends Enum
|
|||||||
'Su' => Days::SUNDAY,
|
'Su' => Days::SUNDAY,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the ISO8601 numeric today to day
|
||||||
|
*/
|
||||||
|
public static $isoDayMap = [
|
||||||
|
1 => Days::MONDAY,
|
||||||
|
2 => Days::TUESDAY,
|
||||||
|
3 => Days::WEDNESDAY,
|
||||||
|
4 => Days::THURSDAY,
|
||||||
|
5 => Days::FRIDAY,
|
||||||
|
6 => Days::SATURDAY,
|
||||||
|
7 => Days::SUNDAY,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the masked value for the days of week
|
* Create the masked value for the days of week
|
||||||
* @param array $days
|
* @param array $days
|
||||||
@@ -64,4 +77,14 @@ class Days extends Enum
|
|||||||
{
|
{
|
||||||
return ($mask & $day) === $day;
|
return ($mask & $day) === $day;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the mask contain today?
|
||||||
|
* @param $val
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isToday($val): bool
|
||||||
|
{
|
||||||
|
return static::in($val, static::$isoDayMap[(int) date('N')]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use App\Interfaces\Model;
|
|||||||
use App\Models\Enums\Days;
|
use App\Models\Enums\Days;
|
||||||
use App\Models\Traits\HashIdTrait;
|
use App\Models\Traits\HashIdTrait;
|
||||||
use App\Support\Units\Distance;
|
use App\Support\Units\Distance;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use PhpUnitsOfMeasure\Exception\NonNumericValue;
|
use PhpUnitsOfMeasure\Exception\NonNumericValue;
|
||||||
use PhpUnitsOfMeasure\Exception\NonStringUnitName;
|
use PhpUnitsOfMeasure\Exception\NonStringUnitName;
|
||||||
@@ -26,6 +27,9 @@ use PhpUnitsOfMeasure\Exception\NonStringUnitName;
|
|||||||
* @property string dpt_airport_id
|
* @property string dpt_airport_id
|
||||||
* @property string arr_airport_id
|
* @property string arr_airport_id
|
||||||
* @property string alt_airport_id
|
* @property string alt_airport_id
|
||||||
|
* @property int active
|
||||||
|
* @property Carbon start_date
|
||||||
|
* @property Carbon end_date
|
||||||
*/
|
*/
|
||||||
class Flight extends Model
|
class Flight extends Model
|
||||||
{
|
{
|
||||||
@@ -178,6 +182,20 @@ class Flight extends Model
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the days parameter. If an array is passed, it's
|
||||||
|
* AND'd together to create the mask value
|
||||||
|
* @param array|int $val
|
||||||
|
*/
|
||||||
|
public function setDaysAttribute($val): void
|
||||||
|
{
|
||||||
|
if (\is_array($val)) {
|
||||||
|
$val = Days::getDaysMask($val);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->attributes['days'] = $val;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Relationship
|
* Relationship
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use App\Cron\Nightly\SetActiveFlights;
|
||||||
use App\Events\CronMonthly;
|
use App\Events\CronMonthly;
|
||||||
use App\Events\CronNightly;
|
use App\Events\CronNightly;
|
||||||
use App\Events\CronWeekly;
|
use App\Events\CronWeekly;
|
||||||
@@ -29,6 +30,7 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
ApplyExpenses::class,
|
ApplyExpenses::class,
|
||||||
RecalculateBalances::class,
|
RecalculateBalances::class,
|
||||||
PilotLeave::class,
|
PilotLeave::class,
|
||||||
|
SetActiveFlights::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
CronWeekly::class => [
|
CronWeekly::class => [
|
||||||
@@ -42,6 +44,7 @@ class EventServiceProvider extends ServiceProvider
|
|||||||
AwardListener::class,
|
AwardListener::class,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $subscribe = [
|
protected $subscribe = [
|
||||||
FinanceEvents::class,
|
FinanceEvents::class,
|
||||||
NotificationEvents::class,
|
NotificationEvents::class,
|
||||||
|
|||||||
@@ -149,6 +149,109 @@ class FlightTest extends TestCase
|
|||||||
|
|
||||||
$flight = Flight::findByDays([Days::WEDNESDAY, Days::THURSDAY])->first();
|
$flight = Flight::findByDays([Days::WEDNESDAY, Days::THURSDAY])->first();
|
||||||
$this->assertNull($flight);
|
$this->assertNull($flight);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure that flights are marked as inactive when they're out of the start/end
|
||||||
|
* zones. also make sure that flights with a specific day of the week are only
|
||||||
|
* active on those days
|
||||||
|
*/
|
||||||
|
public function testDayOfWeekActive(): void
|
||||||
|
{
|
||||||
|
$this->user = factory(App\Models\User::class)->create();
|
||||||
|
|
||||||
|
// Set it to Monday or Tuesday, depending on what today is
|
||||||
|
if (date('N') === 1) { // today is a monday
|
||||||
|
$days = Days::getDaysMask([Days::TUESDAY]);
|
||||||
|
} else {
|
||||||
|
$days = Days::getDaysMask([Days::MONDAY]);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory(App\Models\Flight::class, 5)->create();
|
||||||
|
$flight = factory(App\Models\Flight::class)->create([
|
||||||
|
'days' => $days,
|
||||||
|
#'start_date' => Carbon\Carbon::now('UTC')->subDay(1),
|
||||||
|
#'end_date' => Carbon\Carbon::now('UTC')->addDays(1),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Run the event that will enable/disable flights
|
||||||
|
$event = new \App\Events\CronNightly();
|
||||||
|
(new \App\Cron\Nightly\SetActiveFlights())->handle($event);
|
||||||
|
|
||||||
|
$res = $this->get('/api/flights');
|
||||||
|
$body = $res->json('data');
|
||||||
|
|
||||||
|
$flights = collect($body)->where('id', $flight->id)->first();
|
||||||
|
$this->assertNull($flights);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStartEndDate(): void
|
||||||
|
{
|
||||||
|
$this->user = factory(App\Models\User::class)->create();
|
||||||
|
|
||||||
|
factory(App\Models\Flight::class, 5)->create();
|
||||||
|
$flight = factory(App\Models\Flight::class)->create([
|
||||||
|
'start_date' => Carbon\Carbon::now('UTC')->subDays(1),
|
||||||
|
'end_date' => Carbon\Carbon::now('UTC')->addDays(1),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$flight_not_active = factory(App\Models\Flight::class)->create([
|
||||||
|
'start_date' => Carbon\Carbon::now('UTC')->subDays(10),
|
||||||
|
'end_date' => Carbon\Carbon::now('UTC')->subDays(2),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Run the event that will enable/disable flights
|
||||||
|
$event = new \App\Events\CronNightly();
|
||||||
|
(new \App\Cron\Nightly\SetActiveFlights())->handle($event);
|
||||||
|
|
||||||
|
$res = $this->get('/api/flights');
|
||||||
|
$body = $res->json('data');
|
||||||
|
|
||||||
|
$flights = collect($body)->where('id', $flight->id)->first();
|
||||||
|
$this->assertNotNull($flights);
|
||||||
|
|
||||||
|
$flights = collect($body)->where('id', $flight_not_active->id)->first();
|
||||||
|
$this->assertNull($flights);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStartEndDateDayOfWeek(): void
|
||||||
|
{
|
||||||
|
$this->user = factory(App\Models\User::class)->create();
|
||||||
|
|
||||||
|
// Set it to Monday or Tuesday, depending on what today is
|
||||||
|
if (date('N') === 1) { // today is a monday
|
||||||
|
$days = Days::getDaysMask([Days::TUESDAY]);
|
||||||
|
} else {
|
||||||
|
$days = Days::getDaysMask([Days::MONDAY]);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory(App\Models\Flight::class, 5)->create();
|
||||||
|
$flight = factory(App\Models\Flight::class)->create([
|
||||||
|
'start_date' => Carbon\Carbon::now('UTC')->subDays(1),
|
||||||
|
'end_date' => Carbon\Carbon::now('UTC')->addDays(1),
|
||||||
|
'days' => Days::$isoDayMap[date('N')],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$flight_not_active = factory(App\Models\Flight::class)->create([
|
||||||
|
'start_date' => Carbon\Carbon::now('UTC')->subDays(1),
|
||||||
|
'end_date' => Carbon\Carbon::now('UTC')->addDays(1),
|
||||||
|
'days' => $days,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Run the event that will enable/disable flights
|
||||||
|
$event = new \App\Events\CronNightly();
|
||||||
|
(new \App\Cron\Nightly\SetActiveFlights())->handle($event);
|
||||||
|
|
||||||
|
$res = $this->get('/api/flights');
|
||||||
|
$body = $res->json('data');
|
||||||
|
|
||||||
|
$flights = collect($body)->where('id', $flight->id)->first();
|
||||||
|
$this->assertNotNull($flights);
|
||||||
|
|
||||||
|
$flights = collect($body)->where('id', $flight_not_active->id)->first();
|
||||||
|
$this->assertNull($flights);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user