From 6c667937c56de4987c2bba9e586c5c2fb4383b53 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 11 Nov 2020 14:10:12 +1100 Subject: [PATCH 1/3] Add requirement for django-error-report - Provides an error log viewer in the admin interface at /admin/error_report/error/ - Allows viewing of error logs even in a remote production environment (i.e. no access to command line) --- InvenTree/InvenTree/settings.py | 5 +++++ InvenTree/InvenTree/urls.py | 1 + requirements.txt | 1 + 3 files changed, 7 insertions(+) diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 208220e23a..1c587d7b43 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -155,6 +155,8 @@ INSTALLED_APPS = [ 'markdownify', # Markdown template rendering 'django_tex', # LaTeX output 'django_admin_shell', # Python shell for the admin interface + 'error_report', # Error reporting in the admin interface + ] LOGGING = { @@ -181,6 +183,9 @@ MIDDLEWARE = CONFIG.get('middleware', [ 'InvenTree.middleware.AuthRequiredMiddleware' ]) +# Error reporting middleware +MIDDLEWARE.append('error_report.middleware.ExceptionProcessor') + AUTHENTICATION_BACKENDS = CONFIG.get('authentication_backends', [ 'django.contrib.auth.backends.ModelBackend' ]) diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index d729210235..70fb8c87f8 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -126,6 +126,7 @@ urlpatterns = [ url(r'^edit-user/', EditUserView.as_view(), name='edit-user'), url(r'^set-password/', SetPasswordView.as_view(), name='set-password'), + url(r'^admin/error_log/', include('error_report.urls')), url(r'^admin/shell/', include('django_admin_shell.urls')), url(r'^admin/', admin.site.urls, name='inventree-admin'), diff --git a/requirements.txt b/requirements.txt index 5d2917b57d..01a46bba71 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,5 +26,6 @@ django-tex==1.1.7 # LaTeX PDF export django-weasyprint==1.0.1 # HTML PDF export django-debug-toolbar==2.2 # Debug / profiling toolbar django-admin-shell==0.1.2 # Python shell for the admin interface +django-error-report==0.2.0 # Error report viewer for the admin interface inventree # Install the latest version of the InvenTree API python library \ No newline at end of file From 56765d3f5ae3677e289106911a0875528b052082 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 11 Nov 2020 15:19:15 +1100 Subject: [PATCH 2/3] Fix for unit testing --- InvenTree/users/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/InvenTree/users/models.py b/InvenTree/users/models.py index 98efb14764..6728f6244d 100644 --- a/InvenTree/users/models.py +++ b/InvenTree/users/models.py @@ -109,6 +109,9 @@ class RuleSet(models.Model): 'report_reportasset', 'report_testreport', 'part_partstar', + + # Third-party tables + 'error_report_error', ] RULE_OPTIONS = [ From 039a7badd1be6c3f0a68dc46f80d32fbde541b4e Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Wed, 11 Nov 2020 16:09:14 +1100 Subject: [PATCH 3/3] A little whoopsie-doo: - Part.clean() was incorrectly referencing a BomItem when it should have been referencing BomItem.part --- InvenTree/part/models.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index d6c536db59..1f1c06e81e 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -571,7 +571,8 @@ class Part(MPTTModel): super().clean() if self.trackable: - for parent_part in self.used_in.all(): + for item in self.used_in.all(): + parent_part = item.part if not parent_part.trackable: parent_part.trackable = True parent_part.clean() @@ -1041,8 +1042,16 @@ class Part(MPTTModel): - Exclude parts which this part is in the BOM for """ - parts = Part.objects.filter(component=True).exclude(id=self.id) - parts = parts.exclude(id__in=[part.id for part in self.used_in.all()]) + # Start with a list of all parts designated as 'sub components' + parts = Part.objects.filter(component=True) + + # Exclude this part + parts = parts.exclude(id=self.id) + + # Exclude any parts that this part is used *in* (to prevent recursive BOMs) + used_in = self.used_in.all() + + parts = parts.exclude(id__in=[item.part.id for item in used_in]) return parts