Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Label Engine #12050

Merged
merged 43 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
0e69e42
Fix: Multiple outputs at hardware/{id}/label
Oct 27, 2022
35536b5
Require tecnickcom/tcpdf
Nov 1, 2022
7c355ce
Add helper to convert between units of measurement
Nov 1, 2022
df89406
Create Label model and example
Nov 1, 2022
bbecdb6
Add QR example
Nov 1, 2022
4ed728d
Add template to simulate legacy label
Nov 1, 2022
bb09f01
Create Label View/Generator
Nov 1, 2022
5558a00
Implement API for labels
Nov 1, 2022
6de48b4
Implement settings for labels
Nov 1, 2022
d37605f
Add localization strings
Nov 1, 2022
7b29ddd
Tie into tag generation
Nov 1, 2022
7e2546b
Merge branch 'snipe:develop' into develop
cram42 Nov 1, 2022
6b2fe58
Merge branch 'feature-label2' into develop
Nov 1, 2022
cde2ba7
Fix: Oops
Nov 2, 2022
19150ae
Add P-touch TZe 24mm Tape Example
Nov 2, 2022
d0eb3cf
Merge branch 'feature-label2' into develop
Nov 2, 2022
a60ee77
Add P-touch TZe 12mm Tape Example
Nov 2, 2022
a8b6a4a
Allow passing "template" param
Nov 2, 2022
06ce40a
Don't add data if it's not there
Nov 2, 2022
4bb40ad
Add Asset Tag as separate supported feature
Nov 2, 2022
4fee5ec
Support Avery L7163
Nov 2, 2022
fb467d9
Include Asset for advanced users
Nov 2, 2022
48fb4f2
Add labels route for testing layouts
Nov 2, 2022
36210f1
Allow settings to be overridden in request
Nov 2, 2022
f5fac50
Add preview pane
Nov 2, 2022
53513d9
Rework TZe labels for Asset Tag support
Nov 2, 2022
3d470d6
Drop asset tag from default field def.
Nov 2, 2022
fd96166
Label preview auto-refresh
Nov 3, 2022
f849fcc
Change the way fields are passed
Nov 10, 2022
a4b93d4
Create Field Definitions helper control
Nov 10, 2022
7108156
Fix button disabling
Nov 10, 2022
67d021e
Add alpinejs to deferred scripts
Nov 11, 2022
30a7a31
Move label preview to alpine component
Nov 11, 2022
af0872d
Fix form refresh after bootstrap-table
Nov 11, 2022
60ef568
Add "Pop Out" button for preview
Nov 12, 2022
ffce6ec
Need uppercase
Nov 12, 2022
17e81af
Add more Avery label sheets
Nov 12, 2022
c2c009a
Merge branch 'develop' into develop
cram42 Jan 24, 2023
b72c6b7
Fix 2D barcode defaults
Feb 1, 2023
4b4c228
Correct parameter order
Feb 1, 2023
73fd0a2
Clarify example asset variable
Feb 1, 2023
0f3c5d1
Merge branch 'feature-label2' into develop
Feb 1, 2023
b1464e0
Merge branch 'develop' into develop
cram42 Jul 30, 2023
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
39 changes: 39 additions & 0 deletions app/Helpers/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -1126,4 +1126,43 @@ public static function SettingUrls(){
return $settings;
}

/**
* Conversion between units of measurement
*
* @author Grant Le Roux <[email protected]>
* @since 5.0
* @param float $value Measurement value to convert
* @param string $srcUnit Source unit of measurement
* @param string $dstUnit Destination unit of measurement
* @param int $round Round the result to decimals (Default false - No rounding)
* @return float
*/
public static function convertUnit($value, $srcUnit, $dstUnit, $round=false) {
$srcFactor = static::getUnitConversionFactor($srcUnit);
$dstFactor = static::getUnitConversionFactor($dstUnit);
$output = $value * $srcFactor / $dstFactor;
return ($round !== false) ? round($output, $round) : $output;
}

