diff --git a/.all-contributorsrc b/.all-contributorsrc index 133e8849d..41e7063e3 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -2952,6 +2952,15 @@ "contributions": [ "code" ] + }, + { + "login": "cram42", + "name": "Grant Le Roux", + "avatar_url": "https://avatars.githubusercontent.com/u/5396871?v=4", + "profile": "https://github.com/cram42", + "contributions": [ + "code" + ] } ] } diff --git a/README.md b/README.md index 19310b976..fe57aa2f3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade) -[![All Contributors](https://img.shields.io/badge/all_contributors-325-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev) +[![All Contributors](https://img.shields.io/badge/all_contributors-326-orange.svg?style=flat-square)](#contributors) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.gg/yZFtShAcKk) [![huntr](https://cdn.huntr.dev/huntr_security_badge_mono.svg)](https://huntr.dev) ## Snipe-IT - Open Source Asset Management System @@ -145,7 +145,7 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken | [
Chris Hartjes](http://www.littlehart.net/atthekeyboard)
[💻](https://github.com/snipe/snipe-it/commits?author=chartjes "Code") | [
geo-chen](https://github.com/geo-chen)
[💻](https://github.com/snipe/snipe-it/commits?author=geo-chen "Code") | [
Phan Nguyen](https://github.com/nh314)
[💻](https://github.com/snipe/snipe-it/commits?author=nh314 "Code") | [
Iisakki Jaakkola](https://github.com/StarlessNights)
[💻](https://github.com/snipe/snipe-it/commits?author=StarlessNights "Code") | [
Ikko Ashimine](https://bandism.net/)
[💻](https://github.com/snipe/snipe-it/commits?author=eltociear "Code") | [
Lukas Fehling](https://github.com/lukasfehling)
[💻](https://github.com/snipe/snipe-it/commits?author=lukasfehling "Code") | [
Fernando Almeida](https://github.com/fernando-almeida)
[💻](https://github.com/snipe/snipe-it/commits?author=fernando-almeida "Code") | | [
akemidx](https://github.com/akemidx)
[💻](https://github.com/snipe/snipe-it/commits?author=akemidx "Code") | [
Oguz Bilgic](http://oguz.site)
[💻](https://github.com/snipe/snipe-it/commits?author=oguzbilgic "Code") | [
Scooter Crawford](https://github.com/scoo73r)
[💻](https://github.com/snipe/snipe-it/commits?author=scoo73r "Code") | [
subdriven](https://github.com/subdriven)
[💻](https://github.com/snipe/snipe-it/commits?author=subdriven "Code") | [
Andrew Savinykh](https://github.com/AndrewSav)
[💻](https://github.com/snipe/snipe-it/commits?author=AndrewSav "Code") | [
Tadayuki Onishi](https://kenchan0130.github.io)
[💻](https://github.com/snipe/snipe-it/commits?author=kenchan0130 "Code") | [
Florian](https://github.com/floschoepfer)
[💻](https://github.com/snipe/snipe-it/commits?author=floschoepfer "Code") | | [
Spencer Long](http://spencerlong.com)
[💻](https://github.com/snipe/snipe-it/commits?author=spencerrlongg "Code") | [
Marcus Moore](https://github.com/marcusmoore)
[💻](https://github.com/snipe/snipe-it/commits?author=marcusmoore "Code") | [
Martin Meredith](https://github.com/Mezzle)
| [
dboth](http://dboth.de)
[💻](https://github.com/snipe/snipe-it/commits?author=dboth "Code") | [
Zachary Fleck](https://github.com/zacharyfleck)
[💻](https://github.com/snipe/snipe-it/commits?author=zacharyfleck "Code") | [
VIKAAS-A](https://github.com/vikaas-cyper)
[💻](https://github.com/snipe/snipe-it/commits?author=vikaas-cyper "Code") | [
Abdul Kareem](https://github.com/ak-piracha)
[💻](https://github.com/snipe/snipe-it/commits?author=ak-piracha "Code") | -| [
NojoudAlshehri](https://github.com/NojoudAlshehri)
[💻](https://github.com/snipe/snipe-it/commits?author=NojoudAlshehri "Code") | [
Stefan Stidl](https://github.com/stefanstidlffg)
[💻](https://github.com/snipe/snipe-it/commits?author=stefanstidlffg "Code") | [
Quentin Aymard](https://github.com/qay21)
[💻](https://github.com/snipe/snipe-it/commits?author=qay21 "Code") | +| [
NojoudAlshehri](https://github.com/NojoudAlshehri)
[💻](https://github.com/snipe/snipe-it/commits?author=NojoudAlshehri "Code") | [
Stefan Stidl](https://github.com/stefanstidlffg)
[💻](https://github.com/snipe/snipe-it/commits?author=stefanstidlffg "Code") | [
Quentin Aymard](https://github.com/qay21)
[💻](https://github.com/snipe/snipe-it/commits?author=qay21 "Code") | [
Grant Le Roux](https://github.com/cram42)
[💻](https://github.com/snipe/snipe-it/commits?author=cram42 "Code") | This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! diff --git a/app/Helpers/Helper.php b/app/Helpers/Helper.php index f0f2f5e13..680c7acfd 100644 --- a/app/Helpers/Helper.php +++ b/app/Helpers/Helper.php @@ -1220,10 +1220,60 @@ class Helper return true; \Log::debug('app locked!'); } - + return false; } + + /** + * Conversion between units of measurement + * + * @author Grant Le Roux + * @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 + * @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'); + + return false; + } + } + /* * I know it's gauche to return a shitty HTML string, but this is just a helper and since it will be the same every single time, diff --git a/app/Http/Controllers/Api/LabelsController.php b/app/Http/Controllers/Api/LabelsController.php new file mode 100644 index 000000000..6576ec037 --- /dev/null +++ b/app/Http/Controllers/Api/LabelsController.php @@ -0,0 +1,71 @@ + + * @return JsonResponse + */ + public function index(Request $request) + { + $this->authorize('view', Label::class); + + $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 + * @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); + } + +} diff --git a/app/Http/Controllers/Assets/AssetsController.php b/app/Http/Controllers/Assets/AssetsController.php index 74b3dffa1..e699779a3 100755 --- a/app/Http/Controllers/Assets/AssetsController.php +++ b/app/Http/Controllers/Assets/AssetsController.php @@ -14,6 +14,7 @@ use App\Models\Location; use App\Models\Setting; use App\Models\Statuslabel; use App\Models\User; +use App\View\Label; use Auth; use Carbon\Carbon; use DB; @@ -453,11 +454,12 @@ class AssetsController extends Controller * @since [v3.0] * @return Redirect */ - public function getAssetByTag(Request $request) + public function getAssetByTag(Request $request, $tag=null) { + $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); @@ -554,9 +556,11 @@ class AssetsController extends Controller $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); } diff --git a/app/Http/Controllers/Assets/BulkAssetsController.php b/app/Http/Controllers/Assets/BulkAssetsController.php index 80d17f1b3..841909893 100644 --- a/app/Http/Controllers/Assets/BulkAssetsController.php +++ b/app/Http/Controllers/Assets/BulkAssetsController.php @@ -8,6 +8,7 @@ use App\Http\Controllers\CheckInOutRequest; 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; @@ -45,7 +46,7 @@ class BulkAssetsController extends Controller switch ($request->input('bulk_actions')) { case 'labels': $this->authorize('view', Asset::class); - return view('hardware/labels') + return (new Label) ->with('assets', Asset::find($asset_ids)) ->with('settings', Setting::getSettings()) ->with('bulkedit', true) diff --git a/app/Http/Controllers/LabelsController.php b/app/Http/Controllers/LabelsController.php new file mode 100755 index 000000000..97608cb5e --- /dev/null +++ b/app/Http/Controllers/LabelsController.php @@ -0,0 +1,77 @@ + + * @param string $labelName + * @return \Illuminate\Contracts\View\View + */ + public function show(string $labelName) + { + $labelName = str_replace('/', '\\', $labelName); + $template = Label::find($labelName); + + $exampleAsset = new Asset(); + + $exampleAsset->id = 999999; + $exampleAsset->name = 'AST-AB-CD-1234'; + $exampleAsset->asset_tag = 'TCA-00001'; + $exampleAsset->serial = 'SN9876543210'; + + $exampleAsset->company = new Company(); + $exampleAsset->company->id = 999999; + $exampleAsset->company->name = 'Test Company Limited'; + $exampleAsset->company->image = 'company-image-test.png'; + + $exampleAsset->assignedto = new User(); + $exampleAsset->assignedto->id = 999999; + $exampleAsset->assignedto->first_name = 'Test'; + $exampleAsset->assignedto->last_name = 'Person'; + $exampleAsset->assignedto->username = 'Test.Person'; + $exampleAsset->assignedto->employee_num = '0123456789'; + + $exampleAsset->model = new AssetModel(); + $exampleAsset->model->id = 999999; + $exampleAsset->model->name = 'Test Model'; + $exampleAsset->model->model_number = 'MDL5678'; + $exampleAsset->model->manufacturer = new Manufacturer(); + $exampleAsset->model->manufacturer->id = 999999; + $exampleAsset->model->manufacturer->name = 'Test Manufacturing Inc.'; + $exampleAsset->model->category = new Category(); + $exampleAsset->model->category->id = 999999; + $exampleAsset->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([$exampleAsset])) + ->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')); + } +} diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 87fc98c19..f8c063842 100755 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -827,6 +827,14 @@ class SettingsController extends Controller 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'); diff --git a/app/Http/Transformers/LabelsTransformer.php b/app/Http/Transformers/LabelsTransformer.php new file mode 100644 index 000000000..8e0e8ca44 --- /dev/null +++ b/app/Http/Transformers/LabelsTransformer.php @@ -0,0 +1,71 @@ +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; + } +} diff --git a/app/Models/Labels/DefaultLabel.php b/app/Models/Labels/DefaultLabel.php new file mode 100644 index 000000000..3a7dd5af1 --- /dev/null +++ b/app/Models/Labels/DefaultLabel.php @@ -0,0 +1,224 @@ +textSize = Helper::convertUnit($settings->labels_fontsize, 'pt', 'in'); + + $this->labelWidth = $settings->labels_width; + $this->labelHeight = $settings->labels_height; + + $this->labelSpacingH = $settings->labels_display_sgutter; + $this->labelSpacingV = $settings->labels_display_bgutter; + + $this->pageMarginTop = $settings->labels_pmargin_top; + $this->pageMarginBottom = $settings->labels_pmargin_bottom; + $this->pageMarginLeft = $settings->labels_pmargin_left; + $this->pageMarginRight = $settings->labels_pmargin_right; + + $this->pageWidth = $settings->labels_pagewidth; + $this->pageHeight = $settings->labels_pageheight; + + $usableWidth = $this->pageWidth - $this->pageMarginLeft - $this->pageMarginRight; + $usableHeight = $this->pageHeight - $this->pageMarginTop - $this->pageMarginBottom; + + $this->columns = ($usableWidth + $this->labelSpacingH) / ($this->labelWidth + $this->labelSpacingH); + $this->rows = ($usableHeight + $this->labelSpacingV) / ($this->labelHeight + $this->labelSpacingV); + } + + public function getUnit() { return 'in'; } + + public function getPageWidth() { return $this->pageWidth; } + public function getPageHeight() { return $this->pageHeight; } + + public function getPageMarginTop() { return $this->pageMarginTop; } + public function getPageMarginBottom() { return $this->pageMarginBottom; } + public function getPageMarginLeft() { return $this->pageMarginLeft; } + public function getPageMarginRight() { return $this->pageMarginRight; } + + public function getColumns() { return $this->columns; } + public function getRows() { return $this->rows; } + public function getLabelBorder() { return 0.01; } + + public function getLabelWidth() { return $this->labelWidth; } + public function getLabelHeight() { return $this->labelHeight; } + + public function getLabelMarginTop() { return 0; } + public function getLabelMarginBottom() { return 0; } + public function getLabelMarginLeft() { return 0; } + public function getLabelMarginRight() { return 0; } + + public function getLabelColumnSpacing() { return $this->labelSpacingH; } + public function getLabelRowSpacing() { return $this->labelSpacingV; } + + public function getSupportAssetTag() { return false; } + public function getSupport1DBarcode() { return true; } + public function getSupport2DBarcode() { return true; } + public function getSupportFields() { return 4; } + public function getSupportTitle() { return true; } + public function getSupportLogo() { return true; } + + public function preparePDF($pdf) {} + + public function write($pdf, $record) { + + $asset = $record->get('asset'); + $settings = Setting::getSettings(); + + $textY = 0; + $textX1 = 0; + $textX2 = $this->getLabelWidth(); + + // 1D Barcode + if ($record->get('barcode1d')) { + static::write1DBarcode( + $pdf, $record->get('barcode1d')->content, $record->get('barcode1d')->type, + 0.05, $this->getLabelHeight() - self::BARCODE1D_SIZE, + $this->getLabelWidth() - 0.1, self::BARCODE1D_SIZE + ); + } + + // 2D Barcode + if ($record->get('barcode2d')) { + static::write2DBarcode( + $pdf, $record->get('barcode2d')->content, $record->get('barcode2d')->type, + 0, 0, self::BARCODE2D_SIZE, self::BARCODE2D_SIZE + ); + $textX1 += self::BARCODE2D_SIZE + self::BARCODE2D_MARGIN; + } + + // Logo + if ($record->get('logo')) { + $logoSize = static::writeImage( + $pdf, $record->get('logo'), + $this->labelWidth - self::LOGO_SIZE[0], 0, + self::LOGO_SIZE[0], self::LOGO_SIZE[1], + 'R', 'T', 300, true, false, 0 + ); + $textX2 -= ($logoSize[0] + self::LOGO_MARGIN); + } + + $textW = $textX2 - $textX1; + + // Title + if ($record->get('title')) { + static::writeText( + $pdf, $record->get('title'), + $textX1, 0, + 'freesans', 'b', $this->textSize, 'L', + $textW, $this->textSize, + true, 0 + ); + $textY += $this->textSize + self::TEXT_MARGIN; + } + + // Fields + $fieldsDone = 0; + if ($settings->labels_display_name && $fieldsDone < $this->getSupportFields()) { + if ($asset->name) { + static::writeText( + $pdf, 'N: '.$asset->name, + $textX1, $textY, + 'freesans', '', $this->textSize, 'L', + $textW, $this->textSize, + true, 0 + ); + $textY += $this->textSize + self::TEXT_MARGIN; + $fieldsDone++; + } + } + if ($settings->labels_display_company_name && $fieldsDone < $this->getSupportFields()) { + if ($asset->company) { + static::writeText( + $pdf, 'C: '.$asset->company->name, + $textX1, $textY, + 'freesans', '', $this->textSize, 'L', + $textW, $this->textSize, + true, 0 + ); + $textY += $this->textSize + self::TEXT_MARGIN; + $fieldsDone++; + } + } + if ($settings->labels_display_tag && $fieldsDone < $this->getSupportFields()) { + if ($asset->asset_tag) { + static::writeText( + $pdf, 'T: '.$asset->asset_tag, + $textX1, $textY, + 'freesans', '', $this->textSize, 'L', + $textW, $this->textSize, + true, 0 + ); + $textY += $this->textSize + self::TEXT_MARGIN; + $fieldsDone++; + } + } + if ($settings->labels_display_serial && $fieldsDone < $this->getSupportFields()) { + if ($asset->serial) { + static::writeText( + $pdf, 'S: '.$asset->serial, + $textX1, $textY, + 'freesans', '', $this->textSize, 'L', + $textW, $this->textSize, + true, 0 + ); + $textY += $this->textSize + self::TEXT_MARGIN; + $fieldsDone++; + } + } + if ($settings->labels_display_model && $fieldsDone < $this->getSupportFields()) { + if ($asset->model) { + static::writeText( + $pdf, 'M: '.$asset->model->name, + $textX1, $textY, + 'freesans', '', $this->textSize, 'L', + $textW, $this->textSize, + true, 0 + ); + $textY += $this->textSize + self::TEXT_MARGIN; + $fieldsDone++; + } + } + + } +} + +?> \ No newline at end of file diff --git a/app/Models/Labels/Field.php b/app/Models/Labels/Field.php new file mode 100644 index 000000000..b264c7ac2 --- /dev/null +++ b/app/Models/Labels/Field.php @@ -0,0 +1,39 @@ +options; } + public function setOptions($options) { + $tempCollect = collect($options); + if (!$tempCollect->contains(fn($o) => !is_subclass_of($o, FieldOption::class))) { + $this->options = $options; + } + } + + public function toArray(Asset $asset) { return Field::makeArray($this, $asset); } + + /* Statics */ + + public static function makeArray(Field $field, Asset $asset) { + return $field->getOptions() + ->map(fn($option) => $option->toArray($asset)) + ->filter(fn($result) => $result['value'] != null); + } + + public static function makeString(Field $option) { + return implode('|', $option->getOptions()); + } + + public static function fromString(string $theString) { + $field = new Field(); + $field->options = collect(explode('|', $theString)) + ->filter(fn($optionString) => !empty($optionString)) + ->map(fn($optionString) => FieldOption::fromString($optionString)); + return $field; + } +} \ No newline at end of file diff --git a/app/Models/Labels/FieldOption.php b/app/Models/Labels/FieldOption.php new file mode 100644 index 000000000..76427acca --- /dev/null +++ b/app/Models/Labels/FieldOption.php @@ -0,0 +1,49 @@ +label; } + + protected string $dataSource; + public function getDataSource() { return $this->dataSource; } + + public function getValue(Asset $asset) { + $dataPath = collect(explode('.', $this->dataSource)); + return $dataPath->reduce(function ($myValue, $path) { + try { return $myValue ? $myValue->{$path} : ${$myValue}; } + catch (\Exception $e) { return $myValue; } + }, $asset); + } + + public function toArray(Asset $asset=null) { return FieldOption::makeArray($this, $asset); } + public function toString() { return FieldOption::makeString($this); } + + /* Statics */ + + public static function makeArray(FieldOption $option, Asset $asset=null) { + return [ + 'label' => $option->getLabel(), + 'dataSource' => $option->getDataSource(), + 'value' => $asset ? $option->getValue($asset) : null + ]; + } + + public static function makeString(FieldOption $option) { + return $option->getLabel() . '=' . $option->getDataSource(); + } + + public static function fromString(string $theString) { + $parts = explode('=', $theString); + if (count($parts) == 2) { + $option = new FieldOption(); + $option->label = $parts[0]; + $option->dataSource = $parts[1]; + return $option; + } + } +} \ No newline at end of file diff --git a/app/Models/Labels/Label.php b/app/Models/Labels/Label.php new file mode 100644 index 000000000..ff759ac54 --- /dev/null +++ b/app/Models/Labels/Label.php @@ -0,0 +1,598 @@ +each(function ($record, $index) use ($pdf) { + $pdf->AddPage(); + $this->write($pdf, $record); + }); + } + + /** + * Returns the qualified class name relative to the Label class's namespace. + * + * @return string + */ + public final function getName() { + $refClass = new \ReflectionClass(Label::class); + return str_replace($refClass->getNamespaceName() . '\\', '', get_class($this)); + } + + /** + * Returns the label's orientation as a string. + * 'L' = Landscape + * 'P' = Portrait + * + * @return string + */ + public final function getOrientation() { + return ($this->getWidth() >= $this->getHeight()) ? 'L' : 'P'; + } + + /** + * Returns the label's printable area as an object. + * + * @return object [ 'x1'=>0.00, 'y1'=>0.00, 'x2'=>0.00, 'y2'=>0.00, 'w'=>0.00, 'h'=>0.00 ] + */ + public final function getPrintableArea() { + return (object)[ + 'x1' => $this->getMarginLeft(), + 'y1' => $this->getMarginTop(), + 'x2' => $this->getWidth() - $this->getMarginRight(), + 'y2' => $this->getHeight() - $this->getMarginBottom(), + 'w' => $this->getWidth() - $this->getMarginLeft() - $this->getMarginRight(), + 'h' => $this->getHeight() - $this->getMarginTop() - $this->getMarginBottom(), + ]; + } + + /** + * Write a text cell. + * + * @param TCPDF $pdf The TCPDF instance + * @param string $text The text to write. Supports 'some **bold** text'. + * @param float $x X position of top-left + * @param float $y Y position of top-left + * @param string $font The font family + * @param string $style The font style + * @param int $size The font size in getUnit() units + * @param string $align Align text in the box. 'L' left, 'R' right, 'C' center. + * @param float $width Force text box width. NULL to auto-fit. + * @param float $height Force text box height. NULL to auto-fit. + * @param bool $squash Squash text if it's too big + * @param int $border Thickness of border. Default = 0. + * @param int $spacing Letter spacing. Default = 0. + */ + public final function writeText(TCPDF $pdf, $text, $x, $y, $font=null, $style=null, $size=null, $align='L', $width=null, $height=null, $squash=false, $border=0, $spacing=0) { + $prevFamily = $pdf->getFontFamily(); + $prevStyle = $pdf->getFontStyle(); + $prevSizePt = $pdf->getFontSizePt(); + + $text = !empty($text) ? $text : ''; + + $fontFamily = !empty($font) ? $font : $prevFamily; + $fontStyle = !empty($style) ? $style : $prevStyle; + if ($size) $fontSizePt = Helper::convertUnit($size, $this->getUnit(), 'pt', true); + else $fontSizePt = $prevSizePt; + + $pdf->SetFontSpacing($spacing); + + $parts = collect(explode('**', $text)) + ->map(function ($part, $index) use ($pdf, $fontFamily, $fontStyle, $fontSizePt) { + $modStyle = ($index % 2 == 1) ? 'B' : $fontStyle; + $pdf->setFont($fontFamily, $modStyle, $fontSizePt); + return [ + 'text' => $part, + 'text_width' => $pdf->GetStringWidth($part), + 'font_family' => $fontFamily, + 'font_style' => $modStyle, + 'font_size' => $fontSizePt, + ]; + }); + + $textWidth = $parts->reduce(function ($carry, $part) { return $carry += $part['text_width']; }); + $cellWidth = !empty($width) ? $width : $textWidth; + + if ($squash && ($textWidth > 0)) { + $scaleFactor = min(1.0, $cellWidth / $textWidth); + $parts = $parts->map(function ($part, $index) use ($scaleFactor) { + $part['text_width'] = $part['text_width'] * $scaleFactor; + return $part; + }); + } + $cellHeight = !empty($height) ? $height : Helper::convertUnit($fontSizePt, 'pt', $this->getUnit()); + + if ($border) { + $prevLineWidth = $pdf->getLineWidth(); + $pdf->setLineWidth($border); + $pdf->Rect($x, $y, $cellWidth, $cellHeight); + $pdf->setLineWidth($prevLineWidth); + } + + switch($align) { + case 'R': $startX = ($x + $cellWidth) - min($cellWidth, $textWidth); break; + case 'C': $startX = ($x + ($cellWidth / 2)) - (min($cellWidth, $textWidth) / 2); break; + case 'L': + default: $startX = $x; break; + } + + $parts->reduce(function ($currentX, $part) use ($pdf, $y, $cellHeight) { + $pdf->SetXY($currentX, $y); + $pdf->setFont($part['font_family'], $part['font_style'], $part['font_size']); + $pdf->Cell($part['text_width'], $cellHeight, $part['text'], 0, 0, '', false, '', 1, true); + return $currentX += $part['text_width']; + }, $startX); + + $pdf->SetFont($prevFamily, $prevStyle, $prevSizePt); + $pdf->SetFontSpacing(0); + } + + /** + * Write an image. + * + * @param TCPDF $pdf The TCPDF instance + * @param string $image The image to write + * @param float $x X position of top-left + * @param float $y Y position of top-left + * @param float $width The container width + * @param float $height The container height + * @param string $halign Align text in the box. 'L' left, 'R' right, 'C' center. Default 'L'. + * @param string $valign Align text in the box. 'T' top, 'B' bottom, 'C' center. Default 'T'. + * @param int $dpi Pixels per inch + * @param bool $resize Resize to fit container + * @param bool $stretch Stretch (vs Scale) to fit container + * @param int $border Thickness of border. Default = 0. + * + * @return array Returns the final calculated size [w,h] + */ + public final function writeImage(TCPDF $pdf, $image, $x, $y, $width=null, $height=null, $halign='L', $valign='L', $dpi=300, $resize=false, $stretch=false, $border=0) { + + if (empty($image)) return [0,0]; + + $imageInfo = getimagesize($image); + if (!$imageInfo) return [0,0]; // TODO: SVG or other + + $imageWidthPx = $imageInfo[0]; + $imageHeightPx = $imageInfo[1]; + $imageType = image_type_to_extension($imageInfo[2], false); + + $imageRatio = $imageWidthPx / $imageHeightPx; + $dpu = Helper::convertUnit($dpi, $this->getUnit(), 'in'); + $imageWidth = $imageWidthPx / $dpu; + $imageHeight = $imageHeightPx / $dpu; + + $outputWidth = $imageWidth; + $outputHeight = $imageHeight; + + if ($resize) { + // Assign specified parameters + $limitWidth = $width; + $limitHeight = $height; + + // If not, try calculating from the other dimension + $limitWidth = ($limitWidth > 0) ? $limitWidth : ($limitHeight / $imageRatio); + $limitHeight = ($limitHeight > 0) ? $limitHeight : ($limitWidth * $imageRatio); + + // If not, just use the image size + $limitWidth = ($limitWidth > 0) ? $limitWidth : $imageWidth; + $limitHeight = ($limitHeight > 0) ? $limitHeight : $imageHeight; + + $scaleWidth = $limitWidth / $imageWidth; + $scaleHeight = $limitHeight / $imageHeight; + + // If non-stretch, make both scales factors equal + if (!$stretch) { + // Do we need to scale down at all? That's most important. + if (($scaleWidth < 1.0) || ($scaleHeight < 1.0)) { + // Choose largest scale-down + $scaleWidth = min($scaleWidth, $scaleHeight); + } else { + // Choose smallest scale-up + $scaleWidth = min(max($scaleWidth, 1.0), max($scaleHeight, 1.0)); + } + $scaleHeight = $scaleWidth; + } + + $outputWidth = $imageWidth * $scaleWidth; + $outputHeight = $imageHeight * $scaleHeight; + } + + // Container + $containerWidth = !empty($width) ? $width : $outputWidth; + $containerHeight = !empty($height) ? $height : $outputHeight; + + // Horizontal Position + switch ($halign) { + case 'R': $originX = ($x + $containerWidth) - $outputWidth; break; + case 'C': $originX = ($x + ($containerWidth / 2)) - ($outputWidth / 2); break; + case 'L': + default: $originX = $x; break; + } + + // Vertical Position + switch ($valign) { + case 'B': $originY = ($y + $containerHeight) - $outputHeight; break; + case 'C': $originY = ($y + ($containerHeight / 2)) - ($outputHeight / 2); break; + case 'T': + default: $originY = $y; break; + } + + // Actual Image + $pdf->Image($image, $originX, $originY, $outputWidth, $outputHeight, $imageType, '', '', true); + + // Border + if ($border) { + $prevLineWidth = $pdf->getLineWidth(); + $pdf->setLineWidth($border); + $pdf->Rect($x, $y, $containerWidth, $containerHeight); + $pdf->setLineWidth($prevLineWidth); + } + + return [ $outputWidth, $outputHeight ]; + } + + /** + * Write a 1D barcode. + * + * @param TCPDF $pdf The TCPDF instance + * @param string $value The barcode content + * @param string $type The barcode type + * @param float $x X position of top-left + * @param float $y Y position of top-left + * @param float $width The container width + * @param float $height The container height + */ + public final function write1DBarcode(TCPDF $pdf, $value, $type, $x, $y, $width, $height) { + if (empty($value)) return; + $pdf->write1DBarcode($value, $type, $x, $y, $width, $height, null, ['stretch'=>true]); + } + + /** + * Write a 2D barcode. + * + * @param TCPDF $pdf The TCPDF instance + * @param string $value The barcode content + * @param string $type The barcode type + * @param float $x X position of top-left + * @param float $y Y position of top-left + * @param float $width The container width + * @param float $height The container height + */ + public final function write2DBarcode(TCPDF $pdf, $value, $type, $x, $y, $width, $height) { + if (empty($value)) return; + $pdf->write2DBarcode($value, $type, $x, $y, $width, $height, null, ['stretch'=>true]); + } + + + + /** + * Checks the template is internally valid + */ + public final function validate() { + $this->validateUnits(); + $this->validateSize(); + $this->validateMargins(); + $this->validateSupport(); + } + + private function validateUnits() { + $validUnits = [ 'pt', 'mm', 'cm', 'in' ]; + $unit = $this->getUnit(); + if (!in_array(strtolower($unit), $validUnits)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_value', [ + 'name' => 'getUnit()', + 'expected' => '[ \''.implode('\', \'', $validUnits).'\' ]', + 'actual' => '\''.$unit.'\'' + ])); + } + } + + private function validateSize() { + $width = $this->getWidth(); + if (!is_numeric($width) || is_string($width)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getWidth()', + 'expected' => 'float', + 'actual' => gettype($width) + ])); + } + + $height = $this->getHeight(); + if (!is_numeric($height) || is_string($height)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getHeight()', + 'expected' => 'float', + 'actual' => gettype($height) + ])); + } + } + + private function validateMargins() { + $marginTop = $this->getMarginTop(); + if (!is_numeric($marginTop) || is_string($marginTop)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getMarginTop()', + 'expected' => 'float', + 'actual' => gettype($marginTop) + ])); + } + + $marginBottom = $this->getMarginBottom(); + if (!is_numeric($marginBottom) || is_string($marginBottom)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getMarginBottom()', + 'expected' => 'float', + 'actual' => gettype($marginBottom) + ])); + } + + $marginLeft = $this->getMarginLeft(); + if (!is_numeric($marginLeft) || is_string($marginLeft)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getMarginLeft()', + 'expected' => 'float', + 'actual' => gettype($marginLeft) + ])); + } + + $marginRight = $this->getMarginRight(); + if (!is_numeric($marginRight) || is_string($marginRight)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getMarginRight()', + 'expected' => 'float', + 'actual' => gettype($marginRight) + ])); + } + } + + private function validateSupport() { + $support1D = $this->getSupport1DBarcode(); + if (!is_bool($support1D)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getSupport1DBarcode()', + 'expected' => 'boolean', + 'actual' => gettype($support1D) + ])); + } + + $support2D = $this->getSupport2DBarcode(); + if (!is_bool($support2D)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getSupport2DBarcode()', + 'expected' => 'boolean', + 'actual' => gettype($support2D) + ])); + } + + $supportFields = $this->getSupportFields(); + if (!is_int($supportFields)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getSupportFields()', + 'expected' => 'integer', + 'actual' => gettype($supportFields) + ])); + } + + $supportLogo = $this->getSupportLogo(); + if (!is_bool($supportLogo)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getSupportLogo()', + 'expected' => 'boolean', + 'actual' => gettype($supportLogo) + ])); + } + + $supportTitle = $this->getSupportTitle(); + if (!is_bool($supportTitle)) { + throw new \UnexpectedValueException(trans('admin/labels/message.invalid_return_type', [ + 'name' => 'getSupportTitle()', + 'expected' => 'boolean', + 'actual' => gettype($supportTitle) + ])); + } + } + + + + /** + * Public Static Functions + */ + + /** + * Find size of a page by its format. + * + * @param string $format Format name (eg: 'A4', 'LETTER', etc.) + * @param string $orientation 'L' for Landscape, 'P' for Portrait ('L' default) + * @param string $unit Unit of measure to return in ('mm' default) + * + * @return object (object)[ 'width' => (float)123.4, 'height' => (float)123.4 ] + */ + public static function fromFormat($format, $orientation='L', $unit='mm', $round=false) { + $size = collect(TCPDF_STATIC::getPageSizeFromFormat(strtoupper($format))) + ->sort() + ->map(function ($value) use ($unit) { + return Helper::convertUnit($value, 'pt', $unit); + }) + ->toArray(); + $width = ($orientation == 'L') ? $size[1] : $size[0]; + $height = ($orientation == 'L') ? $size[0] : $size[1]; + return (object)[ + 'width' => ($round !== false) ? round($width, $round) : $width, + 'height' => ($round !== false) ? round($height, $round) : $height, + ]; + } + + /** + * Find a Label by its path (or just return them all). + * + * Unlike most Models, these are defined by their existence as non- + * abstract classes stored in Models\Labels. + * + * @param string|Arrayable|array|null $path Label path[s] + * @return Collection|Label|null + */ + public static function find($name=null) { + // Find many + if (is_array($name) || $name instanceof Arrayable) { + $labels = collect($name) + ->map(function ($thisname) { + return static::find($thisname); + }) + ->whereNotNull(); + return ($labels->count() > 0) ? $labels : null; + } + + // Find one + if ($name !== null) { + return static::find() + ->sole(function ($label) use ($name) { + return $label->getName() == $name; + }); + } + + // Find all + return collect(File::allFiles(__DIR__)) + ->map(function ($file) { + preg_match_all('/\/*(.+?)(?:\/|\.)/', $file->getRelativePathName(), $matches); + return __NAMESPACE__ . '\\' . implode('\\', $matches[1]); + }) + ->filter(function ($name) { + if (!class_exists($name)) return false; + $refClass = new \ReflectionClass($name); + if ($refClass->isAbstract()) return false; + return $refClass->isSubclassOf(Label::class); + }) + ->map(function ($name) { + return new $name(); + }); + } + + + +} diff --git a/app/Models/Labels/RectangleSheet.php b/app/Models/Labels/RectangleSheet.php new file mode 100644 index 000000000..f5fe5cda9 --- /dev/null +++ b/app/Models/Labels/RectangleSheet.php @@ -0,0 +1,48 @@ +getColumns() * $this->getRows(); } + + public function getLabelPosition($index) { + $printIndex = $index + $this->getLabelIndexOffset(); + $row = (int)($printIndex / $this->getColumns()); + $col = $printIndex - ($row * $this->getColumns()); + $x = $this->getPageMarginLeft() + (($this->getLabelWidth() + $this->getLabelColumnSpacing()) * $col); + $y = $this->getPageMarginTop() + (($this->getLabelHeight() + $this->getLabelRowSpacing()) * $row); + return [ $x, $y ]; + } +} + +?> \ No newline at end of file diff --git a/app/Models/Labels/Sheet.php b/app/Models/Labels/Sheet.php new file mode 100644 index 000000000..83e363591 --- /dev/null +++ b/app/Models/Labels/Sheet.php @@ -0,0 +1,209 @@ +getPageWidth(); } + public function getHeight() { return $this->getPageHeight(); } + public function getMarginTop() { return $this->getPageMarginTop(); } + public function getMarginBottom() { return $this->getPageMarginBottom(); } + public function getMarginLeft() { return $this->getPageMarginLeft(); } + public function getMarginRight() { return $this->getPageMarginRight(); } + + /** + * Returns the page width in getUnit() units + * + * @return float + */ + public abstract function getPageWidth(); + + /** + * Returns the page height in getUnit() units + * + * @return float + */ + public abstract function getPageHeight(); + + /** + * Returns the page top margin in getUnit() units + * + * @return float + */ + public abstract function getPageMarginTop(); + + /** + * Returns the page bottom margin in getUnit() units + * + * @return float + */ + public abstract function getPageMarginBottom(); + + /** + * Returns the page left margin in getUnit() units + * + * @return float + */ + public abstract function getPageMarginLeft(); + + /** + * Returns the page right margin in getUnit() units + * + * @return float + */ + public abstract function getPageMarginRight(); + + /** + * Returns the page width in getUnit() units + * + * @return float + */ + public abstract function getLabelWidth(); + + /** + * Returns each label's height in getUnit() units + * + * @return float + */ + public abstract function getLabelHeight(); + + /** + * Returns each label's top margin in getUnit() units + * + * @return float + */ + public abstract function getLabelMarginTop(); + + /** + * Returns each label's bottom margin in getUnit() units + * + * @return float + */ + public abstract function getLabelMarginBottom(); + + /** + * Returns each label's left margin in getUnit() units + * + * @return float + */ + public abstract function getLabelMarginLeft(); + + /** + * Returns each label's right margin in getUnit() units + * + * @return float + */ + public abstract function getLabelMarginRight(); + + /** + * Returns the number of labels each page supports + * + * @return int + */ + public abstract function getLabelsPerPage(); + + /** + * Returns label position based on its index + * + * @param int $index + * + * @return array [x,y] + */ + public abstract function getLabelPosition(int $index); + + /** + * Returns the border to draw around labels + * + * @return int + */ + public abstract function getLabelBorder(); + + /** + * Handle the data here. Override for multiple-per-page handling + * + * @param TCPDF $pdf The TCPDF instance + * @param Collection $data The data + */ + public function writeAll($pdf, $data) { + $prevPageNumber = -1; + + foreach ($data->toArray() as $recordIndex => $record) { + + $pageNumber = (int)($recordIndex / $this->getLabelsPerPage()); + if ($pageNumber != $prevPageNumber) { + $pdf->AddPage(); + $prevPageNumber = $pageNumber; + } + + $pageIndex = $recordIndex - ($this->getLabelsPerPage() * $pageNumber); + $position = $this->getLabelPosition($pageIndex); + + $pdf->StartTemplate(); + $this->write($pdf, $data->get($recordIndex)); + $template = $pdf->EndTemplate(); + + $pdf->printTemplate($template, $position[0], $position[1]); + + if ($this->getLabelBorder()) { + $prevLineWidth = $pdf->GetLineWidth(); + + $borderThickness = $this->getLabelBorder(); + $borderOffset = $borderThickness / 2; + $borderX = $position[0]- $borderOffset; + $borderY = $position[1] - $borderOffset; + $borderW = $this->getLabelWidth() + $borderThickness; + $borderH = $this->getLabelHeight() + $borderThickness; + + $pdf->setLineWidth($borderThickness); + $pdf->Rect($borderX, $borderY, $borderW, $borderH); + $pdf->setLineWidth($prevLineWidth); + } + } + } + + /** + * Returns each label's orientation as a string. + * 'L' = Landscape + * 'P' = Portrait + * + * @return string + */ + public final function getLabelOrientation() { + return ($this->getLabelWidth() >= $this->getLabelHeight()) ? 'L' : 'P'; + } + + /** + * Returns each label's printable area as an object. + * + * @return object [ 'x1'=>0.00, 'y1'=>0.00, 'x2'=>0.00, 'y2'=>0.00, 'w'=>0.00, 'h'=>0.00 ] + */ + public final function getLabelPrintableArea() { + return (object)[ + 'x1' => $this->getLabelMarginLeft(), + 'y1' => $this->getLabelMarginTop(), + 'x2' => $this->getLabelWidth() - $this->getLabelMarginRight(), + 'y2' => $this->getLabelHeight() - $this->getLabelMarginBottom(), + 'w' => $this->getLabelWidth() - $this->getLabelMarginLeft() - $this->getLabelMarginRight(), + 'h' => $this->getLabelHeight() - $this->getLabelMarginTop() - $this->getLabelMarginBottom(), + ]; + } + + /** + * Returns label index offset (skip positions) + * + * @return int + */ + public function getLabelIndexOffset() { return $this->indexOffset; } + + /** + * Sets label index offset (skip positions) + * + * @param int $offset + * + */ + public function setLabelIndexOffset(int $offset) { $this->indexOffset = $offset; } +} + +?> \ No newline at end of file diff --git a/app/Models/Labels/Sheets/Avery/L7162.php b/app/Models/Labels/Sheets/Avery/L7162.php new file mode 100644 index 000000000..e1097db9b --- /dev/null +++ b/app/Models/Labels/Sheets/Avery/L7162.php @@ -0,0 +1,71 @@ +getUnit(), 0); + $this->pageWidth = $paperSize->width; + $this->pageHeight = $paperSize->height; + + $this->pageMarginLeft = Helper::convertUnit(self::COLUMN1_X, 'pt', $this->getUnit()); + $this->pageMarginTop = Helper::convertUnit(self::ROW1_Y, 'pt', $this->getUnit()); + + $columnSpacingPt = self::COLUMN2_X - self::COLUMN1_X - self::LABEL_W; + $this->columnSpacing = Helper::convertUnit($columnSpacingPt, 'pt', $this->getUnit()); + $rowSpacingPt = self::ROW2_Y - self::ROW1_Y - self::LABEL_H; + $this->rowSpacing = Helper::convertUnit($rowSpacingPt, 'pt', $this->getUnit()); + + $this->labelWidth = Helper::convertUnit(self::LABEL_W, 'pt', $this->getUnit()); + $this->labelHeight = Helper::convertUnit(self::LABEL_H, 'pt', $this->getUnit()); + } + + public function getPageWidth() { return $this->pageWidth; } + public function getPageHeight() { return $this->pageHeight; } + + public function getPageMarginTop() { return $this->pageMarginTop; } + public function getPageMarginBottom() { return $this->pageMarginTop; } + public function getPageMarginLeft() { return $this->pageMarginLeft; } + public function getPageMarginRight() { return $this->pageMarginLeft; } + + public function getColumns() { return 2; } + public function getRows() { return 8; } + + public function getLabelColumnSpacing() { return $this->columnSpacing; } + public function getLabelRowSpacing() { return $this->rowSpacing; } + + public function getLabelWidth() { return $this->labelWidth; } + public function getLabelHeight() { return $this->labelHeight; } + + public function getLabelBorder() { return 0; } +} + +?> \ No newline at end of file diff --git a/app/Models/Labels/Sheets/Avery/L7162_A.php b/app/Models/Labels/Sheets/Avery/L7162_A.php new file mode 100644 index 000000000..0b3312ba7 --- /dev/null +++ b/app/Models/Labels/Sheets/Avery/L7162_A.php @@ -0,0 +1,100 @@ +getLabelPrintableArea(); + + $usableWidth = $pa->w; + $usableHeight = $pa->h; + $currentX = $pa->x1; + $currentY = $pa->y1; + $titleShiftX = 0; + + $barcodeSize = $pa->h - self::TAG_SIZE; + + if ($record->has('barcode2d')) { + static::writeText( + $pdf, $record->get('tag'), + $pa->x1, $pa->y2 - self::TAG_SIZE, + 'freemono', 'b', self::TAG_SIZE, 'C', + $barcodeSize, self::TAG_SIZE, true, 0 + ); + static::write2DBarcode( + $pdf, $record->get('barcode2d')->content, $record->get('barcode2d')->type, + $pa->x1, $pa->y1, + $barcodeSize, $barcodeSize + ); + $currentX += $barcodeSize + self::BARCODE_MARGIN; + $usableWidth -= $barcodeSize + self::BARCODE_MARGIN; + } else { + static::writeText( + $pdf, $record->get('tag'), + $pa->x1, $pa->y1, + 'freemono', 'b', self::TITLE_SIZE, 'L', + $barcodeSize, self::TITLE_SIZE, true, 0 + ); + $titleShiftX = $barcodeSize; + } + + if ($record->has('title')) { + static::writeText( + $pdf, $record->get('title'), + $currentX + $titleShiftX, $currentY, + 'freesans', '', self::TITLE_SIZE, 'L', + $usableWidth, self::TITLE_SIZE, true, 0 + ); + $currentY += self::TITLE_SIZE + self::TITLE_MARGIN; + } + + foreach ($record->get('fields') as $field) { + static::writeText( + $pdf, $field['label'], + $currentX, $currentY, + 'freesans', '', self::LABEL_SIZE, 'L', + $usableWidth, self::LABEL_SIZE, true, 0 + ); + $currentY += self::LABEL_SIZE + self::LABEL_MARGIN; + + static::writeText( + $pdf, $field['value'], + $currentX, $currentY, + 'freemono', 'B', self::FIELD_SIZE, 'L', + $usableWidth, self::FIELD_SIZE, true, 0, 0.3 + ); + $currentY += self::FIELD_SIZE + self::FIELD_MARGIN; + } + + } +} + + +?> \ No newline at end of file diff --git a/app/Models/Labels/Sheets/Avery/L7162_B.php b/app/Models/Labels/Sheets/Avery/L7162_B.php new file mode 100644 index 000000000..268754e04 --- /dev/null +++ b/app/Models/Labels/Sheets/Avery/L7162_B.php @@ -0,0 +1,103 @@ +getLabelPrintableArea(); + + $usableWidth = $pa->w; + $usableHeight = $pa->h; + $currentX = $pa->x1; + $currentY = $pa->y1; + + if ($record->has('barcode1d')) { + static::write1DBarcode( + $pdf, $record->get('barcode1d')->content, $record->get('barcode1d')->type, + $pa->x1, $pa->y2 - self::BARCODE_SIZE, + $usableWidth, self::BARCODE_SIZE + ); + $usableHeight -= self::BARCODE_SIZE + self::BARCODE_MARGIN; + } + + if ($record->has('logo')) { + $logoSize = static::writeImage( + $pdf, $record->get('logo'), + $pa->x1, $pa->y1, + self::LOGO_MAX_WIDTH, $usableHeight, + 'L', 'T', 300, true, false, 0.1 + ); + $currentX += $logoSize[0] + self::LOGO_MARGIN; + $usableWidth -= $logoSize[0] + self::LOGO_MARGIN; + } + + if ($record->has('title')) { + static::writeText( + $pdf, $record->get('title'), + $currentX, $currentY, + 'freesans', '', self::TITLE_SIZE, 'L', + $usableWidth, self::TITLE_SIZE, true, 0 + ); + $currentY += self::TITLE_SIZE + self::TITLE_MARGIN; + } + + foreach ($record->get('fields') as $field) { + static::writeText( + $pdf, $field['label'], + $currentX, $currentY, + 'freesans', '', self::LABEL_SIZE, 'L', + $usableWidth, self::LABEL_SIZE, true, 0 + ); + $currentY += self::LABEL_SIZE + self::LABEL_MARGIN; + + static::writeText( + $pdf, $field['value'], + $currentX, $currentY, + 'freemono', 'B', self::FIELD_SIZE, 'L', + $usableWidth, self::FIELD_SIZE, true, 0, 0.3 + ); + $currentY += self::FIELD_SIZE + self::FIELD_MARGIN; + } + + static::writeText( + $pdf, $record->get('tag'), + $currentX, $pa->y2 - self::BARCODE_SIZE - self::BARCODE_MARGIN - self::TAG_SIZE, + 'freemono', 'b', self::TAG_SIZE, 'R', + $usableWidth, self::TAG_SIZE, true, 0, 0.3 + ); + + } +} + + +?> \ No newline at end of file diff --git a/app/Models/Labels/Sheets/Avery/L7163.php b/app/Models/Labels/Sheets/Avery/L7163.php new file mode 100644 index 000000000..f14326033 --- /dev/null +++ b/app/Models/Labels/Sheets/Avery/L7163.php @@ -0,0 +1,71 @@ +getUnit(), 0); + $this->pageWidth = $paperSize->width; + $this->pageHeight = $paperSize->height; + + $this->pageMarginLeft = Helper::convertUnit(self::COLUMN1_X, 'pt', $this->getUnit()); + $this->pageMarginTop = Helper::convertUnit(self::ROW1_Y, 'pt', $this->getUnit()); + + $columnSpacingPt = self::COLUMN2_X - self::COLUMN1_X - self::LABEL_W; + $this->columnSpacing = Helper::convertUnit($columnSpacingPt, 'pt', $this->getUnit()); + $rowSpacingPt = self::ROW2_Y - self::ROW1_Y - self::LABEL_H; + $this->rowSpacing = Helper::convertUnit($rowSpacingPt, 'pt', $this->getUnit()); + + $this->labelWidth = Helper::convertUnit(self::LABEL_W, 'pt', $this->getUnit()); + $this->labelHeight = Helper::convertUnit(self::LABEL_H, 'pt', $this->getUnit()); + } + + public function getPageWidth() { return $this->pageWidth; } + public function getPageHeight() { return $this->pageHeight; } + + public function getPageMarginTop() { return $this->pageMarginTop; } + public function getPageMarginBottom() { return $this->pageMarginTop; } + public function getPageMarginLeft() { return $this->pageMarginLeft; } + public function getPageMarginRight() { return $this->pageMarginLeft; } + + public function getColumns() { return 2; } + public function getRows() { return 7; } + + public function getLabelColumnSpacing() { return $this->columnSpacing; } + public function getLabelRowSpacing() { return $this->rowSpacing; } + + public function getLabelWidth() { return $this->labelWidth; } + public function getLabelHeight() { return $this->labelHeight; } + + public function getLabelBorder() { return 0; } +} + +?> \ No newline at end of file diff --git a/app/Models/Labels/Sheets/Avery/L7163_A.php b/app/Models/Labels/Sheets/Avery/L7163_A.php new file mode 100644 index 000000000..6dc33f64d --- /dev/null +++ b/app/Models/Labels/Sheets/Avery/L7163_A.php @@ -0,0 +1,98 @@ +getLabelPrintableArea(); + + $usableWidth = $pa->w; + $usableHeight = $pa->h; + $currentX = $pa->x1; + $currentY = $pa->y1; + + if ($record->has('title')) { + static::writeText( + $pdf, $record->get('title'), + $currentX, $currentY, + 'freesans', '', self::TITLE_SIZE, 'C', + $usableWidth, self::TITLE_SIZE, true, 0 + ); + $currentY += self::TITLE_SIZE + self::TITLE_MARGIN; + } + + $barcodeSize = $pa->h - self::TITLE_SIZE - self::TITLE_MARGIN - self::TAG_SIZE; + + if ($record->has('barcode2d')) { + static::writeText( + $pdf, $record->get('tag'), + $pa->x1, $pa->y2 - self::TAG_SIZE, + 'freemono', 'b', self::TAG_SIZE, 'C', + $barcodeSize, self::TAG_SIZE, true, 0 + ); + static::write2DBarcode( + $pdf, $record->get('barcode2d')->content, $record->get('barcode2d')->type, + $pa->x1, $currentY, + $barcodeSize, $barcodeSize + ); + $currentX += $barcodeSize + self::BARCODE_MARGIN; + $usableWidth -= $barcodeSize + self::BARCODE_MARGIN; + } else { + static::writeText( + $pdf, $record->get('tag'), + $pa->x1, $pa->y2 - self::TAG_SIZE, + 'freemono', 'b', self::TAG_SIZE, 'R', + $usableWidth, self::TAG_SIZE, true, 0 + ); + } + + foreach ($record->get('fields') as $field) { + static::writeText( + $pdf, $field['label'], + $currentX, $currentY, + 'freesans', '', self::LABEL_SIZE, 'L', + $usableWidth, self::LABEL_SIZE, true, 0 + ); + $currentY += self::LABEL_SIZE + self::LABEL_MARGIN; + + static::writeText( + $pdf, $field['value'], + $currentX, $currentY, + 'freemono', 'B', self::FIELD_SIZE, 'L', + $usableWidth, self::FIELD_SIZE, true, 0, 0.5 + ); + $currentY += self::FIELD_SIZE + self::FIELD_MARGIN; + } + + } +} + + +?> \ No newline at end of file diff --git a/app/Models/Labels/Sheets/Avery/_5267.php b/app/Models/Labels/Sheets/Avery/_5267.php new file mode 100644 index 000000000..f5f2f1355 --- /dev/null +++ b/app/Models/Labels/Sheets/Avery/_5267.php @@ -0,0 +1,71 @@ +getUnit(), 2); + $this->pageWidth = $paperSize->width; + $this->pageHeight = $paperSize->height; + + $this->pageMarginLeft = Helper::convertUnit(self::COLUMN1_X, 'pt', $this->getUnit()); + $this->pageMarginTop = Helper::convertUnit(self::ROW1_Y, 'pt', $this->getUnit()); + + $columnSpacingPt = self::COLUMN2_X - self::COLUMN1_X - self::LABEL_W; + $this->columnSpacing = Helper::convertUnit($columnSpacingPt, 'pt', $this->getUnit()); + $rowSpacingPt = self::ROW2_Y - self::ROW1_Y - self::LABEL_H; + $this->rowSpacing = Helper::convertUnit($rowSpacingPt, 'pt', $this->getUnit()); + + $this->labelWidth = Helper::convertUnit(self::LABEL_W, 'pt', $this->getUnit()); + $this->labelHeight = Helper::convertUnit(self::LABEL_H, 'pt', $this->getUnit()); + } + + public function getPageWidth() { return $this->pageWidth; } + public function getPageHeight() { return $this->pageHeight; } + + public function getPageMarginTop() { return $this->pageMarginTop; } + public function getPageMarginBottom() { return $this->pageMarginTop; } + public function getPageMarginLeft() { return $this->pageMarginLeft; } + public function getPageMarginRight() { return $this->pageMarginLeft; } + + public function getColumns() { return 4; } + public function getRows() { return 20; } + + public function getLabelColumnSpacing() { return $this->columnSpacing; } + public function getLabelRowSpacing() { return $this->rowSpacing; } + + public function getLabelWidth() { return $this->labelWidth; } + public function getLabelHeight() { return $this->labelHeight; } + + public function getLabelBorder() { return 0; } +} + +?> \ No newline at end of file diff --git a/app/Models/Labels/Sheets/Avery/_5267_A.php b/app/Models/Labels/Sheets/Avery/_5267_A.php new file mode 100644 index 000000000..efe0855d5 --- /dev/null +++ b/app/Models/Labels/Sheets/Avery/_5267_A.php @@ -0,0 +1,68 @@ +getLabelPrintableArea(); + + if ($record->has('barcode1d')) { + static::write1DBarcode( + $pdf, $record->get('barcode1d')->content, $record->get('barcode1d')->type, + $pa->x1, $pa->y2 - self::BARCODE_SIZE, + $pa->w, self::BARCODE_SIZE + ); + } + + if ($record->has('title')) { + static::writeText( + $pdf, $record->get('title'), + $pa->x1, $pa->y1, + 'freesans', '', self::TITLE_SIZE, 'L', + $pa->w, self::TITLE_SIZE, true, 0 + ); + } + + $fieldY = $pa->y2 - self::BARCODE_SIZE - self::BARCODE_MARGIN - self::FIELD_SIZE; + if ($record->has('fields')) { + if ($record->get('fields')->count() >= 1) { + $field = $record->get('fields')->first(); + static::writeText( + $pdf, $field['value'], + $pa->x1, $fieldY, + 'freemono', 'B', self::FIELD_SIZE, 'C', + $pa->w, self::FIELD_SIZE, true, 0, 0.01 + ); + } + } + + } +} + + +?> \ No newline at end of file diff --git a/app/Models/Labels/Sheets/Avery/_5520.php b/app/Models/Labels/Sheets/Avery/_5520.php new file mode 100644 index 000000000..00cb0e068 --- /dev/null +++ b/app/Models/Labels/Sheets/Avery/_5520.php @@ -0,0 +1,71 @@ +getUnit(), 2); + $this->pageWidth = $paperSize->width; + $this->pageHeight = $paperSize->height; + + $this->pageMarginLeft = Helper::convertUnit(self::COLUMN1_X, 'pt', $this->getUnit()); + $this->pageMarginTop = Helper::convertUnit(self::ROW1_Y, 'pt', $this->getUnit()); + + $columnSpacingPt = self::COLUMN2_X - self::COLUMN1_X - self::LABEL_W; + $this->columnSpacing = Helper::convertUnit($columnSpacingPt, 'pt', $this->getUnit()); + $rowSpacingPt = self::ROW2_Y - self::ROW1_Y - self::LABEL_H; + $this->rowSpacing = Helper::convertUnit($rowSpacingPt, 'pt', $this->getUnit()); + + $this->labelWidth = Helper::convertUnit(self::LABEL_W, 'pt', $this->getUnit()); + $this->labelHeight = Helper::convertUnit(self::LABEL_H, 'pt', $this->getUnit()); + } + + public function getPageWidth() { return $this->pageWidth; } + public function getPageHeight() { return $this->pageHeight; } + + public function getPageMarginTop() { return $this->pageMarginTop; } + public function getPageMarginBottom() { return $this->pageMarginTop; } + public function getPageMarginLeft() { return $this->pageMarginLeft; } + public function getPageMarginRight() { return $this->pageMarginLeft; } + + public function getColumns() { return 3; } + public function getRows() { return 10; } + + public function getLabelColumnSpacing() { return $this->columnSpacing; } + public function getLabelRowSpacing() { return $this->rowSpacing; } + + public function getLabelWidth() { return $this->labelWidth; } + public function getLabelHeight() { return $this->labelHeight; } + + public function getLabelBorder() { return 0; } +} + +?> \ No newline at end of file diff --git a/app/Models/Labels/Sheets/Avery/_5520_A.php b/app/Models/Labels/Sheets/Avery/_5520_A.php new file mode 100644 index 000000000..199566d24 --- /dev/null +++ b/app/Models/Labels/Sheets/Avery/_5520_A.php @@ -0,0 +1,85 @@ +getLabelPrintableArea(); + + $currentX = $pa->x1; + $currentY = $pa->y1; + $usableWidth = $pa->w; + $usableHeight = $pa->h; + + if ($record->has('title')) { + static::writeText( + $pdf, $record->get('title'), + $pa->x1, $pa->y1, + 'freesans', '', self::TITLE_SIZE, 'C', + $pa->w, self::TITLE_SIZE, true, 0 + ); + $currentY += self::TITLE_SIZE + self::TITLE_MARGIN; + $usableHeight -= self::TITLE_SIZE + self::TITLE_MARGIN; + } + + $barcodeSize = $usableHeight; + if ($record->has('barcode2d')) { + static::write2DBarcode( + $pdf, $record->get('barcode2d')->content, $record->get('barcode2d')->type, + $currentX, $currentY, + $barcodeSize, $barcodeSize + ); + $currentX += $barcodeSize + self::BARCODE_MARGIN; + $usableWidth -= $barcodeSize + self::BARCODE_MARGIN; + } + + foreach ($record->get('fields') as $field) { + static::writeText( + $pdf, $field['label'], + $currentX, $currentY, + 'freesans', '', self::LABEL_SIZE, 'L', + $usableWidth, self::LABEL_SIZE, true, 0 + ); + $currentY += self::LABEL_SIZE + self::LABEL_MARGIN; + + static::writeText( + $pdf, $field['value'], + $currentX, $currentY, + 'freemono', 'B', self::FIELD_SIZE, 'L', + $usableWidth, self::FIELD_SIZE, true, 0, 0.01 + ); + $currentY += self::FIELD_SIZE + self::FIELD_MARGIN; + } + + } +} + + +?> \ No newline at end of file diff --git a/app/Models/Labels/Tapes/Brother/TZe_12mm.php b/app/Models/Labels/Tapes/Brother/TZe_12mm.php new file mode 100644 index 000000000..f9196847c --- /dev/null +++ b/app/Models/Labels/Tapes/Brother/TZe_12mm.php @@ -0,0 +1,19 @@ +getUnit()); } + public function getMarginTop() { return Helper::convertUnit(self::MARGIN_SIDES, 'mm', $this->getUnit()); } + public function getMarginBottom() { return Helper::convertUnit(self::MARGIN_SIDES, 'mm', $this->getUnit());} + public function getMarginLeft() { return Helper::convertUnit(self::MARGIN_ENDS, 'mm', $this->getUnit()); } + public function getMarginRight() { return Helper::convertUnit(self::MARGIN_ENDS, 'mm', $this->getUnit()); } +} \ No newline at end of file diff --git a/app/Models/Labels/Tapes/Brother/TZe_12mm_A.php b/app/Models/Labels/Tapes/Brother/TZe_12mm_A.php new file mode 100644 index 000000000..f89cfc5d4 --- /dev/null +++ b/app/Models/Labels/Tapes/Brother/TZe_12mm_A.php @@ -0,0 +1,56 @@ +getPrintableArea(); + + if ($record->has('barcode1d')) { + static::write1DBarcode( + $pdf, $record->get('barcode1d')->content, $record->get('barcode1d')->type, + $pa->x1, $pa->y1, $pa->w, self::BARCODE_SIZE + ); + } + + $currentY = $pa->y1 + self::BARCODE_SIZE + self::BARCODE_MARGIN; + $usableHeight = $pa->h - self::BARCODE_SIZE - self::BARCODE_MARGIN; + $fontSize = $usableHeight + self::TEXT_SIZE_MOD; + + $tagWidth = $pa->w / 3; + $fieldWidth = $pa->w / 3 * 2; + + static::writeText( + $pdf, $record->get('tag'), + $pa->x1, $currentY, + 'freemono', 'b', $fontSize, 'L', + $tagWidth, $usableHeight, true, 0, 0 + ); + + if ($record->get('fields')->count() >= 1) { + static::writeText( + $pdf, $record->get('fields')->values()->get(0)['value'], + $pa->x1 + ($tagWidth), $currentY, + 'freemono', 'b', $fontSize, 'R', + $fieldWidth, $usableHeight, true, 0, 0 + ); + } + + } +} \ No newline at end of file diff --git a/app/Models/Labels/Tapes/Brother/TZe_24mm.php b/app/Models/Labels/Tapes/Brother/TZe_24mm.php new file mode 100644 index 000000000..3c67bc161 --- /dev/null +++ b/app/Models/Labels/Tapes/Brother/TZe_24mm.php @@ -0,0 +1,19 @@ +getUnit()); } + public function getMarginTop() { return Helper::convertUnit(self::MARGIN_SIDES, 'mm', $this->getUnit()); } + public function getMarginBottom() { return Helper::convertUnit(self::MARGIN_SIDES, 'mm', $this->getUnit());} + public function getMarginLeft() { return Helper::convertUnit(self::MARGIN_ENDS, 'mm', $this->getUnit()); } + public function getMarginRight() { return Helper::convertUnit(self::MARGIN_ENDS, 'mm', $this->getUnit()); } +} \ No newline at end of file diff --git a/app/Models/Labels/Tapes/Brother/TZe_24mm_A.php b/app/Models/Labels/Tapes/Brother/TZe_24mm_A.php new file mode 100644 index 000000000..ea4c6c9df --- /dev/null +++ b/app/Models/Labels/Tapes/Brother/TZe_24mm_A.php @@ -0,0 +1,87 @@ +getPrintableArea(); + + $currentX = $pa->x1; + $currentY = $pa->y1; + $usableWidth = $pa->w; + + $barcodeSize = $pa->h - self::TAG_SIZE; + + if ($record->has('barcode2d')) { + static::writeText( + $pdf, $record->get('tag'), + $pa->x1, $pa->y2 - self::TAG_SIZE, + 'freemono', 'b', self::TAG_SIZE, 'C', + $barcodeSize, self::TAG_SIZE, true, 0 + ); + static::write2DBarcode( + $pdf, $record->get('barcode2d')->content, $record->get('barcode2d')->type, + $currentX, $currentY, + $barcodeSize, $barcodeSize + ); + $currentX += $barcodeSize + self::BARCODE_MARGIN; + $usableWidth -= $barcodeSize + self::BARCODE_MARGIN; + } else { + static::writeText( + $pdf, $record->get('tag'), + $pa->x1, $pa->y2 - self::TAG_SIZE, + 'freemono', 'b', self::TAG_SIZE, 'R', + $usableWidth, self::TAG_SIZE, true, 0 + ); + } + + if ($record->has('title')) { + static::writeText( + $pdf, $record->get('title'), + $currentX, $currentY, + 'freesans', '', self::TITLE_SIZE, 'L', + $usableWidth, self::TITLE_SIZE, true, 0 + ); + $currentY += self::TITLE_SIZE + self::TITLE_MARGIN; + } + + foreach ($record->get('fields') as $field) { + static::writeText( + $pdf, $field['label'], + $currentX, $currentY, + 'freesans', '', self::LABEL_SIZE, 'L', + $usableWidth, self::LABEL_SIZE, true, 0, 0 + ); + $currentY += self::LABEL_SIZE + self::LABEL_MARGIN; + + static::writeText( + $pdf, $field['value'], + $currentX, $currentY, + 'freemono', 'B', self::FIELD_SIZE, 'L', + $usableWidth, self::FIELD_SIZE, true, 0, 0.3 + ); + $currentY += self::FIELD_SIZE + self::FIELD_MARGIN; + } + } +} \ No newline at end of file diff --git a/app/Presenters/LabelPresenter.php b/app/Presenters/LabelPresenter.php new file mode 100644 index 000000000..5ff95d2c4 --- /dev/null +++ b/app/Presenters/LabelPresenter.php @@ -0,0 +1,96 @@ + 'radio', + 'radio' => true, + 'formatter' => 'labelRadioFormatter' + ], [ + 'field' => 'name', + 'searchable' => true, + 'sortable' => true, + 'switchable' => true, + 'title' => trans('general.name'), + 'visible' => true, + ], [ + 'field' => 'size', + 'searchable' => false, + 'sortable' => false, + 'switchable' => true, + 'title' => trans('admin/settings/table.size'), + 'visible' => true, + 'formatter' => 'labelSizeFormatter' + ], [ + 'field' => 'labels_per_page', + 'searchable' => false, + 'sortable' => false, + 'switchable' => true, + 'title' => trans('admin/labels/table.labels_per_page'), + 'visible' => true, + 'formatter' => 'labelPerPageFormatter' + ], [ + 'field' => 'support_fields', + 'searchable' => false, + 'sortable' => true, + 'switchable' => true, + 'title' => trans('admin/labels/table.support_fields'), + 'visible' => true + ], [ + 'field' => 'support_asset_tag', + 'searchable' => false, + 'sortable' => true, + 'switchable' => true, + 'title' => trans('admin/labels/table.support_asset_tag'), + 'visible' => true, + 'formatter' => 'trueFalseFormatter' + ], [ + 'field' => 'support_1d_barcode', + 'searchable' => false, + 'sortable' => true, + 'switchable' => true, + 'title' => trans('admin/labels/table.support_1d_barcode'), + 'visible' => true, + 'formatter' => 'trueFalseFormatter' + ], [ + 'field' => 'support_2d_barcode', + 'searchable' => false, + 'sortable' => true, + 'switchable' => true, + 'title' => trans('admin/labels/table.support_2d_barcode'), + 'visible' => true, + 'formatter' => 'trueFalseFormatter' + ], [ + 'field' => 'support_logo', + 'searchable' => false, + 'sortable' => true, + 'switchable' => true, + 'title' => trans('admin/labels/table.support_logo'), + 'visible' => true, + 'formatter' => 'trueFalseFormatter' + ], [ + 'field' => 'support_title', + 'searchable' => false, + 'sortable' => true, + 'switchable' => true, + 'title' => trans('admin/labels/table.support_title'), + 'visible' => true, + 'formatter' => 'trueFalseFormatter' + ] + ]; + + return json_encode($layout); + } +} diff --git a/app/View/Label.php b/app/View/Label.php new file mode 100644 index 000000000..de955afff --- /dev/null +++ b/app/View/Label.php @@ -0,0 +1,211 @@ +data = new Collection(); + } + + /** + * Render the PDF label. + * + * @param callable|null $callback + */ + public function render(callable $callback = null) + { + $settings = $this->data->get('settings'); + $assets = $this->data->get('assets'); + $offset = $this->data->get('offset'); + $template = $this->data->get('template'); + + // If disabled, pass to legacy view + if ((!$settings->label2_enable) && (!$template)) { + return view('hardware/labels') + ->with('assets', $assets) + ->with('settings', $settings) + ->with('bulkedit', $this->data->get('bulkedit')) + ->with('count', $this->data->get('count')); + } + + if (empty($template)) $template = LabelModel::find($settings->label2_template); + elseif (is_string($template)) $template = LabelModel::find($template); + + $template->validate(); + + $pdf = new TCPDF( + $template->getOrientation(), + $template->getUnit(), + [ $template->getWidth(), $template->getHeight() ] + ); + + // Reset parameters + $pdf->SetPrintHeader(false); + $pdf->SetPrintFooter(false); + $pdf->SetAutoPageBreak(false); + $pdf->SetMargins(0, 0, null, true); + $pdf->SetCellMargins(0, 0, 0, 0); + $pdf->SetCellPaddings(0, 0, 0, 0); + $pdf->setCreator('Snipe-IT'); + $pdf->SetSubject('Asset Labels'); + $template->preparePDF($pdf); + + // Get fields from settings + $fieldDefinitions = collect(explode(';', $settings->label2_fields)) + ->filter(fn($fieldString) => !empty($fieldString)) + ->map(fn($fieldString) => Field::fromString($fieldString)); + + // Prepare data + $data = $assets + ->map(function ($asset) use ($template, $settings, $fieldDefinitions) { + + $assetData = new Collection(); + + $assetData->put('asset', $asset); + $assetData->put('id', $asset->id); + $assetData->put('tag', $asset->asset_tag); + + if ($template->getSupportTitle()) { + $title = !empty($settings->label2_title) ? + str_ireplace(':company', $asset->company->name, $settings->label2_title) : + $settings->qr_text; + if (!empty($title)) $assetData->put('title', $title); + } + + if ($template->getSupportLogo()) { + $logo = $settings->label2_asset_logo ? + ( + !empty($asset->company->image) ? + Storage::disk('public')->path('companies/'.e($asset->company->image)) : + null + ) : + ( + !empty($settings->label_logo) ? + Storage::disk('public')->path(''.e($settings->label_logo)) : + null + ); + if (!empty($logo)) $assetData->put('logo', $logo); + } + + if ($template->getSupport1DBarcode()) { + $barcode1DType = $settings->label2_1d_type; + $barcode1DType = ($barcode1DType == 'default') ? + (($settings->alt_barcode_enabled) ? $settings->alt_barcode : null) : + $barcode1DType; + if ($barcode1DType != 'none') { + $assetData->put('barcode1d', (object)[ + 'type' => $barcode1DType, + 'content' => $asset->asset_tag, + ]); + } + } + + if ($template->getSupport2DBarcode()) { + $barcode2DType = $settings->label2_2d_type; + $barcode2DType = ($barcode2DType == 'default') ? + $settings->barcode_type : + $barcode2DType; + if (($barcode2DType != 'none') && (!is_null($barcode2DType))) { + switch ($settings->label2_2d_target) { + case 'ht_tag': $barcode2DTarget = route('ht/assetTag', $asset->asset_tag); break; + case 'hardware_id': + default: $barcode2DTarget = route('hardware.show', $asset->id); break; + } + $assetData->put('barcode2d', (object)[ + 'type' => $barcode2DType, + 'content' => $barcode2DTarget, + ]); + } + } + + $fields = $fieldDefinitions + ->map(fn($field) => $field->toArray($asset)) + ->filter(fn($field) => $field != null) + ->reduce(function($myFields, $field) { + // Remove Duplicates + $toAdd = $field + ->filter(fn($o) => !$myFields->contains('dataSource', $o['dataSource'])) + ->first(); + + return $toAdd ? $myFields->push($toAdd) : $myFields; + }, new Collection()); + + $assetData->put('fields', $fields->take($template->getSupportFields())); + + return $assetData; + }); + + if ($template instanceof Sheet) { + $template->setLabelIndexOffset($offset ?? 0); + } + $template->writeAll($pdf, $data); + + $filename = $assets->count() > 1 ? 'assets.pdf' : $assets->first()->asset_tag.'.pdf'; + $pdf->Output($filename, 'I'); + } + + /** + * Add a piece of data. + * + * @param string|array $key + * @param mixed $value + * @return $this + */ + public function with($key, $value = null) + { + $this->data->put($key, $value); + return $this; + } + + /** + * Get the array of view data. + * + * @return array + */ + public function getData() + { + return $this->data; + } + + /** + * Get the name of the view. + * + * @return string + */ + public function name() + { + return $this->getName(); + } + + /** + * Get the name of the view. + * + * @return string + */ + public function getName() + { + return self::NAME; + } + +} \ No newline at end of file diff --git a/composer.json b/composer.json index 2b127f907..bb9acd9b1 100644 --- a/composer.json +++ b/composer.json @@ -70,6 +70,7 @@ "spatie/laravel-backup": "^6.16", "symfony/polyfill-mbstring": "^1.22", "tecnickcom/tc-lib-barcode": "^1.15", + "tecnickcom/tcpdf": "^6.5.0", "unicodeveloper/laravel-password": "^1.0", "watson/validating": "^6.1" }, diff --git a/database/migrations/2022_10_25_215520_add_label2_settings.php b/database/migrations/2022_10_25_215520_add_label2_settings.php new file mode 100644 index 000000000..692e8440d --- /dev/null +++ b/database/migrations/2022_10_25_215520_add_label2_settings.php @@ -0,0 +1,50 @@ +boolean('label2_enable')->default(false); + $table->string('label2_template')->nullable()->default('DefaultLabel'); + $table->string('label2_title')->nullable()->default(null); + $table->boolean('label2_asset_logo')->default(false); + $table->string('label2_1d_type')->default('default'); + $table->string('label2_2d_type')->default('default'); + $table->string('label2_2d_target')->default('hardware_id'); + $table->string('label2_fields')->default( + trans('admin/hardware/form.name').'=name;'. + trans('admin/hardware/form.serial').'=serial;'. + trans('admin/hardware/form.model').'=model.name;' + ); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('settings', function (Blueprint $table) { + if (Schema::hasColumn('settings', 'label2_enable')) $table->dropColumn('label2_enable'); + if (Schema::hasColumn('settings', 'label2_template')) $table->dropColumn('label2_template'); + if (Schema::hasColumn('settings', 'label2_title')) $table->dropColumn('label2_title'); + if (Schema::hasColumn('settings', 'label2_asset_logo')) $table->dropColumn('label2_asset_logo'); + if (Schema::hasColumn('settings', 'label2_1d_type')) $table->dropColumn('label2_1d_type'); + if (Schema::hasColumn('settings', 'label2_2d_type')) $table->dropColumn('label2_2d_type'); + if (Schema::hasColumn('settings', 'label2_2d_target')) $table->dropColumn('label2_2d_target'); + if (Schema::hasColumn('settings', 'label2_fields')) $table->dropColumn('label2_fields'); + }); + } +} diff --git a/package-lock.json b/package-lock.json index 649581f94..45a1132bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1883,6 +1883,19 @@ } } }, + "@vue/reactivity": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.5.tgz", + "integrity": "sha512-1tdfLmNjWG6t/CsPldh+foumYFo3cpyCHgBYQ34ylaMsJ+SNHQ1kApMIa8jN+i593zQuaw3AdWH0nJTARzCFhg==", + "requires": { + "@vue/shared": "3.1.5" + } + }, + "@vue/shared": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.5.tgz", + "integrity": "sha512-oJ4F3TnvpXaQwZJNF3ZK+kLPHKarDmJjJ6jyzVNDKH9md1dptjC7lWR//jrGuLdek/U6iltWxqAnYOu8gCiOvA==" + }, "@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", @@ -2187,6 +2200,14 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" }, + "alpinejs": { + "version": "3.12.3", + "resolved": "https://registry.npmjs.org/alpinejs/-/alpinejs-3.12.3.tgz", + "integrity": "sha512-fLz2dfYQ3xCk7Ip8LiIpV2W+9brUyex2TAE7Z0BCvZdUDklJE+n+a8gCgLWzfZ0GzZNZu7HUP8Z0z6Xbm6fsSA==", + "requires": { + "@vue/reactivity": "~3.1.1" + } + }, "ansi-html-community": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", diff --git a/package.json b/package.json index 67b598854..7a497786e 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "acorn-import-assertions": "^1.9.0", "admin-lte": "^2.4.18", "ajv": "^6.12.6", + "alpinejs": "^3.10.5", "blueimp-file-upload": "^9.34.0", "bootstrap": "^3.4.1", "bootstrap-colorpicker": "^2.5.3", diff --git a/public/js/dist/all-defer.js b/public/js/dist/all-defer.js new file mode 100644 index 000000000..0302f4127 --- /dev/null +++ b/public/js/dist/all-defer.js @@ -0,0 +1 @@ +(()=>{var e,t,n,r,i=!1,o=!1,a=[],s=-1;function l(e){!function(e){a.includes(e)||a.push(e);o||i||(i=!0,queueMicrotask(u))}(e)}function c(e){let t=a.indexOf(e);-1!==t&&t>s&&a.splice(t,1)}function u(){i=!1,o=!0;for(let e=0;e{(void 0===t||t.includes(n))&&(r.forEach((e=>e())),delete e._x_attributeCleanups[n])}))}var m=new MutationObserver(S),v=!1;function y(){m.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),v=!0}function b(){(w=w.concat(m.takeRecords())).length&&!E&&(E=!0,queueMicrotask((()=>{S(w),w.length=0,E=!1}))),m.disconnect(),v=!1}var w=[],E=!1;function A(e){if(!v)return e();b();let t=e();return y(),t}var O=!1,k=[];function S(e){if(O)return void(k=k.concat(e));let t=[],n=[],r=new Map,i=new Map;for(let o=0;o1===e.nodeType&&t.push(e))),e[o].removedNodes.forEach((e=>1===e.nodeType&&n.push(e)))),"attributes"===e[o].type)){let t=e[o].target,n=e[o].attributeName,a=e[o].oldValue,s=()=>{r.has(t)||r.set(t,[]),r.get(t).push({name:n,value:t.getAttribute(n)})},l=()=>{i.has(t)||i.set(t,[]),i.get(t).push(n)};t.hasAttribute(n)&&null===a?s():t.hasAttribute(n)?(l(),s()):l()}i.forEach(((e,t)=>{g(t,e)})),r.forEach(((e,t)=>{_.forEach((n=>n(t,e)))}));for(let e of n)if(!t.includes(e)&&(p.forEach((t=>t(e))),e._x_cleanups))for(;e._x_cleanups.length;)e._x_cleanups.pop()();t.forEach((e=>{e._x_ignoreSelf=!0,e._x_ignore=!0}));for(let e of t)n.includes(e)||e.isConnected&&(delete e._x_ignoreSelf,delete e._x_ignore,h.forEach((t=>t(e))),e._x_ignore=!0,e._x_ignoreSelf=!0);t.forEach((e=>{delete e._x_ignoreSelf,delete e._x_ignore})),t=null,n=null,r=null,i=null}function C(e){return N(j(e))}function $(e,t,n){return e._x_dataStack=[t,...j(n||e)],()=>{e._x_dataStack=e._x_dataStack.filter((e=>e!==t))}}function j(e){return e._x_dataStack?e._x_dataStack:"function"==typeof ShadowRoot&&e instanceof ShadowRoot?j(e.host):e.parentNode?j(e.parentNode):[]}function N(e){let t=new Proxy({},{ownKeys:()=>Array.from(new Set(e.flatMap((e=>Object.keys(e))))),has:(t,n)=>e.some((e=>e.hasOwnProperty(n))),get:(n,r)=>(e.find((e=>{if(e.hasOwnProperty(r)){let n=Object.getOwnPropertyDescriptor(e,r);if(n.get&&n.get._x_alreadyBound||n.set&&n.set._x_alreadyBound)return!0;if((n.get||n.set)&&n.enumerable){let i=n.get,o=n.set,a=n;i=i&&i.bind(t),o=o&&o.bind(t),i&&(i._x_alreadyBound=!0),o&&(o._x_alreadyBound=!0),Object.defineProperty(e,r,{...a,get:i,set:o})}return!0}return!1}))||{})[r],set:(t,n,r)=>{let i=e.find((e=>e.hasOwnProperty(n)));return i?i[n]=r:e[e.length-1][n]=r,!0}});return t}function M(e){let t=(n,r="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach((([i,{value:o,enumerable:a}])=>{if(!1===a||void 0===o)return;let s=""===r?i:`${r}.${i}`;var l;"object"==typeof o&&null!==o&&o._x_interceptor?n[i]=o.initialize(e,s,i):"object"!=typeof(l=o)||Array.isArray(l)||null===l||o===n||o instanceof Element||t(o,s)}))};return t(e)}function L(e,t=(()=>{})){let n={initialValue:void 0,_x_interceptor:!0,initialize(t,n,r){return e(this.initialValue,(()=>function(e,t){return t.split(".").reduce(((e,t)=>e[t]),e)}(t,n)),(e=>P(t,n,e)),n,r)}};return t(n),e=>{if("object"==typeof e&&null!==e&&e._x_interceptor){let t=n.initialize.bind(n);n.initialize=(r,i,o)=>{let a=e.initialize(r,i,o);return n.initialValue=a,t(r,i,o)}}else n.initialValue=e;return n}}function P(e,t,n){if("string"==typeof t&&(t=t.split(".")),1!==t.length){if(0===t.length)throw error;return e[t[0]]||(e[t[0]]={}),P(e[t[0]],t.slice(1),n)}e[t[0]]=n}var T={};function R(e,t){T[e]=t}function B(e,t){return Object.entries(T).forEach((([n,r])=>{let i=null;Object.defineProperty(e,`$${n}`,{get:()=>r(t,function(){if(i)return i;{let[e,n]=re(t);return i={interceptor:L,...e},x(t,n),i}}()),enumerable:!1})})),e}function z(e,t,n,...r){try{return n(...r)}catch(n){I(n,e,t)}}function I(e,t,n){Object.assign(e,{el:t,expression:n}),console.warn(`Alpine Expression Error: ${e.message}\n\n${n?'Expression: "'+n+'"\n\n':""}`,t),setTimeout((()=>{throw e}),0)}var D=!0;function q(e){let t=D;D=!1;let n=e();return D=t,n}function F(e,t,n={}){let r;return W(e,t)((e=>r=e),n),r}function W(...e){return U(...e)}var U=V;function V(e,t){let n={};B(n,e);let r=[n,...j(e)],i="function"==typeof t?function(e,t){return(n=(()=>{}),{scope:r={},params:i=[]}={})=>{H(n,t.apply(N([r,...e]),i))}}(r,t):function(e,t,n){let r=function(e,t){if(K[e])return K[e];let n=Object.getPrototypeOf((async function(){})).constructor,r=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(async()=>{ ${e} })()`:e;let i=(()=>{try{return new n(["__self","scope"],`with (scope) { __self.result = ${r} }; __self.finished = true; return __self.result;`)}catch(n){return I(n,t,e),Promise.resolve()}})();return K[e]=i,i}(t,n);return(i=(()=>{}),{scope:o={},params:a=[]}={})=>{r.result=void 0,r.finished=!1;let s=N([o,...e]);if("function"==typeof r){let e=r(r,s).catch((e=>I(e,n,t)));r.finished?(H(i,r.result,s,a,n),r.result=void 0):e.then((e=>{H(i,e,s,a,n)})).catch((e=>I(e,n,t))).finally((()=>r.result=void 0))}}}(r,t,e);return z.bind(null,e,t,i)}var K={};function H(e,t,n,r,i){if(D&&"function"==typeof t){let o=t.apply(n,r);o instanceof Promise?o.then((t=>H(e,t,n,r))).catch((e=>I(e,i,t))):e(o)}else"object"==typeof t&&t instanceof Promise?t.then((t=>e(t))):e(t)}var J="x-";function Z(e=""){return J+e}var X={};function Y(e,t){return X[e]=t,{before(t){if(!X[t])return void console.warn("Cannot find directive `${directive}`. `${name}` will use the default order of execution");const n=fe.indexOf(t);fe.splice(n>=0?n:fe.indexOf("DEFAULT"),0,e)}}}function G(e,t,n){if(t=Array.from(t),e._x_virtualDirectives){let n=Object.entries(e._x_virtualDirectives).map((([e,t])=>({name:e,value:t}))),r=Q(n);n=n.map((e=>r.find((t=>t.name===e.name))?{name:`x-bind:${e.name}`,value:`"${e.value}"`}:e)),t=t.concat(n)}let r={},i=t.map(oe(((e,t)=>r[e]=t))).filter(le).map(function(e,t){return({name:n,value:r})=>{let i=n.match(ce()),o=n.match(/:([a-zA-Z0-9\-:]+)/),a=n.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],s=t||e[n]||n;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:a.map((e=>e.replace(".",""))),expression:r,original:s}}}(r,n)).sort(de);return i.map((t=>function(e,t){let n=()=>{},r=X[t.type]||n,[i,o]=re(e);!function(e,t,n){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(n)}(e,t.original,o);let a=()=>{e._x_ignore||e._x_ignoreSelf||(r.inline&&r.inline(e,t,i),r=r.bind(r,e,t,i),ee?te.get(ne).push(r):r())};return a.runCleanups=o,a}(e,t)))}function Q(e){return Array.from(e).map(oe()).filter((e=>!le(e)))}var ee=!1,te=new Map,ne=Symbol();function re(e){let r=[],[i,o]=function(e){let r=()=>{};return[i=>{let o=t(i);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach((e=>e()))}),e._x_effects.add(o),r=()=>{void 0!==o&&(e._x_effects.delete(o),n(o))},o},()=>{r()}]}(e);r.push(o);return[{Alpine:et,effect:i,cleanup:e=>r.push(e),evaluateLater:W.bind(W,e),evaluate:F.bind(F,e)},()=>r.forEach((e=>e()))]}var ie=(e,t)=>({name:n,value:r})=>(n.startsWith(e)&&(n=n.replace(e,t)),{name:n,value:r});function oe(e=(()=>{})){return({name:t,value:n})=>{let{name:r,value:i}=ae.reduce(((e,t)=>t(e)),{name:t,value:n});return r!==t&&e(r,t),{name:r,value:i}}}var ae=[];function se(e){ae.push(e)}function le({name:e}){return ce().test(e)}var ce=()=>new RegExp(`^${J}([^:^.]+)\\b`);var ue="DEFAULT",fe=["ignore","ref","data","id","bind","init","for","model","modelable","transition","show","if",ue,"teleport"];function de(e,t){let n=-1===fe.indexOf(e.type)?ue:e.type,r=-1===fe.indexOf(t.type)?ue:t.type;return fe.indexOf(n)-fe.indexOf(r)}function _e(e,t,n={}){e.dispatchEvent(new CustomEvent(t,{detail:n,bubbles:!0,composed:!0,cancelable:!0}))}function pe(e,t){if("function"==typeof ShadowRoot&&e instanceof ShadowRoot)return void Array.from(e.children).forEach((e=>pe(e,t)));let n=!1;if(t(e,(()=>n=!0)),n)return;let r=e.firstElementChild;for(;r;)pe(r,t),r=r.nextElementSibling}function he(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var xe=!1;var ge=[],me=[];function ve(){return ge.map((e=>e()))}function ye(){return ge.concat(me).map((e=>e()))}function be(e){ge.push(e)}function we(e){me.push(e)}function Ee(e,t=!1){return Ae(e,(e=>{if((t?ye():ve()).some((t=>e.matches(t))))return!0}))}function Ae(e,t){if(e){if(t(e))return e;if(e._x_teleportBack&&(e=e._x_teleportBack),e.parentElement)return Ae(e.parentElement,t)}}var Oe=[];function ke(e,t=pe,n=(()=>{})){!function(e){ee=!0;let t=Symbol();ne=t,te.set(t,[]);let n=()=>{for(;te.get(t).length;)te.get(t).shift()();te.delete(t)};e(n),ee=!1,n()}((()=>{t(e,((e,t)=>{n(e,t),Oe.forEach((n=>n(e,t))),G(e,e.attributes).forEach((e=>e())),e._x_ignore&&t()}))}))}function Se(e){pe(e,(e=>g(e)))}var Ce=[],$e=!1;function je(e=(()=>{})){return queueMicrotask((()=>{$e||setTimeout((()=>{Ne()}))})),new Promise((t=>{Ce.push((()=>{e(),t()}))}))}function Ne(){for($e=!1;Ce.length;)Ce.shift()()}function Me(e,t){return Array.isArray(t)?Le(e,t.join(" ")):"object"==typeof t&&null!==t?function(e,t){let n=e=>e.split(" ").filter(Boolean),r=Object.entries(t).flatMap((([e,t])=>!!t&&n(e))).filter(Boolean),i=Object.entries(t).flatMap((([e,t])=>!t&&n(e))).filter(Boolean),o=[],a=[];return i.forEach((t=>{e.classList.contains(t)&&(e.classList.remove(t),a.push(t))})),r.forEach((t=>{e.classList.contains(t)||(e.classList.add(t),o.push(t))})),()=>{a.forEach((t=>e.classList.add(t))),o.forEach((t=>e.classList.remove(t)))}}(e,t):"function"==typeof t?Me(e,t()):Le(e,t)}function Le(e,t){return t=!0===t?t="":t||"",n=t.split(" ").filter((t=>!e.classList.contains(t))).filter(Boolean),e.classList.add(...n),()=>{e.classList.remove(...n)};var n}function Pe(e,t){return"object"==typeof t&&null!==t?function(e,t){let n={};return Object.entries(t).forEach((([t,r])=>{n[t]=e.style[t],t.startsWith("--")||(t=t.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase()),e.style.setProperty(t,r)})),setTimeout((()=>{0===e.style.length&&e.removeAttribute("style")})),()=>{Pe(e,n)}}(e,t):function(e,t){let n=e.getAttribute("style",t);return e.setAttribute("style",t),()=>{e.setAttribute("style",n||"")}}(e,t)}function Te(e,t=(()=>{})){let n=!1;return function(){n?t.apply(this,arguments):(n=!0,e.apply(this,arguments))}}function Re(e,t,n={}){e._x_transition||(e._x_transition={enter:{during:n,start:n,end:n},leave:{during:n,start:n,end:n},in(n=(()=>{}),r=(()=>{})){ze(e,t,{during:this.enter.during,start:this.enter.start,end:this.enter.end},n,r)},out(n=(()=>{}),r=(()=>{})){ze(e,t,{during:this.leave.during,start:this.leave.start,end:this.leave.end},n,r)}})}function Be(e){let t=e.parentNode;if(t)return t._x_hidePromise?t:Be(t)}function ze(e,t,{during:n,start:r,end:i}={},o=(()=>{}),a=(()=>{})){if(e._x_transitioning&&e._x_transitioning.cancel(),0===Object.keys(n).length&&0===Object.keys(r).length&&0===Object.keys(i).length)return o(),void a();let s,l,c;!function(e,t){let n,r,i,o=Te((()=>{A((()=>{n=!0,r||t.before(),i||(t.end(),Ne()),t.after(),e.isConnected&&t.cleanup(),delete e._x_transitioning}))}));e._x_transitioning={beforeCancels:[],beforeCancel(e){this.beforeCancels.push(e)},cancel:Te((function(){for(;this.beforeCancels.length;)this.beforeCancels.shift()();o()})),finish:o},A((()=>{t.start(),t.during()})),$e=!0,requestAnimationFrame((()=>{if(n)return;let o=1e3*Number(getComputedStyle(e).transitionDuration.replace(/,.*/,"").replace("s","")),a=1e3*Number(getComputedStyle(e).transitionDelay.replace(/,.*/,"").replace("s",""));0===o&&(o=1e3*Number(getComputedStyle(e).animationDuration.replace("s",""))),A((()=>{t.before()})),r=!0,requestAnimationFrame((()=>{n||(A((()=>{t.end()})),Ne(),setTimeout(e._x_transitioning.finish,o+a),i=!0)}))}))}(e,{start(){s=t(e,r)},during(){l=t(e,n)},before:o,end(){s(),c=t(e,i)},after:a,cleanup(){l(),c()}})}function Ie(e,t,n){if(-1===e.indexOf(t))return n;const r=e[e.indexOf(t)+1];if(!r)return n;if("scale"===t&&isNaN(r))return n;if("duration"===t||"delay"===t){let e=r.match(/([0-9]+)ms/);if(e)return e[1]}return"origin"===t&&["top","right","left","center","bottom"].includes(e[e.indexOf(t)+2])?[r,e[e.indexOf(t)+2]].join(" "):r}Y("transition",((e,{value:t,modifiers:n,expression:r},{evaluate:i})=>{"function"==typeof r&&(r=i(r)),!1!==r&&(r&&"boolean"!=typeof r?function(e,t,n){Re(e,Me,""),{enter:t=>{e._x_transition.enter.during=t},"enter-start":t=>{e._x_transition.enter.start=t},"enter-end":t=>{e._x_transition.enter.end=t},leave:t=>{e._x_transition.leave.during=t},"leave-start":t=>{e._x_transition.leave.start=t},"leave-end":t=>{e._x_transition.leave.end=t}}[n](t)}(e,r,t):function(e,t,n){Re(e,Pe);let r=!t.includes("in")&&!t.includes("out")&&!n,i=r||t.includes("in")||["enter"].includes(n),o=r||t.includes("out")||["leave"].includes(n);t.includes("in")&&!r&&(t=t.filter(((e,n)=>nn>t.indexOf("out"))));let a=!t.includes("opacity")&&!t.includes("scale"),s=a||t.includes("opacity"),l=a||t.includes("scale"),c=s?0:1,u=l?Ie(t,"scale",95)/100:1,f=Ie(t,"delay",0)/1e3,d=Ie(t,"origin","center"),_="opacity, transform",p=Ie(t,"duration",150)/1e3,h=Ie(t,"duration",75)/1e3,x="cubic-bezier(0.4, 0.0, 0.2, 1)";i&&(e._x_transition.enter.during={transformOrigin:d,transitionDelay:`${f}s`,transitionProperty:_,transitionDuration:`${p}s`,transitionTimingFunction:x},e._x_transition.enter.start={opacity:c,transform:`scale(${u})`},e._x_transition.enter.end={opacity:1,transform:"scale(1)"});o&&(e._x_transition.leave.during={transformOrigin:d,transitionDelay:`${f}s`,transitionProperty:_,transitionDuration:`${h}s`,transitionTimingFunction:x},e._x_transition.leave.start={opacity:1,transform:"scale(1)"},e._x_transition.leave.end={opacity:c,transform:`scale(${u})`})}(e,n,t))})),window.Element.prototype._x_toggleAndCascadeWithTransitions=function(e,t,n,r){const i="visible"===document.visibilityState?requestAnimationFrame:setTimeout;let o=()=>i(n);t?e._x_transition&&(e._x_transition.enter||e._x_transition.leave)?e._x_transition.enter&&(Object.entries(e._x_transition.enter.during).length||Object.entries(e._x_transition.enter.start).length||Object.entries(e._x_transition.enter.end).length)?e._x_transition.in(n):o():e._x_transition?e._x_transition.in(n):o():(e._x_hidePromise=e._x_transition?new Promise(((t,n)=>{e._x_transition.out((()=>{}),(()=>t(r))),e._x_transitioning.beforeCancel((()=>n({isFromCancelledTransition:!0})))})):Promise.resolve(r),queueMicrotask((()=>{let t=Be(e);t?(t._x_hideChildren||(t._x_hideChildren=[]),t._x_hideChildren.push(e)):i((()=>{let t=e=>{let n=Promise.all([e._x_hidePromise,...(e._x_hideChildren||[]).map(t)]).then((([e])=>e()));return delete e._x_hidePromise,delete e._x_hideChildren,n};t(e).catch((e=>{if(!e.isFromCancelledTransition)throw e}))}))})))};var De=!1;function qe(e,t=(()=>{})){return(...n)=>De?t(...n):e(...n)}function Fe(t,n,r,i=[]){switch(t._x_bindings||(t._x_bindings=e({})),t._x_bindings[n]=r,n=i.includes("camel")?n.toLowerCase().replace(/-(\w)/g,((e,t)=>t.toUpperCase())):n){case"value":!function(e,t){if("radio"===e.type)void 0===e.attributes.value&&(e.value=t),window.fromModel&&(e.checked=Ue(e.value,t));else if("checkbox"===e.type)Number.isInteger(t)?e.value=t:Number.isInteger(t)||Array.isArray(t)||"boolean"==typeof t||[null,void 0].includes(t)?Array.isArray(t)?e.checked=t.some((t=>Ue(t,e.value))):e.checked=!!t:e.value=String(t);else if("SELECT"===e.tagName)!function(e,t){const n=[].concat(t).map((e=>e+""));Array.from(e.options).forEach((e=>{e.selected=n.includes(e.value)}))}(e,t);else{if(e.value===t)return;e.value=t}}(t,r);break;case"style":!function(e,t){e._x_undoAddedStyles&&e._x_undoAddedStyles();e._x_undoAddedStyles=Pe(e,t)}(t,r);break;case"class":!function(e,t){e._x_undoAddedClasses&&e._x_undoAddedClasses();e._x_undoAddedClasses=Me(e,t)}(t,r);break;case"selected":case"checked":!function(e,t,n){We(e,t,n),function(e,t,n){e[t]!==n&&(e[t]=n)}(e,t,n)}(t,n,r);break;default:We(t,n,r)}}function We(e,t,n){[null,void 0,!1].includes(n)&&function(e){return!["aria-pressed","aria-checked","aria-expanded","aria-selected"].includes(e)}(t)?e.removeAttribute(t):(Ve(t)&&(n=t),function(e,t,n){e.getAttribute(t)!=n&&e.setAttribute(t,n)}(e,t,n))}function Ue(e,t){return e==t}function Ve(e){return["disabled","checked","required","readonly","hidden","open","selected","autofocus","itemscope","multiple","novalidate","allowfullscreen","allowpaymentrequest","formnovalidate","autoplay","controls","loop","muted","playsinline","default","ismap","reversed","async","defer","nomodule"].includes(e)}function Ke(e,t,n){let r=e.getAttribute(t);return null===r?"function"==typeof n?n():n:""===r||(Ve(t)?!![t,"true"].includes(r):r)}function He(e,t){var n;return function(){var r=this,i=arguments,o=function(){n=null,e.apply(r,i)};clearTimeout(n),n=setTimeout(o,t)}}function Je(e,t){let n;return function(){let r=this,i=arguments;n||(e.apply(r,i),n=!0,setTimeout((()=>n=!1),t))}}var Ze={},Xe=!1;var Ye={};function Ge(e,t,n){let r=[];for(;r.length;)r.pop()();let i=Object.entries(t).map((([e,t])=>({name:e,value:t}))),o=Q(i);i=i.map((e=>o.find((t=>t.name===e.name))?{name:`x-bind:${e.name}`,value:`"${e.value}"`}:e)),G(e,i,n).map((e=>{r.push(e.runCleanups),e()}))}var Qe={};var et={get reactive(){return e},get release(){return n},get effect(){return t},get raw(){return r},version:"3.12.3",flushAndStopDeferringMutations:function(){O=!1,S(k),k=[]},dontAutoEvaluateFunctions:q,disableEffectScheduling:function(e){f=!1,e(),f=!0},startObservingMutations:y,stopObservingMutations:b,setReactivityEngine:function(i){e=i.reactive,n=i.release,t=e=>i.effect(e,{scheduler:e=>{f?l(e):e()}}),r=i.raw},closestDataStack:j,skipDuringClone:qe,onlyDuringClone:function(e){return(...t)=>De&&e(...t)},addRootSelector:be,addInitSelector:we,addScopeToNode:$,deferMutations:function(){O=!0},mapAttributes:se,evaluateLater:W,interceptInit:function(e){Oe.push(e)},setEvaluator:function(e){U=e},mergeProxies:N,extractProp:function(e,t,n,r=!0){if(e._x_bindings&&void 0!==e._x_bindings[t])return e._x_bindings[t];if(e._x_inlineBindings&&void 0!==e._x_inlineBindings[t]){let n=e._x_inlineBindings[t];return n.extract=r,q((()=>F(e,n.expression)))}return Ke(e,t,n)},findClosest:Ae,closestRoot:Ee,destroyTree:Se,interceptor:L,transition:ze,setStyles:Pe,mutateDom:A,directive:Y,throttle:Je,debounce:He,evaluate:F,initTree:ke,nextTick:je,prefixed:Z,prefix:function(e){J=e},plugin:function(e){(Array.isArray(e)?e:[e]).forEach((e=>e(et)))},magic:R,store:function(t,n){if(Xe||(Ze=e(Ze),Xe=!0),void 0===n)return Ze[t];Ze[t]=n,"object"==typeof n&&null!==n&&n.hasOwnProperty("init")&&"function"==typeof n.init&&Ze[t].init(),M(Ze[t])},start:function(){var e;xe&&he("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),xe=!0,document.body||he("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` + @@ -1022,6 +1023,5 @@ @livewireScripts - diff --git a/resources/views/partials/bootstrap-table.blade.php b/resources/views/partials/bootstrap-table.blade.php index 14ce6ba4c..c4cae63e8 100644 --- a/resources/views/partials/bootstrap-table.blade.php +++ b/resources/views/partials/bootstrap-table.blade.php @@ -699,6 +699,25 @@ } } + function labelPerPageFormatter(value, row, index, field) { + if (row) { + if (!row.hasOwnProperty('sheet_info')) { return 1; } + else { return row.sheet_info.labels_per_page; } + } + } + + function labelRadioFormatter(value, row, index, field) { + if (row) { + return row.name == '{{ str_replace("\\", "\\\\", $snipeSettings->label2_template) }}'; + } + } + + function labelSizeFormatter(value, row) { + if (row) { + return row.width + ' x ' + row.height + ' ' + row.unit; + } + } + function cleanFloat(number) { if(!number) { // in a JavaScript context, meaning, if it's null or zero or unset return 0.0; diff --git a/resources/views/partials/label2-field-definitions.blade.php b/resources/views/partials/label2-field-definitions.blade.php new file mode 100644 index 000000000..6522b951d --- /dev/null +++ b/resources/views/partials/label2-field-definitions.blade.php @@ -0,0 +1,334 @@ +@once + @push('css') + + @endpush +@endonce + +@push('js') + +@endpush +@php + $selector = '[x-data="'.$name.'"]'; +@endphp +@push('css') + +@endpush + +
+ +
+

Fields

+
+ +
+
+ + + + +
+ +

Options

+
+ + +
+
+ + + + +
+
+
\ No newline at end of file diff --git a/resources/views/partials/label2-preview.blade.php b/resources/views/partials/label2-preview.blade.php new file mode 100644 index 000000000..36617bcc3 --- /dev/null +++ b/resources/views/partials/label2-preview.blade.php @@ -0,0 +1,98 @@ +@once + @push('css') + + @endpush +@endonce + +@push('js') + +@endpush + +
+
+ + +
+ +
diff --git a/resources/views/settings/labels.blade.php b/resources/views/settings/labels.blade.php index e214ce0f4..ae9bfc3a6 100644 --- a/resources/views/settings/labels.blade.php +++ b/resources/views/settings/labels.blade.php @@ -20,8 +20,7 @@ } - - {{ Form::open(['method' => 'POST', 'files' => false, 'autocomplete' => 'off', 'class' => 'form-horizontal', 'role' => 'form' ]) }} + {{ Form::open(['id' => 'settingsForm', 'method' => 'POST', 'files' => false, 'autocomplete' => 'off', 'class' => 'form-horizontal', 'role' => 'form' ]) }} {{csrf_field()}} @@ -40,158 +39,366 @@
-
+ +
- {{ Form::label('labels_per_page', trans('admin/settings/general.labels_per_page')) }} + {{ Form::label('label2_enable', trans('admin/settings/general.label2_enable')) }}
- {{ Form::text('labels_per_page', old('labels_per_page', $setting->labels_per_page), ['class' => 'form-control','style' => 'width: 100px;', 'aria-label'=>'labels_per_page']) }} - {!! $errors->first('labels_per_page', '') !!} + {{ Form::checkbox('label2_enable', '1', old('label2_enable', $setting->label2_enable, [ 'class'=>'minimal', 'aria-label'=>'label2_enable' ])) }} + {{ trans('general.yes') }} + {!! $errors->first('label2_enable', '') !!} +

{!! trans('admin/settings/general.label2_enable_help') !!}

-
-
- {{ Form::label('labels_fontsize', trans('admin/settings/general.labels_fontsize')) }} -
-
-
- {{ Form::text('labels_fontsize', old('labels_fontsize', $setting->labels_fontsize), ['class' => 'form-control', 'aria-label'=>'labels_fontsize']) }} -
{{ trans('admin/settings/general.text_pt') }}
-
-
-
- {!! $errors->first('labels_fontsize', '') !!} -
-
+ @if ($setting->label2_enable) + -
-
- {{ Form::label('labels_width', trans('admin/settings/general.label_dimensions')) }} -
-
-
- {{ Form::text('labels_width', old('labels_width', $setting->labels_width), ['class' => 'form-control', 'aria-label'=>'labels_width']) }} -
{{ trans('admin/settings/general.width_w') }}
+ +
+
+ {{ Form::label('label2_template', trans('admin/settings/general.label2_template')) }} + @include('partials.label2-preview') +
+
+
+
-
-
- {{ Form::text('labels_height', old('labels_height', $setting->labels_height), ['class' => 'form-control', 'aria-label'=>'labels_height']) }} -
{{ trans('admin/settings/general.height_h') }}
-
-
-
- {!! $errors->first('labels_width', '') !!} - {!! $errors->first('labels_height', '') !!} -
-
-
-
- {{ Form::label('labels_display_sgutter', trans('admin/settings/general.label_gutters')) }} -
-
-
- {{ Form::text('labels_display_sgutter', old('labels_display_sgutter', $setting->labels_display_sgutter), ['class' => 'form-control', 'aria-label'=>'labels_display_sgutter']) }} -
{{ trans('admin/settings/general.horizontal') }}
+ +
+
+ {{ Form::label('label2_title', trans('admin/settings/general.label2_title')) }} +
+
+ {{ Form::text('label2_title', old('label2_title', $setting->label2_title), [ 'class'=>'form-control', 'placeholder'=>$setting->qr_text, 'aria-label'=>'label2_title' ]) }} + {!! $errors->first('label2_title', '') !!} +

{!! trans('admin/settings/general.label2_title_help') !!}

+

+ {!! trans('admin/settings/general.label2_title_help_phold') !!}.
+ {!! trans('admin/settings/general.help_asterisk_bold') !!}.
+ {!! + trans('admin/settings/general.help_blank_to_use', [ + 'setting_name' => trans('admin/settings/general.barcodes').' > '.trans('admin/settings/general.qr_text') + ]) + !!} +

-
-
- {{ Form::text('labels_display_bgutter', old('labels_display_bgutter', $setting->labels_display_bgutter), ['class' => 'form-control', 'aria-label'=>'labels_display_bgutter']) }} -
{{ trans('admin/settings/general.vertical') }}
-
-
-
- {!! $errors->first('labels_display_sgutter', '') !!} - {!! $errors->first('labels_display_bgutter', '') !!} -
-
-
-
- {{ Form::label('labels_pmargin_top', trans('admin/settings/general.page_padding')) }} -
-
-
- {{ Form::text('labels_pmargin_top', old('labels_pmargin_top', $setting->labels_pmargin_top), ['class' => 'form-control', 'aria-label'=>'labels_pmargin_top']) }} -
{{ trans('admin/settings/general.top') }}
+ +
+
+ {{ Form::label('label2_asset_logo', trans('admin/settings/general.label2_asset_logo')) }}
-
- {{ Form::text('labels_pmargin_right', old('labels_pmargin_right', $setting->labels_pmargin_right), ['class' => 'form-control', 'aria-label'=>'labels_pmargin_right']) }} -
{{ trans('admin/settings/general.right') }}
+
+ {{ Form::checkbox('label2_asset_logo', '1', old('label2_asset_logo', $setting->label2_asset_logo, [ 'class'=>'minimal', 'aria-label'=>'label2_asset_logo' ])) }} + {{ trans('general.yes') }} + {!! $errors->first('label2_asset_logo', '') !!} +

{!! trans('admin/settings/general.label2_asset_logo_help', ['setting_name' => trans('admin/settings/general.brand').' > '.trans('admin/settings/general.label_logo')]) !!}

-
-
- {{ Form::text('labels_pmargin_bottom', old('labels_pmargin_bottom', $setting->labels_pmargin_bottom), ['class' => 'form-control', 'aria-label'=>'labels_pmargin_bottom']) }} -
{{ trans('admin/settings/general.bottom') }}
+ + +
+
+ {{ Form::label('label2_1d_type', trans('admin/settings/general.label2_1d_type')) }}
-
- {{ Form::text('labels_pmargin_left', old('labels_pmargin_left', $setting->labels_pmargin_left), ['class' => 'form-control', 'aria-label'=>'labels_pmargin_left']) }} -
{{ trans('admin/settings/general.left') }}
-
- -
-
- {!! $errors->first('labels_width', '') !!} - {!! $errors->first('labels_height', '') !!} -
-
- -
-
- {{ Form::label('labels_pagewidth', trans('admin/settings/general.page_dimensions')) }} -
-
-
- {{ Form::text('labels_pagewidth', old('labels_pagewidth', $setting->labels_pagewidth), ['class' => 'form-control', 'aria-label'=>'labels_pagewidth']) }} -
{{ trans('admin/settings/general.width_w') }}
+
+ @php + $select1DValues = [ + 'default' => trans('admin/settings/general.default').' [ '.$setting->alt_barcode.' ]', + 'none' => trans('admin/settings/general.none'), + 'C128' => 'C128', + 'C39' => 'C39', + 'EAN5' => 'EAN5', + 'EAN13' => 'EAN13', + 'UPCA' => 'UPCA', + 'UPCE' => 'UPCE' + ]; + @endphp + {{ Form::select('label2_1d_type', $select1DValues, old('label2_1d_type', $setting->label2_1d_type), [ 'class'=>'select2 col-md-4', 'aria-label'=>'label2_1d_type' ]) }} + {!! $errors->first('label2_1d_type', '') !!} +

+ {{ trans('admin/settings/general.label2_1d_type_help') }}. + {!! + trans('admin/settings/general.help_default_will_use', [ + 'default' => trans('admin/settings/general.default'), + 'setting_name' => trans('admin/settings/general.barcodes').' > '.trans('admin/settings/general.alt_barcode_type'), + ]) + !!} +

-
-
- {{ Form::text('labels_pageheight', old('labels_pageheight', $setting->labels_pageheight), ['class' => 'form-control', 'aria-label'=>'labels_pageheight']) }} -
{{ trans('admin/settings/general.height_h') }}
+ + +
+
+ {{ Form::label('label2_2d_type', trans('admin/settings/general.label2_2d_type')) }} +
+
+ @php + $select2DValues = [ + 'default' => trans('admin/settings/general.default').' [ '.$setting->barcode_type.' ]', + 'none' => trans('admin/settings/general.none'), + 'QRCODE' => 'QRCODE', + 'DATAMATRIX' => 'DATAMATRIX', + 'PDF417' => 'PDF417', + ]; + @endphp + {{ Form::select('label2_2d_type', $select2DValues, old('label2_2d_type', $setting->label2_2d_type), [ 'class'=>'select2 col-md-4', 'aria-label'=>'label2_2d_type' ]) }} + {!! $errors->first('label2_2d_type', '') !!} +

+ {{ trans('admin/settings/general.label2_2d_type_help', ['current' => $setting->barcode_type]) }}. + {!! + trans('admin/settings/general.help_default_will_use', [ + 'default' => trans('admin/settings/general.default'), + 'setting_name' => trans('admin/settings/general.barcodes').' > '.trans('admin/settings/general.barcode_type'), + ]) + !!} +

-
- {!! $errors->first('labels_pagewidth', '') !!} - {!! $errors->first('labels_pageheight', '') !!} + + +
+
+ {{ Form::label('label2_2d_target', trans('admin/settings/general.label2_2d_target')) }} +
+
+ {{ Form::select('label2_2d_target', ['hardware_id'=>'/hardware/{id} ('.trans('admin/settings/general.default').')', 'ht_tag'=>'/ht/{asset_tag}'], old('label2_2d_target', $setting->label2_2d_target), [ 'class'=>'select2 col-md-4', 'aria-label'=>'label2_2d_target' ]) }} + {!! $errors->first('label2_2d_target', '') !!} +

{{ trans('admin/settings/general.label2_2d_target_help') }}

+
-
-
-
- {{ Form::label('labels_display', trans('admin/settings/general.label_fields')) }} + +
+
+ {{ Form::label('label2_fields', trans('admin/settings/general.label2_fields')) }} +
+
+ @include('partials.label2-field-definitions', [ 'name' => 'label2_fields', 'value' => old('label2_fields', $setting->label2_fields) ]) + {!! $errors->first('label2_fields', '') !!} +

{{ trans('admin/settings/general.label2_fields_help') }}

+
-
- - - - - -
-
+ @include('partials.bootstrap-table') + + @else + + {{ Form::hidden('label2_template', old('label2_template', $setting->label2_template)) }} + {{ Form::hidden('label2_title', old('label2_title', $setting->label2_title)) }} + {{ Form::hidden('label2_asset_logo', old('label2_asset_logo', $setting->label2_asset_logo)) }} + {{ Form::hidden('label2_1d_type', old('label2_1d_type', $setting->label2_1d_type)) }} + {{ Form::hidden('label2_2d_type', old('label2_2d_type', $setting->label2_2d_type)) }} + {{ Form::hidden('label2_2d_target', old('label2_2d_target', $setting->label2_2d_target)) }} + {{ Form::hidden('label2_fields', old('label2_fields', $setting->label2_fields)) }} + @endif + @if ($setting->label2_enable && ($setting->label2_template != 'DefaultLabel')) + + {{ Form::hidden('labels_per_page', old('labels_per_page', $setting->labels_per_page)) }} + {{ Form::hidden('labels_fontsize', old('labels_fontsize', $setting->labels_fontsize)) }} + {{ Form::hidden('labels_width', old('labels_width', $setting->labels_width)) }} + {{ Form::hidden('labels_height', old('labels_height', $setting->labels_height)) }} + {{ Form::hidden('labels_display_sgutter', old('labels_display_sgutter', $setting->labels_display_sgutter)) }} + {{ Form::hidden('labels_display_bgutter', old('labels_display_bgutter', $setting->labels_display_bgutter)) }} + {{ Form::hidden('labels_pmargin_top', old('labels_pmargin_top', $setting->labels_pmargin_top)) }} + {{ Form::hidden('labels_pmargin_bottom', old('labels_pmargin_bottom', $setting->labels_pmargin_bottom)) }} + {{ Form::hidden('labels_pmargin_left', old('labels_pmargin_left', $setting->labels_pmargin_left)) }} + {{ Form::hidden('labels_pmargin_right', old('labels_pmargin_right', $setting->labels_pmargin_right)) }} + {{ Form::hidden('labels_pagewidth', old('labels_pagewidth', $setting->labels_pagewidth)) }} + {{ Form::hidden('labels_pageheight', old('labels_pageheight', $setting->labels_pageheight)) }} + {{ Form::hidden('labels_display_name', old('labels_display_name', $setting->labels_display_name)) }} + {{ Form::hidden('labels_display_serial', old('labels_display_serial', $setting->labels_display_serial)) }} + {{ Form::hidden('labels_display_tag', old('labels_display_tag', $setting->labels_display_tag)) }} + {{ Form::hidden('labels_display_model', old('labels_display_model', $setting->labels_display_model)) }} + {{ Form::hidden('labels_display_company_name', old('labels_display_company_name', $setting->labels_display_company_name)) }} + @else + +
+
+ {{ Form::label('labels_per_page', trans('admin/settings/general.labels_per_page')) }} +
+
+ {{ Form::text('labels_per_page', old('labels_per_page', $setting->labels_per_page), ['class' => 'form-control','style' => 'width: 100px;', 'aria-label'=>'labels_per_page']) }} + {!! $errors->first('labels_per_page', '') !!} +
+
+ +
+
+ {{ Form::label('labels_fontsize', trans('admin/settings/general.labels_fontsize')) }} +
+
+
+ {{ Form::text('labels_fontsize', old('labels_fontsize', $setting->labels_fontsize), ['class' => 'form-control', 'aria-label'=>'labels_fontsize']) }} +
{{ trans('admin/settings/general.text_pt') }}
+
+
+
+ {!! $errors->first('labels_fontsize', '') !!} +
+
+ +
+
+ {{ Form::label('labels_width', trans('admin/settings/general.label_dimensions')) }} +
+
+
+ {{ Form::text('labels_width', old('labels_width', $setting->labels_width), ['class' => 'form-control', 'aria-label'=>'labels_width']) }} +
{{ trans('admin/settings/general.width_w') }}
+
+
+
+
+ {{ Form::text('labels_height', old('labels_height', $setting->labels_height), ['class' => 'form-control', 'aria-label'=>'labels_height']) }} +
{{ trans('admin/settings/general.height_h') }}
+
+
+
+ {!! $errors->first('labels_width', '') !!} + {!! $errors->first('labels_height', '') !!} +
+
+ +
+
+ {{ Form::label('labels_display_sgutter', trans('admin/settings/general.label_gutters')) }} +
+
+
+ {{ Form::text('labels_display_sgutter', old('labels_display_sgutter', $setting->labels_display_sgutter), ['class' => 'form-control', 'aria-label'=>'labels_display_sgutter']) }} +
{{ trans('admin/settings/general.horizontal') }}
+
+
+
+
+ {{ Form::text('labels_display_bgutter', old('labels_display_bgutter', $setting->labels_display_bgutter), ['class' => 'form-control', 'aria-label'=>'labels_display_bgutter']) }} +
{{ trans('admin/settings/general.vertical') }}
+
+
+
+ {!! $errors->first('labels_display_sgutter', '') !!} + {!! $errors->first('labels_display_bgutter', '') !!} +
+
+ +
+
+ {{ Form::label('labels_pmargin_top', trans('admin/settings/general.page_padding')) }} +
+
+
+ {{ Form::text('labels_pmargin_top', old('labels_pmargin_top', $setting->labels_pmargin_top), ['class' => 'form-control', 'aria-label'=>'labels_pmargin_top']) }} +
{{ trans('admin/settings/general.top') }}
+
+
+ {{ Form::text('labels_pmargin_right', old('labels_pmargin_right', $setting->labels_pmargin_right), ['class' => 'form-control', 'aria-label'=>'labels_pmargin_right']) }} +
{{ trans('admin/settings/general.right') }}
+
+
+
+
+ {{ Form::text('labels_pmargin_bottom', old('labels_pmargin_bottom', $setting->labels_pmargin_bottom), ['class' => 'form-control', 'aria-label'=>'labels_pmargin_bottom']) }} +
{{ trans('admin/settings/general.bottom') }}
+
+
+ {{ Form::text('labels_pmargin_left', old('labels_pmargin_left', $setting->labels_pmargin_left), ['class' => 'form-control', 'aria-label'=>'labels_pmargin_left']) }} +
{{ trans('admin/settings/general.left') }}
+
+ +
+
+ {!! $errors->first('labels_width', '') !!} + {!! $errors->first('labels_height', '') !!} +
+
+ +
+
+ {{ Form::label('labels_pagewidth', trans('admin/settings/general.page_dimensions')) }} +
+
+
+ {{ Form::text('labels_pagewidth', old('labels_pagewidth', $setting->labels_pagewidth), ['class' => 'form-control', 'aria-label'=>'labels_pagewidth']) }} +
{{ trans('admin/settings/general.width_w') }}
+
+
+
+
+ {{ Form::text('labels_pageheight', old('labels_pageheight', $setting->labels_pageheight), ['class' => 'form-control', 'aria-label'=>'labels_pageheight']) }} +
{{ trans('admin/settings/general.height_h') }}
+
+
+
+ {!! $errors->first('labels_pagewidth', '') !!} + {!! $errors->first('labels_pageheight', '') !!} +
+
+ +
+
+ {{ Form::label('labels_display', trans('admin/settings/general.label_fields')) }} +
+
+ + + + + + +
+
+ + @endif
diff --git a/routes/api.php b/routes/api.php index ef1b821a3..4b8866dc2 100644 --- a/routes/api.php +++ b/routes/api.php @@ -606,6 +606,16 @@ Route::group(['prefix' => 'v1', 'middleware' => ['api', 'throttle:api']], functi ); // end imports API routes + /** + * Labels API routes + */ + Route::group(['prefix' => 'labels'], function() { + Route::get('{name}', [ Api\LabelsController::class, 'show']) + ->where('name', '.*') + ->name('api.labels.show'); + Route::get('', [ Api\LabelsController::class, 'index']) + ->name('api.labels.index'); + }); /** * Licenses API routes diff --git a/routes/web.php b/routes/web.php index 5de6ef902..4bc8b3bb5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -10,6 +10,7 @@ use App\Http\Controllers\DepreciationsController; use App\Http\Controllers\GroupsController; use App\Http\Controllers\HealthController; use App\Http\Controllers\ImportsController; +use App\Http\Controllers\LabelsController; use App\Http\Controllers\LocationsController; use App\Http\Controllers\ManufacturersController; use App\Http\Controllers\ModalController; @@ -39,8 +40,14 @@ Route::group(['middleware' => 'auth'], function () { Route::resource('categories', CategoriesController::class, [ 'parameters' => ['category' => 'category_id'], ]); - - + + /* + * Labels + */ + Route::get( + 'labels/{labelName}', + [LabelsController::class, 'show'] + )->where('labelName', '.*')->name('labels.show'); /* * Locations @@ -68,9 +75,6 @@ Route::group(['middleware' => 'auth'], function () { ]); - - - /* * Manufacturers */ diff --git a/routes/web/hardware.php b/routes/web/hardware.php index 690d8e0d1..1643e5794 100644 --- a/routes/web/hardware.php +++ b/routes/web/hardware.php @@ -187,3 +187,7 @@ Route::resource('hardware', 'parameters' => ['asset' => 'asset_id' ], ]); + +Route::get('ht/{any?}', + [AssetsController::class, 'getAssetByTag'] +)->where('any', '.*')->name('ht/assetTag'); diff --git a/webpack.mix.js b/webpack.mix.js index 2cda1ee50..babab0fad 100644 --- a/webpack.mix.js +++ b/webpack.mix.js @@ -202,6 +202,13 @@ mix ) .version(); +mix + .combine( + ['./node_modules/alpinejs/dist/cdn.js'], + './public/js/dist/all-defer.js' + ) + .version(); + /** * Copy, minify and version skins */