]> _ Git - psq.git/commitdiff
nova work, import capabilities, organization type, pdffile access count
authorLouis Jeckel <louis.jeckel@outlook.cm>
Mon, 20 Apr 2020 12:26:09 +0000 (14:26 +0200)
committerLouis Jeckel <louis.jeckel@outlook.cm>
Mon, 20 Apr 2020 12:26:09 +0000 (14:26 +0200)
24 files changed:
.idea/lettre-pharma.iml
.idea/php.xml
app/AccessLog.php
app/BelongsToPdfFile.php
app/Http/Controllers/FlowpaperController.php
app/Imports/UsersImport.php [new file with mode: 0644]
app/Jobs/ProcessEmailBatch.php
app/Nova/Actions/ImportUsers.php [new file with mode: 0644]
app/Nova/Organization.php
app/Nova/OrganizationType.php [new file with mode: 0644]
app/Nova/PdfFile.php
app/Nova/SearchableText.php
app/Nova/TrackedLink.php
app/Nova/User.php
app/Organization.php
app/OrganizationType.php [new file with mode: 0644]
app/PdfFile.php
app/Policies/PdfFilePolicy.php
app/Providers/NovaServiceProvider.php
app/User.php
composer.json
composer.lock
database/migrations/2020_04_20_104057_create_organization_types_table.php [new file with mode: 0644]
database/migrations/2020_04_20_121532_add_file_col_to_access_logs.php [new file with mode: 0644]

index 5ecb545b7169f7071d1e3e0558a0d37000bc7428..1bce1c66f737ee651ac2da5e1ce3112aeba686b0 100644 (file)
@@ -8,6 +8,7 @@
       <excludeFolder url="file://$MODULE_DIR$/node_modules" />
       <excludeFolder url="file://$MODULE_DIR$/public/js" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/algolia/algoliasearch-client-php" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/anaseqal/nova-import" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/laravel-debugbar" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/laravel-ide-helper" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/reflection-docblock" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/kub-at/php-simple-html-dom-parser" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/laravel/nova-app" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/laravel/scout" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/maatwebsite/excel" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/mailgun/mailgun-php" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/markbaker/complex" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/markbaker/matrix" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/maximebf/debugbar" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/nyholm/psr7" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/paragonie/random_compat" />
@@ -30,6 +34,7 @@
       <excludeFolder url="file://$MODULE_DIR$/vendor/php-http/message-factory" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/php-http/multipart-stream-builder" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/php-http/promise" />
+      <excludeFolder url="file://$MODULE_DIR$/vendor/phpoffice/phpspreadsheet" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
       <excludeFolder url="file://$MODULE_DIR$/vendor/pusher/pusher-php-server" />
index 854870b007751bf5f51481503c2155f7d586d970..b4a0b9b88b9f92bb34334d7c5616181592bb819f 100644 (file)
       <path value="$PROJECT_DIR$/vendor/symfony/filesystem" />
       <path value="$PROJECT_DIR$/vendor/barryvdh/laravel-ide-helper" />
       <path value="$PROJECT_DIR$/vendor/itsgoingd/clockwork" />
+      <path value="$PROJECT_DIR$/vendor/anaseqal/nova-import" />
+      <path value="$PROJECT_DIR$/vendor/phpoffice/phpspreadsheet" />
+      <path value="$PROJECT_DIR$/vendor/maatwebsite/excel" />
+      <path value="$PROJECT_DIR$/vendor/markbaker/matrix" />
+      <path value="$PROJECT_DIR$/vendor/markbaker/complex" />
     </include_path>
   </component>
   <component name="PhpProjectSharedConfiguration" php_language_level="7.2" />
index 7974728a937f1f8afae7f537d6fd948cfbbc77f7..a14b5655190cdd330aef54d0240ce353d3b776e0 100644 (file)
@@ -18,6 +18,8 @@ use Illuminate\Http\Request;
  */
 class AccessLog extends Model
 {
+    use BelongsToPdfFile;
+
     protected $guarded = [];
 
 
@@ -29,17 +31,18 @@ class AccessLog extends Model
         return $this->belongsTo(User::class);
     }
 
-
     /**
      * @param Request $request
+     * @param PdfFile|null $file
      */
-    public static function log(Request $request): void
+    public static function log(Request $request, ?PdfFile $file = null): void
     {
         $entry = new self;
 
         $entry->ip         = implode(', ', $request->ips());
         $entry->user_id    = Auth::check() ? Auth::user()->id : null;
         $entry->user_agent = $request->userAgent();
+        $entry->file_id    = $file ? $file->id : null;
 
         $entry->save();
 
index 3d47fd37a6a687111f99451f19bcdd0e7d09585e..4be5069dc6730f84e075ed7434aebac494980080 100644 (file)
@@ -6,7 +6,8 @@ namespace App;
 /**
  * Trait BelongsToPdfFile
  * @package App
- * @property-read PdfFile $file
+ * @property PdfFile $file
+ * @property int $file_id
  */
 trait BelongsToPdfFile
 {
index 3dbfacbeeea8cb9283ab83ab4999452835c34120..b415b9cb7768aa5c3c5b07a35886a579a16a1909 100644 (file)
@@ -23,7 +23,7 @@ class FlowpaperController extends Controller
     public function view(PdfFile $file, Request $request): View
     {
         $this->authorize('view', $file);
-        AccessLog::log($request);
+        AccessLog::log($request, $file);
         return $file->view();
     }
 
diff --git a/app/Imports/UsersImport.php b/app/Imports/UsersImport.php
new file mode 100644 (file)
index 0000000..769f8e2
--- /dev/null
@@ -0,0 +1,71 @@
+<?php
+
+namespace App\Imports;
+
+use App\Organization;
+use App\OrganizationType;
+use App\User;
+use Illuminate\Support\Str;
+use Maatwebsite\Excel\Concerns\Importable;
+use Maatwebsite\Excel\Concerns\ToModel;
+use Maatwebsite\Excel\Concerns\WithHeadingRow;
+use Maatwebsite\Excel\Concerns\WithValidation;
+
+class UsersImport implements ToModel, WithValidation, WithHeadingRow
+{
+    use Importable;
+    /**
+     * @param array $row
+     *
+     * @return \Illuminate\Database\Eloquent\Model|null
+     */
+    public function model(array $row)
+    {
+
+        $org = null;
+
+        if(!empty($row['org'])) {
+
+            $type = null;
+            if(!empty($row['type'])) {
+                $type = OrganizationType::query()->firstOrCreate([
+                    'slug' => $row['type']
+                ], [
+                    'name' => $row['type']
+                ]);
+            }
+
+
+            $org = Organization::query()->firstOrCreate([
+                'name' => Str::title($row['org']),
+            ], [
+                'type_id' => $type ? $type->id : null,
+                'subscription_active' => false,
+            ]);
+        }
+
+
+        return new User([
+            'first_name' => Str::title($row['first_name']),
+            'last_name' => Str::title($row['last_name']),
+            'email' => Str::lower($row['email']),
+            'position' => Str::title($row['position']),
+            'organization_id' => $org ? $org->id : null,
+            'address_line_1' => $row['address_line_1'],
+            'postal_code' => $row['postal_code'],
+            'city' => $row['city'],
+            'phone' => $row['phone'],
+            'password' => \Hash::make(Str::random()),
+        ]);
+    }
+
+    public function rules(): array
+    {
+        return [
+            '*.email' => 'email|required',
+            'email' => 'email|required',
+        ];
+    }
+
+
+}
index b92a373923319a4f7af4fb5f2cccbd8ff8aa3c9d..083373ed9d771d528828d14d7e165cb3a99a308d 100644 (file)
@@ -102,6 +102,8 @@ class ProcessEmailBatch implements ShouldQueue
             'current' => $count
         ]);
 
+        $this->batch->update(['sent_to', $users->pluck('email')]);
+
 
 
 
diff --git a/app/Nova/Actions/ImportUsers.php b/app/Nova/Actions/ImportUsers.php
new file mode 100644 (file)
index 0000000..14a9538
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+namespace App\Nova\Actions;
+
+use App\Imports\UsersImport;
+use Illuminate\Bus\Queueable;
+use Illuminate\Contracts\Queue\ShouldQueue;
+use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Collection;
+use Laravel\Nova\Fields\ActionFields;
+use Anaseqal\NovaImport\Actions\Action;
+use Laravel\Nova\Fields\File;
+use Maatwebsite\Excel\Facades\Excel;
+
+class ImportUsers extends Action
+{
+    use InteractsWithQueue, Queueable, SerializesModels;
+
+    public $onlyOnIndex = true;
+
+
+    public function name()
+    {
+        return "Import Users";
+    }
+
+        /**
+     * @return string
+     */
+    public function uriKey() :string
+    {
+        return 'import-users';
+    }
+
+    public $confirmButtonText = "Importer";
+
+    /**
+     * Perform the action on the given models.
+     *
+     * @param  \Laravel\Nova\Fields\ActionFields  $fields
+     * @param  \Illuminate\Support\Collection  $models
+     * @return mixed
+     */
+    public function handle(ActionFields $fields, Collection $models)
+    {
+        Excel::import(new UsersImport, $fields->file);
+        return Action::message("Import rĂ©ussi");
+    }
+
+    /**
+     * Get the fields available on the action.
+     *
+     * @return array
+     */
+    public function fields()
+    {
+        return [
+            File::make('File')
+                ->rules('required'),
+        ];    }
+}
index 5c15551c2b7dbc28ce5a06d3028d8bdbd9f7d9a0..cbe5f287b0a64b8eae1b58160f627be319aac440 100644 (file)
@@ -3,6 +3,7 @@
 namespace App\Nova;
 
 use Illuminate\Http\Request;
+use Laravel\Nova\Fields\BelongsTo;
 use Laravel\Nova\Fields\Boolean;
 use Laravel\Nova\Fields\HasMany;
 use Laravel\Nova\Fields\ID;
@@ -55,6 +56,7 @@ class Organization extends Resource
             ID::make()->sortable(),
             Text::make('Nom', 'name'),
             HasMany::make('Membres', 'members', User::class),
+            BelongsTo::make('Type', 'type', OrganizationType::class),
             Boolean::make('Abonnement actif', 'subscription_active')
 
         ];
diff --git a/app/Nova/OrganizationType.php b/app/Nova/OrganizationType.php
new file mode 100644 (file)
index 0000000..bdb8af2
--- /dev/null
@@ -0,0 +1,97 @@
+<?php
+
+namespace App\Nova;
+
+use Illuminate\Http\Request;
+use Laravel\Nova\Fields\HasMany;
+use Laravel\Nova\Fields\ID;
+use Laravel\Nova\Fields\Text;
+use Laravel\Nova\Http\Requests\NovaRequest;
+
+class OrganizationType extends Resource
+{
+    /**
+     * The model the resource corresponds to.
+     *
+     * @var string
+     */
+    public static $model = \App\OrganizationType::class;
+
+    /**
+     * The single value that should be used to represent the resource when being displayed.
+     *
+     * @var string
+     */
+    public static $title = 'name';
+
+    /**
+     * The columns that should be searched.
+     *
+     * @var array
+     */
+    public static $search = [
+        'name',
+    ];
+
+    public static $group = "CRM";
+
+    /**
+     * 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('Nom', 'name'),
+            Text::make('Raccourci', 'slug')->nullable(),
+            HasMany::make('Organisations', 'organizations', Organization::class),
+        ];
+    }
+
+    /**
+     * 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 e3301acbc49af8dd765bc81ca0457c1819222316..f982191abc92e020d1207dfd2cb57d952fb8f848 100644 (file)
@@ -3,7 +3,9 @@
 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;
 
@@ -46,7 +48,12 @@ class PdfFile extends Resource
             ID::make()->sortable(),
             Text::make('Titre', 'title'),
             Text::make('Slug')->readonly(),
-            Text::make('Nom du fichier', 'file_name'),
+            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(),
+
 
         ];
     }
index 16c87ffed7f3879052fb7eaed08d44b803eaf949..8fa5121785c4ec69d3b2598316bd51b51b1eec98 100644 (file)
@@ -22,15 +22,8 @@ class SearchableText extends Resource
      */
     public static $title = 'id';
 
-    /**
-     * The columns that should be searched.
-     *
-     * @var array
-     */
-    public static $search = [
-        'id',
-    ];
 
+public static $globallySearchable = false;
 
 
     /**
index 737f1158db1d5ad4a620028f443090bca1ed1662..a90593a970cc6e55c79a633765a5256b5c6aa933 100644 (file)
@@ -4,6 +4,8 @@ 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
@@ -20,7 +22,7 @@ class TrackedLink extends Resource
      *
      * @var string
      */
-    public static $title = 'id';
+    public static $title = 'title';
 
     /**
      * The columns that should be searched.
@@ -28,7 +30,7 @@ class TrackedLink extends Resource
      * @var array
      */
     public static $search = [
-        'id',
+        'title',
     ];
 
     /**
@@ -40,7 +42,12 @@ class TrackedLink extends Resource
     public function fields(Request $request)
     {
         return [
-            ID::make()->sortable(),
+
+            Text::make('Titre', 'title'),
+            Text::make('slug')->hideFromIndex(),
+            Text::make('Target')->hideFromIndex(),
+            Number::make('Clicks'),
+
         ];
     }
 
index 17da52526dc540aac41a50dab53a438f03f32c93..e39c30221b36ee8bcc53cfc1752066fc4af56fde 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace App\Nova;
 
+use App\Nova\Actions\ImportUsers;
 use Illuminate\Http\Request;
 use Laravel\Nova\Fields\BelongsTo;
 use Laravel\Nova\Fields\Boolean;
@@ -126,6 +127,8 @@ class User extends Resource
      */
     public function actions(Request $request)
     {
-        return [];
+        return [
+            new ImportUsers,
+        ];
     }
 }
index 82b39f2993b945c7eafa179ff9212322a65f79a1..55fd1b26c3332d26e5862d001b94b4efdec30ac3 100644 (file)
@@ -4,6 +4,7 @@ namespace App;
 
 use Illuminate\Database\Eloquent\Builder;
 use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
 use Illuminate\Database\Eloquent\Relations\HasMany;
 
 /**
@@ -18,6 +19,8 @@ class Organization extends Model
         'subscription_active' => 'boolean'
     ];
 
+    protected $guarded = [];
+
 
     /**
      * @return boolean
@@ -44,4 +47,12 @@ class Organization extends Model
         return $this->hasMany(User::class);
     }
 
+    /**
+     * @return BelongsTo
+     */
+    public function type(): BelongsTo
+    {
+        return $this->belongsTo(OrganizationType::class, 'type_id');
+    }
+
 }
diff --git a/app/OrganizationType.php b/app/OrganizationType.php
new file mode 100644 (file)
index 0000000..47c9161
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Model;
+
+class OrganizationType extends Model
+{
+
+    protected $guarded = [];
+
+    public $timestamps = false;
+
+    /**
+     * @return \Illuminate\Database\Eloquent\Relations\HasMany
+     */
+    public function organizations()
+    {
+        return $this->hasMany(Organization::class, 'type_id');
+    }
+
+    /**
+     * @return string
+     */
+    public function __toString(): string
+    {
+        return 'name';
+    }
+}
index ea86e6940f826909ea10a17421af7eb30b7b23d8..c0ea27b712cc45d0a0303302e2f2d03545420503 100644 (file)
@@ -7,6 +7,7 @@ use A17\Twill\Models\Behaviors\Sortable;
 use A17\Twill\Models\Model as TwillModel;
 use App\Flowpaper\Pdf2Json;
 use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Collection;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations;
 use Illuminate\Http\File;
@@ -41,6 +42,8 @@ use Vaites\ApacheTika\Client as TikaClient;
  * @property string $coverUrl
  * @property string $directory
  * @property bool $is_free
+ * @property Collection $accessLogs
+ * @property-read int $accessCount
  *
  */
 class PdfFile extends TwillModel implements Sortable
