- "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
This commit is contained in:
Bernd Bestel 2021-06-12 17:16:08 +02:00
parent f915c7653b
commit 7a70311063
No known key found for this signature in database
GPG Key ID: 71BD34C0D4891300
12 changed files with 207 additions and 177 deletions

View File

@ -187,7 +187,7 @@ Setting('FEATURE_FLAG_TASKS', true);
Setting('FEATURE_FLAG_BATTERIES', true);
Setting('FEATURE_FLAG_EQUIPMENT', true);
Setting('FEATURE_FLAG_CALENDAR', true);
Setting('FEATURE_FLAG_LABELPRINTER', true);
Setting('FEATURE_FLAG_LABELPRINTER', false);
// Sub feature flags
Setting('FEATURE_FLAG_STOCK_PRICE_TRACKING', true);

View File

@ -626,7 +626,7 @@ class StockApiController extends BaseApiController
(new WebhookRunner())->run(GROCY_LABEL_PRINTER_WEBHOOK, $webhookData, GROCY_LABEL_PRINTER_HOOK_JSON);
}
return $this->ApiResponse($response, $webhookData);
return $this->EmptyApiResponse($response);
}
public function StockEntryPrintLabel(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
@ -649,7 +649,7 @@ class StockApiController extends BaseApiController
(new WebhookRunner())->run(GROCY_LABEL_PRINTER_WEBHOOK, $webhookData, GROCY_LABEL_PRINTER_HOOK_JSON);
}
return $this->ApiResponse($response, $webhookData);
return $this->EmptyApiResponse($response);
}
public function RemoveProductFromShoppingList(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)

View File

@ -174,10 +174,14 @@ class StockController extends BaseController
public function ProductGrocycodeImage(\Psr\Http\Message\ServerRequestInterface $request, \Psr\Http\Message\ResponseInterface $response, array $args)
{
$size = $request->getQueryParam('size', null);
$product = $this->getDatabase()->products($args['productId']);
$gc = new Grocycode(Grocycode::PRODUCT, $product->id);
$png = (new DatamatrixFactory())->setCode((string) $gc)->getDatamatrixPngData();
// Explicitly suppress errors, otherwise deprecations warnings would cause invalid PNG data
// See also https://github.com/jucksearm/php-barcode/issues/3
$png = @(new DatamatrixFactory())->setCode((string) $gc)->setSize($size)->getDatamatrixPngData();
$isDownload = $request->getQueryParam('download', false);
@ -464,7 +468,10 @@ class StockController extends BaseController
$stockEntry = $this->getDatabase()->stock()->where('id', $args['entryId'])->fetch();
$gc = new Grocycode(Grocycode::PRODUCT, $stockEntry->product_id, [$stockEntry->stock_id]);
$png = (new DatamatrixFactory())->setCode((string) $gc)->setSize($size)->getDatamatrixPngData();
// Explicitly suppress errors, otherwise deprecations warnings would cause invalid PNG data
// See also https://github.com/jucksearm/php-barcode/issues/3
$png = @(new DatamatrixFactory())->setCode((string) $gc)->setSize($size)->getDatamatrixPngData();
$isDownload = $request->getQueryParam('download', false);

View File

@ -1,7 +1,7 @@
Grocycode
grocycode
==========
Grocycode is, in essence, a simple way to reference to arbitrary grocy entities.
grocycode is, in essence, a simple way to reference to arbitrary grocy entities.
Each grocycode includes a magic, an entitiy identifier, an id and an ordered set of extra data.
It is supported to be entered anywhere grocy expects one to read a barcode, but can also reference
grocy-internal properties like specific stock entries, or specific batteries.
@ -33,22 +33,22 @@ Example
In this example, we encode a *Product* with ID *13*, which results in `grcy:p:13` when serialized.
Product Grocycodes
Product grocycodes
----
Product Grocycodes extend the data format to include an optional stock id, thus may reference a specific stock entry directly.
Product grocycodes extend the data format to include an optional stock id, thus may reference a specific stock entry directly.
Example: `grcy:p:13:60bf8b5244b04`
Battery Grocycodes
Battery grocycodes
----
Currently, Battery Grocycodes do not define any extra fields.
Currently, Battery grocycodes do not define any extra fields.
Chore Grocycodes
Chore grocycodes
----
Currently, Chore Grocycodes do not define any extra fields.
Currently, Chore grocycodes do not define any extra fields.
Visual Encoding
----
@ -63,4 +63,4 @@ so that the double colons get entered correctly.
Notes
---
[0]: Obviously, it needs to be encoded into some usable visual representation and then read. So probably you only want to encode stuff that can be typed on a keyboard.
[0]: Obviously, it needs to be encoded into some usable visual representation and then read. So probably you only want to encode stuff that can be typed on a keyboard.

View File

@ -1402,7 +1402,7 @@
"in": "path",
"name": "entryId",
"required": true,
"description": "A valid stock row id",
"description": "A valid stock entry id",
"schema": {
"type": "integer"
}
@ -1441,7 +1441,7 @@
"in": "path",
"name": "entryId",
"required": true,
"description": "A valid stock row id",
"description": "A valid stock entry id",
"schema": {
"type": "integer"
}
@ -1529,6 +1529,40 @@
}
}
},
"/stock/entry/{entryId}/printlabel": {
"get": {
"summary": "Prints the label of the given stock entry",
"tags": [
"Stock"
],
"parameters": [
{
"in": "path",
"name": "entryId",
"required": true,
"description": "A valid stock entry id",
"schema": {
"type": "integer"
}
}
],
"responses": {
"204": {
"description": "The operation was successful"
},
"400": {
"description": "The operation was not successful (possible errors are: Not existing stock entry, error on WebHook execution)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error400"
}
}
}
}
}
}
},
"/stock/volatile": {
"get": {
"summary": "Returns all products which are due soon, overdue, expired or currently missing",
@ -1850,6 +1884,10 @@
"type": "number",
"format": "integer",
"description": "If omitted, no store will be affected"
},
"print_stock_label": {
"type": "boolean",
"description": "True when the stock entry label should be printed"
}
},
"example": {
@ -2213,6 +2251,40 @@
}
}
},
"/stock/products/{productId}/printlabel": {
"get": {
"summary": "Prints the product label of the given product",
"tags": [
"Stock"
],
"parameters": [
{
"in": "path",
"name": "productId",
"required": true,
"description": "A valid product id",
"schema": {
"type": "integer"
}
}
],
"responses": {
"204": {
"description": "The operation was successful"
},
"400": {
"description": "The operation was not successful (possible errors are: Not existing product, error on WebHook execution)",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error400"
}
}
}
}
}
}
},
"/stock/products/{productIdToKeep}/merge/{productIdToRemove}": {
"post": {
"summary": "Merges two products into one",

View File

@ -2374,51 +2374,3 @@ msgstr "Druckoptionen"
msgid "A product or a note is required"
msgstr "Ein Produkt oder eine Notiz ist erforderlich"
msgid "Grocycode"
msgstr "Grocycode"
msgid "Download"
msgstr "Herunterladen"
msgid "Download stock entry grocycode"
msgstr "Bestandseingrags-Grocycode herunterladen"
msgid "Download product grocycode"
msgstr "Produkt-Grocycode herunterladen"
msgid "Grocycode is a unique referer to this product in your grocy instance. Print it onto a label and scan it like any other barcode!"
msgstr "Grocycode ist eine eindeutige Referenz zu diesem Produkt in dieser Grocy-Instanz. Ausgedruckt kann es wie jeder andere Barcode gescannt werden!"
msgid "Open print label in new Window"
msgstr "Druck-Label in neuem Fenster öffnen"
msgid "DD"
msgstr "MHD"
msgid "Print stock label"
msgstr "Etikett drucken"
msgid "Print Product Label"
msgstr "Produkt-Etikett drucken"
msgid "Print stock entry label"
msgstr "Etikett drucken"
msgid "Stock label"
msgstr "Etikett"
msgid "No Label"
msgstr "Kein Etikett"
msgid "Single Label"
msgstr "Ein Etikett pro Einkauf"
msgid "Label per Unit"
msgstr "Ein Etikett pro Mengeneinheit"
msgid "Allow label printing per unit"
msgstr "Erlaube Etikettendruck pro Mengeneinheit"
msgid "Allow printing of one label per unit in a purchase (after conversion). E.g. 1 purchased pack adding 10 pieces of stock would print 10 labels."
msgstr "Erlaube Etikettendruck pro Mengeneinheit nach Umrechnung. Beispiel: 1 gekauftes Paket, das 10 Einheiten hinzufügt, druckt 10 Etiketten."

View File

@ -2078,7 +2078,7 @@ msgstr ""
msgid "A product or a note is required"
msgstr ""
msgid "Grocycode"
msgid "grocycode"
msgstr ""
msgid "Download"
@ -2090,46 +2090,42 @@ msgstr ""
msgid "Download product grocycode"
msgstr ""
msgid ""
"If enabled, the min. stock amount of sub products will be accumulated into this product, means the sub product will never be \"\n"
"\t\t\t\t\t\t\tmissing\",\n"
"\t\t\t\t\t\t\tonly\n"
"\t\t\t\t\t\t\tthis\n"
"\t\t\t\t\t\t\tproduct"
msgstr ""
msgid "Grocycode is a unique referer to this product in your grocy instance. Print it onto a label and scan it like any other barcode!"
msgstr ""
msgid "Open print label in new Window"
msgid "grocycode is a unique referer to this product in your grocy instance - print it onto a label and scan it like any other barcode"
msgstr ""
# Abbreviation for "due date"
msgid "DD"
msgstr ""
msgid "Print stock label"
msgid "Print on label printer"
msgstr ""
msgid "Print Product Label"
msgid "Stock entry label"
msgstr ""
msgid "Print stock entry label"
msgid "No label"
msgstr ""
msgid "Stock label"
msgid "Single label"
msgstr ""
msgid "No Label"
msgstr ""
msgid "Single Label"
msgstr ""
msgid "Label per Unit"
msgid "Label per unit"
msgstr ""
msgid "Allow label printing per unit"
msgstr ""
msgid "Allow printing of one label per unit in a purchase (after conversion). E.g. 1 purchased pack adding 10 pieces of stock would print 10 labels."
msgid "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"
msgstr ""
msgid "Error while executing WebHook"
msgstr ""
msgid "Print product grocycode on label printer"
msgstr ""
msgid "Print stock entry grocycode on label printer"
msgstr ""
msgid "Open stock entry print label in new window"
msgstr ""

View File

@ -488,7 +488,7 @@ Grocy.FrontendHelpers.RunWebhook = function(webhook, data, repetitions = 1)
if (!hasAlreadyFailed)
{
hasAlreadyFailed = true;
Grocy.FrontendHelpers.ShowGenericError(__t("Unable to connect to webhook.", { "status": status, "errorThrown": errorThrown }));
Grocy.FrontendHelpers.ShowGenericError(__t("Error while executing WebHook", { "status": status, "errorThrown": errorThrown }));
}
});
}

