Repository: inventree/InvenTree

Issue:
Plugin UrlsMixin Issue referencing urls / django.urls.exceptions.NoReverseMatch : not a registered namespace inside 'plugin'
### Please verify that this bug has NOT been raised before.

- [X] I checked and didn't find similar issue

### Describe the bug*

I've update my test/dev inventree instance, and I've got urls referecing issues.

The update leads to :

> InvenTree Version 	[0.9.0 dev](https://github.com/inventree/InvenTree/releases)
> Development Version
> Commit Hash	2f7be7028
> Commit Date	12/12/2022

ran invoke updates.

My composite plugin `PanelMixin/UrlsMixin`throw an error when trying to access/reverse urls in `get_custom_panels ` previously defined in `setup_urls`.
(see stack trace below and plugin code at [StockTrackPanel](https://github.com/Bbillyben/StockTrackPanel_plugin/blob/main/StockTrackPanel.py) )


As Element of debugging : 

the method `setup_urls` is called during server start, and paths seems well formed.
the property `urlpatterns` is not called at all. 

When I print in `plugin.urls.get_plugin_urls ` the plugins referenced in `registry.plugins.values`:
```
def get_plugin_urls():
    """Returns a urlpattern that can be integrated into the global urls."""
    urls = []
    print("get_plugin_urls")
    for plugin in registry.plugins.values():
        print("####### :"+str(plugin.slug))
        if plugin.mixin_enabled('urls'):
            print(      "urls :"+str(plugin.urlpatterns))
            urls.append(plugin.urlpatterns)

    return re_path(f'^{PLUGIN_BASE}/', include((urls, 'plugin')))
```
I only trace `builtin` plugins:

> get_plugin_urls
> ####### :inventreebarcode
> ####### :corenotificationsplugin


and after that, is called the `setup_urls` from my plugin without any error (not in the loop in `get_plugin_urls`, somewhere else, but I do not know where...)

**Strange behavior** : If I activate the `SampleIntegrationPlugin` It works again!!!!!
and the output from `get_plugin_urls `become:

```
get_plugin_urls
####### :inventreebarcode
####### :corenotificationsplugin
####### :sample
urls :<URLResolver <URLPattern list> (sample:sample) '^sample/'>
####### :stocktrack
[StockTrackPanel]-urlpatterns
urls :<URLResolver <URLPattern list> (stocktrack:stocktrack) '^stocktrack/'>
```
And urls are well referenced !!

I'm trying to search in plugin.registry as I can spot some recent commits for it.

If I comment all about urls in the code (path and elements for panel tempalte context), all works without error.

It works on my 'semi-prod' version : 
> InvenTree-Version: 0.9.0 dev
> Django Version: 3.2.15
> Commit Hash: fbc9925
> Commit Date: 07/10/2022




### Steps to Reproduce

Don't really know. I haven't tried with simple URLsmixin.

### Expected behavior

reference the url as it did before.

### Deployment Method

- [X] Docker
- [ ] Bare metal

### Version Information

# Version Information:
InvenTree-Version: 0.9.0 dev
Django Version: 3.2.16
Commit Hash: 2f7be7028
Commit Date: 12/12/2022
Database: postgresql
Debug-Mode: True
Deployed using Docker: True
Active plugins: [{'name': 'CoreNotificationsPlugin', 'slug': 'corenotificationsplugin', 'version': '1.0.0'}, {'name': 'StockTrackPanel', 'slug': 'stocktrack', 'version': '0.1'}]



### Relevant log output

```shell
File "/home/inventree/data/env/lib/python3.9/site-packages/django/urls/base.py", line 71, in reverse
extra, resolver = resolver.namespace_dict[ns]
KeyError: 'stocktrack'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/inventree/InvenTree/plugin/views.py", line 26, in get_plugin_panels
panels += plug.render_panels(self, self.request, ctx)
File "/home/inventree/InvenTree/plugin/base/integration/mixins.py", line 704, in render_panels
for panel in self.get_custom_panels(view, request):
File "/home/inventree/InvenTree/plugins/StockTrackPanel_plugin/StockTrackPanel.py", line 55, in get_custom_panels
urlTrac=reverse('plugin:stocktrack:track-list')
File "/home/inventree/data/env/lib/python3.9/site-packages/django/urls/base.py", line 77, in reverse
raise NoReverseMatch(
django.urls.exceptions.NoReverseMatch: 'stocktrack' is not a registered namespace inside 'plugin'
```
```



Discussion:

Resolving patch:
diff --git a/InvenTree/plugin/registry.py b/InvenTree/plugin/registry.py
--- a/InvenTree/plugin/registry.py
+++ b/InvenTree/plugin/registry.py
@@ -462,6 +462,7 @@ def _activate_plugins(self, force_reload=False, full_reload: bool = False):
         self.activate_plugin_settings(plugins)
         self.activate_plugin_schedule(plugins)
         self.activate_plugin_app(plugins, force_reload=force_reload, full_reload=full_reload)
+        self.activate_plugin_url(plugins, force_reload=force_reload, full_reload=full_reload)
 
     def _deactivate_plugins(self):
         """Run deactivation functions for all plugins."""
@@ -564,7 +565,6 @@ def activate_plugin_app(self, plugins, force_reload=False, full_reload: bool = F
                         settings.INSTALLED_APPS += [plugin_path]
                         self.installed_apps += [plugin_path]
                         apps_changed = True
-
             # if apps were changed or force loading base apps -> reload
             if apps_changed or force_reload:
                 # first startup or force loading of base apps -> registry is prob false
@@ -580,6 +580,27 @@ def activate_plugin_app(self, plugins, force_reload=False, full_reload: bool = F
                 # update urls - must be last as models must be registered for creating admin routes
                 self._update_urls()
 
+    def activate_plugin_url(self, plugins, force_reload=False, full_reload: bool = False):
+        """Activate UrlsMixin plugins - add custom urls .
+
+        Args:
+            plugins (dict): List of IntegrationPlugins that should be installed
+            force_reload (bool, optional): Only reload base apps. Defaults to False.
+            full_reload (bool, optional): Reload everything - including plugin mechanism. Defaults to False.
+        """
+        from common.models import InvenTreeSetting
+        if settings.PLUGIN_TESTING or InvenTreeSetting.get_setting('ENABLE_PLUGINS_URL'):
+            logger.info('Registering UrlsMixin Plugin')
+            urls_changed = False
+            # check whether an activated plugin extends UrlsMixin
+            for _key, plugin in plugins:
+                if plugin.mixin_enabled('urls'):
+                    urls_changed = True
+            # if apps were changed or force loading base apps -> reload
+            if urls_changed or force_reload or full_reload:
+                # update urls - must be last as models must be registered for creating admin routes
+                self._update_urls()
+
     def _reregister_contrib_apps(self):
         """Fix reloading of contrib apps - models and admin.
 


Test patch: