mirror of
https://github.com/grocy/grocy.git
synced 2025-08-17 11:06:36 +00:00
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:
@@ -123,7 +123,9 @@ Example: Button "**P** Add as new product" can be "pressed" by using the `P` key
|
|||||||
### Barcode lookup via external services
|
### Barcode lookup via external services
|
||||||
|
|
||||||
Products can be directly added to the database via looking them up against external services by a barcode.
|
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`.
|
There is no plugin included for any service, see the reference implementation in `data/plugins/DemoBarcodeLookupPlugin.php`.
|
||||||
|
|
||||||
### Database migrations
|
### Database migrations
|
||||||
|
@@ -29,6 +29,6 @@
|
|||||||
- Also applies to quantity units, n-plural forms can be entered on the quantity unit edit page
|
- Also applies to quantity units, n-plural forms can be entered on the quantity unit edit page
|
||||||
- It's not required to install the PHP gettext extension, on both, server and client, managed implementations of gettext are used ([oscarotero/Gettext](https://github.com/oscarotero/Gettext) & [oscarotero/gettext-translator](https://github.com/oscarotero/gettext-translator))
|
- It's not required to install the PHP gettext extension, on both, server and client, managed implementations of gettext are used ([oscarotero/Gettext](https://github.com/oscarotero/Gettext) & [oscarotero/gettext-translator](https://github.com/oscarotero/gettext-translator))
|
||||||
- Some other small fixes and improvements
|
- Some other small fixes and improvements
|
||||||
- The "Add as barcode to existing product" productpicker workflow failed to add the barcode to the given product
|
- The "Add as barcode to existing product" product picker workflow failed to add the barcode to the given product
|
||||||
- Recipes can now be filter by stock availability
|
- Recipes can now be filter by stock availability
|
||||||
- Added a feature flag (`config.php` setting) to also be able to hide all stock related UI elements and routes
|
- Added a feature flag (`config.php` setting) to also be able to hide all stock related UI elements and routes
|
||||||
|
@@ -64,7 +64,7 @@
|
|||||||
- Fixed the form validation on the shopping list item page (thanks @Forceu)
|
- Fixed the form validation on the shopping list item page (thanks @Forceu)
|
||||||
- Fixed that when adding products to the shopping list from the stock overview page, the used quantity unit was always the products default purchase QU (and not the selected one)
|
- Fixed that when adding products to the shopping list from the stock overview page, the used quantity unit was always the products default purchase QU (and not the selected one)
|
||||||
- Fixed that the displayed last unit/total price was wrong when the used quantity unit was not the products stock QU
|
- Fixed that the displayed last unit/total price was wrong when the used quantity unit was not the products stock QU
|
||||||
- Fixed that the "Add as barcode to existing product" productpicker workflow did not work
|
- Fixed that the "Add as barcode to existing product" product picker workflow did not work
|
||||||
|
|
||||||
### Recipe improvements/fixes
|
### Recipe improvements/fixes
|
||||||
- Recipe printing improvements (thanks @Ape)
|
- Recipe printing improvements (thanks @Ape)
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
- When adding (purchase) a product with "Default due days after freezing" set directly to a freezer location, the due date is now prefilled by that (instead of the normal "Default due days") (thanks @grahamc for the initial work on this)
|
- When adding (purchase) a product with "Default due days after freezing" set directly to a freezer location, the due date is now prefilled by that (instead of the normal "Default due days") (thanks @grahamc for the initial work on this)
|
||||||
- Chores can now be merged (new item in the context-/more-menu on the chores list page)
|
- Chores can now be merged (new item in the context-/more-menu on the chores list page)
|
||||||
- Fixed that "Label per unit" stock entry labels (on purchase) weren't unique per unit
|
- Fixed that "Label per unit" stock entry labels (on purchase) weren't unique per unit
|
||||||
- Fixed that the "Add as new product" productpicker workflow, started from the shopping list item form, always selected the default shopping list after finishing the flow
|
- Fixed that the "Add as new product" product picker workflow, started from the shopping list item form, always selected the default shopping list after finishing the flow
|
||||||
- Fixed that when undoing a product opened transaction and when the product has "Default due days after opened" set, the original due date wasn't restored
|
- Fixed that when undoing a product opened transaction and when the product has "Default due days after opened" set, the original due date wasn't restored
|
||||||
- Fixed that "Track date only"-chores were shown as overdue on the due day on the chores overview page
|
- Fixed that "Track date only"-chores were shown as overdue on the due day on the chores overview page
|
||||||
- Fixed that dropdown filters for tables maybe did not work after reordering columns
|
- Fixed that dropdown filters for tables maybe did not work after reordering columns
|
||||||
|
@@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
### Stock
|
### 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 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
|
- Fixed that the status filter "n products are overdue" on the stock overview page also counted/included stock entries due today or tomorrow
|
||||||
|
|
||||||
|
@@ -442,7 +442,6 @@ class StockApiController extends BaseApiController
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
$addFoundProduct = false;
|
$addFoundProduct = false;
|
||||||
|
|
||||||
if (isset($request->getQueryParams()['add']) && ($request->getQueryParams()['add'] === 'true' || $request->getQueryParams()['add'] === 1))
|
if (isset($request->getQueryParams()['add']) && ($request->getQueryParams()['add'] === 'true' || $request->getQueryParams()['add'] === 1))
|
||||||
{
|
{
|
||||||
$addFoundProduct = true;
|
$addFoundProduct = true;
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
use Grocy\Helpers\BaseBarcodeLookupPlugin;
|
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
|
class DemoBarcodeLookupPlugin extends BaseBarcodeLookupPlugin
|
||||||
{
|
{
|
||||||
@@ -14,8 +14,11 @@ class DemoBarcodeLookupPlugin extends BaseBarcodeLookupPlugin
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
To try it:
|
To try it:
|
||||||
|
|
||||||
Call the API function at /api/stock/barcodes/external-lookup/{barcode}
|
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,
|
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
|
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)
|
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)
|
protected function ExecuteLookup($barcode)
|
||||||
{
|
{
|
||||||
if ($barcode === 'x')
|
if ($barcode === 'nothing')
|
||||||
{ // Demonstration when nothing is found
|
{
|
||||||
|
// Demonstration when nothing is found
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
elseif ($barcode === 'e')
|
elseif ($barcode === 'error')
|
||||||
{ // Demonstration when an error occurred
|
{
|
||||||
|
// Demonstration when an error occurred
|
||||||
throw new \Exception('This is the error message from the plugin...');
|
throw new \Exception('This is the error message from the plugin...');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -29,7 +29,8 @@ abstract class BaseBarcodeLookupPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!IsAssociativeArray($pluginOutput))
|
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');
|
throw new \Exception('Plugin output must be an associative array');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +54,7 @@ abstract class BaseBarcodeLookupPlugin
|
|||||||
|
|
||||||
// $pluginOutput contains all needed properties here
|
// $pluginOutput contains all needed properties here
|
||||||
|
|
||||||
// Check referenced entity ids are valid
|
// Check if referenced entity ids are valid
|
||||||
$locationId = $pluginOutput['location_id'];
|
$locationId = $pluginOutput['location_id'];
|
||||||
if (FindObjectInArrayByPropertyValue($this->Locations, 'id', $locationId) === null)
|
if (FindObjectInArrayByPropertyValue($this->Locations, 'id', $locationId) === null)
|
||||||
{
|
{
|
||||||
|
@@ -2423,3 +2423,12 @@ msgid "This means 1 label will be printed"
|
|||||||
msgid_plural "This means %1$s labels will be printed"
|
msgid_plural "This means %1$s labels will be printed"
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
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 ""
|
||||||
|
@@ -249,6 +249,32 @@ $('#product_id_text_input').on('blur', function(e)
|
|||||||
Grocy.Components.ProductPicker.PopupOpen = false;
|
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);
|
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();
|
$('.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
|
else
|
||||||
|
@@ -1702,14 +1702,12 @@ class StockService extends BaseService
|
|||||||
private function LoadBarcodeLookupPlugin()
|
private function LoadBarcodeLookupPlugin()
|
||||||
{
|
{
|
||||||
$pluginName = defined('GROCY_STOCK_BARCODE_LOOKUP_PLUGIN') ? GROCY_STOCK_BARCODE_LOOKUP_PLUGIN : '';
|
$pluginName = defined('GROCY_STOCK_BARCODE_LOOKUP_PLUGIN') ? GROCY_STOCK_BARCODE_LOOKUP_PLUGIN : '';
|
||||||
|
|
||||||
if (empty($pluginName))
|
if (empty($pluginName))
|
||||||
{
|
{
|
||||||
throw new \Exception('No barcode lookup plugin defined');
|
throw new \Exception('No barcode lookup plugin defined');
|
||||||
}
|
}
|
||||||
|
|
||||||
$path = GROCY_DATAPATH . "/plugins/$pluginName.php";
|
$path = GROCY_DATAPATH . "/plugins/$pluginName.php";
|
||||||
|
|
||||||
if (file_exists($path))
|
if (file_exists($path))
|
||||||
{
|
{
|
||||||
require_once $path;
|
require_once $path;
|
||||||
|
Reference in New Issue
Block a user