/**
* Get conversion factor from unit of measurement to mm
*
* @author Grant Le Roux <[email protected]>
* @since 5.0
* @param string $unit Unit of measurement
* @return float
*/
public static function getUnitConversionFactor($unit) {
switch (strtolower($unit)) {
case 'mm': return 1.0;
case 'cm': return 10.0;
case 'm': return 1000.0;
case 'in': return 25.4;
case 'ft': return 12 * static::getUnitConversionFactor('in');
case 'yd': return 3 * static::getUnitConversionFactor('ft');
case 'pt': return (1/72) * static::getUnitConversionFactor('in');
default: throw new \InvalidArgumentException('Unit: \''.$unit.'\' is not supported');
}
}

}
71 changes: 71 additions & 0 deletions app/Http/Controllers/Api/LabelsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace App\Http\Controllers\Api;

use App\Helpers\Helper;
use App\Http\Controllers\Controller;
use App\Http\Transformers\LabelsTransformer;
use App\Models\Labels\Label;
use Illuminate\Http\Request;
use Illuminate\Support\ItemNotFoundException;
use Auth;

class LabelsController extends Controller
{
/**
* Returns JSON listing of all labels.
*
* @author Grant Le Roux <[email protected]>
* @return JsonResponse
*/
public function index(Request $request)
{
$this->authorize('view', Label::class);
Copy link
Owner

@snipe snipe Dec 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t see this permission actually being created or settable anywhere in the code?

Copy link

@MoralCode MoralCode Jan 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is having a permission for this feature something that would be useful to include in this PR? if its not doing anything, it seems like its pretty easy to just remove unless there's a need/desire to have it behind a permission setting

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding another JS framework kinda gives me the oogs

Yeah, I get it! I really didn't want to add another one. I tried using Livewire, but it made me sad. I just can't get me head around it to do what I want.

What’s the difference in page weight

93.8k :(

is the defer.js part of that?

Sadly it is. Alpine's loading has to be after the DOM. So I needed to mix an "all-defer.js" and load it as <script defer src=...

I'll revisit a Livewire option now that I'm back from holidays.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t see this permission actually being created or settable anywhere in the code?

Oops, nope. It was really just a placeholder in case locking it down was required.

Is having a permission for this feature something that would be useful to include in this PR? if its not doing anything, it seems like its pretty easy to just remove unless there's a need/desire to have it behind a permission setting

I can remove it for now and reintroduce if needed.


$labels = Label::find();

if ($request->filled('search')) {
$search = $request->get('search');
$labels = $labels->filter(function ($label, $index) use ($search) {
return stripos($label->getName(), $search) !== false;
});
}

$total = $labels->count();

$offset = $request->get('offset', 0);
$offset = ($offset > $total) ? $total : $offset;

$maxLimit = config('app.max_results');
$limit = $request->get('limit', $maxLimit);
$limit = ($limit > $maxLimit) ? $maxLimit : $limit;

$labels = $labels->skip($offset)->take($limit);

return (new LabelsTransformer)->transformLabels($labels, $total, $request);
}

/**
* Returns JSON with information about a label for detail view.
*
* @author Grant Le Roux <[email protected]>
* @param string $labelName
* @return JsonResponse
*/
public function show(string $labelName)
{
$labelName = str_replace('/', '\\', $labelName);
try {
$label = Label::find($labelName);
} catch(ItemNotFoundException $e) {
return response()
->json(
Helper::formatStandardApiResponse('error', null, trans('admin/labels/message.does_not_exist')),
404
);
}
$this->authorize('view', $label);
return (new LabelsTransformer)->transformLabel($label);
}

}
12 changes: 8 additions & 4 deletions app/Http/Controllers/Assets/AssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use App\Models\Location;
use App\Models\Setting;
use App\Models\User;
use App\View\Label;
use Auth;
use Carbon\Carbon;
use DB;
Expand Down Expand Up @@ -441,11 +442,12 @@ public function getAssetBySerial(Request $request)
* @since [v3.0]
* @return Redirect
*/
public function getAssetByTag(Request $request)
public function getAssetByTag($tag=null, Request $request)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TINY nit here (and I’d accept this without this change) but stylistically, we typically order method parameters with Request first, required (not nullable) variables next, and nullable/optional variables last.

Copy link

@MoralCode MoralCode Jan 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in case its useful, i swapped these parameters on my fork since it was a relatively easy, low risk change to make. I don't have the right access to directly add it here, but my branch is based on this one so it should be easy for someone with write access to push the commits to the right place

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep. This was a derp on my part. Sorry.

{
$tag = $tag ? $tag : $request->get('assetTag');
$topsearch = ($request->get('topsearch') == 'true');

if (! $asset = Asset::where('asset_tag', '=', $request->get('assetTag'))->first()) {
if (! $asset = Asset::where('asset_tag', '=', $tag)->first()) {
return redirect()->route('hardware.index')->with('error', trans('admin/hardware/message.does_not_exist'));
}
$this->authorize('view', $asset);
Expand Down Expand Up @@ -542,9 +544,11 @@ public function getLabel($assetId = null)
$asset = Asset::find($assetId);
$this->authorize('view', $asset);

return view('hardware/labels')
->with('assets', Asset::find($asset))
return (new Label())
->with('assets', collect([ $asset ]))
->with('settings', Setting::getSettings())
->with('template', request()->get('template'))
->with('offset', request()->get('offset'))
->with('bulkedit', false)
->with('count', 0);
}
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Controllers/Assets/BulkAssetsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Http\Controllers\Controller;
use App\Models\Asset;
use App\Models\Setting;
use App\View\Label;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
Expand Down Expand Up @@ -44,7 +45,7 @@ public function edit(Request $request)
if ($request->filled('bulk_actions')) {
switch ($request->input('bulk_actions')) {
case 'labels':
return view('hardware/labels')
return (new Label)
->with('assets', Asset::find($asset_ids))
->with('settings', Setting::getSettings())
->with('bulkedit', true)
Expand Down
81 changes: 81 additions & 0 deletions app/Http/Controllers/LabelsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace App\Http\Controllers;

use App\Models\Asset;
use App\Models\AssetModel;
use App\Models\Category;
use App\Models\Company;
use App\Models\Labels\Label;
use App\Models\Manufacturer;
use App\Models\Setting;
use App\Models\User;
use App\View\Label as LabelView;
use Illuminate\Support\Facades\Storage;

class LabelsController extends Controller
{
/**
* Returns the Label view with test data
*
* @author Grant Le Roux <[email protected]>
* @param string $labelName
* @return \Illuminate\Contracts\View\View
*/
public function show(string $labelName)
{
$this->authorize('view', Label::class);

$labelName = str_replace('/', '\\', $labelName);
$template = Label::find($labelName);

$this->authorize('view', $template);

$testAsset = new Asset();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, TINY nit - can we rename this to something a little clearer, like $exampleAsset or $previewAsset?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i have a branch on my fork that renames this to $exampleAsset in case that's useful in helping get this merged


$testAsset->id = 999999;
$testAsset->name = 'AST-AB-CD-1234';
$testAsset->asset_tag = 'TCA-00001';
$testAsset->serial = 'SN9876543210';

$testAsset->company = new Company();
$testAsset->company->id = 999999;
$testAsset->company->name = 'Test Company Limited';
$testAsset->company->image = 'company-image-test.png';

$testAsset->assignedto = new User();
$testAsset->assignedto->id = 999999;
$testAsset->assignedto->first_name = 'Test';
$testAsset->assignedto->last_name = 'Person';
$testAsset->assignedto->username = 'Test.Person';
$testAsset->assignedto->employee_num = '0123456789';

$testAsset->model = new AssetModel();
$testAsset->model->id = 999999;
$testAsset->model->name = 'Test Model';
$testAsset->model->model_number = 'MDL5678';
$testAsset->model->manufacturer = new Manufacturer();
$testAsset->model->manufacturer->id = 999999;
$testAsset->model->manufacturer->name = 'Test Manufacturing Inc.';
$testAsset->model->category = new Category();
$testAsset->model->category->id = 999999;
$testAsset->model->category->name = 'Test Category';

$settings = Setting::getSettings();
if (request()->has('settings')) {
$overrides = request()->get('settings');
foreach ($overrides as $key => $value) {
$settings->$key = $value;
}
}

return (new LabelView())
->with('assets', collect([$testAsset]))
->with('settings', $settings)
->with('template', $template)
->with('bulkedit', false)
->with('count', 0);

return redirect()->route('home')->with('error', trans('admin/labels/message.does_not_exist'));
}
}
8 changes: 8 additions & 0 deletions app/Http/Controllers/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,14 @@ public function postLabels(Request $request)
if (is_null($setting = Setting::getSettings())) {
return redirect()->to('admin')->with('error', trans('admin/settings/message.update.error'));
}
$setting->label2_enable = $request->input('label2_enable');
$setting->label2_template = $request->input('label2_template');
$setting->label2_title = $request->input('label2_title');
$setting->label2_asset_logo = $request->input('label2_asset_logo');
$setting->label2_1d_type = $request->input('label2_1d_type');
$setting->label2_2d_type = $request->input('label2_2d_type');
$setting->label2_2d_target = $request->input('label2_2d_target');
$setting->label2_fields = $request->input('label2_fields');
$setting->labels_per_page = $request->input('labels_per_page');
$setting->labels_width = $request->input('labels_width');
$setting->labels_height = $request->input('labels_height');
Expand Down
71 changes: 71 additions & 0 deletions app/Http/Transformers/LabelsTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace App\Http\Transformers;

use App\Helpers\Helper;
use App\Models\Labels\Label;
use App\Models\Labels\Sheet;
use App\Models\Labels\RectangleSheet;
use Illuminate\Support\Collection;

class LabelsTransformer
{
public function transformLabels(Collection $labels, $total)
{
$array = [];
foreach ($labels as $label) {
$array[] = self::transformLabel($label);
}

return (new DatatablesTransformer)->transformDatatables($array, $total);
}

public function transformLabel(Label $label)
{
$array = [
'name' => $label->getName(),
'unit' => $label->getUnit(),

'width' => $label->getWidth(),
'height' => $label->getHeight(),

'margin_top' => $label->getMarginTop(),
'margin_bottom' => $label->getMarginBottom(),
'margin_left' => $label->getMarginLeft(),
'margin_right' => $label->getMarginRight(),

'support_asset_tag' => $label->getSupportAssetTag(),
'support_1d_barcode' => $label->getSupport1DBarcode(),
'support_2d_barcode' => $label->getSupport2DBarcode(),
'support_fields' => $label->getSupportFields(),
'support_logo' => $label->getSupportLogo(),
'support_title' => $label->getSupportTitle(),
];

if ($label instanceof Sheet) {
$array['sheet_info'] = [
'label_width' => $label->getLabelWidth(),
'label_height' => $label->getLabelHeight(),

'label_margin_top' => $label->getLabelMarginTop(),
'label_margin_bottom' => $label->getLabelMarginBottom(),
'label_margin_left' => $label->getLabelMarginLeft(),
'label_margin_right' => $label->getLabelMarginRight(),

'labels_per_page' => $label->getLabelsPerPage(),
'label_border' => $label->getLabelBorder(),
];
}

if ($label instanceof RectangleSheet) {
$array['rectanglesheet_info'] = [
'columns' => $label->getColumns(),
'rows' => $label->getRows(),
'column_spacing' => $label->getLabelColumnSpacing(),
'row_spacing' => $label->getLabelRowSpacing(),
];
}

return $array;
}
}
Loading