View File

@ -145,12 +145,7 @@
for="cumulate_min_stock_amount_of_sub_products">{{ $__t('Accumulate sub products min. stock amount') }}
&nbsp;<i class="fas fa-question-circle text-muted"
data-toggle="tooltip"
title="{{ $__t('If enabled, the min. stock amount of sub products will be accumulated into this product, means the sub product will never be "
missing",
only
this
product')
}}"></i>
title="{{ $__t('If enabled, the min. stock amount of sub products will be accumulated into this product, means the sub product will never be "missing", only this product') }}"></i>
</label>
</div>
</div>
@ -414,7 +409,7 @@
<label class="form-check-label custom-control-label"
for="allow_label_per_unit">{{ $__t('Allow label printing per unit') }}&nbsp;<i class="fas fa-question-circle text-muted"
data-toggle="tooltip"
title="{{ $__t('Allow printing of one label per unit in a purchase (after conversion). E.g. 1 purchased pack adding 10 pieces of stock would print 10 labels.') }}"></i>
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>
@ -426,28 +421,32 @@
$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 = "";
}
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 label') }}</label>
<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>
<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
@ -479,33 +478,7 @@
<div class="col-lg-6 col-xs-12 @if($mode == 'create') d-none @endif">
<div class="row">
<div class="col clearfix">
<div class="title-related-links">
<h4>
{{ $__t('Grocycode') }}
</h4>
<p>
<img src="{{ $U('/product/' . $product->id . '/grocycode') }}"
class="float-lg-left mr-2">
{{ $__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!') }}
</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 Product Label') }}
</a>
@endif
</p>
</div>
</div>
</div>
<div class="row @if(!GROCY_FEATURE_FLAG_STOCK) d-none @endif mt-5">
<div class="row @if(!GROCY_FEATURE_FLAG_STOCK) d-none @endif">
<div class="col">
<div class="title-related-links">
<h4>
@ -612,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">

View File

@ -150,14 +150,14 @@
@if(GROCY_FEATURE_FLAG_LABELPRINTER)
<div class="form-group">
<label for="print_stock_label">{{ $__t('Stock label') }}</label>
<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="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>
id="label-option-per-unit">{{ $__t('Label per unit') }}</option>
</select>
<div class="invalid-feedback">{{ $__t('A quantity unit is required') }}</div>
</div>

View File

@ -185,25 +185,6 @@
href="#">
{{ $__t('Product overview') }}
</a>
<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 label') }}
</a>
@endif
<a class="dropdown-item stockentry-label-link"
type="button"
target="_blank"
href="{{ $U('/stockentry/' . $stockEntry->id . '/label') }}">
{{ $__t('Open print label in new Window') }}
</a>
<a class="dropdown-item show-as-dialog-link"
type="button"
href="{{ $U('/stockjournal?embedded&product=') }}{{ $stockEntry->product_id }}">
@ -219,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>
@ -298,4 +299,4 @@
</div>
</div>
</div>
@stop
@stop

View File

@ -277,19 +277,6 @@
href="#">
<span class="dropdown-item-text">{{ $__t('Product overview') }}</span>
</a>
<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 Label') }}
</a>
@endif
<a class="dropdown-item show-as-dialog-link"
type="button"
href="{{ $U('/stockentries?embedded&product=') }}{{ $currentStockEntry->product_id }}"
@ -311,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>
@ -427,4 +428,4 @@
</div>
</div>
</div>
@stop
@stop