namespace App\Console;
+use App\Jobs\CheckForTrialExpirationDates;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
*/
protected function schedule(Schedule $schedule)
{
- // $schedule->command('inspire')->hourly();
+ $schedule->job(new CheckForTrialExpirationDates)->dailyAt('13:00');
}
/**
--- /dev/null
+<?php
+
+namespace App\Jobs;
+
+use App\Notifications\TrialExpired;
+use App\Notifications\TrialExpiresSoon;
+use App\User;
+use Carbon\Carbon;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Foundation\Bus\Dispatchable;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+use function GuzzleHttp\Promise\queue;
+
+/**
+ * Class CheckForTrialExpirationDates
+ * @package App\Jobs
+ * This jobs should run after the number of the day was sent.
+ * This job should only be run ONCE A DAY
+ */
+class CheckForTrialExpirationDates implements ShouldQueue
+{
+ use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+
+ /**
+ * Create a new job instance.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ //
+ }
+
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ self::getExpiresSoonProfiles()->map(fn(User $user) => $user->notify(new TrialExpiresSoon));
+
+ self::getLastEditionTodayProfiles()->map(fn(User $user) => $user->notify(new TrialExpired));
+ }
+
+
+ /**
+ * @return \Illuminate\Support\Collection
+ * Returns profiles that only have 2 numbers left to receive
+ */
+ public static function getExpiresSoonProfiles()
+ {
+ /**
+ * @var array
+ * keys : today, values: next day of week that trial expires.
+ * Example. If today is sunday 07/01, profiles expiring
+ * next tuesday and thursday should be notified with the "2 editions left" notification
+ * That's for PSQ en Mon, Tue, Thu, Fri w/ trial ending at end of day.
+ */
+ $dm2_map = [
+ 1 => [4],
+ 2 => [],
+ 3 => [5,6,7],
+ 4 => [1],
+ 5 => [],
+ 6 => [],
+ 7 => [2, 3],
+ ];
+
+ return self::getProfilesFromMap($dm2_map);
+
+
+ }
+
+
+ /**
+ * @return \Illuminate\Support\Collection
+ *
+ * Returns profiles that expire today
+ */
+ public static function getLastEditionTodayProfiles()
+ {
+ $dd_map = [
+ 1 => [1],
+ 2 => [2, 3],
+ 3 => [],
+ 4 => [4],
+ 5 => [5,6,7],
+ 6 => [],
+ 7 => [],
+ ];
+
+ return self::getProfilesFromMap($dd_map);
+ }
+
+
+ /**
+ * @param $map
+ * @return \Illuminate\Support\Collection
+ */
+ protected static function getProfilesFromMap($map)
+ {
+ $currentDayOfWeek = now()->dayOfWeekIso;
+ $datesToSearch = collect(array_map(function($dayOfWeek) use ($currentDayOfWeek){
+ $addDays = $dayOfWeek < $currentDayOfWeek ?
+ 7 + $dayOfWeek - $currentDayOfWeek :
+ $dayOfWeek - $currentDayOfWeek;
+ return now()->addDays($addDays)->startOfDay();
+
+ }, $map[$currentDayOfWeek]));
+
+
+ return $datesToSearch->flatMap(function(Carbon $date) {
+ return User::query()
+ ->whereDate('discover_ends_at', $date)
+ ->orWhereDate('trial_ends_at', $date)
+ ->get();
+ });
+
+ }
+
+}
--- /dev/null
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use App\Mail\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class TrialExpired extends Notification
+{
+ use Queueable;
+
+ /**
+ * Create a new notification instance.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ //
+ }
+
+ /**
+ * Get the notification's delivery channels.
+ *
+ * @param mixed $notifiable
+ * @return array
+ */
+ public function via($notifiable)
+ {
+ return ['mail'];
+ }
+
+ /**
+ * Get the mail representation of the notification.
+ *
+ * @param mixed $notifiable
+ * @return \Illuminate\Notifications\Messages\MailMessage
+ */
+ public function toMail($notifiable)
+ {
+ return (new MailMessage)
+ ->addTag('trial-expired')
+ ->subject("Votre période découverte est arrivée à son terme !")
+ ->greeting('Cher Lecteur,')
+ ->line("Au cours des deux dernières semaines, vous avez reçu gratuitement les éditions de **Prescription Santé Quotidien** dans le cadre de notre offre Découverte.")
+ ->line("Malheureusement, cette offre, non reconductible, arrive est arrivée à son terme aujourd’hui et l'édition transmise ce matin est donc la dernière. **Vous pouvez dès maintenant nous contacter en cliquant sur le bouton ci-dessous** pour nous préciser le cadre d’un éventuel abonnement, et ce afin de ne pas rater une seule de nos éditions.")
+ ->action("Nous contacter", route('contact.index'))
+ ->line("Nous vous répondrons sous 24 heures et vous pourrez ainsi faire un choix éclairé.")
+ ->line("En espérant vous compter bientôt parmi nos abonnés")
+ ->salutation("LE RÉDACTEUR EN CHEF, OLIVIER ROBICHON");
+ }
+
+ /**
+ * Get the array representation of the notification.
+ *
+ * @param mixed $notifiable
+ * @return array
+ */
+ public function toArray($notifiable)
+ {
+ return [
+ //
+ ];
+ }
+}
--- /dev/null
+<?php
+
+namespace App\Notifications;
+
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use App\Mail\MailMessage;
+use Illuminate\Notifications\Notification;
+
+class TrialExpiresSoon extends Notification
+{
+ use Queueable;
+
+ /**
+ * Create a new notification instance.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ //
+ }
+
+ /**
+ * Get the notification's delivery channels.
+ *
+ * @param mixed $notifiable
+ * @return array
+ */
+ public function via($notifiable)
+ {
+ return ['mail'];
+ }
+
+ /**
+ * Get the mail representation of the notification.
+ *
+ * @param mixed $notifiable
+ * @return \Illuminate\Notifications\Messages\MailMessage
+ */
+ public function toMail($notifiable)
+ {
+ return (new MailMessage)
+ ->addTag('trial-expires-soon')
+ ->subject("Votre période découverte expire bientôt !")
+ ->greeting('Cher Lecteur,')
+ ->line("Depuis quelques jours vous recevez gratuitement les éditions de **Prescription Santé Quotidien** dans le cadre de notre offre Découverte.")
+ ->line("Nous espérons que vous appréciez ce média différent à destination des acteurs industriels de la santé et de leurs partenaires.")
+ ->line("**Dans 48 heures cette offre, non reconductible, arrivera à son terme.** Vous pouvez dès maintenant **nous contacter en cliquant sur le bouton ci-dessous** pour nous préciser le cadre d’un éventuel abonnement, et ce afin de ne pas rater une seule de nos éditions.")
+ ->action("Nous contacter", route('contact.index'))
+ ->line("Nous vous répondrons sous 24 heures et vous pourrez ainsi faire un choix éclairé.")
+ ->line("En espérant vous compter bientôt parmi nos abonnés")
+ ->salutation("LE RÉDACTEUR EN CHEF, OLIVIER ROBICHON");
+ }
+
+ /**
+ * Get the array representation of the notification.
+ *
+ * @param mixed $notifiable
+ * @return array
+ */
+ public function toArray($notifiable)
+ {
+ return [
+ //
+ ];
+ }
+}
+++ /dev/null
-<?php
-
-namespace App\Nova;
-
-use Illuminate\Http\Request;
-use Laravel\Nova\Fields\Boolean;
-use Laravel\Nova\Fields\ID;
-use Laravel\Nova\Fields\Number;
-use Laravel\Nova\Fields\Text;
-use Laravel\Nova\Http\Requests\NovaRequest;
-
-class PdfFile extends Resource
-{
- /**
- * The model the resource corresponds to.
- *
- * @var string
- */
- public static $model = \App\PdfFile::class;
-
- /**
- * The single value that should be used to represent the resource when being displayed.
- *
- * @var string
- */
- public static $title = 'title';
-
- /**
- * The columns that should be searched.
- *
- * @var array
- */
- public static $search = [
- 'title',
- ];
-
-
-
- /**
- * Get the fields displayed by the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function fields(Request $request)
- {
- return [
- ID::make()->sortable(),
- Text::make('Titre', 'title'),
- Text::make('Slug')->readonly(),
- Boolean::make('Gratuit', 'free'),
- Text::make('Lien', function(){
- return "<a class='no-underline dim text-primary font-bold' href='/preview/$this->slug' target='_blank'>Prévisualiser</a>";
- })->asHtml()->readonly(),
- Number::make('Nombre de visualisations', 'accessCount')->readonly(),
-
-
- ];
- }
-
- /**
- * Get the cards available for the request.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function cards(Request $request)
- {
- return [];
- }
-
- /**
- * Get the filters available for the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function filters(Request $request)
- {
- return [];
- }
-
- /**
- * Get the lenses available for the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function lenses(Request $request)
- {
- return [];
- }
-
- /**
- * Get the actions available for the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function actions(Request $request)
- {
- return [];
- }
-}
+++ /dev/null
-<?php
-
-namespace App\Nova;
-
-use Illuminate\Http\Request;
-use Laravel\Nova\Fields\ID;
-use Laravel\Nova\Http\Requests\NovaRequest;
-
-class SearchableText extends Resource
-{
- /**
- * The model the resource corresponds to.
- *
- * @var string
- */
- public static $model = \App\SearchableText::class;
-
- /**
- * The single value that should be used to represent the resource when being displayed.
- *
- * @var string
- */
- public static $title = 'id';
-
-
-public static $globallySearchable = false;
-
-
- /**
- * Get the fields displayed by the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function fields(Request $request)
- {
- return [
- ID::make()->sortable(),
- ];
- }
-
- /**
- * Get the cards available for the request.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function cards(Request $request)
- {
- return [];
- }
-
- /**
- * Get the filters available for the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function filters(Request $request)
- {
- return [];
- }
-
- /**
- * Get the lenses available for the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function lenses(Request $request)
- {
- return [];
- }
-
- /**
- * Get the actions available for the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function actions(Request $request)
- {
- return [];
- }
-}
+++ /dev/null
-<?php
-
-namespace App\Nova;
-
-use Illuminate\Http\Request;
-use Laravel\Nova\Fields\ID;
-use Laravel\Nova\Fields\Number;
-use Laravel\Nova\Fields\Text;
-use Laravel\Nova\Http\Requests\NovaRequest;
-
-class TrackedLink extends Resource
-{
- /**
- * The model the resource corresponds to.
- *
- * @var string
- */
- public static $model = \App\TrackedLink::class;
-
- /**
- * The single value that should be used to represent the resource when being displayed.
- *
- * @var string
- */
- public static $title = 'title';
-
- /**
- * The columns that should be searched.
- *
- * @var array
- */
- public static $search = [
- 'title',
- ];
-
- /**
- * Get the fields displayed by the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function fields(Request $request)
- {
- return [
-
- Text::make('Titre', 'title'),
- Text::make('slug')->hideFromIndex(),
- Text::make('Target')->hideFromIndex(),
- Number::make('Clicks'),
-
- ];
- }
-
- /**
- * Get the cards available for the request.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function cards(Request $request)
- {
- return [];
- }
-
- /**
- * Get the filters available for the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function filters(Request $request)
- {
- return [];
- }
-
- /**
- * Get the lenses available for the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function lenses(Request $request)
- {
- return [];
- }
-
- /**
- * Get the actions available for the resource.
- *
- * @param \Illuminate\Http\Request $request
- * @return array
- */
- public function actions(Request $request)
- {
- return [];
- }
-}
/**
* Trial duration in days
*/
- public const TRIAL_DURATION_DAYS = 14;
+ public const TRIAL_DURATION_DAYS = 15;
/**
* Discover duration in days
*/
- public const DISCOVER_DURATION_DAYS = 14;
+ public const DISCOVER_DURATION_DAYS = 15;
/**
* Possible Statuses
*/
public function startTrial(): void
{
- $this->trial_ends_at = now()->addDays(self::TRIAL_DURATION_DAYS);
+ $this->trial_ends_at = now()->addDays(self::TRIAL_DURATION_DAYS)->endOfDay();
$this->save();
}
*/
public function startDiscover(): void
{
- $this->discover_ends_at = now()->addDays(self::DISCOVER_DURATION_DAYS);
+ $this->discover_ends_at = now()->addDays(self::DISCOVER_DURATION_DAYS)->endOfDay();
$this->type = self::TYPE_DISCOVER;
$this->save();
}