diff --git a/app/Http/Controllers/Account/AcceptanceController.php b/app/Http/Controllers/Account/AcceptanceController.php index b25a8df45..788a921f9 100644 --- a/app/Http/Controllers/Account/AcceptanceController.php +++ b/app/Http/Controllers/Account/AcceptanceController.php @@ -7,13 +7,22 @@ use App\Events\CheckoutDeclined; use App\Events\ItemAccepted; use App\Events\ItemDeclined; use App\Http\Controllers\Controller; +use App\Models\Actionlog; +use App\Models\Asset; use App\Models\CheckoutAcceptance; use App\Models\Company; use App\Models\Contracts\Acceptable; +use App\Models\User; +use App\Models\AssetModel; +use App\Models\Accessory; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; +use App\Http\Controllers\SettingsController; +use Barryvdh\DomPDF\Facade\Pdf; +use Carbon\Carbon; class AcceptanceController extends Controller { @@ -39,6 +48,7 @@ class AcceptanceController extends Controller { $acceptance = CheckoutAcceptance::find($id); + if (is_null($acceptance)) { return redirect()->route('account.accept')->with('error', trans('admin/hardware/message.does_not_exist')); } @@ -102,7 +112,8 @@ class AcceptanceController extends Controller $data_uri = e($request->input('signature_output')); $encoded_image = explode(',', $data_uri); $decoded_image = base64_decode($encoded_image[1]); - Storage::put('private_uploads/signatures/'.$sig_filename, (string) $decoded_image); + $acceptance->stored_eula_file = 'accepted-eula-'.date('Y-m-d-h-i-s').'.pdf'; + $path = Storage::put('private_uploads/signatures/'.$sig_filename, (string) $decoded_image); } if ($request->input('asset_acceptance') == 'accepted') { @@ -111,6 +122,8 @@ class AcceptanceController extends Controller event(new CheckoutAccepted($acceptance)); $return_msg = trans('admin/users/message.accepted'); + + } else { $acceptance->decline($sig_filename); @@ -119,6 +132,61 @@ class AcceptanceController extends Controller $return_msg = trans('admin/users/message.declined'); } + $item = $acceptance->checkoutable_type::find($acceptance->checkoutable_id); + + if ($acceptance->checkoutable_type== 'App\Models\Asset') { + $assigned_to = User::find($item->assigned_to); + $asset_model = AssetModel::find($item->model_id); + $branding_settings = SettingsController::getPDFBranding(); + $data = [ + 'item_tag' => $item->asset_tag, + 'item_model' => $asset_model->name, + 'item_serial' => $item->serial, + 'eula' => $item->getEula(), + 'check_out_date' => Carbon::parse($acceptance->created_at)->format($branding_settings->date_display_format), + 'accepted_date' => Carbon::parse($acceptance->accepted_at)->format($branding_settings->date_display_format), + 'assigned_to' => $assigned_to->first_name . ' ' . $assigned_to->last_name, + 'company_name' => $branding_settings->site_name, + 'signature' => storage_path() . '/private_uploads/signatures/' . $sig_filename, + 'logo' => public_path() . '/uploads/' . $branding_settings->logo, + 'date_settings' => $branding_settings->date_display_format, + ]; + $pdf = Pdf::loadView('account.accept.accept-asset-eula', $data); + Storage::put('private_uploads/eula-pdfs/' . $acceptance->stored_eula_file, $pdf->output()); + + $a = new Actionlog(); + $a->stored_eula = $item->getEula(); + $a->stored_eula_file = $acceptance->stored_eula_file; + $a->save(); + + return redirect()->to('account/accept')->with('success', $return_msg); + } +// + $accessory_user= DB::table('checkout_acceptances')->find($acceptance->assigned_to_id); + $assigned_to = User::find($accessory_user->assigned_to_id); + $accessory_model = Accessory::find($item->id); + $branding_settings = SettingsController::getPDFBranding(); + $data = [ + 'item_tag' => $item->model_number, + 'item_model' => $accessory_model->name, + 'eula' => $item->getEula(), + 'check_out_date' => Carbon::parse($acceptance->created_at)->format($branding_settings->date_display_format), + 'accepted_date' => Carbon::parse($acceptance->accepted_at)->format($branding_settings->date_display_format), +// 'assigned_by' => self + 'assigned_to' => $assigned_to->first_name . ' ' . $assigned_to->last_name, + 'company_name' => $branding_settings->site_name, + 'signature' => storage_path() . '/private_uploads/signatures/' . $sig_filename, + 'logo' => public_path() . '/uploads/' . $branding_settings->logo, + 'date_settings' => $branding_settings->date_display_format, + ]; + $pdf = Pdf::loadView('account.accept.accept-accessory-eula', $data); + Storage::put('private_uploads/eula-pdfs/' . $acceptance->stored_eula_file, $pdf->output()); + + $a = new Actionlog(); + $a->stored_eula = $item->getEula(); + $a->stored_eula_file = $acceptance->stored_eula_file; + $a->save(); + return redirect()->to('account/accept')->with('success', $return_msg); } -} +} \ No newline at end of file diff --git a/app/Http/Controllers/ActionlogController.php b/app/Http/Controllers/ActionlogController.php index dcd062ce4..c0c8a997d 100644 --- a/app/Http/Controllers/ActionlogController.php +++ b/app/Http/Controllers/ActionlogController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Helpers\Helper; +use App\Models\Actionlog; use Response; class ActionlogController extends Controller @@ -26,4 +27,10 @@ class ActionlogController extends Controller } } + public function getStoredEula($filename){ + $this->authorize('view', \App\Models\Asset::class); + $file = config('app.private_uploads').'/eula-pdfs/'.$filename; + + return Response::download($file); + } } diff --git a/app/Http/Controllers/Api/ReportsController.php b/app/Http/Controllers/Api/ReportsController.php index 1406dba79..815138654 100644 --- a/app/Http/Controllers/Api/ReportsController.php +++ b/app/Http/Controllers/Api/ReportsController.php @@ -52,6 +52,7 @@ class ReportsController extends Controller 'accept_signature', 'action_type', 'note', + 'stored_eula_file', ]; $sort = in_array($request->input('sort'), $allowed_columns) ? e($request->input('sort')) : 'created_at'; diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 852212ef3..1f0fc8c3b 100755 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -1025,6 +1025,12 @@ class SettingsController extends Controller return redirect()->back()->withInput()->withErrors($setting->getErrors()); } + public static function getPDFBranding() + { + $pdf_branding= Setting::getSettings(); + + return $pdf_branding; + } /** * Show the listing of backups. diff --git a/app/Http/Transformers/ActionlogsTransformer.php b/app/Http/Transformers/ActionlogsTransformer.php index a82b70fee..fb2e291fd 100644 --- a/app/Http/Transformers/ActionlogsTransformer.php +++ b/app/Http/Transformers/ActionlogsTransformer.php @@ -96,7 +96,7 @@ class ActionlogsTransformer 'signature_file' => ($actionlog->accept_signature) ? route('log.signature.view', ['filename' => $actionlog->accept_signature ]) : null, 'log_meta' => ((isset($clean_meta)) && (is_array($clean_meta))) ? $clean_meta: null, 'action_date' => ($actionlog->action_date) ? Helper::getFormattedDateObject($actionlog->action_date, 'datetime'): Helper::getFormattedDateObject($actionlog->created_at, 'datetime'), - + 'stored_eula_file' => ($actionlog->stored_eula_file) ? route('log.storedeula.download', ['filename' => $actionlog->stored_eula_file]) : null, ]; //\Log::info("Clean Meta is: ".print_r($clean_meta,true)); diff --git a/app/Listeners/LogListener.php b/app/Listeners/LogListener.php index f337df60f..3988d116c 100644 --- a/app/Listeners/LogListener.php +++ b/app/Listeners/LogListener.php @@ -34,11 +34,12 @@ class LogListener public function onCheckoutAccepted(CheckoutAccepted $event) { - $logaction = new Actionlog(); + $logaction = new Actionlog(); $logaction->item()->associate($event->acceptance->checkoutable); $logaction->target()->associate($event->acceptance->assignedTo); $logaction->accept_signature = $event->acceptance->signature_filename; + $logaction->stored_eula_file = $event->acceptance->stored_eula_file; $logaction->action_type = 'accepted'; // TODO: log the actual license seat that was checked out diff --git a/app/Models/Actionlog.php b/app/Models/Actionlog.php index edbc9d9ee..de313a1b2 100755 --- a/app/Models/Actionlog.php +++ b/app/Models/Actionlog.php @@ -25,7 +25,7 @@ class Actionlog extends SnipeModel protected $table = 'action_logs'; public $timestamps = true; - protected $fillable = ['created_at', 'item_type', 'user_id', 'item_id', 'action_type', 'note', 'target_id', 'target_type']; + protected $fillable = ['created_at', 'item_type', 'user_id', 'item_id', 'action_type', 'note', 'target_id', 'target_type', 'stored_eula', 'stored_eula_file']; use Searchable; diff --git a/composer.json b/composer.json index ec2ebdae7..f029b8ae5 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ "alek13/slack": "^2.0", "bacon/bacon-qr-code": "^2.0", "barryvdh/laravel-debugbar": "^3.6", + "barryvdh/laravel-dompdf": "^1.0", "doctrine/cache": "^1.10", "doctrine/common": "^2.12", "doctrine/dbal": "^3.1", diff --git a/composer.lock b/composer.lock index 322113f0b..72e1c19bc 100644 --- a/composer.lock +++ b/composer.lock @@ -408,6 +408,82 @@ ], "time": "2022-02-09T07:52:32+00:00" }, + { + "name": "barryvdh/laravel-dompdf", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/barryvdh/laravel-dompdf.git", + "reference": "e3f429e97087b2ef19b83e5ed313f080f2477685" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/e3f429e97087b2ef19b83e5ed313f080f2477685", + "reference": "e3f429e97087b2ef19b83e5ed313f080f2477685", + "shasum": "" + }, + "require": { + "dompdf/dompdf": "^1", + "illuminate/support": "^6|^7|^8|^9", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "nunomaduro/larastan": "^1|^2", + "orchestra/testbench": "^4|^5|^6|^7", + "phpro/grumphp": "^1", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "laravel": { + "providers": [ + "Barryvdh\\DomPDF\\ServiceProvider" + ], + "aliases": { + "PDF": "Barryvdh\\DomPDF\\Facade\\Pdf" + } + } + }, + "autoload": { + "psr-4": { + "Barryvdh\\DomPDF\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Barry vd. Heuvel", + "email": "barryvdh@gmail.com" + } + ], + "description": "A DOMPDF Wrapper for Laravel", + "keywords": [ + "dompdf", + "laravel", + "pdf" + ], + "support": { + "issues": "https://github.com/barryvdh/laravel-dompdf/issues", + "source": "https://github.com/barryvdh/laravel-dompdf/tree/v1.0.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2022-01-29T08:02:59+00:00" + }, { "name": "brick/math", "version": "0.9.3", @@ -1672,6 +1748,73 @@ "abandoned": "roave/better-reflection", "time": "2020-10-27T21:46:55+00:00" }, + { + "name": "dompdf/dompdf", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/dompdf/dompdf.git", + "reference": "60b704331479a69e9bcdb3496da2315b5c4f94fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/60b704331479a69e9bcdb3496da2315b5c4f94fd", + "reference": "60b704331479a69e9bcdb3496da2315b5c4f94fd", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "phenx/php-font-lib": "^0.5.4", + "phenx/php-svg-lib": "^0.3.3 || ^0.4.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.3", + "phpunit/phpunit": "^7.5 || ^8 || ^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "suggest": { + "ext-gd": "Needed to process images", + "ext-gmagick": "Improves image processing performance", + "ext-imagick": "Improves image processing performance", + "ext-zlib": "Needed for pdf stream compression" + }, + "type": "library", + "autoload": { + "psr-4": { + "Dompdf\\": "src/" + }, + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + }, + { + "name": "Brian Sweeney", + "email": "eclecticgeek@gmail.com" + }, + { + "name": "Gabriel Bull", + "email": "me@gabrielbull.com" + } + ], + "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", + "homepage": "https://github.com/dompdf/dompdf", + "support": { + "issues": "https://github.com/dompdf/dompdf/issues", + "source": "https://github.com/dompdf/dompdf/tree/v1.2.0" + }, + "time": "2022-02-07T13:02:10+00:00" + }, { "name": "dragonmantank/cron-expression", "version": "v3.3.1", @@ -5965,6 +6108,96 @@ "abandoned": "symfony/polyfill-mbstring or symfony/string", "time": "2021-01-07T16:38:58+00:00" }, + { + "name": "phenx/php-font-lib", + "version": "0.5.4", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-font-lib.git", + "reference": "dd448ad1ce34c63d09baccd05415e361300c35b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/dd448ad1ce34c63d09baccd05415e361300c35b4", + "reference": "dd448ad1ce34c63d09baccd05415e361300c35b4", + "shasum": "" + }, + "require": { + "ext-mbstring": "*" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3 || ^4 || ^5" + }, + "type": "library", + "autoload": { + "psr-4": { + "FontLib\\": "src/FontLib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "description": "A library to read, parse, export and make subsets of different types of font files.", + "homepage": "https://github.com/PhenX/php-font-lib", + "support": { + "issues": "https://github.com/dompdf/php-font-lib/issues", + "source": "https://github.com/dompdf/php-font-lib/tree/0.5.4" + }, + "time": "2021-12-17T19:44:54+00:00" + }, + { + "name": "phenx/php-svg-lib", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-svg-lib.git", + "reference": "3ffbbb037f0871c3a819e90cff8b36dd7e656189" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/3ffbbb037f0871c3a819e90cff8b36dd7e656189", + "reference": "3ffbbb037f0871c3a819e90cff8b36dd7e656189", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.4 || ^8.0", + "sabberworm/php-css-parser": "^8.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Svg\\": "src/Svg" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "description": "A library to read, parse and export to PDF SVG files.", + "homepage": "https://github.com/PhenX/php-svg-lib", + "support": { + "issues": "https://github.com/dompdf/php-svg-lib/issues", + "source": "https://github.com/dompdf/php-svg-lib/tree/0.4.0" + }, + "time": "2021-12-17T14:08:35+00:00" + }, { "name": "php-http/message-factory", "version": "v1.0.2", @@ -7606,6 +7839,59 @@ }, "time": "2022-02-21T21:48:29+00:00" }, + { + "name": "sabberworm/php-css-parser", + "version": "8.4.0", + "source": { + "type": "git", + "url": "https://github.com/sabberworm/PHP-CSS-Parser.git", + "reference": "e41d2140031d533348b2192a83f02d8dd8a71d30" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/e41d2140031d533348b2192a83f02d8dd8a71d30", + "reference": "e41d2140031d533348b2192a83f02d8dd8a71d30", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=5.6.20" + }, + "require-dev": { + "codacy/coverage": "^1.4", + "phpunit/phpunit": "^4.8.36" + }, + "suggest": { + "ext-mbstring": "for parsing UTF-8 CSS" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sabberworm\\CSS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Raphael Schweikert" + } + ], + "description": "Parser for CSS Files written in PHP", + "homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser", + "keywords": [ + "css", + "parser", + "stylesheet" + ], + "support": { + "issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues", + "source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.4.0" + }, + "time": "2021-12-11T13:40:54+00:00" + }, { "name": "sebastian/comparator", "version": "4.0.6", diff --git a/config/app.php b/config/app.php index b6d777780..d9fc45bb0 100755 --- a/config/app.php +++ b/config/app.php @@ -328,6 +328,7 @@ return [ Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, + Barryvdh\DomPDF\ServiceProvider::class, /* * Package Service Providers... @@ -396,6 +397,7 @@ return [ 'Mail' => Illuminate\Support\Facades\Mail::class, 'Notification' => Illuminate\Support\Facades\Notification::class, 'Password' => Illuminate\Support\Facades\Password::class, + 'PDF' => Barryvdh\DomPDF\Facade::class, 'Queue' => Illuminate\Support\Facades\Queue::class, 'Redirect' => Illuminate\Support\Facades\Redirect::class, 'Redis' => Illuminate\Support\Facades\Redis::class, diff --git a/database/migrations/2022_03_09_001334_add_eula_to_checkout_acceptance.php b/database/migrations/2022_03_09_001334_add_eula_to_checkout_acceptance.php new file mode 100644 index 000000000..07101d169 --- /dev/null +++ b/database/migrations/2022_03_09_001334_add_eula_to_checkout_acceptance.php @@ -0,0 +1,38 @@ +text('stored_eula')->nullable()->default(null); + $table->string('stored_eula_file')->nullable()->default(null); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('checkout_acceptances', function (Blueprint $table) { + if (Schema::hasColumn('checkout_acceptances', 'stored_eula')) { + $table->dropColumn('stored_eula'); + } + if (Schema::hasColumn('checkout_acceptances', 'stored_eula_file')) { + $table->dropColumn('stored_eula_file'); + } + }); + } +} \ No newline at end of file diff --git a/database/migrations/2022_03_10_175740_add_eula_to_action_logs.php b/database/migrations/2022_03_10_175740_add_eula_to_action_logs.php new file mode 100644 index 000000000..d970baa07 --- /dev/null +++ b/database/migrations/2022_03_10_175740_add_eula_to_action_logs.php @@ -0,0 +1,34 @@ +text('stored_eula')->nullable()->default(null); + $table->string('stored_eula_file')->nullable()->default(null); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('action_logs', function (Blueprint $table) { + $table->dropColumn('stored_eula'); + $table->dropColumn('stored_eula_file'); + }); + } +} diff --git a/resources/lang/en/general.php b/resources/lang/en/general.php index 0e38b2193..6ebc333c3 100644 --- a/resources/lang/en/general.php +++ b/resources/lang/en/general.php @@ -237,6 +237,7 @@ 'state' => 'State', 'status_labels' => 'Status Labels', 'status' => 'Status', + 'accept_eula' => 'Acceptance Agreement', 'supplier' => 'Supplier', 'suppliers' => 'Suppliers', 'sure_to_delete' => 'Are you sure you wish to delete', diff --git a/resources/views/account/accept/accept-accessory-eula.blade.php b/resources/views/account/accept/accept-accessory-eula.blade.php new file mode 100644 index 000000000..d2eb09017 --- /dev/null +++ b/resources/views/account/accept/accept-accessory-eula.blade.php @@ -0,0 +1,36 @@ + + +
+ + + + + + +@if ($signature) +{{$company_name}}
+Date: {{ date($date_settings) }}
Asset Tag: {{ $item_tag }}
+Asset Model: {{ $item_model }}
+@if ($eula) + {!! $eula !!} +@endif + +Assigned on: {{$check_out_date}}
+Accepted on: {{$accepted_date}}
+Assigned to: {{$assigned_to}}
+@if ($signature) +{{$company_name}}
+Date: {{ date($date_settings) }}
Asset Tag: {{ $item_tag }}
+Asset Model: {{ $item_model }}
+Asset Serial: {{ $item_serial }}
Assigned on: {{$check_out_date}}
+Accepted on: {{$accepted_date}}
+Assigned to: {{$assigned_to}}
+@if ($signature) +