Implemented a way to use the external barcode lookup plugin also from within the frontend as a product picker workflow

This commit is contained in:
Bernd Bestel
2023-11-03 20:47:43 +01:00
parent c9215a9a4e
commit 27f9d70b56
11 changed files with 62 additions and 14 deletions

View File

@@ -123,7 +123,9 @@ Example: Button "**P** Add as new product" can be "pressed" by using the `P` key
### Barcode lookup via external services
Products can be directly added to the database via looking them up against external services by a barcode.
This is currently only possible through the REST API.
This can be done in-place using the product picker workflow "External barcode lookup (via plugin)" (the workflow dialog is displayed when entering something unknown in any product input field).
There is no plugin included for any service, see the reference implementation in `data/plugins/DemoBarcodeLookupPlugin.php`.
### Database migrations

View File

@@ -10,6 +10,10 @@
### Stock
- Added a new product picker workflow "External barcode lookup (via plugin)"
- This executes the configured barcode lookup plugin with the given barcode
- If the lookup was successful, the product edit page of the created product is displayed, where the product setup can be completed (if required)
- After that, the purchase transaction is continued with that product
- Fixed that the location dropdown on the consume page contained the same location multiple times if there are currently stock entries at multiple locations of the corresponding product
- Fixed that the status filter "n products are overdue" on the stock overview page also counted/included stock entries due today or tomorrow

View File

@@ -442,7 +442,6 @@ class StockApiController extends BaseApiController
try
{
$addFoundProduct = false;
if (isset($request->getQueryParams()['add']) && ($request->getQueryParams()['add'] === 'true' || $request->getQueryParams()['add'] === 1))
{
$addFoundProduct = true;

View File

@@ -3,7 +3,7 @@
use Grocy\Helpers\BaseBarcodeLookupPlugin;
/*
This class must extend BaseBarcodeLookupPlugin (in namespace \Grocy\Helpers)
This class must extend BaseBarcodeLookupPlugin (in namespace Grocy\Helpers)
*/
class DemoBarcodeLookupPlugin extends BaseBarcodeLookupPlugin
{
@@ -14,8 +14,11 @@ class DemoBarcodeLookupPlugin extends BaseBarcodeLookupPlugin
/*
To try it:
Call the API function at /api/stock/barcodes/external-lookup/{barcode}
Or use the product picker workflow "External barcode lookup (via plugin)"
When you also add ?add=true as a query parameter to the API call,
on a successful lookup the product is added to the database and in the output
the new product id is included (automatically, nothing to do here in the plugin)
@@ -55,12 +58,14 @@ class DemoBarcodeLookupPlugin extends BaseBarcodeLookupPlugin
*/
protected function ExecuteLookup($barcode)
{
if ($barcode === 'x')
{ // Demonstration when nothing is found
if ($barcode === 'nothing')
{
// Demonstration when nothing is found
return null;
}
elseif ($barcode === 'e')
{ // Demonstration when an error occurred
elseif ($barcode === 'error')
{
// Demonstration when an error occurred
throw new \Exception('This is the error message from the plugin...');
}
else

View File

@@ -29,7 +29,8 @@ abstract class BaseBarcodeLookupPlugin
}
if (!IsAssociativeArray($pluginOutput))
{ // $pluginOutput is at least an indexed array here
{
// $pluginOutput is at least an indexed array here
throw new \Exception('Plugin output must be an associative array');
}
@@ -53,7 +54,7 @@ abstract class BaseBarcodeLookupPlugin
// $pluginOutput contains all needed properties here
// Check referenced entity ids are valid
// Check if referenced entity ids are valid
$locationId = $pluginOutput['location_id'];
if (FindObjectInArrayByPropertyValue($this->Locations, 'id', $locationId) === null)
{

View File

@@ -2423,3 +2423,12 @@ msgid "This means 1 label will be printed"
msgid_plural "This means %1$s labels will be printed"
msgstr[0] ""
msgstr[1] ""
msgid "External barcode lookup (via plugin)"
msgstr ""
msgid "Error while executing the barcode lookup plugin"
msgstr ""
msgid "Nothing was found for the given barcode"
msgstr ""

View File

@@ -249,6 +249,32 @@ $('#product_id_text_input').on('blur', function(e)
Grocy.Components.ProductPicker.PopupOpen = false;
window.location.href = U('/product/new?flow=InplaceNewProductWithBarcode&barcode=' + encodeURIComponent(input) + '&returnto=' + encodeURIComponent(Grocy.CurrentUrlRelative + "?flow=InplaceAddBarcodeToExistingProduct&barcode=" + input + "&" + embedded) + "&" + embedded);
}
},
barcodepluginlookup: {
label: '<strong>E</strong> ' + __t('External barcode lookup (via plugin)'),
className: 'btn-dark add-new-product-plugin-dialog-button responsive-button ' + addProductWorkflowsAdditionalCssClasses,
callback: function()
{
Grocy.Components.ProductPicker.PopupOpen = false;
Grocy.Api.Get("stock/barcodes/external-lookup/" + encodeURIComponent(input) + "?add=true",
function(pluginResponse)
{
if (pluginResponse == null)
{
toastr.warning(__t("Nothing was found for the given barcode"));
}
else
{
window.location.href = U("/product/" + pluginResponse.id + "?flow=InplaceNewProductByPlugin&returnto=" + encodeURIComponent(Grocy.CurrentUrlRelative + "?flow=InplaceNewProductWithName&" + embedded) + "&" + embedded);
}
},
function(xhr)
{
Grocy.FrontendHelpers.ShowGenericError("Error while executing the barcode lookup plugin", xhr.response);
}
);
}
}
};
@@ -321,6 +347,10 @@ $('#product_id_text_input').on('blur', function(e)
{
$('.retry-camera-scanning-button').not(".d-none").click();
}
if (e.key === 'e' || e.key === 'E')
{
$('.add-new-product-plugin-dialog-button').not(".d-none").click();
}
});
}
else

View File

@@ -1702,14 +1702,12 @@ class StockService extends BaseService
private function LoadBarcodeLookupPlugin()
{
$pluginName = defined('GROCY_STOCK_BARCODE_LOOKUP_PLUGIN') ? GROCY_STOCK_BARCODE_LOOKUP_PLUGIN : '';
if (empty($pluginName))
{
throw new \Exception('No barcode lookup plugin defined');
}
$path = GROCY_DATAPATH . "/plugins/$pluginName.php";
if (file_exists($path))
{
require_once $path;