@@ -171,6 +174,23 @@ class PdfFile extends TwillModel implements Sortable
         );
     }
 
+    /**
+     * @return Relations\HasMany
+     */
+    public function accessLogs(): Relations\HasMany
+    {
+        return $this->hasMany(AccessLog::class, 'file_id');
+    }
+
+
+    /**
+     * @return int
+     */
+    public function getAccessCountAttribute(): int
+    {
+        return $this->accessLogs()->count();
+    }
+
 
     /**
      * @return string
index 1e96858b6bd53eaabe9f1332c81cb30f2c60929e..41662220a2cb23fac467b6eb82de990b3e957efa 100644 (file)
@@ -2,6 +2,8 @@
 
 namespace App\Policies;
 
+use A17\Twill\Models\User as TwillUser;
+use App\Models\Admin;
 use App\PdfFile;
 use Illuminate\Auth\Access\HandlesAuthorization;
 use Illuminate\Auth\AuthenticationException;
@@ -15,6 +17,8 @@ class PdfFilePolicy
 {
     use HandlesAuthorization;
 
+
+
     /**
      * Determine whether the user can view any models.
      *
@@ -23,6 +27,9 @@ class PdfFilePolicy
      */
     public function viewAny($user)
     {
+        if($user instanceof TwillUser) {
+            return true;
+        }
 
     }
 
@@ -36,6 +43,10 @@ class PdfFilePolicy
      */
     public function view($user = null, PdfFile $pdfFile)
     {
+        if($user instanceof TwillUser) {
+            return true;
+        }
+
         if($pdfFile->is_free || ($user instanceof \App\User ? $user->isSubscribed : false)) {
             return true;
         }
index 8a564a1f010c51ce5b862ed586e826a14d2c831f..05d973dc23e4678fbf13918b63303c3d0ef705e1 100644 (file)
@@ -3,6 +3,7 @@
 namespace App\Providers;
 
 use A17\Twill\Models\User as TwillUser;
+use Anaseqal\NovaImport\NovaImport;
 use Illuminate\Support\Facades\Gate;
 use Laravel\Nova\Cards\Help;
 use Laravel\Nova\Nova;
@@ -77,6 +78,7 @@ class NovaServiceProvider extends NovaApplicationServiceProvider
     public function tools()
     {
         return [
+            new NovaImport,
         ];
     }
 
index ba1976ddaf1debcd3c4461f547c9924d9393f2cd..836da127c265c0d0d6eec3235ebed94febfed394 100644 (file)
@@ -31,7 +31,17 @@ class User extends Authenticatable
      * @var array
      */
     protected $fillable = [
-        'first_name', 'last_name', 'email', 'password', 'reg_complete'
+        'first_name',
+        'last_name',
+        'email',
+        'password',
+        'reg_complete',
+        'position',
+        'organization_id',
+        'address_line_1',
+        'postal_code',
+        'city',
+        'phone',
     ];
 
     /**
@@ -60,7 +70,7 @@ class User extends Authenticatable
             'first_name' => $this->first_name,
             'last_name' => $this->last_name,
             'position' => $this->position,
-            'organization' => $this->organization->name,
+            'organization' => $this->organization->name ?? null,
         ];
     }
 
index 05812184747f73110835eb4633b4b9446747207c..26e94761178368b241e4c53857bad8f324b10cf9 100644 (file)
@@ -12,6 +12,7 @@
         "ext-dom": "*",
         "ext-json": "*",
         "algolia/algoliasearch-client-php": "^2.6",
+        "anaseqal/nova-import": "^0.0.3",
         "area17/twill": "^2.0",
         "fideloper/proxy": "^4.2",
         "fruitcake/laravel-cors": "^1.0",
index 9e5545eeff6439f3b7a5026f7c4de64761ece2d2..81c15df71d0d3733704b57d2f3458e9925e27f6b 100644 (file)
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "b53dc867ef2193fc1017ea0794762a36",
+    "content-hash": "170735a710a465a709486727eadb7f99",
     "packages": [
         {
             "name": "algolia/algoliasearch-client-php",
             ],
             "time": "2020-03-09T09:11:44+00:00"
         },
+        {
+            "name": "anaseqal/nova-import",
+            "version": "0.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/anaseqal/nova-import.git",
+                "reference": "548fa4d39ea914b1a5ce82b388a9d1df1bdd857a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/anaseqal/nova-import/zipball/548fa4d39ea914b1a5ce82b388a9d1df1bdd857a",
+                "reference": "548fa4d39ea914b1a5ce82b388a9d1df1bdd857a",
+                "shasum": ""
+            },
+            "require": {
+                "maatwebsite/excel": "*",
+                "php": ">=7.1.0"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Anaseqal\\NovaImport\\ToolServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Anaseqal\\NovaImport\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "A Laravel Nova tool.",
+            "keywords": [
+                "laravel",
+                "nova"
+            ],
+            "time": "2020-04-13T12:32:35+00:00"
+        },
         {
             "name": "area17/twill",
             "version": "2.0.1",
             ],
             "time": "2016-08-17T00:36:58+00:00"
         },
+        {
+            "name": "maatwebsite/excel",
+            "version": "3.1.19",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Maatwebsite/Laravel-Excel.git",
+                "reference": "96527a9ebc2e79e9a5fa7eaef7e23c9e9bcc587c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Maatwebsite/Laravel-Excel/zipball/96527a9ebc2e79e9a5fa7eaef7e23c9e9bcc587c",
+                "reference": "96527a9ebc2e79e9a5fa7eaef7e23c9e9bcc587c",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "illuminate/support": "5.5.*|5.6.*|5.7.*|5.8.*|^6.0|^7.0",
+                "php": "^7.0",
+                "phpoffice/phpspreadsheet": "^1.10"
+            },
+            "require-dev": {
+                "mockery/mockery": "^1.1",
+                "orchestra/database": "^4.0",
+                "orchestra/testbench": "^4.0",
+                "phpunit/phpunit": "^8.0",
+                "predis/predis": "^1.1"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Maatwebsite\\Excel\\ExcelServiceProvider"
+                    ],
+                    "aliases": {
+                        "Excel": "Maatwebsite\\Excel\\Facades\\Excel"
+                    }
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Maatwebsite\\Excel\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Patrick Brouwers",
+                    "email": "patrick@maatwebsite.nl"
+                }
+            ],
+            "description": "Supercharged Excel exports and imports in Laravel",
+            "keywords": [
+                "PHPExcel",
+                "batch",
+                "csv",
+                "excel",
+                "export",
+                "import",
+                "laravel",
+                "php",
+                "phpspreadsheet"
+            ],
+            "time": "2020-02-28T15:47:45+00:00"
+        },
         {
             "name": "mailgun/mailgun-php",
             "version": "3.0.0",
             "description": "The Mailgun SDK provides methods for all API functions.",
             "time": "2019-09-13T20:14:46+00:00"
         },
+        {
+            "name": "markbaker/complex",
+            "version": "1.4.8",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/MarkBaker/PHPComplex.git",
+                "reference": "8eaa40cceec7bf0518187530b2e63871be661b72"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/8eaa40cceec7bf0518187530b2e63871be661b72",
+                "reference": "8eaa40cceec7bf0518187530b2e63871be661b72",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.6.0|^7.0.0"
+            },
+            "require-dev": {
+                "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0",
+                "phpcompatibility/php-compatibility": "^9.0",
+                "phpdocumentor/phpdocumentor": "2.*",
+                "phploc/phploc": "2.*",
+                "phpmd/phpmd": "2.*",
+                "phpunit/phpunit": "^4.8.35|^5.4.0",
+                "sebastian/phpcpd": "2.*",
+                "squizlabs/php_codesniffer": "^3.4.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Complex\\": "classes/src/"
+                },
+                "files": [
+                    "classes/src/functions/abs.php",
+                    "classes/src/functions/acos.php",
+                    "classes/src/functions/acosh.php",
+                    "classes/src/functions/acot.php",
+                    "classes/src/functions/acoth.php",
+                    "classes/src/functions/acsc.php",
+                    "classes/src/functions/acsch.php",
+                    "classes/src/functions/argument.php",
+                    "classes/src/functions/asec.php",
+                    "classes/src/functions/asech.php",
+                    "classes/src/functions/asin.php",
+                    "classes/src/functions/asinh.php",
+                    "classes/src/functions/atan.php",
+                    "classes/src/functions/atanh.php",
+                    "classes/src/functions/conjugate.php",
+                    "classes/src/functions/cos.php",
+                    "classes/src/functions/cosh.php",
+                    "classes/src/functions/cot.php",
+                    "classes/src/functions/coth.php",
+                    "classes/src/functions/csc.php",
+                    "classes/src/functions/csch.php",
+                    "classes/src/functions/exp.php",
+                    "classes/src/functions/inverse.php",
+                    "classes/src/functions/ln.php",
+                    "classes/src/functions/log2.php",
+                    "classes/src/functions/log10.php",
+                    "classes/src/functions/negative.php",
+                    "classes/src/functions/pow.php",
+                    "classes/src/functions/rho.php",
+                    "classes/src/functions/sec.php",
+                    "classes/src/functions/sech.php",
+                    "classes/src/functions/sin.php",
+                    "classes/src/functions/sinh.php",
+                    "classes/src/functions/sqrt.php",
+                    "classes/src/functions/tan.php",
+                    "classes/src/functions/tanh.php",
+                    "classes/src/functions/theta.php",
+                    "classes/src/operations/add.php",
+                    "classes/src/operations/subtract.php",
+                    "classes/src/operations/multiply.php",
+                    "classes/src/operations/divideby.php",
+                    "classes/src/operations/divideinto.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mark Baker",
+                    "email": "mark@lange.demon.co.uk"
+                }
+            ],
+            "description": "PHP Class for working with complex numbers",
+            "homepage": "https://github.com/MarkBaker/PHPComplex",
+            "keywords": [
+                "complex",
+                "mathematics"
+            ],
+            "time": "2020-03-11T20:15:49+00:00"
+        },
+        {
+            "name": "markbaker/matrix",
+            "version": "1.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/MarkBaker/PHPMatrix.git",
+                "reference": "5348c5a67e3b75cd209d70103f916a93b1f1ed21"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/5348c5a67e3b75cd209d70103f916a93b1f1ed21",
+                "reference": "5348c5a67e3b75cd209d70103f916a93b1f1ed21",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.6.0|^7.0.0"
+            },
+            "require-dev": {
+                "dealerdirect/phpcodesniffer-composer-installer": "dev-master",
+                "phpcompatibility/php-compatibility": "dev-master",
+                "phploc/phploc": "^4",
+                "phpmd/phpmd": "dev-master",
+                "phpunit/phpunit": "^5.7",
+                "sebastian/phpcpd": "^3.0",
+                "squizlabs/php_codesniffer": "^3.0@dev"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Matrix\\": "classes/src/"
+                },
+                "files": [
+                    "classes/src/functions/adjoint.php",
+                    "classes/src/functions/antidiagonal.php",
+                    "classes/src/functions/cofactors.php",
+                    "classes/src/functions/determinant.php",
+                    "classes/src/functions/diagonal.php",
+                    "classes/src/functions/identity.php",
+                    "classes/src/functions/inverse.php",
+                    "classes/src/functions/minors.php",
+                    "classes/src/functions/trace.php",
+                    "classes/src/functions/transpose.php",
+                    "classes/src/operations/add.php",
+                    "classes/src/operations/directsum.php",
+                    "classes/src/operations/subtract.php",
+                    "classes/src/operations/multiply.php",
+                    "classes/src/operations/divideby.php",
+                    "classes/src/operations/divideinto.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mark Baker",
+                    "email": "mark@lange.demon.co.uk"
+                }
+            ],
+            "description": "PHP Class for working with matrices",
+            "homepage": "https://github.com/MarkBaker/PHPMatrix",
+            "keywords": [
+                "mathematics",
+                "matrix",
+                "vector"
+            ],
+            "time": "2019-10-06T11:29:25+00:00"
+        },
         {
             "name": "matthewbdaly/laravel-azure-storage",
             "version": "1.3.8",
             ],
             "time": "2016-01-26T13:27:02+00:00"
         },
+        {
+            "name": "phpoffice/phpspreadsheet",
+            "version": "1.11.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
+                "reference": "c2a205e82f9cf1cc9fab86b79e808d86dd680470"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/c2a205e82f9cf1cc9fab86b79e808d86dd680470",
+                "reference": "c2a205e82f9cf1cc9fab86b79e808d86dd680470",
+                "shasum": ""
+            },
+            "require": {
+                "ext-ctype": "*",
+                "ext-dom": "*",
+                "ext-fileinfo": "*",
+                "ext-gd": "*",
+                "ext-iconv": "*",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-simplexml": "*",
+                "ext-xml": "*",
+                "ext-xmlreader": "*",
+                "ext-xmlwriter": "*",
+                "ext-zip": "*",
+                "ext-zlib": "*",
+                "markbaker/complex": "^1.4",
+                "markbaker/matrix": "^1.2",
+                "php": "^7.1",
+                "psr/simple-cache": "^1.0"
+            },
+            "require-dev": {
+                "dompdf/dompdf": "^0.8.3",
+                "friendsofphp/php-cs-fixer": "^2.16",
+                "jpgraph/jpgraph": "^4.0",
+                "mpdf/mpdf": "^8.0",
+                "phpcompatibility/php-compatibility": "^9.3",
+                "phpunit/phpunit": "^7.5",
+                "squizlabs/php_codesniffer": "^3.5",
+                "tecnickcom/tcpdf": "^6.3"
+            },
+            "suggest": {
+                "dompdf/dompdf": "Option for rendering PDF with PDF Writer",
+                "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
+                "mpdf/mpdf": "Option for rendering PDF with PDF Writer",
+                "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Maarten Balliauw",
+                    "homepage": "https://blog.maartenballiauw.be"
+                },
+                {
+                    "name": "Mark Baker",
+                    "homepage": "https://markbakeruk.net"
+                },
+                {
+                    "name": "Franck Lefevre",
+                    "homepage": "https://rootslabs.net"
+                },
+                {
+                    "name": "Erik Tilt"
+                },
+                {
+                    "name": "Adrien Crivelli"
+                }
+            ],
+            "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
+            "homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
+            "keywords": [
+                "OpenXML",
+                "excel",
+                "gnumeric",
+                "ods",
+                "php",
+                "spreadsheet",
+                "xls",
+                "xlsx"
+            ],
+            "time": "2020-03-02T13:09:03+00:00"
+        },
         {
             "name": "phpoption/phpoption",
             "version": "1.7.3",
diff --git a/database/migrations/2020_04_20_104057_create_organization_types_table.php b/database/migrations/2020_04_20_104057_create_organization_types_table.php
new file mode 100644 (file)
index 0000000..0b8806a
--- /dev/null
@@ -0,0 +1,43 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class CreateOrganizationTypesTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('organization_types', function (Blueprint $table) {
+            $table->id();
+            $table->string('name');
+            $table->string('slug')->nullable();
+
+        });
+
+
+
+        Schema::table('organizations', function (Blueprint $table) {
+            $table->unsignedBigInteger('type_id')->nullable();
+            $table->foreign('type_id')->references('id')->on('organization_types');
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('organization_types');
+        Schema::table('organizations', function (Blueprint $table) {
+           $table->dropColumn('type_id');
+        });
+    }
+}
diff --git a/database/migrations/2020_04_20_121532_add_file_col_to_access_logs.php b/database/migrations/2020_04_20_121532_add_file_col_to_access_logs.php
new file mode 100644 (file)
index 0000000..89b4da2
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class AddFileColToAccessLogs extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('access_logs', function (Blueprint $table) {
+            $table->foreignId('file_id')->nullable()->constrained('pdf_files')->cascadeOnDelete();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('access_logs', function (Blueprint $table) {
+            $table->dropColumn('file_id');
+        });
+    }
+}