introduce cronjob to automatically deactivate expired events

This commit is contained in:
Annika Wolff 2020-05-27 11:31:35 +02:00
parent 3568e0d316
commit a22c2e02be
9 changed files with 188 additions and 6 deletions

View File

@ -24,8 +24,7 @@ class Kernel extends ConsoleKernel
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
$schedule->command('booking:cron')->dailyAt('3:00');
}
/**
@ -36,6 +35,7 @@ class Kernel extends ConsoleKernel
protected function commands()
{
$this->load(__DIR__.'/Commands');
$this->load(__DIR__.'/../../packages/Webkul/Core/src/Console/Commands');
require base_path('routes/console.php');
}

View File

@ -0,0 +1,19 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Carbon\Carbon;
use Faker\Generator as Faker;
use Webkul\BookingProduct\Models\BookingProduct;
use Webkul\BookingProduct\Models\BookingProductEventTicket;
use Webkul\Product\Models\Product;
$factory->define(BookingProductEventTicket::class, function (Faker $faker, array $attributes) {
return [
'price' => $faker->randomFloat(4, 3, 900),
'qty' => $faker->randomNumber(2),
'booking_product_id' => static function () {
return factory(BookingProduct::class)->create(['type' => 'event'])->id;
}
];
});

View File

@ -0,0 +1,20 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Carbon\Carbon;
use Faker\Generator as Faker;
use Webkul\BookingProduct\Models\BookingProduct;
use Webkul\Product\Models\Product;
$factory->define(BookingProduct::class, function (Faker $faker, array $attributes) {
return [
'type' => array_rand(['event']),
'qty' => $faker->randomNumber(2),
'available_from' => Carbon::yesterday(),
'available_to' => Carbon::tomorrow(),
'product_id' => function () {
return factory(Product::class)->create(['type' => 'booking'])->id;
}
];
});

View File

@ -2,6 +2,7 @@
namespace Webkul\BookingProduct\Providers;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;
class BookingProductServiceProvider extends ServiceProvider
@ -10,8 +11,9 @@ class BookingProductServiceProvider extends ServiceProvider
* Bootstrap services.
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function boot()
public function boot(): void
{
$this->loadRoutesFrom(__DIR__ . '/../Http/front-routes.php');
@ -26,6 +28,8 @@ class BookingProductServiceProvider extends ServiceProvider
], 'public');
$this->app->register(EventServiceProvider::class);
$this->app->make(EloquentFactory::class)->load(__DIR__ . '/../Database/Factories');
}
/**
@ -33,7 +37,7 @@ class BookingProductServiceProvider extends ServiceProvider
*
* @return void
*/
public function register()
public function register(): void
{
$this->mergeConfigFrom(
dirname(__DIR__) . '/Config/product_types.php', 'product_types'

View File

@ -0,0 +1,75 @@
<?php
namespace Webkul\Core\Console\Commands;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Webkul\Attribute\Models\Attribute;
use Webkul\BookingProduct\Models\BookingProduct;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Models\ProductFlat;
class BookingCron extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'booking:cron';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Deactivates all expired Booking Products of type event';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$expiredEvents = BookingProduct::query()
->join('product_flat', 'booking_products.product_id', '=', 'product_flat.product_id')
->where('booking_products.type', 'event')
->where('booking_products.available_to', '<=', Carbon::now())
->where('product_flat.status', 1)
->get();
if (count($expiredEvents) > 0) {
$attStatusId = Attribute::query()->select('id')
->where('code', 'status')
->first()
->id;
foreach ($expiredEvents as $expEvent) {
ProductAttributeValue::query()->where('product_id', $expEvent->product_id)
->where('attribute_id', $attStatusId)
->update(['boolean_value' => 0]);
ProductFlat::query()->where('product_id', $expEvent->product_id)
->update(['status' => 0]);
Log::info('BookingCron: deactivated expired event', ['booking_product_id' => $expEvent->id, 'product_id' => $expEvent->product_id]);
}
$this->info('All expired events have been deactivated');
} else {
Log::info('BookingCron: Did not find any expired events to be deactivated');
$this->info('Did not find any expired events to be deactivated');
}
}
}

View File

@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\AliasLoader;
use Webkul\Core\Console\Commands\BookingCron;
use Webkul\Core\Core;
use Webkul\Core\Exceptions\Handler;
use Webkul\Core\Facades\Core as CoreFacade;
@ -22,6 +23,7 @@ class CoreServiceProvider extends ServiceProvider
* Bootstrap services.
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function boot()
{
@ -86,7 +88,12 @@ class CoreServiceProvider extends ServiceProvider
protected function registerCommands(): void
{
if ($this->app->runningInConsole()) {
$this->commands([BagistoVersion::class, Install::class, ExchangeRateUpdate::class]);
$this->commands([
BagistoVersion::class,
Install::class,
ExchangeRateUpdate::class,
BookingCron::class
]);
}
}
@ -96,6 +103,7 @@ class CoreServiceProvider extends ServiceProvider
* @param string $path
*
* @return void
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
protected function registerEloquentFactoriesFrom($path): void
{

View File

@ -15,7 +15,7 @@ class DataMocker extends Module
/**
* Get an instance of the faker
*
* @return Generator
* @return \Faker\Generator
*
* @author florianbosdorff
*/

View File

@ -8,6 +8,7 @@ modules:
- Asserts
- Filesystem
- \Helper\Unit
- \Helper\DataMocker
- Webkul\Core\Helpers\Laravel5Helper:
environment_file: .env.testing
run_database_migrations: true

View File

@ -0,0 +1,55 @@
<?php
namespace Tests\Unit\Core\Commands;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;
use UnitTester;
use Webkul\BookingProduct\Models\BookingProduct;
use Webkul\BookingProduct\Models\BookingProductEventTicket;
use Webkul\Core\Helpers\Laravel5Helper;
use Webkul\Product\Models\Product;
class BookingCronCest
{
public function testBookingCronDeactivateSomeEvents(UnitTester $I): void
{
$index = $I->fake()->numberBetween(2, 6);
for ($i=0; $i<$index; $i++) {
$products[$i] = $I->haveProduct(Laravel5Helper::VIRTUAL_PRODUCT);
Product::query()->where('id', $products[$i]->id)->update(['type' => 'booking']);
if ($I->fake()->randomDigitNotNull <= 5) {
$availableTo = Carbon::now()->subMinutes($I->fake()->numberBetween(2, 59));
} else {
$availableTo = Carbon::now()->addMinutes($I->fake()->numberBetween(2, 59));
}
$bookingProducts[$i] = $I->have(BookingProduct::class, [
'type' => 'event',
'available_to' => $availableTo->toDateTimeString(),
'product_id' => $products[$i]->id,
]);
$I->have(BookingProductEventTicket::class,
['booking_product_id' => $bookingProducts[$i]->id]);
$products[$i]->refresh();
$I->assertNotFalse($products[$i]->status);
}
$I->callArtisan('booking:cron');
for ($i=0; $i<$index; $i++) {
$products[$i]->refresh();
if ($bookingProducts[$i]->available_to < Carbon::now()) {
$I->assertEquals(0, $products[$i]->status);
} else {
$I->assertEquals(1, $products[$i]->status);
}
}
}
}