From 2d2dbd2414eaf139e0f5d43486019d4cc9133288 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Tue, 12 Oct 2021 00:12:43 +0200 Subject: [PATCH 01/14] fixing paths --- docs/extend/plugins.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index 9a230c7..1e11e1d 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -6,7 +6,8 @@ title: Plugins The InvenTree server code supports an extensible plugin architecture, allowing custom plugins to be integrated directly into the database server. This allows development of complex behaviours which are decoupled from core InvenTree code. -InvenTree plugins are located in the directory `./InvenTree/plugins/`. +InvenTree builtin plugins are located in the directory `./InvenTree/plugin/builtin`. +Custom plugins should be placed in the directory `./InvenTree/plugins`. Plugins are discovered and loaded when the server is started. @@ -54,4 +55,4 @@ POST { } ``` -For an example of a very simple action plugin, refer to `/InvenTree/plugins/action/action.py` \ No newline at end of file +For an example of a very simple action plugin, refer to `/InvenTree/plugin/builtin/action/simpleactionplugin.py` \ No newline at end of file From f96418701622c797dcd23e97571b58d66b4ac2fd Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Tue, 12 Oct 2021 00:33:14 +0200 Subject: [PATCH 02/14] mixin structure --- docs/extend/plugins.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index 1e11e1d..a6547d7 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -55,4 +55,22 @@ POST { } ``` -For an example of a very simple action plugin, refer to `/InvenTree/plugin/builtin/action/simpleactionplugin.py` \ No newline at end of file +For an example of a very simple action plugin, refer to `/InvenTree/plugin/builtin/action/simpleactionplugin.py` + +### Integration Plugins + +Integration Plugins provide a wide area of deep integration into the interface of InvenTree. + +#### Mixins + +Common usecases are covered by pre-supplied modules in the form of Mixins (similar to how (https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/)[django] does it). + +##### SettingsMixin + +##### UrlsMixin + +##### NavigationMixin + +##### AppMixin + +For an example of a pretty much full Integration Plugin, refer to `/InvenTree/plugin/samples/integration/sample.py` \ No newline at end of file From 79611be2040ebd7c94cf5a6eb17ba9373742864a Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Tue, 19 Oct 2021 23:13:22 +0200 Subject: [PATCH 03/14] added mixin definitions --- docs/extend/plugins.md | 107 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 8 deletions(-) diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index a6547d7..5723e4b 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -6,7 +6,7 @@ title: Plugins The InvenTree server code supports an extensible plugin architecture, allowing custom plugins to be integrated directly into the database server. This allows development of complex behaviours which are decoupled from core InvenTree code. -InvenTree builtin plugins are located in the directory `./InvenTree/plugin/builtin`. +InvenTree built-in plugins are located in the directory `./InvenTree/plugin/builtin`. Custom plugins should be placed in the directory `./InvenTree/plugins`. Plugins are discovered and loaded when the server is started. @@ -26,7 +26,7 @@ InvenTree supports decoding of arbitrary barcode data via a **Barcode Plugin** i InvenTree can generate native QR codes to represent database objects (e.g. a single StockItem). This barcode can then be used to perform quick lookup of a stock item or location in the database. A client application (for example the InvenTree mobile app) scans a barcode, and sends the barcode data to the InvenTree server. The server then uses the **InvenTreeBarcodePlugin** (found at `/InvenTree/plugins/barcode/inventree.py`) to decode the supplied barcode data. -Any third-party barcodes can be decoded by writing a matching plugin to decode the barcode data. These plugins could then perform a server-side action, or render a JSON response back to the client for further action. +Any third-party barcodes can be decoded by writing a matching plugin to decode the barcode data. These plugins could then perform a server-side action or render a JSON response back to the client for further action. Some examples of possible uses for barcode integration: @@ -61,16 +61,107 @@ For an example of a very simple action plugin, refer to `/InvenTree/plugin/built Integration Plugins provide a wide area of deep integration into the interface of InvenTree. +For an example of a pretty much full Integration Plugin, refer to `/InvenTree/plugin/samples/integration/sample.py` + +#### Plugin Options + +Some metadata options can be defined as constants in the plugins class. + +python +``` +PLUGIN_SLUG = None # Used in URLs, setting-names etc. when a unique slug as a reference is needed -> the plugin name is used if not set +PLUGIN_TITLE = None # A nice human friendly name for the plugin -> used in titles, as plugin name etc. + +AUTHOR = None # Author of the plugin, git commit information is used if not present +PUBLISH_DATE = None # Publishing date of the plugin, git commit information is used if not present +VERSION = None # Version of the plugin +WEBSITE = None # Website for the plugin, developer etc. -> is shown in plugin overview if set +``` + + #### Mixins -Common usecases are covered by pre-supplied modules in the form of Mixins (similar to how (https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/)[django] does it). +Common use cases are covered by pre-supplied modules in the form of mixins (similar to how (https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/)[django] does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. -##### SettingsMixin +##### Basic Mixin Functions -##### UrlsMixin +All mixins are registered with the plugin on start-up so you can access all added mixins as a dict with the `plugin.registered_mixins` property that is added to each plugin. -##### NavigationMixin +The function `plugin.mixin_enabled(key)` returns if a mixin is present in a plugin and configured correctly. -##### AppMixin +##### Initialisation -For an example of a pretty much full Integration Plugin, refer to `/InvenTree/plugin/samples/integration/sample.py` \ No newline at end of file +Each mixin must call `super().__init__()` in it's `__init__` function and register itself with a call to `self.add_mixin()`. Check out the built-in mixins for examples. + +python +``` +def __init__(self): + super().__init__() + self.add_mixin('settings', 'has_settings', __class__) +``` + +##### Meta Options + +Each mixin can define additional options as a Meta subclass. These are used to describe the mixin. + + +#### SettingsMixin + +Use the class constant `SETTINGS` for a dict of settings that should be added as global database settings. +The dict must be formatted similar to the following sample. Take a look at the settings defined in `InvenTree.common.models.InvenTreeSetting` for all possible parameters. + + +``` +SETTINGS = { + 'PO_FUNCTION_ENABLE': { + 'name': _('Enable PO'), + 'description': _('Enable PO functionality in InvenTree interface'), + 'default': True, + 'validator': bool, + }, +} +``` + +!!! note "Use carefully" + All global and user settings are exposed to the frontend code and can be read out via the browsers developer tools. You can protect a setting from export by adding `'protected': True` to sensitive settings. + You can access settings in frontend JS code under the global variable `global_settings`. + +This mixin defines the helper functions `plugin.get_setting` and `plugin.set_seting` to access all plugin specific settings. + + +#### UrlsMixin + +Use the class constant `URLS` for a array of URLs that should be added to InvenTrees URL paths or override the `plugin.setup_urls` function. +The array has to contain valid URL patterns as defined in the (https://docs.djangoproject.com/en/3.2/topics/http/urls/)[django documentation]. + +python +``` +URLS = [ + url(r'increase/(?P\d+)/(?P\d+)/', self.view_increase, name='increase-level'), +] +``` + +The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the (https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#url)[url tag]). + + +#### NavigationMixin + +Use the class constant `NAVIGATION` for a array of links that should be added to InvenTrees navigation header. +The array must contain at least one dict that at least define a name and a link for each element. The link must be formatted for a URL pattern name lookup - links to external sites are not possible directly. The optional icon must be a class reference to an icon (InvenTree ships with fontawesome 4 by default). + +python +``` +NAVIGATION = [ + {'name': 'SampleIntegration', 'link': 'plugin:sample:hi', 'icon': 'fas fa-box'}, +] +``` + +The optional class constants `NAVIGATION_TAB_NAME` and `NAVIGATION_TAB_ICON` can be used to change the name and icon for the parent navigation node. + + +#### AppMixin + +If this mixin is added to a plugin the directory the plugin class is defined in is added to InvenTrees `INSTALLED_APPS`. + +!!! warning "Danger Zone" + Only use this plugin if you have an understanding of djangos (https://docs.djangoproject.com/en/3.2/ref/applications/)[app system]. Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree. From 42282d956f056c5cbf87a5ede23d5acd7dd46395 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Tue, 19 Oct 2021 23:17:31 +0200 Subject: [PATCH 04/14] fix links --- docs/extend/plugins.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index 5723e4b..ff7e606 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -81,7 +81,7 @@ WEBSITE = None # Website for the plugin, developer etc. -> is shown in plugin o #### Mixins -Common use cases are covered by pre-supplied modules in the form of mixins (similar to how (https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/)[django] does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. +Common use cases are covered by pre-supplied modules in the form of mixins (similar to how [https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/](django) does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. ##### Basic Mixin Functions @@ -132,7 +132,7 @@ This mixin defines the helper functions `plugin.get_setting` and `plugin.set_set #### UrlsMixin Use the class constant `URLS` for a array of URLs that should be added to InvenTrees URL paths or override the `plugin.setup_urls` function. -The array has to contain valid URL patterns as defined in the (https://docs.djangoproject.com/en/3.2/topics/http/urls/)[django documentation]. +The array has to contain valid URL patterns as defined in the [https://docs.djangoproject.com/en/3.2/topics/http/urls/](django documentation). python ``` @@ -141,7 +141,7 @@ URLS = [ ] ``` -The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the (https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#url)[url tag]). +The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the [https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#url](url tag)). #### NavigationMixin @@ -164,4 +164,4 @@ The optional class constants `NAVIGATION_TAB_NAME` and `NAVIGATION_TAB_ICON` can If this mixin is added to a plugin the directory the plugin class is defined in is added to InvenTrees `INSTALLED_APPS`. !!! warning "Danger Zone" - Only use this plugin if you have an understanding of djangos (https://docs.djangoproject.com/en/3.2/ref/applications/)[app system]. Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree. + Only use this plugin if you have an understanding of djangos [https://docs.djangoproject.com/en/3.2/ref/applications/](app system). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree. From 9e027eaf941c70fe8532c4acf5dcf6e4cd66695e Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Tue, 19 Oct 2021 23:19:57 +0200 Subject: [PATCH 05/14] fix code blocks --- docs/extend/plugins.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index ff7e606..5251694 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -67,8 +67,7 @@ For an example of a pretty much full Integration Plugin, refer to `/InvenTree/pl Some metadata options can be defined as constants in the plugins class. -python -``` +``` python PLUGIN_SLUG = None # Used in URLs, setting-names etc. when a unique slug as a reference is needed -> the plugin name is used if not set PLUGIN_TITLE = None # A nice human friendly name for the plugin -> used in titles, as plugin name etc. @@ -93,8 +92,7 @@ The function `plugin.mixin_enabled(key)` returns if a mixin is present in a plug Each mixin must call `super().__init__()` in it's `__init__` function and register itself with a call to `self.add_mixin()`. Check out the built-in mixins for examples. -python -``` +``` python def __init__(self): super().__init__() self.add_mixin('settings', 'has_settings', __class__) @@ -111,7 +109,7 @@ Use the class constant `SETTINGS` for a dict of settings that should be added as The dict must be formatted similar to the following sample. Take a look at the settings defined in `InvenTree.common.models.InvenTreeSetting` for all possible parameters. -``` +``` python SETTINGS = { 'PO_FUNCTION_ENABLE': { 'name': _('Enable PO'), @@ -134,8 +132,7 @@ This mixin defines the helper functions `plugin.get_setting` and `plugin.set_set Use the class constant `URLS` for a array of URLs that should be added to InvenTrees URL paths or override the `plugin.setup_urls` function. The array has to contain valid URL patterns as defined in the [https://docs.djangoproject.com/en/3.2/topics/http/urls/](django documentation). -python -``` +``` python URLS = [ url(r'increase/(?P\d+)/(?P\d+)/', self.view_increase, name='increase-level'), ] @@ -149,8 +146,7 @@ The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the temp Use the class constant `NAVIGATION` for a array of links that should be added to InvenTrees navigation header. The array must contain at least one dict that at least define a name and a link for each element. The link must be formatted for a URL pattern name lookup - links to external sites are not possible directly. The optional icon must be a class reference to an icon (InvenTree ships with fontawesome 4 by default). -python -``` +``` python NAVIGATION = [ {'name': 'SampleIntegration', 'link': 'plugin:sample:hi', 'icon': 'fas fa-box'}, ] From 8112c7216d8e65a8cd7d488677a0c0de795c7e20 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Tue, 19 Oct 2021 23:26:52 +0200 Subject: [PATCH 06/14] added new to docs setting --- docs/settings/global.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/docs/settings/global.md b/docs/settings/global.md index 1b39a24..2fc95da 100644 --- a/docs/settings/global.md +++ b/docs/settings/global.md @@ -67,4 +67,15 @@ Options for purchase orders ### Sales orders -Options for sales orders \ No newline at end of file +Options for sales orders + +### Plugin Settings + +Change into what parts plugins can integrate into. + +| Setting | Type | Description | Default | +| --- | --- | --- | --- | +| Enable URL integration | Boolean | Enable plugins to add URL routes | False | +| Enable navigation integration | Boolean | Enable plugins to integrate into navigation | False | +| Enable setting integration | Boolean | Enable plugins to integrate into inventree settings | False | +| Enable app integration | Boolean | Enable plugins to add apps | False | \ No newline at end of file From dc71db8ba9c1980557d64f1a9263c70b3b3b568d Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Wed, 3 Nov 2021 22:46:17 +0100 Subject: [PATCH 07/14] more info about loading --- docs/extend/plugins.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index 5251694..ff6dbb9 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -78,6 +78,13 @@ WEBSITE = None # Website for the plugin, developer etc. -> is shown in plugin o ``` + +#### Installing a Plugin + +Plugins can either be loaded from paths in the InvenTree install directory or as a plugin installed via pip. We recommend installation via pip as this enables hassle-free upgrades. + +For development new plugins can be placed ina a subdirectroy in `src/InvenTree/plugins`. Built-In plugins ship in `src/InvenTree/plugin/builtin`. To achive full unit-testing for all mixins there are some sample implementations in `src/InvenTree/plugin/samples`. These are not loaded in production mode. + #### Mixins Common use cases are covered by pre-supplied modules in the form of mixins (similar to how [https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/](django) does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. From 09f0c85b76677a1118c79ee2f39e87c28122b301 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Thu, 11 Nov 2021 11:32:03 +0100 Subject: [PATCH 08/14] fix links --- docs/extend/plugins.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index ff6dbb9..9f52827 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -87,7 +87,7 @@ For development new plugins can be placed ina a subdirectroy in `src/InvenTree/p #### Mixins -Common use cases are covered by pre-supplied modules in the form of mixins (similar to how [https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/](django) does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. +Common use cases are covered by pre-supplied modules in the form of mixins (similar to how [django](https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/) does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. ##### Basic Mixin Functions @@ -137,7 +137,7 @@ This mixin defines the helper functions `plugin.get_setting` and `plugin.set_set #### UrlsMixin Use the class constant `URLS` for a array of URLs that should be added to InvenTrees URL paths or override the `plugin.setup_urls` function. -The array has to contain valid URL patterns as defined in the [https://docs.djangoproject.com/en/3.2/topics/http/urls/](django documentation). +The array has to contain valid URL patterns as defined in the [django documentation](https://docs.djangoproject.com/en/3.2/topics/http/urls/). ``` python URLS = [ @@ -145,7 +145,7 @@ URLS = [ ] ``` -The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the [https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#url](url tag)). +The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the [url tag](https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#url)). #### NavigationMixin @@ -167,4 +167,4 @@ The optional class constants `NAVIGATION_TAB_NAME` and `NAVIGATION_TAB_ICON` can If this mixin is added to a plugin the directory the plugin class is defined in is added to InvenTrees `INSTALLED_APPS`. !!! warning "Danger Zone" - Only use this plugin if you have an understanding of djangos [https://docs.djangoproject.com/en/3.2/ref/applications/](app system). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree. + Only use this plugin if you have an understanding of djangos [app system](https://docs.djangoproject.com/en/3.2/ref/applications). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree. From cb0943494cbab212440eb90e3778afd4777f2d0a Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Wed, 29 Dec 2021 18:17:22 +0100 Subject: [PATCH 09/14] move plugins into directories --- docs/extend/plugins/action.md | 18 +++++ docs/extend/plugins/barcode.md | 25 +++++++ docs/extend/plugins/integration.md | 115 +++++++++++++++++++++++++++++ docs/extend/plugins/report.md | 10 +++ mkdocs.yml | 7 +- 5 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 docs/extend/plugins/action.md create mode 100644 docs/extend/plugins/barcode.md create mode 100644 docs/extend/plugins/integration.md create mode 100644 docs/extend/plugins/report.md diff --git a/docs/extend/plugins/action.md b/docs/extend/plugins/action.md new file mode 100644 index 0000000..94c2feb --- /dev/null +++ b/docs/extend/plugins/action.md @@ -0,0 +1,18 @@ +--- +title: Action Plugins +--- + +### Action Plugins + +Arbitrary "actions" can be called by POSTing data to the `/api/action/` endpoint. The POST request must include the name of the action to be performed, and a matching ActionPlugin plugin must be loaded by the server. Arbitrary data can also be provided to the action plugin via the POST data: + +``` +POST { + action: "MyCustomAction", + data: { + foo: "bar", + } +} +``` + +For an example of a very simple action plugin, refer to `/InvenTree/plugin/builtin/action/simpleactionplugin.py` diff --git a/docs/extend/plugins/barcode.md b/docs/extend/plugins/barcode.md new file mode 100644 index 0000000..c5d188d --- /dev/null +++ b/docs/extend/plugins/barcode.md @@ -0,0 +1,25 @@ +--- +title: Barcode Plugins +--- + +### Barcode Plugins + +InvenTree supports decoding of arbitrary barcode data via a **Barcode Plugin** interface. Barcode data POSTed to the `/api/barcode/` endpoint will be supplied to all loaded barcode plugins, and the first plugin to successfully interpret the barcode data will return a response to the client. + +InvenTree can generate native QR codes to represent database objects (e.g. a single StockItem). This barcode can then be used to perform quick lookup of a stock item or location in the database. A client application (for example the InvenTree mobile app) scans a barcode, and sends the barcode data to the InvenTree server. The server then uses the **InvenTreeBarcodePlugin** (found at `/InvenTree/plugins/barcode/inventree.py`) to decode the supplied barcode data. + +Any third-party barcodes can be decoded by writing a matching plugin to decode the barcode data. These plugins could then perform a server-side action or render a JSON response back to the client for further action. + +Some examples of possible uses for barcode integration: + +- Stock lookup by scanning a barcode on a box of items +- Receiving goods against a PurchaseOrder by scanning a supplier barcode +- Perform a stock adjustment action (e.g. take 10 parts from stock whenever a barcode is scanned) + +Barcode data are POSTed to the server as follows: + +``` +POST { + barcode_data: "[(>someBarcodeDataWhichThePluginKnowsHowToDealWith" +} +``` diff --git a/docs/extend/plugins/integration.md b/docs/extend/plugins/integration.md new file mode 100644 index 0000000..6a96788 --- /dev/null +++ b/docs/extend/plugins/integration.md @@ -0,0 +1,115 @@ +--- +title: Integration Plugins +--- + +### Integration Plugins + +Integration Plugins provide a wide area of deep integration into the interface of InvenTree. + +For an example of a pretty much full Integration Plugin, refer to `/InvenTree/plugin/samples/integration/sample.py` + +#### Plugin Options + +Some metadata options can be defined as constants in the plugins class. + +``` python +PLUGIN_SLUG = None # Used in URLs, setting-names etc. when a unique slug as a reference is needed -> the plugin name is used if not set +PLUGIN_TITLE = None # A nice human friendly name for the plugin -> used in titles, as plugin name etc. + +AUTHOR = None # Author of the plugin, git commit information is used if not present +PUBLISH_DATE = None # Publishing date of the plugin, git commit information is used if not present +VERSION = None # Version of the plugin +WEBSITE = None # Website for the plugin, developer etc. -> is shown in plugin overview if set +``` + + + +#### Installing a Plugin + +Plugins can either be loaded from paths in the InvenTree install directory or as a plugin installed via pip. We recommend installation via pip as this enables hassle-free upgrades. + +For development new plugins can be placed ina a subdirectroy in `src/InvenTree/plugins`. Built-In plugins ship in `src/InvenTree/plugin/builtin`. To achive full unit-testing for all mixins there are some sample implementations in `src/InvenTree/plugin/samples`. These are not loaded in production mode. + +#### Mixins + +Common use cases are covered by pre-supplied modules in the form of mixins (similar to how [django](https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/) does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. + +##### Basic Mixin Functions + +All mixins are registered with the plugin on start-up so you can access all added mixins as a dict with the `plugin.registered_mixins` property that is added to each plugin. + +The function `plugin.mixin_enabled(key)` returns if a mixin is present in a plugin and configured correctly. + +##### Initialisation + +Each mixin must call `super().__init__()` in it's `__init__` function and register itself with a call to `self.add_mixin()`. Check out the built-in mixins for examples. + +``` python +def __init__(self): + super().__init__() + self.add_mixin('settings', 'has_settings', __class__) +``` + +##### Meta Options + +Each mixin can define additional options as a Meta subclass. These are used to describe the mixin. + + +#### SettingsMixin + +Use the class constant `SETTINGS` for a dict of settings that should be added as global database settings. +The dict must be formatted similar to the following sample. Take a look at the settings defined in `InvenTree.common.models.InvenTreeSetting` for all possible parameters. + + +``` python +SETTINGS = { + 'PO_FUNCTION_ENABLE': { + 'name': _('Enable PO'), + 'description': _('Enable PO functionality in InvenTree interface'), + 'default': True, + 'validator': bool, + }, +} +``` + +!!! note "Use carefully" + All global and user settings are exposed to the frontend code and can be read out via the browsers developer tools. You can protect a setting from export by adding `'protected': True` to sensitive settings. + You can access settings in frontend JS code under the global variable `global_settings`. + +This mixin defines the helper functions `plugin.get_setting` and `plugin.set_seting` to access all plugin specific settings. + + +#### UrlsMixin + +Use the class constant `URLS` for a array of URLs that should be added to InvenTrees URL paths or override the `plugin.setup_urls` function. +The array has to contain valid URL patterns as defined in the [django documentation](https://docs.djangoproject.com/en/3.2/topics/http/urls/). + +``` python +URLS = [ + url(r'increase/(?P\d+)/(?P\d+)/', self.view_increase, name='increase-level'), +] +``` + +The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the [url tag](https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#url)). + + +#### NavigationMixin + +Use the class constant `NAVIGATION` for a array of links that should be added to InvenTrees navigation header. +The array must contain at least one dict that at least define a name and a link for each element. The link must be formatted for a URL pattern name lookup - links to external sites are not possible directly. The optional icon must be a class reference to an icon (InvenTree ships with fontawesome 4 by default). + +``` python +NAVIGATION = [ + {'name': 'SampleIntegration', 'link': 'plugin:sample:hi', 'icon': 'fas fa-box'}, +] +``` + +The optional class constants `NAVIGATION_TAB_NAME` and `NAVIGATION_TAB_ICON` can be used to change the name and icon for the parent navigation node. + + +#### AppMixin + +If this mixin is added to a plugin the directory the plugin class is defined in is added to InvenTrees `INSTALLED_APPS`. + +!!! warning "Danger Zone" + Only use this plugin if you have an understanding of djangos [app system](https://docs.djangoproject.com/en/3.2/ref/applications). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree. diff --git a/docs/extend/plugins/report.md b/docs/extend/plugins/report.md new file mode 100644 index 0000000..d4b4f89 --- /dev/null +++ b/docs/extend/plugins/report.md @@ -0,0 +1,10 @@ +--- +title: Reporting Plugins +--- + +### Reporting Plugins + +InvenTree can generate customized reports (for example stocktake information, packing lists, acceptance test reports, etc). + +!!! missing "TODO" + Include more information here on reporting plugins diff --git a/mkdocs.yml b/mkdocs.yml index 53fe68f..3efed27 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -110,7 +110,12 @@ nav: - Extend: - API: extend/api.md - Python Interface: extend/python.md - - Plugins: extend/plugins.md + - Plugins: + - Overview: extend/plugins.md + - Reporting: extend/plugins/report.md + - Barcode: extend/plugins/barcode.md + - Action: extend/plugins/action.md + - Integration: extend/plugins/integration.md - Themes: extend/themes.md - Third-Party: extend/integrate.md - App: From f686c3f00c3d83f99e265c8cef7dff011bbe34c9 Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Wed, 29 Dec 2021 18:24:01 +0100 Subject: [PATCH 10/14] add links to plugin overview --- docs/extend/plugins.md | 160 ++--------------------------------------- 1 file changed, 4 insertions(+), 156 deletions(-) diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index 9f52827..3c661b6 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -12,159 +12,7 @@ Custom plugins should be placed in the directory `./InvenTree/plugins`. Plugins are discovered and loaded when the server is started. Multiple plugins are supported: - -### Reporting Plugins - -InvenTree can generate customized reports (for example stocktake information, packing lists, acceptance test reports, etc). - -!!! missing "TODO" - Include more information here on reporting plugins - -### Barcode Plugins - -InvenTree supports decoding of arbitrary barcode data via a **Barcode Plugin** interface. Barcode data POSTed to the `/api/barcode/` endpoint will be supplied to all loaded barcode plugins, and the first plugin to successfully interpret the barcode data will return a response to the client. - -InvenTree can generate native QR codes to represent database objects (e.g. a single StockItem). This barcode can then be used to perform quick lookup of a stock item or location in the database. A client application (for example the InvenTree mobile app) scans a barcode, and sends the barcode data to the InvenTree server. The server then uses the **InvenTreeBarcodePlugin** (found at `/InvenTree/plugins/barcode/inventree.py`) to decode the supplied barcode data. - -Any third-party barcodes can be decoded by writing a matching plugin to decode the barcode data. These plugins could then perform a server-side action or render a JSON response back to the client for further action. - -Some examples of possible uses for barcode integration: - -- Stock lookup by scanning a barcode on a box of items -- Receiving goods against a PurchaseOrder by scanning a supplier barcode -- Perform a stock adjustment action (e.g. take 10 parts from stock whenever a barcode is scanned) - -Barcode data are POSTed to the server as follows: - -``` -POST { - barcode_data: "[(>someBarcodeDataWhichThePluginKnowsHowToDealWith" -} -``` - -### Action Plugins - -Arbitrary "actions" can be called by POSTing data to the `/api/action/` endpoint. The POST request must include the name of the action to be performed, and a matching ActionPlugin plugin must be loaded by the server. Arbitrary data can also be provided to the action plugin via the POST data: - -``` -POST { - action: "MyCustomAction", - data: { - foo: "bar", - } -} -``` - -For an example of a very simple action plugin, refer to `/InvenTree/plugin/builtin/action/simpleactionplugin.py` - -### Integration Plugins - -Integration Plugins provide a wide area of deep integration into the interface of InvenTree. - -For an example of a pretty much full Integration Plugin, refer to `/InvenTree/plugin/samples/integration/sample.py` - -#### Plugin Options - -Some metadata options can be defined as constants in the plugins class. - -``` python -PLUGIN_SLUG = None # Used in URLs, setting-names etc. when a unique slug as a reference is needed -> the plugin name is used if not set -PLUGIN_TITLE = None # A nice human friendly name for the plugin -> used in titles, as plugin name etc. - -AUTHOR = None # Author of the plugin, git commit information is used if not present -PUBLISH_DATE = None # Publishing date of the plugin, git commit information is used if not present -VERSION = None # Version of the plugin -WEBSITE = None # Website for the plugin, developer etc. -> is shown in plugin overview if set -``` - - - -#### Installing a Plugin - -Plugins can either be loaded from paths in the InvenTree install directory or as a plugin installed via pip. We recommend installation via pip as this enables hassle-free upgrades. - -For development new plugins can be placed ina a subdirectroy in `src/InvenTree/plugins`. Built-In plugins ship in `src/InvenTree/plugin/builtin`. To achive full unit-testing for all mixins there are some sample implementations in `src/InvenTree/plugin/samples`. These are not loaded in production mode. - -#### Mixins - -Common use cases are covered by pre-supplied modules in the form of mixins (similar to how [django](https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/) does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. - -##### Basic Mixin Functions - -All mixins are registered with the plugin on start-up so you can access all added mixins as a dict with the `plugin.registered_mixins` property that is added to each plugin. - -The function `plugin.mixin_enabled(key)` returns if a mixin is present in a plugin and configured correctly. - -##### Initialisation - -Each mixin must call `super().__init__()` in it's `__init__` function and register itself with a call to `self.add_mixin()`. Check out the built-in mixins for examples. - -``` python -def __init__(self): - super().__init__() - self.add_mixin('settings', 'has_settings', __class__) -``` - -##### Meta Options - -Each mixin can define additional options as a Meta subclass. These are used to describe the mixin. - - -#### SettingsMixin - -Use the class constant `SETTINGS` for a dict of settings that should be added as global database settings. -The dict must be formatted similar to the following sample. Take a look at the settings defined in `InvenTree.common.models.InvenTreeSetting` for all possible parameters. - - -``` python -SETTINGS = { - 'PO_FUNCTION_ENABLE': { - 'name': _('Enable PO'), - 'description': _('Enable PO functionality in InvenTree interface'), - 'default': True, - 'validator': bool, - }, -} -``` - -!!! note "Use carefully" - All global and user settings are exposed to the frontend code and can be read out via the browsers developer tools. You can protect a setting from export by adding `'protected': True` to sensitive settings. - You can access settings in frontend JS code under the global variable `global_settings`. - -This mixin defines the helper functions `plugin.get_setting` and `plugin.set_seting` to access all plugin specific settings. - - -#### UrlsMixin - -Use the class constant `URLS` for a array of URLs that should be added to InvenTrees URL paths or override the `plugin.setup_urls` function. -The array has to contain valid URL patterns as defined in the [django documentation](https://docs.djangoproject.com/en/3.2/topics/http/urls/). - -``` python -URLS = [ - url(r'increase/(?P\d+)/(?P\d+)/', self.view_increase, name='increase-level'), -] -``` - -The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the [url tag](https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#url)). - - -#### NavigationMixin - -Use the class constant `NAVIGATION` for a array of links that should be added to InvenTrees navigation header. -The array must contain at least one dict that at least define a name and a link for each element. The link must be formatted for a URL pattern name lookup - links to external sites are not possible directly. The optional icon must be a class reference to an icon (InvenTree ships with fontawesome 4 by default). - -``` python -NAVIGATION = [ - {'name': 'SampleIntegration', 'link': 'plugin:sample:hi', 'icon': 'fas fa-box'}, -] -``` - -The optional class constants `NAVIGATION_TAB_NAME` and `NAVIGATION_TAB_ICON` can be used to change the name and icon for the parent navigation node. - - -#### AppMixin - -If this mixin is added to a plugin the directory the plugin class is defined in is added to InvenTrees `INSTALLED_APPS`. - -!!! warning "Danger Zone" - Only use this plugin if you have an understanding of djangos [app system](https://docs.djangoproject.com/en/3.2/ref/applications). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree. +* [Reporting plugins](./plugins/report.md) +* [Barcode plugins](./plugins/barcode.md) +* [Action plugins](./plugins/action.md) +* [Integration plugins](./plugins/integration.md) From 5ee8c4d282972219f124d56fffe2be56b54bf38b Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Wed, 29 Dec 2021 18:33:58 +0100 Subject: [PATCH 11/14] use stable as a link target --- docs/extend/plugins/integration.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/extend/plugins/integration.md b/docs/extend/plugins/integration.md index 6a96788..b0d9aec 100644 --- a/docs/extend/plugins/integration.md +++ b/docs/extend/plugins/integration.md @@ -32,7 +32,7 @@ For development new plugins can be placed ina a subdirectroy in `src/InvenTree/p #### Mixins -Common use cases are covered by pre-supplied modules in the form of mixins (similar to how [django](https://docs.djangoproject.com/en/3.2/topics/class-based-views/mixins/) does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. +Common use cases are covered by pre-supplied modules in the form of mixins (similar to how [django](https://docs.djangoproject.com/en/stable/topics/class-based-views/mixins/) does it). Each mixin enables the integration into a specific area of InvenTree. Sometimes it also enhances the plugin with helper functions to supply often used functions out-of-the-box. ##### Basic Mixin Functions @@ -82,7 +82,7 @@ This mixin defines the helper functions `plugin.get_setting` and `plugin.set_set #### UrlsMixin Use the class constant `URLS` for a array of URLs that should be added to InvenTrees URL paths or override the `plugin.setup_urls` function. -The array has to contain valid URL patterns as defined in the [django documentation](https://docs.djangoproject.com/en/3.2/topics/http/urls/). +The array has to contain valid URL patterns as defined in the [django documentation](https://docs.djangoproject.com/en/stable/topics/http/urls/). ``` python URLS = [ @@ -90,7 +90,7 @@ URLS = [ ] ``` -The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the [url tag](https://docs.djangoproject.com/en/3.2/ref/templates/builtins/#url)). +The URLs get exposed under `/plugin/{plugin.slug}/*` and get exposed to the template engine with the prefix `plugin:{plugin.slug}:` (for usage with the [url tag](https://docs.djangoproject.com/en/stable/ref/templates/builtins/#url)). #### NavigationMixin @@ -112,4 +112,4 @@ The optional class constants `NAVIGATION_TAB_NAME` and `NAVIGATION_TAB_ICON` can If this mixin is added to a plugin the directory the plugin class is defined in is added to InvenTrees `INSTALLED_APPS`. !!! warning "Danger Zone" - Only use this plugin if you have an understanding of djangos [app system](https://docs.djangoproject.com/en/3.2/ref/applications). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree. + Only use this plugin if you have an understanding of djangos [app system](https://docs.djangoproject.com/en/stable/ref/applications). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree. From f829dd5d11c115387ff330f9c1761df17545fc8c Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Wed, 29 Dec 2021 18:35:27 +0100 Subject: [PATCH 12/14] fix warning text --- docs/extend/plugins/integration.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/extend/plugins/integration.md b/docs/extend/plugins/integration.md index b0d9aec..fb109d8 100644 --- a/docs/extend/plugins/integration.md +++ b/docs/extend/plugins/integration.md @@ -112,4 +112,4 @@ The optional class constants `NAVIGATION_TAB_NAME` and `NAVIGATION_TAB_ICON` can If this mixin is added to a plugin the directory the plugin class is defined in is added to InvenTrees `INSTALLED_APPS`. !!! warning "Danger Zone" - Only use this plugin if you have an understanding of djangos [app system](https://docs.djangoproject.com/en/stable/ref/applications). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree. + Only use this mixin if you have an understanding of djangos [app system](https://docs.djangoproject.com/en/stable/ref/applications). Plugins with this mixin are deeply integrated into InvenTree and can cause difficult to reproduce or long-running errors. Use the built-in testing functions of django to make sure your code does not cause unwanted behaviour in InvenTree before releasing. From 72ba2483bb7bc5cbba22b33a5aeceee17099ce1d Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Thu, 30 Dec 2021 01:24:27 +0100 Subject: [PATCH 13/14] fix list formatting --- docs/extend/plugins.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index 3c661b6..da1b86d 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -12,6 +12,7 @@ Custom plugins should be placed in the directory `./InvenTree/plugins`. Plugins are discovered and loaded when the server is started. Multiple plugins are supported: + * [Reporting plugins](./plugins/report.md) * [Barcode plugins](./plugins/barcode.md) * [Action plugins](./plugins/action.md) From e943207397e0de6428428df9409a80c9c09d08ec Mon Sep 17 00:00:00 2001 From: Matthias Mair Date: Thu, 30 Dec 2021 01:27:15 +0100 Subject: [PATCH 14/14] maybe this works? --- docs/extend/plugins.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/extend/plugins.md b/docs/extend/plugins.md index da1b86d..63588be 100644 --- a/docs/extend/plugins.md +++ b/docs/extend/plugins.md @@ -13,7 +13,7 @@ Plugins are discovered and loaded when the server is started. Multiple plugins are supported: -* [Reporting plugins](./plugins/report.md) -* [Barcode plugins](./plugins/barcode.md) -* [Action plugins](./plugins/action.md) -* [Integration plugins](./plugins/integration.md) +- [Reporting plugins](./plugins/report.md) +- [Barcode plugins](./plugins/barcode.md) +- [Action plugins](./plugins/action.md) +- [Integration plugins](./plugins/integration.md)