Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/Console/Commands/SendExpirationAlerts.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public function handle()
->filter(fn($item) => !empty($item))
->all();
// Expiring Assets
$assets = Asset::getExpiringWarrantee($alert_interval);
$assets = Asset::getExpiringWarrantyOrEol($alert_interval);

if ($assets->count() > 0) {
$this->info(trans_choice('mail.assets_warrantee_alert', $assets->count(), ['count' => $assets->count(), 'threshold' => $alert_interval]));
Expand Down
28 changes: 28 additions & 0 deletions app/Helpers/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,34 @@ public static function defaultChartColors(int $index = 0)
return $colors[$index];
}

/**
* Check if a string has any RTL characters
* @param $value
* @return bool
*/
public static function hasRtl($string) {
$rtlChar = '/[\x{0590}-\x{083F}]|[\x{08A0}-\x{08FF}]|[\x{FB1D}-\x{FDFF}]|[\x{FE70}-\x{FEFF}]/u';
return preg_match($rtlChar, $string) != 0;
}

// is chinese, japanese or korean language
public static function isCjk($string) {
return Helper::isChinese($string) || Helper::isJapanese($string) || Helper::isKorean($string);
}

public static function isChinese($string) {
return preg_match("/\p{Han}+/u", $string);
}

public static function isJapanese($string) {
return preg_match('/[\x{4E00}-\x{9FBF}\x{3040}-\x{309F}\x{30A0}-\x{30FF}]/u', $string);
}

public static function isKorean($string) {
return preg_match('/[\x{3130}-\x{318F}\x{AC00}-\x{D7AF}]/u', $string);
}


/**
* Increases or decreases the brightness of a color by a percentage of the current brightness.
*
Expand Down
207 changes: 84 additions & 123 deletions app/Http/Controllers/Account/AcceptanceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
use App\Events\ItemDeclined;
use App\Http\Controllers\Controller;
use App\Mail\CheckoutAcceptanceResponseMail;
use App\Models\Actionlog;
use App\Models\Asset;
use App\Models\CheckoutAcceptance;
use App\Models\Company;
use App\Models\Contracts\Acceptable;
Expand All @@ -25,16 +23,16 @@
use App\Notifications\AcceptanceAssetDeclinedNotification;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use App\Http\Controllers\SettingsController;
use Barryvdh\DomPDF\Facade\Pdf;
use Carbon\Carbon;
use \Illuminate\Contracts\View\View;
use \Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Log;
use TCPDF;
use App\Helpers\Helper;

class AcceptanceController extends Controller
{
Expand Down Expand Up @@ -107,12 +105,18 @@ public function store(Request $request, $id) : RedirectResponse
}

/**
* Get the signature and save it
* Check for the signature directory
*/
if (! Storage::exists('private_uploads/signatures')) {
Storage::makeDirectory('private_uploads/signatures', 775);
}

/**
* Check for the eula-pdfs directory
*/
if (! Storage::exists('private_uploads/eula-pdfs')) {
Storage::makeDirectory('private_uploads/eula-pdfs', 775);
}


$item = $acceptance->checkoutable_type::find($acceptance->checkoutable_id);
Expand All @@ -123,19 +127,7 @@ public function store(Request $request, $id) : RedirectResponse

if ($request->input('asset_acceptance') == 'accepted') {

/**
* Check for the eula-pdfs directory
*/
if (! Storage::exists('private_uploads/eula-pdfs')) {
Storage::makeDirectory('private_uploads/eula-pdfs', 775);
}

if (Setting::getSettings()->require_accept_signature == '1') {

// Check if the signature directory exists, if not create it
if (!Storage::exists('private_uploads/signatures')) {
Storage::makeDirectory('private_uploads/signatures', 775);
}

// The item was accepted, check for a signature
if ($request->filled('signature_output')) {
Expand All @@ -152,56 +144,8 @@ public function store(Request $request, $id) : RedirectResponse
}
}


$assigned_user = User::find($acceptance->assigned_to_id);
// this is horrible
switch($acceptance->checkoutable_type){
case 'App\Models\Asset':
$pdf_view_route ='account.accept.accept-asset-eula';
$asset_model = AssetModel::find($item->model_id);
if (!$asset_model) {
return redirect()->back()->with('error', trans('admin/models/message.does_not_exist'));
}
$display_model = $asset_model->name;
break;

case 'App\Models\Accessory':
$pdf_view_route ='account.accept.accept-accessory-eula';
$accessory = Accessory::find($item->id);
$display_model = $accessory->name;
break;

case 'App\Models\LicenseSeat':
$pdf_view_route ='account.accept.accept-license-eula';
$license = License::find($item->license_id);
$display_model = $license->name;
break;

case 'App\Models\Component':
$pdf_view_route ='account.accept.accept-component-eula';
$component = Component::find($item->id);
$display_model = $component->name;
break;

case 'App\Models\Consumable':
$pdf_view_route ='account.accept.accept-consumable-eula';
$consumable = Consumable::find($item->id);
$display_model = $consumable->name;
break;
}
// if ($acceptance->checkoutable_type == 'App\Models\Asset') {
// $pdf_view_route ='account.accept.accept-asset-eula';
// $asset_model = AssetModel::find($item->model_id);
// $display_model = $asset_model->name;
// $assigned_to = User::find($item->assigned_to)->present()->fullName;
//
// } elseif ($acceptance->checkoutable_type== 'App\Models\Accessory') {
// $pdf_view_route ='account.accept.accept-accessory-eula';
// $accessory = Accessory::find($item->id);
// $display_model = $accessory->name;
// $assigned_to = User::find($item->assignedTo);
//
// }


/**
* Gather the data for the PDF. We fire this whether there is a signature required or not,
Expand All @@ -225,9 +169,9 @@ public function store(Request $request, $id) : RedirectResponse
'item_status' => $item->assetstatus?->name,
'eula' => $item->getEula(),
'note' => $request->input('note'),
'check_out_date' => Carbon::parse($acceptance->created_at)->format('Y-m-d'),
'accepted_date' => Carbon::parse($acceptance->accepted_at)->format('Y-m-d'),
'assigned_to' => $assigned_user->present()->fullName,
'check_out_date' => Carbon::parse($acceptance->created_at)->format('Y-m-d H:i:s'),
'accepted_date' => Carbon::parse($acceptance->accepted_at)->format('Y-m-d H:i:s'),
'assigned_to' => $assigned_user->display_name,
'company_name' => $branding_settings->site_name,
'signature' => ($sig_filename) ? storage_path() . '/private_uploads/signatures/' . $sig_filename : null,
'logo' => $path_logo,
Expand All @@ -236,11 +180,73 @@ public function store(Request $request, $id) : RedirectResponse
'qty' => $acceptance->qty ?? 1,
];

if ($pdf_view_route!='') {
Log::debug($pdf_filename.' is the filename, and the route was specified.');
$pdf = Pdf::loadView($pdf_view_route, $data);
Storage::put('private_uploads/eula-pdfs/' .$pdf_filename, $pdf->output());
// set some language dependent data:
$lg = Array();
$lg['a_meta_charset'] = 'UTF-8';
$lg['w_page'] = 'page';

$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);
$pdf->setRTL(false);
$pdf->setLanguageArray($lg);
$pdf->SetFontSubsetting(true);
$pdf->SetCreator('Snipe-IT');
$pdf->SetAuthor($data['assigned_to']);
$pdf->SetTitle('Asset Acceptance: '.$data['item_tag']);
$pdf->SetSubject('Asset Acceptance: '.$data['item_tag']);
$pdf->SetKeywords('Snipe-IT, assets, acceptance, eula', 'tos');
$pdf->SetFont('dejavusans', '', 8, '', true);
$pdf->SetPrintHeader(false);
$pdf->SetPrintFooter(false);
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));

$pdf->AddPage();
$pdf->writeHTML('<img src="'.$path_logo.'" height="30">', true, 0, true, 0, '');

if ($data['item_serial']) {
$pdf->writeHTML("<strong>" . trans('general.asset_tag') . '</strong>: ' . $data['item_tag'], true, 0, true, 0, '');
}
$pdf->writeHTML("<strong>".trans('general.asset_model').'</strong>: '.$data['item_model'], true, 0, true, 0, '');
if ($data['item_serial']) {
$pdf->writeHTML("<strong>".trans('admin/hardware/form.serial').'</strong>: '.$data['item_serial'], true, 0, true, 0, '');
}
$pdf->writeHTML("<strong>".trans('general.assigned_date').'</strong>: '.$data['check_out_date'], true, 0, true, 0, '');
$pdf->writeHTML("<strong>".trans('general.assignee').'</strong>: '.$data['assigned_to'], true, 0, true, 0, '');
$pdf->Ln();

// Break the EULA into lines based on newlines, and check each line for RTL or CJK characters
$eula_lines = preg_split("/\r\n|\n|\r/", $item->getEula());

foreach ($eula_lines as $eula_line) {
Helper::hasRtl($eula_line) ? $pdf->setRTL(true) : $pdf->setRTL(false);
Helper::isCjk($eula_line) ? $pdf->SetFont('cid0cs', '', 9) : $pdf->SetFont('dejavusans', '', 8, '', true);

$pdf->writeHTML(Helper::parseEscapedMarkedown($eula_line), true, 0, true, 0, '');
}
$pdf->Ln();
$pdf->Ln();
$pdf->setRTL(false);
$pdf->writeHTML('<br><br>', true, 0, true, 0, '');

if ($data['note'] != null) {
Helper::isCjk($data['note']) ? $pdf->SetFont('cid0cs', '', 9) : $pdf->SetFont('dejavusans', '', 8, '', true);
$pdf->writeHTML("<strong>".trans('general.notes') . '</strong>: ' . $data['note'], true, 0, true, 0, '');
$pdf->Ln();
}

if ($data['signature'] != null) {

$pdf->writeHTML('<img src="'.$data['signature'].'" style="max-width: 600px;">', true, 0, true, 0, '');
$pdf->writeHTML('<hr>', true, 0, true, 0, '');
}

$pdf->writeHTML("<strong>".trans('general.accepted_date').'</strong>: '.$data['accepted_date'], true, 0, true, 0, '');


$pdf_content = $pdf->Output($pdf_filename, 'S');

Storage::put('private_uploads/eula-pdfs/' .$pdf_filename, $pdf_content);


$acceptance->accept($sig_filename, $item->getEula(), $pdf_filename, $request->input('note'));

Expand All @@ -249,9 +255,8 @@ public function store(Request $request, $id) : RedirectResponse

// Add the attachment for the signing user into the $data array
$data['file'] = $pdf_filename;
$locale = $assigned_user->locale;
try {
$assigned_user->notify((new AcceptanceAssetAcceptedToUserNotification($data))->locale($locale));
$assigned_user->notify((new AcceptanceAssetAcceptedToUserNotification($data))->locale($assigned_user->locale));
} catch (\Exception $e) {
Log::warning($e);
}
Expand All @@ -265,23 +270,12 @@ public function store(Request $request, $id) : RedirectResponse

$return_msg = trans('admin/users/message.accepted');

// Item was not accepted
} else {

/**
* Check for the eula-pdfs directory
*/
if (! Storage::exists('private_uploads/eula-pdfs')) {
Storage::makeDirectory('private_uploads/eula-pdfs', 775);
}

if (Setting::getSettings()->require_accept_signature == '1') {

// Check if the signature directory exists, if not create it
if (!Storage::exists('private_uploads/signatures')) {
Storage::makeDirectory('private_uploads/signatures', 775);
}

// The item was accepted, check for a signature
// The item was declined, check for a signature
if ($request->filled('signature_output')) {
$sig_filename = 'siglog-' . Str::uuid() . '-' . date('Y-m-d-his') . '.png';
$data_uri = $request->input('signature_output');
Expand All @@ -298,39 +292,11 @@ public function store(Request $request, $id) : RedirectResponse

// Format the data to send the declined notification
$branding_settings = SettingsController::getPDFBranding();

// This is the most horriblest
switch($acceptance->checkoutable_type){
case 'App\Models\Asset':
$asset_model = AssetModel::find($item->model_id);
$display_model = $asset_model->name;
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;

case 'App\Models\Accessory':
$accessory = Accessory::find($item->id);
$display_model = $accessory->name;
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;

case 'App\Models\LicenseSeat':
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;

case 'App\Models\Component':
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;

case 'App\Models\Consumable':
$consumable = Consumable::find($item->id);
$display_model = $consumable->name;
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;
break;
}
$assigned_to = User::find($acceptance->assigned_to_id)->present()->fullName;

$data = [
'item_tag' => $item->asset_tag,
'item_model' => $display_model,
'item_model' => $item->model ? $item->model->name : $item->display_name,
'item_serial' => $item->serial,
'item_status' => $item->assetstatus?->name,
'note' => $request->input('note'),
Expand All @@ -342,11 +308,6 @@ public function store(Request $request, $id) : RedirectResponse
'qty' => $acceptance->qty ?? 1,
];

if ($pdf_view_route!='') {
Log::debug($pdf_filename.' is the filename, and the route was specified.');
$pdf = Pdf::loadView($pdf_view_route, $data);
Storage::put('private_uploads/eula-pdfs/' .$pdf_filename, $pdf->output());
}

for ($i = 0; $i < ($acceptance->qty ?? 1); $i++) {
$acceptance->decline($sig_filename, $request->input('note'));
Expand Down
2 changes: 2 additions & 0 deletions app/Http/Controllers/Api/CategoriesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public function index(Request $request) : array
'consumables_count',
'components_count',
'licenses_count',
'created_at',
'updated_at',
'image',
'notes',
];
Expand Down
21 changes: 0 additions & 21 deletions app/Models/Accessory.php
Original file line number Diff line number Diff line change
Expand Up @@ -309,27 +309,6 @@ public function requireAcceptance()
return $this->category->require_acceptance ?? false;
}

/**
* Checks for a category-specific EULA, and if that doesn't exist,
* checks for a settings level EULA
*
* @author [A. Gianotto] [<snipe@snipe.net>]
* @since [v3.0]
* @return string
*/
public function getEula()
{

if ($this->category->eula_text) {
return Helper::parseEscapedMarkedown($this->category->eula_text);
} elseif ((Setting::getSettings()->default_eula_text) && ($this->category->use_default_eula == '1')) {
return Helper::parseEscapedMarkedown(Setting::getSettings()->default_eula_text);
}

return null;
}


/**
* Check how many items within an accessory are checked out
*
Expand Down
Loading
Loading