]> _ Git - psq.git/commitdiff
new trial ending emails
authorLouis Jeckel <louis.jeckel@outlook.cm>
Tue, 22 Sep 2020 10:50:05 +0000 (12:50 +0200)
committerLouis Jeckel <louis.jeckel@outlook.cm>
Tue, 22 Sep 2020 10:50:05 +0000 (12:50 +0200)
app/Console/Kernel.php
app/Jobs/CheckForTrialExpirationDates.php [new file with mode: 0644]
app/Notifications/TrialExpired.php [new file with mode: 0644]
app/Notifications/TrialExpiresSoon.php [new file with mode: 0644]
app/Nova/PdfFile.php [deleted file]
app/Nova/SearchableText.php [deleted file]
app/Nova/TrackedLink.php [deleted file]
app/User.php

index 69914e9937839b2a0fa23ec9142ca20fd7ab7a8d..fbb7f2d133245147431bf962bdc23f36de86d2f9 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace App\Console;
 
+use App\Jobs\CheckForTrialExpirationDates;
 use Illuminate\Console\Scheduling\Schedule;
 use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
 
@@ -24,7 +25,7 @@ class Kernel extends ConsoleKernel
      */
     protected function schedule(Schedule $schedule)
     {
-        // $schedule->command('inspire')->hourly();
+        $schedule->job(new CheckForTrialExpirationDates)->dailyAt('13:00');
     }
 
     /**
diff --git a/app/Jobs/CheckForTrialExpirationDates.php b/app/Jobs/CheckForTrialExpirationDates.php
new file mode 100644 (file)
index 0000000..96d345a
--- /dev/null
@@ -0,0 +1,124 @@
+<?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();
+        });
+
+    }
+
+}
diff --git a/app/Notifications/TrialExpired.php b/app/Notifications/TrialExpired.php
new file mode 100644 (file)
index 0000000..1e29e52
--- /dev/null
@@ -0,0 +1,67 @@
+<?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 [
+            //
+        ];
+    }
+}
diff --git a/app/Notifications/TrialExpiresSoon.php b/app/Notifications/TrialExpiresSoon.php
new file mode 100644 (file)
index 0000000..209a9a8
--- /dev/null
@@ -0,0 +1,68 @@
+<?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 [
+            //
+        ];
+    }
+}
diff --git a/app/Nova/PdfFile.php b/app/Nova/PdfFile.php
deleted file mode 100644 (file)
index f982191..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-<?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 [];
-    }
-}
diff --git a/app/Nova/SearchableText.php b/app/Nova/SearchableText.php
deleted file mode 100644 (file)
index 8fa5121..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-<?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 [];
-    }
-}
diff --git a/app/Nova/TrackedLink.php b/app/Nova/TrackedLink.php
deleted file mode 100644 (file)
index a90593a..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-<?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 [];
-    }
-}
index 21df16fe85c20781774f60ec831bdaa8bee19e8f..77f342ec1671605cd34c4b3b93d5f03381ff16bc 100644 (file)
@@ -98,11 +98,11 @@ class User extends Authenticatable implements MustVerifyEmail
     /**
      * 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
@@ -246,7 +246,7 @@ class User extends Authenticatable implements MustVerifyEmail
      */
     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();
     }
 
@@ -255,7 +255,7 @@ class User extends Authenticatable implements MustVerifyEmail
      */
     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();
     }