Brand stats part 1 Create and schedule brand stats
This commit is contained in:
parent
8938dc4201
commit
6bd00e78d6
6 changed files with 221 additions and 0 deletions
35
app/Console/Commands/StartStatJobs.php
Normal file
35
app/Console/Commands/StartStatJobs.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Jobs\StartStatJobs as JobsStartStatJobs;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class StartStatJobs extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'stats:collect';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Force push the collect stats jobs into the queue (stats)';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
\dispatch(new JobsStartStatJobs())->afterResponse();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Jobs\StartStatJobs;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
|
|
@ -23,6 +24,8 @@ class Kernel extends ConsoleKernel
|
|||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// stats job on night
|
||||
$schedule->job(StartStatJobs::class)->dailyAt('03:30');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
17
app/Jobs/StartStatJobs.php
Normal file
17
app/Jobs/StartStatJobs.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Brand;
|
||||
|
||||
class StartStatJobs
|
||||
{
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$brands = Brand::all();
|
||||
foreach ($brands as $brand) {
|
||||
\dispatch(new StatJob($brand))->onQueue('stats')->delay(rand(0, 90));
|
||||
}
|
||||
}
|
||||
}
|
||||
78
app/Jobs/StatJob.php
Normal file
78
app/Jobs/StatJob.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Brand;
|
||||
use App\Models\BrandStat;
|
||||
use App\Models\CustomerInfo;
|
||||
use App\Models\CustomerLogin;
|
||||
use App\Models\SingleOptin;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class StatJob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
// Set high max tries as using prevent overlap
|
||||
public $tries = 10;
|
||||
|
||||
/** Used to prevent overlaping */
|
||||
private const JOBKEY = 32644296;
|
||||
|
||||
/** @var \App\Models\Brand */
|
||||
private $brand;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Brand $brand)
|
||||
{
|
||||
$this->brand = $brand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$stats = new BrandStat([
|
||||
'active' => CustomerLogin::whereBrandId($this->brand->id)
|
||||
->whereDate('last_connection', '<', Carbon::now()->subMonths(6))->count(),
|
||||
'inactive' => CustomerLogin::whereBrandId($this->brand->id)
|
||||
->whereDate('last_connection', '>', Carbon::now()->subMonths(6))->count(),
|
||||
'new_accounts' => CustomerLogin::whereBrandId($this->brand->id)
|
||||
->whereDate('created_at', '<', Carbon::now()->subMonths(6))->count(),
|
||||
'old_accounts' => CustomerLogin::whereBrandId($this->brand->id)
|
||||
->whereDate('created_at', '>', Carbon::now()->subMonths(6))->count(),
|
||||
'total_accounts' => CustomerLogin::whereBrandId($this->brand->id)->count(),
|
||||
'total_opt_in' => CustomerInfo::whereBrandId($this->brand->id)
|
||||
->whereOptIn(true)->count() + SingleOptin::whereBrandId($this->brand->id)->count()
|
||||
]);
|
||||
$stats->brand()->associate($this->brand);
|
||||
$stats->saveOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the middleware the job should pass through.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function middleware()
|
||||
{
|
||||
// dispatch randomly overlaping jobs if overlapping
|
||||
return [(new WithoutOverlapping(self::JOBKEY))->releaseAfter(rand(20, 90))];
|
||||
}
|
||||
}
|
||||
36
app/Models/BrandStat.php
Normal file
36
app/Models/BrandStat.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class BrandStat extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
public $casts = [
|
||||
'created_at' => 'date'
|
||||
];
|
||||
|
||||
protected $fillable = [
|
||||
'active', 'inactive',
|
||||
'old_accounts', 'new_accounts',
|
||||
'total_accounts', 'total_opt_in'
|
||||
];
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function (BrandStat $stat) {
|
||||
$stat->created_at = Carbon::now();
|
||||
});
|
||||
}
|
||||
|
||||
public function brand()
|
||||
{
|
||||
return $this->belongsTo(Brand::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateBrandStatsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('brand_stats', function (Blueprint $table) {
|
||||
// Le nombre de comptes actifs (dernière connexion inférieure à 6 mois)
|
||||
$table->unsignedInteger('active');
|
||||
|
||||
// Le nombre de comptes inactifs (dernière connexion supérieure à 6 mois)
|
||||
$table->unsignedInteger('inactive');
|
||||
|
||||
// Le nombre d’anciens comptes (date de création supérieure à 6 mois
|
||||
$table->unsignedInteger('old_accounts');
|
||||
|
||||
// Le nombre de nouveaux comptes (date de création inférieure à 6 mois)
|
||||
$table->unsignedInteger('new_accounts');
|
||||
|
||||
// Le nombre de comptes total
|
||||
$table->unsignedInteger('total_accounts');
|
||||
|
||||
// Le nombre d’optins (single optin compris)
|
||||
$table->unsignedInteger('total_opt_in');
|
||||
|
||||
$table->timestamp('created_at')->nullable();
|
||||
|
||||
$table->foreignId('brand_id')->constrained('brands');
|
||||
|
||||
$table->index(['brand_id', 'created_at']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('brand_stats');
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue