Skip to content
Draft
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
30 changes: 29 additions & 1 deletion app/Http/Controllers/Assets/AssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use App\Models\Statuslabel;
use App\Models\User;
use App\Observers\AssetObserver;
use App\Services\PrintableService;
use App\View\Label;
use Carbon\Carbon;
use Com\Tecnick\Barcode\Barcode;
Expand Down Expand Up @@ -48,7 +49,7 @@ class AssetsController extends Controller

protected $barCodeDimensions = ['height' => 2, 'width' => 22];

public function __construct()
public function __construct(private readonly PrintableService $printableService)
{
$this->middleware('auth');
parent::__construct();
Expand Down Expand Up @@ -340,6 +341,8 @@ public function show(Asset $asset): View|RedirectResponse
$settings = Setting::getSettings();

if (isset($asset)) {
$asset->loadMissing(['model.category.printables']);

$audit_log = Actionlog::where('action_type', '=', 'audit')
->where('item_id', '=', $asset->id)
->where('item_type', '=', Asset::class)
Expand Down Expand Up @@ -1096,4 +1099,29 @@ public function getRequestedIndex($user_id = null)

return view('hardware/requested', compact('requestedItems'));
}

/**
* Render a Printable template populated with a single asset's data.
*
* @author [A. Gianotto] [<snipe@snipe.net>]
*/
public function getPrintable(Asset $asset, \App\Models\Printable $printable): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
{
$this->authorize('view', $asset);

// Ensure the printable belongs to the asset's category
$categoryId = $asset->model?->category_id;
if (! $categoryId || ! $printable->categories->contains('id', $categoryId)) {
return redirect()->route('hardware.show', $asset->id)
->with('error', trans('admin/printables/message.not_associated'));
}

$rendered = $this->printableService->render($printable, $asset);

return view('printables.show', [
'asset' => $asset,
'printable' => $printable,
'rendered' => $rendered,
]);
}
}
22 changes: 22 additions & 0 deletions app/Http/Controllers/Assets/BulkAssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,28 @@ public function edit(Request $request): View|RedirectResponse
->with('statuslabel_list', Helper::statusLabelList())
->with('models', $models->pluck(['model']))
->with('modelNames', $modelNames);

case 'printables':
$this->authorize('view', Asset::class);

$printableId = $request->input('printable_id');
if (! $printableId) {
return redirect()->back()->with('error', trans('admin/printables/message.no_printable_selected'));
}

$printable = \App\Models\Printable::find($printableId);
if (! $printable) {
return redirect()->back()->with('error', trans('admin/printables/message.does_not_exist'));
}

$service = new \App\Services\PrintableService;
$rendered = $service->renderBulk($printable, $assets);

return view('printables.bulk-generate', [
'printable' => $printable,
'assets' => $assets,
'rendered' => $rendered,
]);
}
}

Expand Down
12 changes: 10 additions & 2 deletions app/Http/Controllers/CategoriesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ public function create(): View
$this->authorize('create', Category::class);

return view('categories/edit')->with('item', new Category)
->with('category_types', Helper::categoryTypeList());
->with('category_types', Helper::categoryTypeList())
->with('printables', \App\Models\Printable::orderBy('name')->get());
}

/**
Expand Down Expand Up @@ -79,6 +80,8 @@ public function store(ImageUploadRequest $request): RedirectResponse

$category = $request->handleImages($category);
if ($category->save()) {
$category->printables()->sync($request->input('printable_ids', []));

return redirect()->route('categories.index')->with('success', trans('admin/categories/message.create.success'));
}

Expand All @@ -100,8 +103,11 @@ public function edit(Category $category): RedirectResponse|View
{
$this->authorize('update', Category::class);

$category->loadMissing('printables');

return view('categories/edit')->with('item', $category)
->with('category_types', Helper::categoryTypeList());
->with('category_types', Helper::categoryTypeList())
->with('printables', \App\Models\Printable::orderBy('name')->get());
}

/**
Expand Down Expand Up @@ -140,6 +146,8 @@ public function update(ImageUploadRequest $request, Category $category): Redirec
$category = $request->handleImages($category);

if ($category->save()) {
$category->printables()->sync($request->input('printable_ids', []));

// Redirect to the new category page
return redirect()->route('categories.index')->with('success', trans('admin/categories/message.update.success'));
}
Expand Down
145 changes: 145 additions & 0 deletions app/Http/Controllers/PrintablesController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?php

namespace App\Http\Controllers;

use App\Http\Requests\SavePrintableRequest;
use App\Models\Category;
use App\Models\CustomField;
use App\Models\Printable;
use App\Services\PrintableService;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Gate;

/**
* This class controls all actions related to Printable HTML templates.
*
* Printables are HTML templates that can be assigned to Categories.
* Assets that belong to a category with a Printable assigned to it can
* have that Printable generated/rendered with asset-specific variable data.
*
* Template management requires admin or superuser access (enforced via
* the `PrintablePolicy` which maps to the 'categories' permission column).
*/
class PrintablesController extends Controller
{
public function __construct(private readonly PrintableService $service) {}

/**
* Display a listing of all printable templates.
*/
public function index(): View
{
$this->authorize('view', Printable::class);

$printables = Printable::with('categories', 'creator')
->withCount('categories')
->latest()
->paginate(25);

return view('printables.index', compact('printables'));
}

/**
* Show the form for creating a new printable template.
*/
public function create(): View
{
$this->authorize('create', Printable::class);

$categories = Category::where('category_type', 'asset')->orderBy('name')->get();
$customFields = $this->getVisibleCustomFields();
$variables = PrintableService::availableVariables($customFields);

return view('printables.edit', [
'item' => new Printable,
'categories' => $categories,
'variables' => $variables,
]);
}

/**
* Store a newly created printable template.
*/
public function store(SavePrintableRequest $request): RedirectResponse
{
$this->authorize('create', Printable::class);

$printable = new Printable;
$printable->name = $request->input('name');
$printable->content = $request->input('content');
$printable->created_by = auth()->id();

if (! $printable->save()) {
return redirect()->back()->withInput()->withErrors($printable->getErrors());
}

$printable->categories()->sync($request->input('category_ids', []));

return redirect()->route('printables.index')
->with('success', trans('admin/printables/message.create.success'));
}

/**
* Show the form for editing an existing printable template.
*/
public function edit(Printable $printable): View
{
$this->authorize('update', Printable::class);

$categories = Category::where('category_type', 'asset')->orderBy('name')->get();
$customFields = $this->getVisibleCustomFields();
$variables = PrintableService::availableVariables($customFields);

return view('printables.edit', [
'item' => $printable,
'categories' => $categories,
'variables' => $variables,
]);
}

/**
* Update the specified printable template.
*/
public function update(SavePrintableRequest $request, Printable $printable): RedirectResponse
{
$this->authorize('update', Printable::class);

$printable->name = $request->input('name');
$printable->content = $request->input('content');

if (! $printable->save()) {
return redirect()->back()->withInput()->withErrors($printable->getErrors());
}

$printable->categories()->sync($request->input('category_ids', []));

return redirect()->route('printables.index')
->with('success', trans('admin/printables/message.update.success'));
}

/**
* Remove the specified printable template.
*/
public function destroy(Printable $printable): RedirectResponse
{
$this->authorize('delete', Printable::class);

$printable->delete();

return redirect()->route('printables.index')
->with('success', trans('admin/printables/message.delete.success'));
}

private function getVisibleCustomFields(): Collection
{
$customFieldsQuery = CustomField::query();

if (Gate::denies('assets.view.encrypted_custom_fields')) {
$customFieldsQuery->where('field_encrypted', 0);
}

return $customFieldsQuery->orderBy('name')->get();
}
}
31 changes: 31 additions & 0 deletions app/Http/Requests/SavePrintableRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class SavePrintableRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}

/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'name' => 'required|string|min:1|max:255',
'content' => 'required|string',
'category_ids' => 'nullable|array',
'category_ids.*' => 'integer|exists:categories,id',
];
}
}
24 changes: 12 additions & 12 deletions app/Http/Transformers/CustomFieldsTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@ public function transformCustomField(CustomField $field)
'id' => $field->id,
'name' => e($field->name),
'db_column_name' => e($field->db_column_name()),
'format' => e($field->format),
'field_values' => ($field->field_values) ? e($field->field_values) : null,
'field_encrypted' => ($field->field_encrypted == '1') ? true : false,
'field_values_array' => ($field->field_values) ? explode("\r\n", e($field->field_values)) : null,
'type' => e($field->element),
'required' => (($field->pivot) && ($field->pivot->required == '1')) ? true : false,
'display_in_user_view' => ($field->display_in_user_view == '1') ? true : false,
'auto_add_to_fieldsets' => ($field->auto_add_to_fieldsets == '1') ? true : false,
'show_in_listview' => ($field->show_in_listview == '1') ? true : false,
'display_checkin' => ($field->display_checkin == '1') ? true : false,
'display_checkout' => ($field->display_checkout == '1') ? true : false,
'display_audit' => ($field->display_audit == '1') ? true : false,
'format' => e($field->format),
'field_values' => ($field->field_values) ? e($field->field_values) : null,
'field_encrypted' => ($field->field_encrypted =='1') ? true : false,
'field_values_array' => ($field->field_values) ? explode("\r\n", e($field->field_values)) : null,
'type' => e($field->element),
'required' => (($field->pivot) && ($field->pivot->required=='1')) ? true : false,
'display_in_user_view' => ($field->display_in_user_view =='1') ? true : false,
'auto_add_to_fieldsets' => ($field->auto_add_to_fieldsets == '1') ? true : false,
'show_in_listview' => ($field->show_in_listview == '1') ? true : false,
'display_checkin' => ($field->display_checkin == '1') ? true : false,
'display_checkout' => ($field->display_checkout == '1') ? true : false,
'display_audit' => ($field->display_audit == '1') ? true : false,
'created_at' => Helper::getFormattedDateObject($field->created_at, 'datetime'),
'updated_at' => Helper::getFormattedDateObject($field->updated_at, 'datetime'),
];
Expand Down
10 changes: 10 additions & 0 deletions app/Models/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,16 @@ public function models()
return $this->hasMany(AssetModel::class, 'category_id');
}

/**
* Establishes the category -> printable templates relationship.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany<Printable>
*/
public function printables()
{
return $this->belongsToMany(Printable::class, 'category_printable');
}

/**
* Checks for a category-specific EULA, and if that doesn't exist,
* checks for a settings level EULA
Expand Down
Loading