Check start/end/days of week in cron and active/deactivate flights accordingly
This commit is contained in:
parent
395642f69c
commit
9d3d284df7
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
|
||||
/**
|
||||
* Create flights
|
||||
*/
|
||||
|
||||
use Faker\Generator as Faker;
|
||||
|
||||
# Match the list available in tests/data/*.yml
|
||||
|
||||
$airlinesAvailable = [1];
|
||||
|
||||
$factory->define(App\Models\Flight::class, function (Faker $faker) use ($airlinesAvailable) {
|
||||
$factory->define(App\Models\Flight::class, function (Faker $faker) {
|
||||
return [
|
||||
'id' => null,
|
||||
'airline_id' => function () {
|
||||
@ -26,13 +25,15 @@ $factory->define(App\Models\Flight::class, function (Faker $faker) use ($airline
|
||||
},
|
||||
'distance' => $faker->numberBetween(0, 3000),
|
||||
'route' => null,
|
||||
'days' => 0,
|
||||
'level' => 0,
|
||||
'dpt_time' => $faker->time(),
|
||||
'arr_time' => $faker->time(),
|
||||
'flight_time' => $faker->numberBetween(60, 360),
|
||||
'has_bid' => false,
|
||||
'active' => true,
|
||||
'days' => 0,
|
||||
'start_date' => null,
|
||||
'end_date' => null,
|
||||
'created_at' => $faker->dateTimeBetween('-1 week', 'now'),
|
||||
'updated_at' => function (array $flight) {
|
||||
return $flight['created_at'];
|
||||
|
@ -39,6 +39,19 @@ class Days extends Enum
|
||||
'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
|
||||
* @param array $days
|
||||
@ -64,4 +77,14 @@ class Days extends Enum
|
||||
{
|
||||
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\Traits\HashIdTrait;
|
||||
use App\Support\Units\Distance;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use PhpUnitsOfMeasure\Exception\NonNumericValue;
|
||||
use PhpUnitsOfMeasure\Exception\NonStringUnitName;
|
||||
@ -26,6 +27,9 @@ use PhpUnitsOfMeasure\Exception\NonStringUnitName;
|
||||
* @property string dpt_airport_id
|
||||
* @property string arr_airport_id
|
||||
* @property string alt_airport_id
|
||||
* @property int active
|
||||
* @property Carbon start_date
|
||||
* @property Carbon end_date
|
||||
*/
|
||||
class Flight extends Model
|
||||
{
|
||||
@ -178,6 +182,20 @@ class Flight extends Model
|
||||
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
|
||||
*/
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Cron\Nightly\SetActiveFlights;
|
||||
use App\Events\CronMonthly;
|
||||
use App\Events\CronNightly;
|
||||
use App\Events\CronWeekly;
|
||||
@ -29,6 +30,7 @@ class EventServiceProvider extends ServiceProvider
|
||||
ApplyExpenses::class,
|
||||
RecalculateBalances::class,
|
||||
PilotLeave::class,
|
||||
SetActiveFlights::class,
|
||||
],
|
||||
|
||||
CronWeekly::class => [
|
||||
@ -42,6 +44,7 @@ class EventServiceProvider extends ServiceProvider
|
||||
AwardListener::class,
|
||||
],
|
||||
];
|
||||
|
||||
protected $subscribe = [
|
||||
FinanceEvents::class,
|
||||
NotificationEvents::class,
|
||||
|
@ -149,6 +149,109 @@ class FlightTest extends TestCase
|
||||
|
||||
$flight = Flight::findByDays([Days::WEDNESDAY, Days::THURSDAY])->first();
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user