mirror of
https://github.com/grocy/grocy.git
synced 2025-08-28 09:01:14 +00:00
Grocycode, label printing (#1500)
* Grocycode: Productpicker, StockService * Grocycode: Datamatrix generation * Grocycode: Display in UI, make Images downloadable * Grocycode: Do not show on product card * Grocycode: Stockentry Label view * Grocycode: Webhooks & Labelprinter Feature * Grocycode: Manual Label printing * Grocycode: Print Label from product form * Quagga2: use zxing for DataMatrix recognition * Grocycode: Default settings for label printing * Prepare merge of master * Grocycode: docs * Docs: label printing webhook * Review - "grocy" is currently written lower-case everywhere, so let's do this also for "grocycode" - Unified phrases / capitalization - Minor UI adjustments (mainly context menu item ordering / ordering/spacing on product edit page) - Documented API changes for Swagger UI (grocy.openapi.json) - Reverted German localizations (those are managed via Transifex; would cause conflicts when manually edited - will import them later there) - Reverted a somehow messed up localization string (productform/help text for `cumulate_min_stock_amount_of_sub_products`) - Suppress deprecation warnings when generating Datamatrix PNG (otherwise the PNG is invalid, https://github.com/jucksearm/php-barcode/issues/3) - Default `FEATURE_FLAG_LABELPRINTER` to disabled Co-authored-by: Bernd Bestel <bernd@berrnd.de>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
@push('pageScripts')
|
||||
<script src="{{ $U('/node_modules/@ericblade/quagga2/dist/quagga.min.js?v=', true) }}{{ $version }}"></script>
|
||||
<script src="{{ $U('/components_unmanaged/quagga2-reader-datamatrix/index.js', true) }}?v={{ $version }}"></script>
|
||||
@endpush
|
||||
|
||||
@push('pageStyles')
|
||||
@@ -21,8 +22,7 @@
|
||||
.combobox-container #barcodescanner-start-button {
|
||||
margin-right: 36px !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
@endpush
|
||||
|
||||
@endif
|
||||
@endif
|
@@ -68,4 +68,4 @@
|
||||
class="font-italic d-none">{{ $__t('No price history available') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -95,6 +95,14 @@
|
||||
Grocy.CalendarShowWeekNumbers = {{ BoolToString(GROCY_CALENDAR_SHOW_WEEK_OF_YEAR) }};
|
||||
Grocy.GettextPo = {!! $GettextPo !!};
|
||||
Grocy.FeatureFlags = {!! json_encode($featureFlags) !!};
|
||||
Grocy.Webhooks = {
|
||||
@if(GROCY_FEATURE_FLAG_LABELPRINTER && !GROCY_LABEL_PRINTER_RUN_SERVER)
|
||||
"labelprinter" : {
|
||||
"hook" : "{{ GROCY_LABEL_PRINTER_WEBHOOK}}",
|
||||
"extra_data" : {!! json_encode(GROCY_LABEL_PRINTER_PARAMS) !!}
|
||||
}
|
||||
@endif
|
||||
};
|
||||
|
||||
@if (GROCY_AUTHENTICATED)
|
||||
Grocy.UserSettings = {!! json_encode($userSettings) !!};
|
||||
|
@@ -400,6 +400,57 @@
|
||||
'entity' => 'products'
|
||||
))
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_LABELPRINTER)
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input @if($mode=='edit'
|
||||
&&
|
||||
$product->allow_label_per_unit == 1) checked @endif class="form-check-input custom-control-input" type="checkbox" id="allow_label_per_unit" name="allow_label_per_unit" value="1">
|
||||
<label class="form-check-label custom-control-label"
|
||||
for="allow_label_per_unit">{{ $__t('Allow label printing per unit') }} <i class="fas fa-question-circle text-muted"
|
||||
data-toggle="tooltip"
|
||||
title="{{ $__t('Allow printing of one label per unit on purchase (after conversion) - e.g. 1 purchased pack adding 10 pieces of stock would print 10 labels') }}"></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@php
|
||||
$no_label = "";
|
||||
$single_label = "";
|
||||
$per_unit_label = "";
|
||||
$disable_per_unit = "";
|
||||
|
||||
if($mode == 'edit') {
|
||||
switch($product->default_print_stock_label) {
|
||||
case 0: $no_label = "selected"; break;
|
||||
case 1: $single_label = "selected"; break;
|
||||
case 2: $per_unit_label = "selected"; break;
|
||||
default: break; // yolo
|
||||
}
|
||||
if($product->allow_label_per_unit == 0) {
|
||||
$disable_per_unit="disabled";
|
||||
$per_unit_label = "";
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div class="form-group">
|
||||
<label for="default_print_stock_label">{{ $__t('Stock entry label') }}</label>
|
||||
<select class="form-control"
|
||||
id="default_print_stock_label"
|
||||
name="default_print_stock_label">
|
||||
<option value="0"
|
||||
{{ $no_label }}>{{ $__t('No label') }}</option>
|
||||
<option value="1"
|
||||
{{ $single_label }}>{{ $__t('Single label') }}</option>
|
||||
<option value="2"
|
||||
{{ $per_unit_label }}
|
||||
{{ $disable_per_unit }}
|
||||
id="label-option-per-unit">{{ $__t('Label per unit') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input @if($mode=='edit'
|
||||
@@ -426,6 +477,7 @@
|
||||
</div>
|
||||
|
||||
<div class="col-lg-6 col-xs-12 @if($mode == 'create') d-none @endif">
|
||||
|
||||
<div class="row @if(!GROCY_FEATURE_FLAG_STOCK) d-none @endif">
|
||||
<div class="col">
|
||||
<div class="title-related-links">
|
||||
@@ -533,6 +585,34 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
<div class="col clearfix">
|
||||
<div class="title-related-links">
|
||||
<h4>
|
||||
{{ $__t('grocycode') }}
|
||||
<i class="fas fa-question-circle text-muted"
|
||||
data-toggle="tooltip"
|
||||
title="{{ $__t('grocycode is a unique referer to this product in your grocy instance - print it onto a label and scan it like any other barcode') }}"></i>
|
||||
</h4>
|
||||
<p>
|
||||
<img src="{{ $U('/product/' . $product->id . '/grocycode?size=60') }}"
|
||||
class="float-lg-left">
|
||||
</p>
|
||||
<p>
|
||||
<a class="btn btn-outline-primary btn-sm"
|
||||
href="{{ $U('/product/' . $product->id . '/grocycode?download=true') }}">{{ $__t('Download') }}</a>
|
||||
@if(GROCY_FEATURE_FLAG_LABELPRINTER)
|
||||
<a class="btn btn-outline-primary btn-sm stockentry-grocycode-product-label-print"
|
||||
data-product-id="{{ $product->id }}"
|
||||
href="#">
|
||||
{{ $__t('Print on label printer') }}
|
||||
</a>
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row @if(GROCY_FEATURE_FLAG_STOCK) mt-5 @endif">
|
||||
<div class="col">
|
||||
<div class="title-related-links">
|
||||
|
@@ -12,7 +12,7 @@
|
||||
<script>
|
||||
Grocy.QuantityUnits = {!! json_encode($quantityUnits) !!};
|
||||
Grocy.QuantityUnitConversionsResolved = {!! json_encode($quantityUnitConversionsResolved) !!};
|
||||
Grocy.DefaultMinAmount = '{{$DEFAULT_MIN_AMOUNT}}';
|
||||
Grocy.DefaultMinAmount = '{{ $DEFAULT_MIN_AMOUNT }}';
|
||||
</script>
|
||||
|
||||
<div class="row">
|
||||
@@ -148,6 +148,21 @@
|
||||
))
|
||||
@endif
|
||||
|
||||
@if(GROCY_FEATURE_FLAG_LABELPRINTER)
|
||||
<div class="form-group">
|
||||
<label for="print_stock_label">{{ $__t('Stock entry label') }}</label>
|
||||
<select class="form-control"
|
||||
id="print_stock_label"
|
||||
name="print_stock_label">
|
||||
<option value="0">{{ $__t('No label') }}</option>
|
||||
<option value="1">{{ $__t('Single label') }}</option>
|
||||
<option value="2"
|
||||
id="label-option-per-unit">{{ $__t('Label per unit') }}</option>
|
||||
</select>
|
||||
<div class="invalid-feedback">{{ $__t('A quantity unit is required') }}</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<button id="save-purchase-button"
|
||||
class="btn btn-success d-block">{{ $__t('OK') }}</button>
|
||||
|
||||
|
@@ -200,6 +200,26 @@
|
||||
href="{{ $U('/product/') }}{{ $stockEntry->product_id . '?returnto=/stockentries' }}">
|
||||
{{ $__t('Edit product') }}
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item stockentry-grocycode-link"
|
||||
type="button"
|
||||
href="{{ $U('/stockentry/' . $stockEntry->id . '/grocycode?download=true') }}">
|
||||
{{ $__t('Download stock entry grocycode') }}
|
||||
</a>
|
||||
@if(GROCY_FEATURE_FLAG_LABELPRINTER)
|
||||
<a class="dropdown-item stockentry-grocycode-stockentry-label-print"
|
||||
data-stock-id="{{ $stockEntry->id }}"
|
||||
type="button"
|
||||
href="#">
|
||||
{{ $__t('Print stock entry grocycode on label printer') }}
|
||||
</a>
|
||||
@endif
|
||||
<a class="dropdown-item stockentry-label-link"
|
||||
type="button"
|
||||
target="_blank"
|
||||
href="{{ $U('/stockentry/' . $stockEntry->id . '/label') }}">
|
||||
{{ $__t('Open stock entry print label in new window') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
40
views/stockentrylabel.blade.php
Normal file
40
views/stockentrylabel.blade.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>{{ $product->name }}</title>
|
||||
<link href="{{ $U('/components_unmanaged/noto-sans-v11-latin/noto-sans-v11-latin.min.css?v=', true) }}{{ $version }}"
|
||||
rel="stylesheet">
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Noto Sans', sans-serif;
|
||||
}
|
||||
|
||||
img {
|
||||
float: left;
|
||||
margin-right: .5rem;
|
||||
max-height: 25px;
|
||||
width: auto;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.productname {
|
||||
font-size: 20px;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>
|
||||
<!-- Size gets determined by CSS, so printing works better (more pixels = sharper printed image).
|
||||
Unfortunately, this also means the code is blurred on screen. -->
|
||||
<img src="{{ $U('/stockentry/'. $stockEntry->id . '/grocycode?size=100') }}">
|
||||
<span class="productname">{{ $product->name }}</span><br>
|
||||
@if (GROCY_FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING)
|
||||
<span>{{ $__t('DD') }}: {{ $stockEntry->best_before_date }}</span>
|
||||
@endif
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
@@ -298,6 +298,20 @@
|
||||
href="{{ $U('/product/') }}{{ $currentStockEntry->product_id . '?returnto=%2Fstockoverview' }}">
|
||||
<span class="dropdown-item-text">{{ $__t('Edit product') }}</span>
|
||||
</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item stockentry-grocycode-link"
|
||||
type="button"
|
||||
href="{{ $U('/product/' . $currentStockEntry->product_id . '/grocycode?download=true') }}">
|
||||
{{ $__t('Download product grocycode') }}
|
||||
</a>
|
||||
@if(GROCY_FEATURE_FLAG_LABELPRINTER)
|
||||
<a class="dropdown-item stockentry-grocycode-product-label-print"
|
||||
data-product-id="{{ $currentStockEntry->product_id }}"
|
||||
type="button"
|
||||
href="#">
|
||||
{{ $__t('Print product grocycode on label printer') }}
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@@ -308,7 +322,8 @@
|
||||
<td>
|
||||
@if($currentStockEntry->product_group_name !== null){{ $currentStockEntry->product_group_name }}@endif
|
||||
</td>
|
||||
<td data-order={{ $currentStockEntry->amount }}>
|
||||
<td data-order={{
|
||||
$currentStockEntry->amount }}>
|
||||
<span id="product-{{ $currentStockEntry->product_id }}-amount"
|
||||
class="locale-number locale-number-quantity-amount">{{ $currentStockEntry->amount }}</span> <span id="product-{{ $currentStockEntry->product_id }}-qu-name">{{ $__n($currentStockEntry->amount, $currentStockEntry->qu_unit_name, $currentStockEntry->qu_unit_name_plural) }}</span>
|
||||
<span id="product-{{ $currentStockEntry->product_id }}-opened-amount"
|
||||
|
Reference in New Issue
Block a user