mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #2913 from matmair/codebase-cleanup
Codebase cleanup to python 3.9 / django 3.2
This commit is contained in:
commit
ef52be82d9
@ -44,6 +44,31 @@ The HEAD of the "stable" branch represents the latest stable release code.
|
||||
- When approved, the branch is merged back *into* stable, with an incremented PATCH number (e.g. 0.4.1 -> 0.4.2)
|
||||
- The bugfix *must* also be cherry picked into the *master* branch.
|
||||
|
||||
## Environment
|
||||
#### Target version
|
||||
We are currently targeting:
|
||||
| Name | Minimum version |
|
||||
|---|---|
|
||||
| Python | 3.9 |
|
||||
| Django | 3.2 |
|
||||
|
||||
### Auto creating updates
|
||||
The following tools can be used to auto-upgrade syntax that was depreciated in new versions:
|
||||
```bash
|
||||
pip install pyupgrade
|
||||
pip install django-upgrade
|
||||
```
|
||||
|
||||
To update the codebase run the following script.
|
||||
```bash
|
||||
pyupgrade `find . -name "*.py"`
|
||||
django-upgrade --target-version 3.2 `find . -name "*.py"`
|
||||
```
|
||||
|
||||
### Credits
|
||||
If you add any new dependencies / libraries, they need to be added to [the docs](https://github.com/inventree/inventree-docs/blob/master/docs/credits.md). Please try to do that as timely as possible.
|
||||
|
||||
|
||||
## Migration Files
|
||||
|
||||
Any required migration files **must** be included in the commit, or the pull-request will be rejected. If you change the underlying database schema, make sure you run `invoke migrate` and commit the migration files before submitting the PR.
|
||||
|
@ -5,7 +5,7 @@ Main JSON interface views
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.conf import settings
|
||||
from django.http import JsonResponse
|
||||
|
||||
|
@ -6,7 +6,7 @@ import sys
|
||||
|
||||
from .validators import allowable_url_schemes
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django.forms.fields import URLField as FormURLField
|
||||
from django.db import models as models
|
||||
|
@ -7,7 +7,7 @@ from __future__ import unicode_literals
|
||||
from urllib.parse import urlencode
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django import forms
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.conf import settings
|
||||
@ -319,7 +319,7 @@ class CustomSocialAccountAdapter(RegistratonMixin, DefaultSocialAccountAdapter):
|
||||
redirect_url = reverse('two-factor-authenticate')
|
||||
# Add GET parameters to the URL if they exist.
|
||||
if request.GET:
|
||||
redirect_url += u'?' + urlencode(request.GET)
|
||||
redirect_url += '?' + urlencode(request.GET)
|
||||
|
||||
raise ImmediateHttpResponse(
|
||||
response=HttpResponseRedirect(redirect_url)
|
||||
|
@ -13,7 +13,7 @@ from decimal import Decimal, InvalidOperation
|
||||
from wsgiref.util import FileWrapper
|
||||
from django.http import StreamingHttpResponse
|
||||
from django.core.exceptions import ValidationError, FieldError
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django.contrib.auth.models import Permission
|
||||
|
||||
@ -432,7 +432,7 @@ def extract_serial_numbers(serials, expected_quantity, next_number: int):
|
||||
next_number += 1
|
||||
|
||||
# Split input string by whitespace or comma (,) characters
|
||||
groups = re.split("[\s,]+", serials)
|
||||
groups = re.split(r"[\s,]+", serials)
|
||||
|
||||
numbers = []
|
||||
errors = []
|
||||
|
@ -1,7 +1,7 @@
|
||||
from django.shortcuts import HttpResponseRedirect
|
||||
from django.urls import reverse_lazy, Resolver404
|
||||
from django.shortcuts import redirect
|
||||
from django.conf.urls import include, url
|
||||
from django.urls import include, re_path
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.middleware import PersistentRemoteUserMiddleware
|
||||
|
||||
@ -85,14 +85,14 @@ class AuthRequiredMiddleware(object):
|
||||
if path not in urls and not path.startswith('/api/'):
|
||||
# Save the 'next' parameter to pass through to the login view
|
||||
|
||||
return redirect('%s?next=%s' % (reverse_lazy('account_login'), request.path))
|
||||
return redirect('{}?next={}'.format(reverse_lazy('account_login'), request.path))
|
||||
|
||||
response = self.get_response(request)
|
||||
|
||||
return response
|
||||
|
||||
|
||||
url_matcher = url('', include(frontendpatterns))
|
||||
url_matcher = re_path('', include(frontendpatterns))
|
||||
|
||||
|
||||
class Check2FAMiddleware(BaseRequire2FAMiddleware):
|
||||
|
@ -15,7 +15,7 @@ from collections import OrderedDict
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ValidationError as DjangoValidationError
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.db import models
|
||||
|
||||
from djmoney.contrib.django_rest_framework.fields import MoneyField
|
||||
|
@ -3,7 +3,7 @@ Provides system status functionality checks.
|
||||
"""
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils import timezone
|
||||
|
||||
import logging
|
||||
|
@ -1,4 +1,4 @@
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
|
||||
class StatusCode:
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
import json
|
||||
from test.support import EnvironmentVarGuard
|
||||
|
||||
@ -186,7 +185,7 @@ class TestDownloadFile(TestCase):
|
||||
|
||||
def test_download(self):
|
||||
helpers.DownloadFile("hello world", "out.txt")
|
||||
helpers.DownloadFile(bytes("hello world".encode("utf8")), "out.bin")
|
||||
helpers.DownloadFile(bytes(b"hello world"), "out.bin")
|
||||
|
||||
|
||||
class TestMPTT(TestCase):
|
||||
|
@ -4,8 +4,7 @@ Top-level URL lookup for InvenTree application.
|
||||
Passes URL lookup downstream to each app as required.
|
||||
"""
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import path
|
||||
from django.urls import include, path, re_path
|
||||
from django.contrib import admin
|
||||
|
||||
from company.urls import company_urls
|
||||
@ -56,144 +55,144 @@ apipatterns = []
|
||||
|
||||
if settings.PLUGINS_ENABLED:
|
||||
apipatterns.append(
|
||||
url(r'^plugin/', include(plugin_api_urls))
|
||||
re_path(r'^plugin/', include(plugin_api_urls))
|
||||
)
|
||||
|
||||
apipatterns += [
|
||||
url(r'^barcode/', include(barcode_api_urls)),
|
||||
url(r'^settings/', include(settings_api_urls)),
|
||||
url(r'^part/', include(part_api_urls)),
|
||||
url(r'^bom/', include(bom_api_urls)),
|
||||
url(r'^company/', include(company_api_urls)),
|
||||
url(r'^stock/', include(stock_api_urls)),
|
||||
url(r'^build/', include(build_api_urls)),
|
||||
url(r'^order/', include(order_api_urls)),
|
||||
url(r'^label/', include(label_api_urls)),
|
||||
url(r'^report/', include(report_api_urls)),
|
||||
re_path(r'^barcode/', include(barcode_api_urls)),
|
||||
re_path(r'^settings/', include(settings_api_urls)),
|
||||
re_path(r'^part/', include(part_api_urls)),
|
||||
re_path(r'^bom/', include(bom_api_urls)),
|
||||
re_path(r'^company/', include(company_api_urls)),
|
||||
re_path(r'^stock/', include(stock_api_urls)),
|
||||
re_path(r'^build/', include(build_api_urls)),
|
||||
re_path(r'^order/', include(order_api_urls)),
|
||||
re_path(r'^label/', include(label_api_urls)),
|
||||
re_path(r'^report/', include(report_api_urls)),
|
||||
|
||||
# User URLs
|
||||
url(r'^user/', include(user_urls)),
|
||||
re_path(r'^user/', include(user_urls)),
|
||||
|
||||
# Plugin endpoints
|
||||
url(r'^action/', ActionPluginView.as_view(), name='api-action-plugin'),
|
||||
re_path(r'^action/', ActionPluginView.as_view(), name='api-action-plugin'),
|
||||
|
||||
# Webhook enpoint
|
||||
path('', include(common_api_urls)),
|
||||
|
||||
# InvenTree information endpoint
|
||||
url(r'^$', InfoView.as_view(), name='api-inventree-info'),
|
||||
path('', InfoView.as_view(), name='api-inventree-info'),
|
||||
|
||||
# Unknown endpoint
|
||||
url(r'^.*$', NotFoundView.as_view(), name='api-404'),
|
||||
re_path(r'^.*$', NotFoundView.as_view(), name='api-404'),
|
||||
]
|
||||
|
||||
settings_urls = [
|
||||
|
||||
url(r'^i18n/?', include('django.conf.urls.i18n')),
|
||||
re_path(r'^i18n/?', include('django.conf.urls.i18n')),
|
||||
|
||||
url(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'),
|
||||
url(r'^currencies-refresh/', CurrencyRefreshView.as_view(), name='settings-currencies-refresh'),
|
||||
re_path(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'),
|
||||
re_path(r'^currencies-refresh/', CurrencyRefreshView.as_view(), name='settings-currencies-refresh'),
|
||||
|
||||
url(r'^category/', SettingCategorySelectView.as_view(), name='settings-category'),
|
||||
re_path(r'^category/', SettingCategorySelectView.as_view(), name='settings-category'),
|
||||
|
||||
# Catch any other urls
|
||||
url(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/settings.html'), name='settings'),
|
||||
re_path(r'^.*$', SettingsView.as_view(template_name='InvenTree/settings/settings.html'), name='settings'),
|
||||
]
|
||||
|
||||
notifications_urls = [
|
||||
|
||||
# Catch any other urls
|
||||
url(r'^.*$', NotificationsView.as_view(), name='notifications'),
|
||||
re_path(r'^.*$', NotificationsView.as_view(), name='notifications'),
|
||||
]
|
||||
|
||||
# These javascript files are served "dynamically" - i.e. rendered on demand
|
||||
dynamic_javascript_urls = [
|
||||
url(r'^calendar.js', DynamicJsView.as_view(template_name='js/dynamic/calendar.js'), name='calendar.js'),
|
||||
url(r'^nav.js', DynamicJsView.as_view(template_name='js/dynamic/nav.js'), name='nav.js'),
|
||||
url(r'^settings.js', DynamicJsView.as_view(template_name='js/dynamic/settings.js'), name='settings.js'),
|
||||
re_path(r'^calendar.js', DynamicJsView.as_view(template_name='js/dynamic/calendar.js'), name='calendar.js'),
|
||||
re_path(r'^nav.js', DynamicJsView.as_view(template_name='js/dynamic/nav.js'), name='nav.js'),
|
||||
re_path(r'^settings.js', DynamicJsView.as_view(template_name='js/dynamic/settings.js'), name='settings.js'),
|
||||
]
|
||||
|
||||
# These javascript files are pased through the Django translation layer
|
||||
translated_javascript_urls = [
|
||||
url(r'^api.js', DynamicJsView.as_view(template_name='js/translated/api.js'), name='api.js'),
|
||||
url(r'^attachment.js', DynamicJsView.as_view(template_name='js/translated/attachment.js'), name='attachment.js'),
|
||||
url(r'^barcode.js', DynamicJsView.as_view(template_name='js/translated/barcode.js'), name='barcode.js'),
|
||||
url(r'^bom.js', DynamicJsView.as_view(template_name='js/translated/bom.js'), name='bom.js'),
|
||||
url(r'^build.js', DynamicJsView.as_view(template_name='js/translated/build.js'), name='build.js'),
|
||||
url(r'^company.js', DynamicJsView.as_view(template_name='js/translated/company.js'), name='company.js'),
|
||||
url(r'^filters.js', DynamicJsView.as_view(template_name='js/translated/filters.js'), name='filters.js'),
|
||||
url(r'^forms.js', DynamicJsView.as_view(template_name='js/translated/forms.js'), name='forms.js'),
|
||||
url(r'^helpers.js', DynamicJsView.as_view(template_name='js/translated/helpers.js'), name='helpers.js'),
|
||||
url(r'^label.js', DynamicJsView.as_view(template_name='js/translated/label.js'), name='label.js'),
|
||||
url(r'^model_renderers.js', DynamicJsView.as_view(template_name='js/translated/model_renderers.js'), name='model_renderers.js'),
|
||||
url(r'^modals.js', DynamicJsView.as_view(template_name='js/translated/modals.js'), name='modals.js'),
|
||||
url(r'^order.js', DynamicJsView.as_view(template_name='js/translated/order.js'), name='order.js'),
|
||||
url(r'^part.js', DynamicJsView.as_view(template_name='js/translated/part.js'), name='part.js'),
|
||||
url(r'^report.js', DynamicJsView.as_view(template_name='js/translated/report.js'), name='report.js'),
|
||||
url(r'^search.js', DynamicJsView.as_view(template_name='js/translated/search.js'), name='search.js'),
|
||||
url(r'^stock.js', DynamicJsView.as_view(template_name='js/translated/stock.js'), name='stock.js'),
|
||||
url(r'^plugin.js', DynamicJsView.as_view(template_name='js/translated/plugin.js'), name='plugin.js'),
|
||||
url(r'^tables.js', DynamicJsView.as_view(template_name='js/translated/tables.js'), name='tables.js'),
|
||||
url(r'^table_filters.js', DynamicJsView.as_view(template_name='js/translated/table_filters.js'), name='table_filters.js'),
|
||||
url(r'^notification.js', DynamicJsView.as_view(template_name='js/translated/notification.js'), name='notification.js'),
|
||||
re_path(r'^api.js', DynamicJsView.as_view(template_name='js/translated/api.js'), name='api.js'),
|
||||
re_path(r'^attachment.js', DynamicJsView.as_view(template_name='js/translated/attachment.js'), name='attachment.js'),
|
||||
re_path(r'^barcode.js', DynamicJsView.as_view(template_name='js/translated/barcode.js'), name='barcode.js'),
|
||||
re_path(r'^bom.js', DynamicJsView.as_view(template_name='js/translated/bom.js'), name='bom.js'),
|
||||
re_path(r'^build.js', DynamicJsView.as_view(template_name='js/translated/build.js'), name='build.js'),
|
||||
re_path(r'^company.js', DynamicJsView.as_view(template_name='js/translated/company.js'), name='company.js'),
|
||||
re_path(r'^filters.js', DynamicJsView.as_view(template_name='js/translated/filters.js'), name='filters.js'),
|
||||
re_path(r'^forms.js', DynamicJsView.as_view(template_name='js/translated/forms.js'), name='forms.js'),
|
||||
re_path(r'^helpers.js', DynamicJsView.as_view(template_name='js/translated/helpers.js'), name='helpers.js'),
|
||||
re_path(r'^label.js', DynamicJsView.as_view(template_name='js/translated/label.js'), name='label.js'),
|
||||
re_path(r'^model_renderers.js', DynamicJsView.as_view(template_name='js/translated/model_renderers.js'), name='model_renderers.js'),
|
||||
re_path(r'^modals.js', DynamicJsView.as_view(template_name='js/translated/modals.js'), name='modals.js'),
|
||||
re_path(r'^order.js', DynamicJsView.as_view(template_name='js/translated/order.js'), name='order.js'),
|
||||
re_path(r'^part.js', DynamicJsView.as_view(template_name='js/translated/part.js'), name='part.js'),
|
||||
re_path(r'^report.js', DynamicJsView.as_view(template_name='js/translated/report.js'), name='report.js'),
|
||||
re_path(r'^search.js', DynamicJsView.as_view(template_name='js/translated/search.js'), name='search.js'),
|
||||
re_path(r'^stock.js', DynamicJsView.as_view(template_name='js/translated/stock.js'), name='stock.js'),
|
||||
re_path(r'^plugin.js', DynamicJsView.as_view(template_name='js/translated/plugin.js'), name='plugin.js'),
|
||||
re_path(r'^tables.js', DynamicJsView.as_view(template_name='js/translated/tables.js'), name='tables.js'),
|
||||
re_path(r'^table_filters.js', DynamicJsView.as_view(template_name='js/translated/table_filters.js'), name='table_filters.js'),
|
||||
re_path(r'^notification.js', DynamicJsView.as_view(template_name='js/translated/notification.js'), name='notification.js'),
|
||||
]
|
||||
|
||||
backendpatterns = [
|
||||
# "Dynamic" javascript files which are rendered using InvenTree templating.
|
||||
url(r'^js/dynamic/', include(dynamic_javascript_urls)),
|
||||
url(r'^js/i18n/', include(translated_javascript_urls)),
|
||||
re_path(r'^js/dynamic/', include(dynamic_javascript_urls)),
|
||||
re_path(r'^js/i18n/', include(translated_javascript_urls)),
|
||||
|
||||
url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
url(r'^auth/?', auth_request),
|
||||
re_path(r'^auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
re_path(r'^auth/?', auth_request),
|
||||
|
||||
url(r'^api/', include(apipatterns)),
|
||||
url(r'^api-doc/', include_docs_urls(title='InvenTree API')),
|
||||
re_path(r'^api/', include(apipatterns)),
|
||||
re_path(r'^api-doc/', include_docs_urls(title='InvenTree API')),
|
||||
|
||||
# 3rd party endpoints
|
||||
url(r'^markdownx/', include('markdownx.urls')),
|
||||
re_path(r'^markdownx/', include('markdownx.urls')),
|
||||
]
|
||||
|
||||
frontendpatterns = [
|
||||
url(r'^part/', include(part_urls)),
|
||||
url(r'^manufacturer-part/', include(manufacturer_part_urls)),
|
||||
url(r'^supplier-part/', include(supplier_part_urls)),
|
||||
re_path(r'^part/', include(part_urls)),
|
||||
re_path(r'^manufacturer-part/', include(manufacturer_part_urls)),
|
||||
re_path(r'^supplier-part/', include(supplier_part_urls)),
|
||||
|
||||
url(r'^common/', include(common_urls)),
|
||||
re_path(r'^common/', include(common_urls)),
|
||||
|
||||
url(r'^stock/', include(stock_urls)),
|
||||
re_path(r'^stock/', include(stock_urls)),
|
||||
|
||||
url(r'^company/', include(company_urls)),
|
||||
url(r'^order/', include(order_urls)),
|
||||
re_path(r'^company/', include(company_urls)),
|
||||
re_path(r'^order/', include(order_urls)),
|
||||
|
||||
url(r'^build/', include(build_urls)),
|
||||
re_path(r'^build/', include(build_urls)),
|
||||
|
||||
url(r'^settings/', include(settings_urls)),
|
||||
re_path(r'^settings/', include(settings_urls)),
|
||||
|
||||
url(r'^notifications/', include(notifications_urls)),
|
||||
re_path(r'^notifications/', include(notifications_urls)),
|
||||
|
||||
url(r'^edit-user/', EditUserView.as_view(), name='edit-user'),
|
||||
url(r'^set-password/', SetPasswordView.as_view(), name='set-password'),
|
||||
re_path(r'^edit-user/', EditUserView.as_view(), name='edit-user'),
|
||||
re_path(r'^set-password/', SetPasswordView.as_view(), name='set-password'),
|
||||
|
||||
url(r'^index/', IndexView.as_view(), name='index'),
|
||||
url(r'^search/', SearchView.as_view(), name='search'),
|
||||
url(r'^stats/', DatabaseStatsView.as_view(), name='stats'),
|
||||
re_path(r'^index/', IndexView.as_view(), name='index'),
|
||||
re_path(r'^search/', SearchView.as_view(), name='search'),
|
||||
re_path(r'^stats/', DatabaseStatsView.as_view(), name='stats'),
|
||||
|
||||
# admin sites
|
||||
url(f'^{settings.INVENTREE_ADMIN_URL}/error_log/', include('error_report.urls')),
|
||||
url(f'^{settings.INVENTREE_ADMIN_URL}/shell/', include('django_admin_shell.urls')),
|
||||
url(f'^{settings.INVENTREE_ADMIN_URL}/', admin.site.urls, name='inventree-admin'),
|
||||
re_path(f'^{settings.INVENTREE_ADMIN_URL}/error_log/', include('error_report.urls')),
|
||||
re_path(f'^{settings.INVENTREE_ADMIN_URL}/shell/', include('django_admin_shell.urls')),
|
||||
re_path(f'^{settings.INVENTREE_ADMIN_URL}/', admin.site.urls, name='inventree-admin'),
|
||||
|
||||
# DB user sessions
|
||||
url(r'^accounts/sessions/other/delete/$', view=CustomSessionDeleteOtherView.as_view(), name='session_delete_other', ),
|
||||
url(r'^accounts/sessions/(?P<pk>\w+)/delete/$', view=CustomSessionDeleteView.as_view(), name='session_delete', ),
|
||||
path('accounts/sessions/other/delete/', view=CustomSessionDeleteOtherView.as_view(), name='session_delete_other', ),
|
||||
re_path(r'^accounts/sessions/(?P<pk>\w+)/delete/$', view=CustomSessionDeleteView.as_view(), name='session_delete', ),
|
||||
|
||||
# Single Sign On / allauth
|
||||
# overrides of urlpatterns
|
||||
url(r'^accounts/email/', CustomEmailView.as_view(), name='account_email'),
|
||||
url(r'^accounts/social/connections/', CustomConnectionsView.as_view(), name='socialaccount_connections'),
|
||||
url(r"^accounts/password/reset/key/(?P<uidb36>[0-9A-Za-z]+)-(?P<key>.+)/$", CustomPasswordResetFromKeyView.as_view(), name="account_reset_password_from_key"),
|
||||
url(r'^accounts/', include('allauth_2fa.urls')), # MFA support
|
||||
url(r'^accounts/', include('allauth.urls')), # included urlpatterns
|
||||
re_path(r'^accounts/email/', CustomEmailView.as_view(), name='account_email'),
|
||||
re_path(r'^accounts/social/connections/', CustomConnectionsView.as_view(), name='socialaccount_connections'),
|
||||
re_path(r"^accounts/password/reset/key/(?P<uidb36>[0-9A-Za-z]+)-(?P<key>.+)/$", CustomPasswordResetFromKeyView.as_view(), name="account_reset_password_from_key"),
|
||||
re_path(r'^accounts/', include('allauth_2fa.urls')), # MFA support
|
||||
re_path(r'^accounts/', include('allauth.urls')), # included urlpatterns
|
||||
]
|
||||
|
||||
# Append custom plugin URLs (if plugin support is enabled)
|
||||
@ -201,8 +200,8 @@ if settings.PLUGINS_ENABLED:
|
||||
frontendpatterns.append(get_plugin_urls())
|
||||
|
||||
urlpatterns = [
|
||||
url('', include(frontendpatterns)),
|
||||
url('', include(backendpatterns)),
|
||||
re_path('', include(frontendpatterns)),
|
||||
re_path('', include(backendpatterns)),
|
||||
]
|
||||
|
||||
# Server running in "DEBUG" mode?
|
||||
@ -221,4 +220,4 @@ if settings.DEBUG:
|
||||
] + urlpatterns
|
||||
|
||||
# Send any unknown URLs to the parts page
|
||||
urlpatterns += [url(r'^.*$', RedirectView.as_view(url='/index/', permanent=False), name='index')]
|
||||
urlpatterns += [re_path(r'^.*$', RedirectView.as_view(url='/index/', permanent=False), name='index')]
|
||||
|
@ -1,8 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.urls import reverse
|
||||
from django.conf.urls import url
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.urls import path, re_path
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework import permissions
|
||||
@ -240,8 +240,8 @@ class BarcodeAssign(APIView):
|
||||
|
||||
barcode_api_urls = [
|
||||
|
||||
url(r'^link/$', BarcodeAssign.as_view(), name='api-barcode-link'),
|
||||
path('link/', BarcodeAssign.as_view(), name='api-barcode-link'),
|
||||
|
||||
# Catch-all performs barcode 'scan'
|
||||
url(r'^.*$', BarcodeScan.as_view(), name='api-barcode-scan'),
|
||||
re_path(r'^.*$', BarcodeScan.as_view(), name='api-barcode-scan'),
|
||||
]
|
||||
|
@ -5,7 +5,7 @@ JSON API for the Build app
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
|
||||
from rest_framework import filters, generics
|
||||
|
||||
@ -508,29 +508,29 @@ class BuildAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, AttachmentMix
|
||||
build_api_urls = [
|
||||
|
||||
# Attachments
|
||||
url(r'^attachment/', include([
|
||||
url(r'^(?P<pk>\d+)/', BuildAttachmentDetail.as_view(), name='api-build-attachment-detail'),
|
||||
url(r'^.*$', BuildAttachmentList.as_view(), name='api-build-attachment-list'),
|
||||
re_path(r'^attachment/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', BuildAttachmentDetail.as_view(), name='api-build-attachment-detail'),
|
||||
re_path(r'^.*$', BuildAttachmentList.as_view(), name='api-build-attachment-list'),
|
||||
])),
|
||||
|
||||
# Build Items
|
||||
url(r'^item/', include([
|
||||
url(r'^(?P<pk>\d+)/', BuildItemDetail.as_view(), name='api-build-item-detail'),
|
||||
url(r'^.*$', BuildItemList.as_view(), name='api-build-item-list'),
|
||||
re_path(r'^item/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', BuildItemDetail.as_view(), name='api-build-item-detail'),
|
||||
re_path(r'^.*$', BuildItemList.as_view(), name='api-build-item-list'),
|
||||
])),
|
||||
|
||||
# Build Detail
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^allocate/', BuildAllocate.as_view(), name='api-build-allocate'),
|
||||
url(r'^auto-allocate/', BuildAutoAllocate.as_view(), name='api-build-auto-allocate'),
|
||||
url(r'^complete/', BuildOutputComplete.as_view(), name='api-build-output-complete'),
|
||||
url(r'^create-output/', BuildOutputCreate.as_view(), name='api-build-output-create'),
|
||||
url(r'^delete-outputs/', BuildOutputDelete.as_view(), name='api-build-output-delete'),
|
||||
url(r'^finish/', BuildFinish.as_view(), name='api-build-finish'),
|
||||
url(r'^unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'),
|
||||
url(r'^.*$', BuildDetail.as_view(), name='api-build-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^allocate/', BuildAllocate.as_view(), name='api-build-allocate'),
|
||||
re_path(r'^auto-allocate/', BuildAutoAllocate.as_view(), name='api-build-auto-allocate'),
|
||||
re_path(r'^complete/', BuildOutputComplete.as_view(), name='api-build-output-complete'),
|
||||
re_path(r'^create-output/', BuildOutputCreate.as_view(), name='api-build-output-create'),
|
||||
re_path(r'^delete-outputs/', BuildOutputDelete.as_view(), name='api-build-output-delete'),
|
||||
re_path(r'^finish/', BuildFinish.as_view(), name='api-build-finish'),
|
||||
re_path(r'^unallocate/', BuildUnallocate.as_view(), name='api-build-unallocate'),
|
||||
re_path(r'^.*$', BuildDetail.as_view(), name='api-build-detail'),
|
||||
])),
|
||||
|
||||
# Build List
|
||||
url(r'^.*$', BuildList.as_view(), name='api-build-list'),
|
||||
re_path(r'^.*$', BuildList.as_view(), name='api-build-list'),
|
||||
]
|
||||
|
@ -6,7 +6,7 @@ Django Forms for interacting with Build objects
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django import forms
|
||||
|
||||
from InvenTree.forms import HelperForm
|
||||
|
@ -18,7 +18,7 @@ from django.db.models.functions import Coalesce
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch.dispatcher import receiver
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from markdownx.models import MarkdownxField
|
||||
|
||||
@ -53,7 +53,7 @@ def get_next_build_number():
|
||||
|
||||
build = Build.objects.exclude(reference=None).last()
|
||||
|
||||
attempts = set([build.reference])
|
||||
attempts = {build.reference}
|
||||
|
||||
reference = build.reference
|
||||
|
||||
|
@ -7,7 +7,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.db import transaction
|
||||
from django.core.exceptions import ValidationError as DjangoValidationError
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django.db.models import Case, When, Value
|
||||
from django.db.models import BooleanField
|
||||
|
@ -4,7 +4,7 @@ from __future__ import unicode_literals
|
||||
from decimal import Decimal
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from allauth.account.models import EmailAddress
|
||||
|
@ -2,20 +2,20 @@
|
||||
URL lookup for Build app
|
||||
"""
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
|
||||
from . import views
|
||||
|
||||
build_detail_urls = [
|
||||
url(r'^cancel/', views.BuildCancel.as_view(), name='build-cancel'),
|
||||
url(r'^delete/', views.BuildDelete.as_view(), name='build-delete'),
|
||||
re_path(r'^cancel/', views.BuildCancel.as_view(), name='build-cancel'),
|
||||
re_path(r'^delete/', views.BuildDelete.as_view(), name='build-delete'),
|
||||
|
||||
url(r'^.*$', views.BuildDetail.as_view(), name='build-detail'),
|
||||
re_path(r'^.*$', views.BuildDetail.as_view(), name='build-detail'),
|
||||
]
|
||||
|
||||
build_urls = [
|
||||
|
||||
url(r'^(?P<pk>\d+)/', include(build_detail_urls)),
|
||||
re_path(r'^(?P<pk>\d+)/', include(build_detail_urls)),
|
||||
|
||||
url(r'.*$', views.BuildIndex.as_view(), name='build-index'),
|
||||
re_path(r'.*$', views.BuildIndex.as_view(), name='build-index'),
|
||||
]
|
||||
|
@ -5,7 +5,7 @@ Django views for interacting with Build objects
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import DetailView, ListView
|
||||
|
||||
from .models import Build
|
||||
|
@ -11,7 +11,7 @@ from django.http.response import HttpResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.urls import path
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
@ -336,21 +336,21 @@ class NotificationReadAll(generics.RetrieveAPIView):
|
||||
|
||||
settings_api_urls = [
|
||||
# User settings
|
||||
url(r'^user/', include([
|
||||
re_path(r'^user/', include([
|
||||
# User Settings Detail
|
||||
url(r'^(?P<pk>\d+)/', UserSettingsDetail.as_view(), name='api-user-setting-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', UserSettingsDetail.as_view(), name='api-user-setting-detail'),
|
||||
|
||||
# User Settings List
|
||||
url(r'^.*$', UserSettingsList.as_view(), name='api-user-setting-list'),
|
||||
re_path(r'^.*$', UserSettingsList.as_view(), name='api-user-setting-list'),
|
||||
])),
|
||||
|
||||
# Global settings
|
||||
url(r'^global/', include([
|
||||
re_path(r'^global/', include([
|
||||
# Global Settings Detail
|
||||
url(r'^(?P<pk>\d+)/', GlobalSettingsDetail.as_view(), name='api-global-setting-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', GlobalSettingsDetail.as_view(), name='api-global-setting-detail'),
|
||||
|
||||
# Global Settings List
|
||||
url(r'^.*$', GlobalSettingsList.as_view(), name='api-global-setting-list'),
|
||||
re_path(r'^.*$', GlobalSettingsList.as_view(), name='api-global-setting-list'),
|
||||
])),
|
||||
]
|
||||
|
||||
@ -359,18 +359,18 @@ common_api_urls = [
|
||||
path('webhook/<slug:endpoint>/', WebhookView.as_view(), name='api-webhook'),
|
||||
|
||||
# Notifications
|
||||
url(r'^notifications/', include([
|
||||
re_path(r'^notifications/', include([
|
||||
# Individual purchase order detail URLs
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^read/', NotificationRead.as_view(), name='api-notifications-read'),
|
||||
url(r'^unread/', NotificationUnread.as_view(), name='api-notifications-unread'),
|
||||
url(r'.*$', NotificationDetail.as_view(), name='api-notifications-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^read/', NotificationRead.as_view(), name='api-notifications-read'),
|
||||
re_path(r'^unread/', NotificationUnread.as_view(), name='api-notifications-unread'),
|
||||
re_path(r'.*$', NotificationDetail.as_view(), name='api-notifications-detail'),
|
||||
])),
|
||||
# Read all
|
||||
url(r'^readall/', NotificationReadAll.as_view(), name='api-notifications-readall'),
|
||||
re_path(r'^readall/', NotificationReadAll.as_view(), name='api-notifications-readall'),
|
||||
|
||||
# Notification messages list
|
||||
url(r'^.*$', NotificationList.as_view(), name='api-notifications-list'),
|
||||
re_path(r'^.*$', NotificationList.as_view(), name='api-notifications-list'),
|
||||
])),
|
||||
|
||||
]
|
||||
|
@ -33,7 +33,7 @@ from djmoney.contrib.exchange.exceptions import MissingRate
|
||||
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.core.validators import MinValueValidator, URLValidator
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
from django.test import TestCase
|
||||
|
||||
|
@ -7,7 +7,7 @@ from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.conf import settings
|
||||
from django.core.files.storage import FileSystemStorage
|
||||
|
||||
|
@ -11,7 +11,7 @@ from django_filters import rest_framework as rest_filters
|
||||
from rest_framework import filters
|
||||
from rest_framework import generics
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
from django.db.models import Q
|
||||
|
||||
from InvenTree.helpers import str2bool
|
||||
@ -390,42 +390,42 @@ class SupplierPriceBreakDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
|
||||
manufacturer_part_api_urls = [
|
||||
|
||||
url(r'^parameter/', include([
|
||||
url(r'^(?P<pk>\d+)/', ManufacturerPartParameterDetail.as_view(), name='api-manufacturer-part-parameter-detail'),
|
||||
re_path(r'^parameter/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', ManufacturerPartParameterDetail.as_view(), name='api-manufacturer-part-parameter-detail'),
|
||||
|
||||
# Catch anything else
|
||||
url(r'^.*$', ManufacturerPartParameterList.as_view(), name='api-manufacturer-part-parameter-list'),
|
||||
re_path(r'^.*$', ManufacturerPartParameterList.as_view(), name='api-manufacturer-part-parameter-list'),
|
||||
])),
|
||||
|
||||
url(r'^(?P<pk>\d+)/?', ManufacturerPartDetail.as_view(), name='api-manufacturer-part-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/?', ManufacturerPartDetail.as_view(), name='api-manufacturer-part-detail'),
|
||||
|
||||
# Catch anything else
|
||||
url(r'^.*$', ManufacturerPartList.as_view(), name='api-manufacturer-part-list'),
|
||||
re_path(r'^.*$', ManufacturerPartList.as_view(), name='api-manufacturer-part-list'),
|
||||
]
|
||||
|
||||
|
||||
supplier_part_api_urls = [
|
||||
|
||||
url(r'^(?P<pk>\d+)/?', SupplierPartDetail.as_view(), name='api-supplier-part-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/?', SupplierPartDetail.as_view(), name='api-supplier-part-detail'),
|
||||
|
||||
# Catch anything else
|
||||
url(r'^.*$', SupplierPartList.as_view(), name='api-supplier-part-list'),
|
||||
re_path(r'^.*$', SupplierPartList.as_view(), name='api-supplier-part-list'),
|
||||
]
|
||||
|
||||
|
||||
company_api_urls = [
|
||||
url(r'^part/manufacturer/', include(manufacturer_part_api_urls)),
|
||||
re_path(r'^part/manufacturer/', include(manufacturer_part_api_urls)),
|
||||
|
||||
url(r'^part/', include(supplier_part_api_urls)),
|
||||
re_path(r'^part/', include(supplier_part_api_urls)),
|
||||
|
||||
# Supplier price breaks
|
||||
url(r'^price-break/', include([
|
||||
re_path(r'^price-break/', include([
|
||||
|
||||
url(r'^(?P<pk>\d+)/?', SupplierPriceBreakDetail.as_view(), name='api-part-supplier-price-detail'),
|
||||
url(r'^.*$', SupplierPriceBreakList.as_view(), name='api-part-supplier-price-list'),
|
||||
re_path(r'^(?P<pk>\d+)/?', SupplierPriceBreakDetail.as_view(), name='api-part-supplier-price-detail'),
|
||||
re_path(r'^.*$', SupplierPriceBreakList.as_view(), name='api-part-supplier-price-list'),
|
||||
])),
|
||||
|
||||
url(r'^(?P<pk>\d+)/?', CompanyDetail.as_view(), name='api-company-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/?', CompanyDetail.as_view(), name='api-company-detail'),
|
||||
|
||||
url(r'^.*$', CompanyList.as_view(), name='api-company-list'),
|
||||
re_path(r'^.*$', CompanyList.as_view(), name='api-company-list'),
|
||||
]
|
||||
|
@ -8,7 +8,7 @@ from __future__ import unicode_literals
|
||||
from InvenTree.forms import HelperForm
|
||||
from InvenTree.fields import RoundingDecimalFormField
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
import django.forms
|
||||
|
||||
from .models import Company
|
||||
|
@ -7,7 +7,7 @@ from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.core.validators import MinValueValidator
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
JSON serializers for Company app
|
||||
"""
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from rest_framework import serializers
|
||||
|
||||
|
@ -2,37 +2,37 @@
|
||||
URL lookup for Company app
|
||||
"""
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
|
||||
from . import views
|
||||
|
||||
|
||||
company_detail_urls = [
|
||||
|
||||
url(r'^thumb-download/', views.CompanyImageDownloadFromURL.as_view(), name='company-image-download'),
|
||||
re_path(r'^thumb-download/', views.CompanyImageDownloadFromURL.as_view(), name='company-image-download'),
|
||||
|
||||
# Any other URL
|
||||
url(r'^.*$', views.CompanyDetail.as_view(), name='company-detail'),
|
||||
re_path(r'^.*$', views.CompanyDetail.as_view(), name='company-detail'),
|
||||
]
|
||||
|
||||
|
||||
company_urls = [
|
||||
|
||||
url(r'^(?P<pk>\d+)/', include(company_detail_urls)),
|
||||
re_path(r'^(?P<pk>\d+)/', include(company_detail_urls)),
|
||||
|
||||
url(r'suppliers/', views.CompanyIndex.as_view(), name='supplier-index'),
|
||||
url(r'manufacturers/', views.CompanyIndex.as_view(), name='manufacturer-index'),
|
||||
url(r'customers/', views.CompanyIndex.as_view(), name='customer-index'),
|
||||
re_path(r'suppliers/', views.CompanyIndex.as_view(), name='supplier-index'),
|
||||
re_path(r'manufacturers/', views.CompanyIndex.as_view(), name='manufacturer-index'),
|
||||
re_path(r'customers/', views.CompanyIndex.as_view(), name='customer-index'),
|
||||
|
||||
# Redirect any other patterns to the 'company' index which displays all companies
|
||||
url(r'^.*$', views.CompanyIndex.as_view(), name='company-index'),
|
||||
re_path(r'^.*$', views.CompanyIndex.as_view(), name='company-index'),
|
||||
]
|
||||
|
||||
manufacturer_part_urls = [
|
||||
|
||||
url(r'^(?P<pk>\d+)/', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part.html'), name='manufacturer-part-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part.html'), name='manufacturer-part-detail'),
|
||||
]
|
||||
|
||||
supplier_part_urls = [
|
||||
url(r'^(?P<pk>\d+)/', views.SupplierPartDetail.as_view(template_name='company/supplier_part.html'), name='supplier-part-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', views.SupplierPartDetail.as_view(template_name='company/supplier_part.html'), name='supplier-part-detail'),
|
||||
]
|
||||
|
@ -6,7 +6,7 @@ Django views for interacting with Company app
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import DetailView, ListView
|
||||
|
||||
from django.urls import reverse
|
||||
|
@ -4,10 +4,10 @@ from __future__ import unicode_literals
|
||||
from io import BytesIO
|
||||
from PIL import Image
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django.conf import settings
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
from django.core.exceptions import ValidationError, FieldError
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
|
||||
@ -579,38 +579,38 @@ class PartLabelPrint(generics.RetrieveAPIView, PartLabelMixin, LabelPrintMixin):
|
||||
label_api_urls = [
|
||||
|
||||
# Stock item labels
|
||||
url(r'stock/', include([
|
||||
re_path(r'stock/', include([
|
||||
# Detail views
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'print/?', StockItemLabelPrint.as_view(), name='api-stockitem-label-print'),
|
||||
url(r'^.*$', StockItemLabelDetail.as_view(), name='api-stockitem-label-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'print/?', StockItemLabelPrint.as_view(), name='api-stockitem-label-print'),
|
||||
re_path(r'^.*$', StockItemLabelDetail.as_view(), name='api-stockitem-label-detail'),
|
||||
])),
|
||||
|
||||
# List view
|
||||
url(r'^.*$', StockItemLabelList.as_view(), name='api-stockitem-label-list'),
|
||||
re_path(r'^.*$', StockItemLabelList.as_view(), name='api-stockitem-label-list'),
|
||||
])),
|
||||
|
||||
# Stock location labels
|
||||
url(r'location/', include([
|
||||
re_path(r'location/', include([
|
||||
# Detail views
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'print/?', StockLocationLabelPrint.as_view(), name='api-stocklocation-label-print'),
|
||||
url(r'^.*$', StockLocationLabelDetail.as_view(), name='api-stocklocation-label-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'print/?', StockLocationLabelPrint.as_view(), name='api-stocklocation-label-print'),
|
||||
re_path(r'^.*$', StockLocationLabelDetail.as_view(), name='api-stocklocation-label-detail'),
|
||||
])),
|
||||
|
||||
# List view
|
||||
url(r'^.*$', StockLocationLabelList.as_view(), name='api-stocklocation-label-list'),
|
||||
re_path(r'^.*$', StockLocationLabelList.as_view(), name='api-stocklocation-label-list'),
|
||||
])),
|
||||
|
||||
# Part labels
|
||||
url(r'^part/', include([
|
||||
re_path(r'^part/', include([
|
||||
# Detail views
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^print/', PartLabelPrint.as_view(), name='api-part-label-print'),
|
||||
url(r'^.*$', PartLabelDetail.as_view(), name='api-part-label-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^print/', PartLabelPrint.as_view(), name='api-part-label-print'),
|
||||
re_path(r'^.*$', PartLabelDetail.as_view(), name='api-part-label-detail'),
|
||||
])),
|
||||
|
||||
# List view
|
||||
url(r'^.*$', PartLabelList.as_view(), name='api-part-label-list'),
|
||||
re_path(r'^.*$', PartLabelList.as_view(), name='api-part-label-list'),
|
||||
])),
|
||||
]
|
||||
|
@ -5,7 +5,7 @@ JSON API for the Order app
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, path, re_path
|
||||
from django.db.models import Q, F
|
||||
|
||||
from django_filters import rest_framework as rest_filters
|
||||
@ -1096,78 +1096,78 @@ class PurchaseOrderAttachmentDetail(generics.RetrieveUpdateDestroyAPIView, Attac
|
||||
order_api_urls = [
|
||||
|
||||
# API endpoints for purchase orders
|
||||
url(r'^po/', include([
|
||||
re_path(r'^po/', include([
|
||||
|
||||
# Purchase order attachments
|
||||
url(r'attachment/', include([
|
||||
url(r'^(?P<pk>\d+)/$', PurchaseOrderAttachmentDetail.as_view(), name='api-po-attachment-detail'),
|
||||
url(r'^.*$', PurchaseOrderAttachmentList.as_view(), name='api-po-attachment-list'),
|
||||
re_path(r'attachment/', include([
|
||||
path('<int:pk>/', PurchaseOrderAttachmentDetail.as_view(), name='api-po-attachment-detail'),
|
||||
re_path(r'^.*$', PurchaseOrderAttachmentList.as_view(), name='api-po-attachment-list'),
|
||||
])),
|
||||
|
||||
# Individual purchase order detail URLs
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^receive/', PurchaseOrderReceive.as_view(), name='api-po-receive'),
|
||||
url(r'.*$', PurchaseOrderDetail.as_view(), name='api-po-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^receive/', PurchaseOrderReceive.as_view(), name='api-po-receive'),
|
||||
re_path(r'.*$', PurchaseOrderDetail.as_view(), name='api-po-detail'),
|
||||
])),
|
||||
|
||||
# Purchase order list
|
||||
url(r'^.*$', PurchaseOrderList.as_view(), name='api-po-list'),
|
||||
re_path(r'^.*$', PurchaseOrderList.as_view(), name='api-po-list'),
|
||||
])),
|
||||
|
||||
# API endpoints for purchase order line items
|
||||
url(r'^po-line/', include([
|
||||
url(r'^(?P<pk>\d+)/$', PurchaseOrderLineItemDetail.as_view(), name='api-po-line-detail'),
|
||||
url(r'^.*$', PurchaseOrderLineItemList.as_view(), name='api-po-line-list'),
|
||||
re_path(r'^po-line/', include([
|
||||
path('<int:pk>/', PurchaseOrderLineItemDetail.as_view(), name='api-po-line-detail'),
|
||||
re_path(r'^.*$', PurchaseOrderLineItemList.as_view(), name='api-po-line-list'),
|
||||
])),
|
||||
|
||||
# API endpoints for purchase order extra line
|
||||
url(r'^po-extra-line/', include([
|
||||
url(r'^(?P<pk>\d+)/$', PurchaseOrderExtraLineDetail.as_view(), name='api-po-extra-line-detail'),
|
||||
url(r'^$', PurchaseOrderExtraLineList.as_view(), name='api-po-extra-line-list'),
|
||||
re_path(r'^po-extra-line/', include([
|
||||
path('<int:pk>/', PurchaseOrderExtraLineDetail.as_view(), name='api-po-extra-line-detail'),
|
||||
path('', PurchaseOrderExtraLineList.as_view(), name='api-po-extra-line-list'),
|
||||
])),
|
||||
|
||||
# API endpoints for sales ordesr
|
||||
url(r'^so/', include([
|
||||
url(r'attachment/', include([
|
||||
url(r'^(?P<pk>\d+)/$', SalesOrderAttachmentDetail.as_view(), name='api-so-attachment-detail'),
|
||||
url(r'^.*$', SalesOrderAttachmentList.as_view(), name='api-so-attachment-list'),
|
||||
re_path(r'^so/', include([
|
||||
re_path(r'attachment/', include([
|
||||
path('<int:pk>/', SalesOrderAttachmentDetail.as_view(), name='api-so-attachment-detail'),
|
||||
re_path(r'^.*$', SalesOrderAttachmentList.as_view(), name='api-so-attachment-list'),
|
||||
])),
|
||||
|
||||
url(r'^shipment/', include([
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^ship/$', SalesOrderShipmentComplete.as_view(), name='api-so-shipment-ship'),
|
||||
url(r'^.*$', SalesOrderShipmentDetail.as_view(), name='api-so-shipment-detail'),
|
||||
re_path(r'^shipment/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
path('ship/', SalesOrderShipmentComplete.as_view(), name='api-so-shipment-ship'),
|
||||
re_path(r'^.*$', SalesOrderShipmentDetail.as_view(), name='api-so-shipment-detail'),
|
||||
])),
|
||||
url(r'^.*$', SalesOrderShipmentList.as_view(), name='api-so-shipment-list'),
|
||||
re_path(r'^.*$', SalesOrderShipmentList.as_view(), name='api-so-shipment-list'),
|
||||
])),
|
||||
|
||||
# Sales order detail view
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^complete/', SalesOrderComplete.as_view(), name='api-so-complete'),
|
||||
url(r'^allocate/', SalesOrderAllocate.as_view(), name='api-so-allocate'),
|
||||
url(r'^allocate-serials/', SalesOrderAllocateSerials.as_view(), name='api-so-allocate-serials'),
|
||||
url(r'^.*$', SalesOrderDetail.as_view(), name='api-so-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^complete/', SalesOrderComplete.as_view(), name='api-so-complete'),
|
||||
re_path(r'^allocate/', SalesOrderAllocate.as_view(), name='api-so-allocate'),
|
||||
re_path(r'^allocate-serials/', SalesOrderAllocateSerials.as_view(), name='api-so-allocate-serials'),
|
||||
re_path(r'^.*$', SalesOrderDetail.as_view(), name='api-so-detail'),
|
||||
])),
|
||||
|
||||
# Sales order list view
|
||||
url(r'^.*$', SalesOrderList.as_view(), name='api-so-list'),
|
||||
re_path(r'^.*$', SalesOrderList.as_view(), name='api-so-list'),
|
||||
])),
|
||||
|
||||
# API endpoints for sales order line items
|
||||
url(r'^so-line/', include([
|
||||
url(r'^(?P<pk>\d+)/$', SalesOrderLineItemDetail.as_view(), name='api-so-line-detail'),
|
||||
url(r'^$', SalesOrderLineItemList.as_view(), name='api-so-line-list'),
|
||||
re_path(r'^so-line/', include([
|
||||
path('<int:pk>/', SalesOrderLineItemDetail.as_view(), name='api-so-line-detail'),
|
||||
path('', SalesOrderLineItemList.as_view(), name='api-so-line-list'),
|
||||
])),
|
||||
|
||||
# API endpoints for sales order extra line
|
||||
url(r'^so-extra-line/', include([
|
||||
url(r'^(?P<pk>\d+)/$', SalesOrderExtraLineDetail.as_view(), name='api-so-extra-line-detail'),
|
||||
url(r'^$', SalesOrderExtraLineList.as_view(), name='api-so-extra-line-list'),
|
||||
re_path(r'^so-extra-line/', include([
|
||||
path('<int:pk>/', SalesOrderExtraLineDetail.as_view(), name='api-so-extra-line-detail'),
|
||||
path('', SalesOrderExtraLineList.as_view(), name='api-so-extra-line-list'),
|
||||
])),
|
||||
|
||||
# API endpoints for sales order allocations
|
||||
url(r'^so-allocation/', include([
|
||||
url(r'^(?P<pk>\d+)/$', SalesOrderAllocationDetail.as_view(), name='api-so-allocation-detail'),
|
||||
url(r'^.*$', SalesOrderAllocationList.as_view(), name='api-so-allocation-list'),
|
||||
re_path(r'^so-allocation/', include([
|
||||
path('<int:pk>/', SalesOrderAllocationDetail.as_view(), name='api-so-allocation-detail'),
|
||||
re_path(r'^.*$', SalesOrderAllocationList.as_view(), name='api-so-allocation-list'),
|
||||
])),
|
||||
]
|
||||
|
@ -6,7 +6,7 @@ Django Forms for interacting with Order objects
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from InvenTree.forms import HelperForm
|
||||
from InvenTree.fields import InvenTreeMoneyField
|
||||
|
@ -33,7 +33,7 @@ def calculate_shipped_quantity(apps, schema_editor):
|
||||
part=item.part
|
||||
)
|
||||
|
||||
q = sum([item.quantity for item in items])
|
||||
q = sum(item.quantity for item in items)
|
||||
|
||||
item.shipped = q
|
||||
|
||||
|
@ -17,7 +17,7 @@ from django.core.validators import MinValueValidator
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.contrib.auth.models import User
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from markdownx.models import MarkdownxField
|
||||
from mptt.models import TreeForeignKey
|
||||
@ -49,7 +49,7 @@ def get_next_po_number():
|
||||
|
||||
order = PurchaseOrder.objects.exclude(reference=None).last()
|
||||
|
||||
attempts = set([order.reference])
|
||||
attempts = {order.reference}
|
||||
|
||||
reference = order.reference
|
||||
|
||||
@ -78,7 +78,7 @@ def get_next_so_number():
|
||||
|
||||
order = SalesOrder.objects.exclude(reference=None).last()
|
||||
|
||||
attempts = set([order.reference])
|
||||
attempts = {order.reference}
|
||||
|
||||
reference = order.reference
|
||||
|
||||
@ -161,10 +161,10 @@ class Order(ReferenceIndexingMixin):
|
||||
# gather name reference
|
||||
price_ref = 'sale_price' if isinstance(self, SalesOrder) else 'purchase_price'
|
||||
# order items
|
||||
total += sum([a.quantity * convert_money(getattr(a, price_ref), target_currency) for a in self.lines.all() if getattr(a, price_ref)])
|
||||
total += sum(a.quantity * convert_money(getattr(a, price_ref), target_currency) for a in self.lines.all() if getattr(a, price_ref))
|
||||
|
||||
# extra lines
|
||||
total += sum([a.quantity * convert_money(a.price, target_currency) for a in self.extra_lines.all() if a.price])
|
||||
total += sum(a.quantity * convert_money(a.price, target_currency) for a in self.extra_lines.all() if a.price)
|
||||
|
||||
# set decimal-places
|
||||
total.decimal_places = 4
|
||||
|
@ -7,7 +7,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django.core.exceptions import ValidationError as DjangoValidationError
|
||||
from django.db import models, transaction
|
||||
|
@ -5,50 +5,50 @@ URL lookup for the Order app. Provides URL endpoints for:
|
||||
- Detail view of Purchase Orders
|
||||
"""
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
|
||||
from . import views
|
||||
|
||||
purchase_order_detail_urls = [
|
||||
|
||||
url(r'^cancel/', views.PurchaseOrderCancel.as_view(), name='po-cancel'),
|
||||
url(r'^issue/', views.PurchaseOrderIssue.as_view(), name='po-issue'),
|
||||
url(r'^complete/', views.PurchaseOrderComplete.as_view(), name='po-complete'),
|
||||
re_path(r'^cancel/', views.PurchaseOrderCancel.as_view(), name='po-cancel'),
|
||||
re_path(r'^issue/', views.PurchaseOrderIssue.as_view(), name='po-issue'),
|
||||
re_path(r'^complete/', views.PurchaseOrderComplete.as_view(), name='po-complete'),
|
||||
|
||||
url(r'^upload/', views.PurchaseOrderUpload.as_view(), name='po-upload'),
|
||||
url(r'^export/', views.PurchaseOrderExport.as_view(), name='po-export'),
|
||||
re_path(r'^upload/', views.PurchaseOrderUpload.as_view(), name='po-upload'),
|
||||
re_path(r'^export/', views.PurchaseOrderExport.as_view(), name='po-export'),
|
||||
|
||||
url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='po-detail'),
|
||||
re_path(r'^.*$', views.PurchaseOrderDetail.as_view(), name='po-detail'),
|
||||
]
|
||||
|
||||
purchase_order_urls = [
|
||||
|
||||
url(r'^order-parts/', views.OrderParts.as_view(), name='order-parts'),
|
||||
url(r'^pricing/', views.LineItemPricing.as_view(), name='line-pricing'),
|
||||
re_path(r'^order-parts/', views.OrderParts.as_view(), name='order-parts'),
|
||||
re_path(r'^pricing/', views.LineItemPricing.as_view(), name='line-pricing'),
|
||||
|
||||
# Display detail view for a single purchase order
|
||||
url(r'^(?P<pk>\d+)/', include(purchase_order_detail_urls)),
|
||||
re_path(r'^(?P<pk>\d+)/', include(purchase_order_detail_urls)),
|
||||
|
||||
# Display complete list of purchase orders
|
||||
url(r'^.*$', views.PurchaseOrderIndex.as_view(), name='po-index'),
|
||||
re_path(r'^.*$', views.PurchaseOrderIndex.as_view(), name='po-index'),
|
||||
]
|
||||
|
||||
sales_order_detail_urls = [
|
||||
url(r'^cancel/', views.SalesOrderCancel.as_view(), name='so-cancel'),
|
||||
url(r'^export/', views.SalesOrderExport.as_view(), name='so-export'),
|
||||
re_path(r'^cancel/', views.SalesOrderCancel.as_view(), name='so-cancel'),
|
||||
re_path(r'^export/', views.SalesOrderExport.as_view(), name='so-export'),
|
||||
|
||||
url(r'^.*$', views.SalesOrderDetail.as_view(), name='so-detail'),
|
||||
re_path(r'^.*$', views.SalesOrderDetail.as_view(), name='so-detail'),
|
||||
]
|
||||
|
||||
sales_order_urls = [
|
||||
# Display detail view for a single SalesOrder
|
||||
url(r'^(?P<pk>\d+)/', include(sales_order_detail_urls)),
|
||||
re_path(r'^(?P<pk>\d+)/', include(sales_order_detail_urls)),
|
||||
|
||||
# Display list of all sales orders
|
||||
url(r'^.*$', views.SalesOrderIndex.as_view(), name='so-index'),
|
||||
re_path(r'^.*$', views.SalesOrderIndex.as_view(), name='so-index'),
|
||||
]
|
||||
|
||||
order_urls = [
|
||||
url(r'^purchase-order/', include(purchase_order_urls)),
|
||||
url(r'^sales-order/', include(sales_order_urls)),
|
||||
re_path(r'^purchase-order/', include(purchase_order_urls)),
|
||||
re_path(r'^sales-order/', include(sales_order_urls)),
|
||||
]
|
||||
|
@ -11,7 +11,7 @@ from django.http.response import JsonResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.urls import reverse
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import DetailView, ListView
|
||||
from django.forms import HiddenInput, IntegerField
|
||||
|
||||
|
@ -7,11 +7,11 @@ from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, path, re_path
|
||||
from django.http import JsonResponse
|
||||
from django.db.models import Q, F, Count, Min, Max, Avg
|
||||
from django.db import transaction
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
@ -1916,100 +1916,100 @@ class BomItemSubstituteDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
part_api_urls = [
|
||||
|
||||
# Base URL for PartCategory API endpoints
|
||||
url(r'^category/', include([
|
||||
url(r'^tree/', CategoryTree.as_view(), name='api-part-category-tree'),
|
||||
url(r'^parameters/', CategoryParameterList.as_view(), name='api-part-category-parameter-list'),
|
||||
re_path(r'^category/', include([
|
||||
re_path(r'^tree/', CategoryTree.as_view(), name='api-part-category-tree'),
|
||||
re_path(r'^parameters/', CategoryParameterList.as_view(), name='api-part-category-parameter-list'),
|
||||
|
||||
url(r'^(?P<pk>\d+)/?', CategoryDetail.as_view(), name='api-part-category-detail'),
|
||||
url(r'^$', CategoryList.as_view(), name='api-part-category-list'),
|
||||
re_path(r'^(?P<pk>\d+)/?', CategoryDetail.as_view(), name='api-part-category-detail'),
|
||||
path('', CategoryList.as_view(), name='api-part-category-list'),
|
||||
])),
|
||||
|
||||
# Base URL for PartTestTemplate API endpoints
|
||||
url(r'^test-template/', include([
|
||||
url(r'^(?P<pk>\d+)/', PartTestTemplateDetail.as_view(), name='api-part-test-template-detail'),
|
||||
url(r'^$', PartTestTemplateList.as_view(), name='api-part-test-template-list'),
|
||||
re_path(r'^test-template/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', PartTestTemplateDetail.as_view(), name='api-part-test-template-detail'),
|
||||
path('', PartTestTemplateList.as_view(), name='api-part-test-template-list'),
|
||||
])),
|
||||
|
||||
# Base URL for PartAttachment API endpoints
|
||||
url(r'^attachment/', include([
|
||||
url(r'^(?P<pk>\d+)/', PartAttachmentDetail.as_view(), name='api-part-attachment-detail'),
|
||||
url(r'^$', PartAttachmentList.as_view(), name='api-part-attachment-list'),
|
||||
re_path(r'^attachment/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', PartAttachmentDetail.as_view(), name='api-part-attachment-detail'),
|
||||
path('', PartAttachmentList.as_view(), name='api-part-attachment-list'),
|
||||
])),
|
||||
|
||||
# Base URL for part sale pricing
|
||||
url(r'^sale-price/', include([
|
||||
url(r'^(?P<pk>\d+)/', PartSalePriceDetail.as_view(), name='api-part-sale-price-detail'),
|
||||
url(r'^.*$', PartSalePriceList.as_view(), name='api-part-sale-price-list'),
|
||||
re_path(r'^sale-price/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', PartSalePriceDetail.as_view(), name='api-part-sale-price-detail'),
|
||||
re_path(r'^.*$', PartSalePriceList.as_view(), name='api-part-sale-price-list'),
|
||||
])),
|
||||
|
||||
# Base URL for part internal pricing
|
||||
url(r'^internal-price/', include([
|
||||
url(r'^(?P<pk>\d+)/', PartInternalPriceDetail.as_view(), name='api-part-internal-price-detail'),
|
||||
url(r'^.*$', PartInternalPriceList.as_view(), name='api-part-internal-price-list'),
|
||||
re_path(r'^internal-price/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', PartInternalPriceDetail.as_view(), name='api-part-internal-price-detail'),
|
||||
re_path(r'^.*$', PartInternalPriceList.as_view(), name='api-part-internal-price-list'),
|
||||
])),
|
||||
|
||||
# Base URL for PartRelated API endpoints
|
||||
url(r'^related/', include([
|
||||
url(r'^(?P<pk>\d+)/', PartRelatedDetail.as_view(), name='api-part-related-detail'),
|
||||
url(r'^.*$', PartRelatedList.as_view(), name='api-part-related-list'),
|
||||
re_path(r'^related/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', PartRelatedDetail.as_view(), name='api-part-related-detail'),
|
||||
re_path(r'^.*$', PartRelatedList.as_view(), name='api-part-related-list'),
|
||||
])),
|
||||
|
||||
# Base URL for PartParameter API endpoints
|
||||
url(r'^parameter/', include([
|
||||
url(r'^template/$', PartParameterTemplateList.as_view(), name='api-part-parameter-template-list'),
|
||||
re_path(r'^parameter/', include([
|
||||
path('template/', PartParameterTemplateList.as_view(), name='api-part-parameter-template-list'),
|
||||
|
||||
url(r'^(?P<pk>\d+)/', PartParameterDetail.as_view(), name='api-part-parameter-detail'),
|
||||
url(r'^.*$', PartParameterList.as_view(), name='api-part-parameter-list'),
|
||||
re_path(r'^(?P<pk>\d+)/', PartParameterDetail.as_view(), name='api-part-parameter-detail'),
|
||||
re_path(r'^.*$', PartParameterList.as_view(), name='api-part-parameter-list'),
|
||||
])),
|
||||
|
||||
url(r'^thumbs/', include([
|
||||
url(r'^$', PartThumbs.as_view(), name='api-part-thumbs'),
|
||||
url(r'^(?P<pk>\d+)/?', PartThumbsUpdate.as_view(), name='api-part-thumbs-update'),
|
||||
re_path(r'^thumbs/', include([
|
||||
path('', PartThumbs.as_view(), name='api-part-thumbs'),
|
||||
re_path(r'^(?P<pk>\d+)/?', PartThumbsUpdate.as_view(), name='api-part-thumbs-update'),
|
||||
])),
|
||||
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
|
||||
# Endpoint for extra serial number information
|
||||
url(r'^serial-numbers/', PartSerialNumberDetail.as_view(), name='api-part-serial-number-detail'),
|
||||
re_path(r'^serial-numbers/', PartSerialNumberDetail.as_view(), name='api-part-serial-number-detail'),
|
||||
|
||||
# Endpoint for future scheduling information
|
||||
url(r'^scheduling/', PartScheduling.as_view(), name='api-part-scheduling'),
|
||||
re_path(r'^scheduling/', PartScheduling.as_view(), name='api-part-scheduling'),
|
||||
|
||||
# Endpoint for duplicating a BOM for the specific Part
|
||||
url(r'^bom-copy/', PartCopyBOM.as_view(), name='api-part-bom-copy'),
|
||||
re_path(r'^bom-copy/', PartCopyBOM.as_view(), name='api-part-bom-copy'),
|
||||
|
||||
# Endpoint for validating a BOM for the specific Part
|
||||
url(r'^bom-validate/', PartValidateBOM.as_view(), name='api-part-bom-validate'),
|
||||
re_path(r'^bom-validate/', PartValidateBOM.as_view(), name='api-part-bom-validate'),
|
||||
|
||||
# Part detail endpoint
|
||||
url(r'^.*$', PartDetail.as_view(), name='api-part-detail'),
|
||||
re_path(r'^.*$', PartDetail.as_view(), name='api-part-detail'),
|
||||
])),
|
||||
|
||||
url(r'^.*$', PartList.as_view(), name='api-part-list'),
|
||||
re_path(r'^.*$', PartList.as_view(), name='api-part-list'),
|
||||
]
|
||||
|
||||
bom_api_urls = [
|
||||
|
||||
url(r'^substitute/', include([
|
||||
re_path(r'^substitute/', include([
|
||||
|
||||
# Detail view
|
||||
url(r'^(?P<pk>\d+)/', BomItemSubstituteDetail.as_view(), name='api-bom-substitute-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', BomItemSubstituteDetail.as_view(), name='api-bom-substitute-detail'),
|
||||
|
||||
# Catch all
|
||||
url(r'^.*$', BomItemSubstituteList.as_view(), name='api-bom-substitute-list'),
|
||||
re_path(r'^.*$', BomItemSubstituteList.as_view(), name='api-bom-substitute-list'),
|
||||
])),
|
||||
|
||||
# BOM Item Detail
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^validate/?', BomItemValidate.as_view(), name='api-bom-item-validate'),
|
||||
url(r'^.*$', BomDetail.as_view(), name='api-bom-item-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^validate/?', BomItemValidate.as_view(), name='api-bom-item-validate'),
|
||||
re_path(r'^.*$', BomDetail.as_view(), name='api-bom-item-detail'),
|
||||
])),
|
||||
|
||||
# API endpoint URLs for importing BOM data
|
||||
url(r'^import/upload/', BomImportUpload.as_view(), name='api-bom-import-upload'),
|
||||
url(r'^import/extract/', BomImportExtract.as_view(), name='api-bom-import-extract'),
|
||||
url(r'^import/submit/', BomImportSubmit.as_view(), name='api-bom-import-submit'),
|
||||
re_path(r'^import/upload/', BomImportUpload.as_view(), name='api-bom-import-upload'),
|
||||
re_path(r'^import/extract/', BomImportExtract.as_view(), name='api-bom-import-extract'),
|
||||
re_path(r'^import/submit/', BomImportSubmit.as_view(), name='api-bom-import-submit'),
|
||||
|
||||
# Catch-all
|
||||
url(r'^.*$', BomList.as_view(), name='api-bom-list'),
|
||||
re_path(r'^.*$', BomList.as_view(), name='api-bom-list'),
|
||||
]
|
||||
|
@ -6,7 +6,7 @@ Django Forms for interacting with Part objects
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from mptt.fields import TreeNodeChoiceField
|
||||
|
||||
|
@ -2510,7 +2510,7 @@ def validate_template_name(name):
|
||||
Prevent illegal characters in "name" field for PartParameterTemplate
|
||||
"""
|
||||
|
||||
for c in "!@#$%^&*()<>{}[].,?/\|~`_+-=\'\"":
|
||||
for c in "!@#$%^&*()<>{}[].,?/\\|~`_+-=\'\"":
|
||||
if c in str(name):
|
||||
raise ValidationError(_(f"Illegal character in template name ({c})"))
|
||||
|
||||
|
@ -11,7 +11,7 @@ from django.db.models import ExpressionWrapper, F, Q, Func
|
||||
from django.db.models import Subquery, OuterRef, FloatField
|
||||
|
||||
from django.db.models.functions import Coalesce
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from rest_framework import serializers
|
||||
from sql_util.utils import SubqueryCount, SubquerySum
|
||||
|
@ -3,7 +3,7 @@ from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
import InvenTree.helpers
|
||||
import InvenTree.tasks
|
||||
|
@ -12,7 +12,7 @@ import logging
|
||||
|
||||
from django.utils.html import format_html
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.conf import settings as djangosettings
|
||||
|
||||
from django import template
|
||||
|
@ -8,53 +8,53 @@ URL lookup for Part app. Provides URL endpoints for:
|
||||
|
||||
"""
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
|
||||
from . import views
|
||||
|
||||
|
||||
part_parameter_urls = [
|
||||
url(r'^template/new/', views.PartParameterTemplateCreate.as_view(), name='part-param-template-create'),
|
||||
url(r'^template/(?P<pk>\d+)/edit/', views.PartParameterTemplateEdit.as_view(), name='part-param-template-edit'),
|
||||
url(r'^template/(?P<pk>\d+)/delete/', views.PartParameterTemplateDelete.as_view(), name='part-param-template-edit'),
|
||||
re_path(r'^template/new/', views.PartParameterTemplateCreate.as_view(), name='part-param-template-create'),
|
||||
re_path(r'^template/(?P<pk>\d+)/edit/', views.PartParameterTemplateEdit.as_view(), name='part-param-template-edit'),
|
||||
re_path(r'^template/(?P<pk>\d+)/delete/', views.PartParameterTemplateDelete.as_view(), name='part-param-template-edit'),
|
||||
]
|
||||
|
||||
part_detail_urls = [
|
||||
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
|
||||
url(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'),
|
||||
re_path(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
|
||||
re_path(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'),
|
||||
|
||||
url(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'),
|
||||
re_path(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'),
|
||||
|
||||
url(r'^bom-upload/?', views.BomUpload.as_view(), name='upload-bom'),
|
||||
re_path(r'^bom-upload/?', views.BomUpload.as_view(), name='upload-bom'),
|
||||
|
||||
url(r'^qr_code/?', views.PartQRCode.as_view(), name='part-qr'),
|
||||
re_path(r'^qr_code/?', views.PartQRCode.as_view(), name='part-qr'),
|
||||
|
||||
# Normal thumbnail with form
|
||||
url(r'^thumb-select/?', views.PartImageSelect.as_view(), name='part-image-select'),
|
||||
url(r'^thumb-download/', views.PartImageDownloadFromURL.as_view(), name='part-image-download'),
|
||||
re_path(r'^thumb-select/?', views.PartImageSelect.as_view(), name='part-image-select'),
|
||||
re_path(r'^thumb-download/', views.PartImageDownloadFromURL.as_view(), name='part-image-download'),
|
||||
|
||||
# Any other URLs go to the part detail page
|
||||
url(r'^.*$', views.PartDetail.as_view(), name='part-detail'),
|
||||
re_path(r'^.*$', views.PartDetail.as_view(), name='part-detail'),
|
||||
]
|
||||
|
||||
category_parameter_urls = [
|
||||
url(r'^new/', views.CategoryParameterTemplateCreate.as_view(), name='category-param-template-create'),
|
||||
url(r'^(?P<pid>\d+)/edit/', views.CategoryParameterTemplateEdit.as_view(), name='category-param-template-edit'),
|
||||
url(r'^(?P<pid>\d+)/delete/', views.CategoryParameterTemplateDelete.as_view(), name='category-param-template-delete'),
|
||||
re_path(r'^new/', views.CategoryParameterTemplateCreate.as_view(), name='category-param-template-create'),
|
||||
re_path(r'^(?P<pid>\d+)/edit/', views.CategoryParameterTemplateEdit.as_view(), name='category-param-template-edit'),
|
||||
re_path(r'^(?P<pid>\d+)/delete/', views.CategoryParameterTemplateDelete.as_view(), name='category-param-template-delete'),
|
||||
]
|
||||
|
||||
category_urls = [
|
||||
|
||||
# Top level subcategory display
|
||||
url(r'^subcategory/', views.PartIndex.as_view(template_name='part/subcategory.html'), name='category-index-subcategory'),
|
||||
re_path(r'^subcategory/', views.PartIndex.as_view(template_name='part/subcategory.html'), name='category-index-subcategory'),
|
||||
|
||||
# Category detail views
|
||||
url(r'(?P<pk>\d+)/', include([
|
||||
url(r'^delete/', views.CategoryDelete.as_view(), name='category-delete'),
|
||||
url(r'^parameters/', include(category_parameter_urls)),
|
||||
re_path(r'(?P<pk>\d+)/', include([
|
||||
re_path(r'^delete/', views.CategoryDelete.as_view(), name='category-delete'),
|
||||
re_path(r'^parameters/', include(category_parameter_urls)),
|
||||
|
||||
# Anything else
|
||||
url(r'^.*$', views.CategoryDetail.as_view(), name='category-detail'),
|
||||
re_path(r'^.*$', views.CategoryDetail.as_view(), name='category-detail'),
|
||||
]))
|
||||
]
|
||||
|
||||
@ -62,27 +62,27 @@ category_urls = [
|
||||
part_urls = [
|
||||
|
||||
# Upload a part
|
||||
url(r'^import/', views.PartImport.as_view(), name='part-import'),
|
||||
url(r'^import-api/', views.PartImportAjax.as_view(), name='api-part-import'),
|
||||
re_path(r'^import/', views.PartImport.as_view(), name='part-import'),
|
||||
re_path(r'^import-api/', views.PartImportAjax.as_view(), name='api-part-import'),
|
||||
|
||||
# Download a BOM upload template
|
||||
url(r'^bom_template/?', views.BomUploadTemplate.as_view(), name='bom-upload-template'),
|
||||
re_path(r'^bom_template/?', views.BomUploadTemplate.as_view(), name='bom-upload-template'),
|
||||
|
||||
# Individual part using pk
|
||||
url(r'^(?P<pk>\d+)/', include(part_detail_urls)),
|
||||
re_path(r'^(?P<pk>\d+)/', include(part_detail_urls)),
|
||||
|
||||
# Part category
|
||||
url(r'^category/', include(category_urls)),
|
||||
re_path(r'^category/', include(category_urls)),
|
||||
|
||||
# Part parameters
|
||||
url(r'^parameter/', include(part_parameter_urls)),
|
||||
re_path(r'^parameter/', include(part_parameter_urls)),
|
||||
|
||||
# Change category for multiple parts
|
||||
url(r'^set-category/?', views.PartSetCategory.as_view(), name='part-set-category'),
|
||||
re_path(r'^set-category/?', views.PartSetCategory.as_view(), name='part-set-category'),
|
||||
|
||||
# Individual part using IPN as slug
|
||||
url(r'^(?P<slug>[-\w]+)/', views.PartDetailFromIPN.as_view(), name='part-detail-from-ipn'),
|
||||
re_path(r'^(?P<slug>[-\w]+)/', views.PartDetailFromIPN.as_view(), name='part-detail-from-ipn'),
|
||||
|
||||
# Top level part list (display top level parts and categories)
|
||||
url(r'^.*$', views.PartIndex.as_view(), name='part-index'),
|
||||
re_path(r'^.*$', views.PartIndex.as_view(), name='part-index'),
|
||||
]
|
||||
|
@ -5,7 +5,7 @@ JSON API for the plugin app
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
|
||||
from rest_framework import generics
|
||||
from rest_framework import status
|
||||
@ -118,18 +118,18 @@ class PluginSettingDetail(generics.RetrieveUpdateAPIView):
|
||||
plugin_api_urls = [
|
||||
|
||||
# Plugin settings URLs
|
||||
url(r'^settings/', include([
|
||||
url(r'^(?P<pk>\d+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'),
|
||||
url(r'^.*$', PluginSettingList.as_view(), name='api-plugin-setting-list'),
|
||||
re_path(r'^settings/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'),
|
||||
re_path(r'^.*$', PluginSettingList.as_view(), name='api-plugin-setting-list'),
|
||||
])),
|
||||
|
||||
# Detail views for a single PluginConfig item
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'),
|
||||
])),
|
||||
|
||||
url(r'^install/', PluginInstall.as_view(), name='api-plugin-install'),
|
||||
re_path(r'^install/', PluginInstall.as_view(), name='api-plugin-install'),
|
||||
|
||||
# Anything else
|
||||
url(r'^.*$', PluginList.as_view(), name='api-plugin-list'),
|
||||
re_path(r'^.*$', PluginList.as_view(), name='api-plugin-list'),
|
||||
]
|
||||
|
@ -5,7 +5,7 @@ import logging
|
||||
|
||||
from django.apps import AppConfig
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from maintenance_mode.core import set_maintenance_mode
|
||||
|
||||
|
@ -6,7 +6,7 @@ import logging
|
||||
import json
|
||||
import requests
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
from django.db.utils import OperationalError, ProgrammingError
|
||||
|
||||
from plugin.models import PluginConfig, PluginSetting
|
||||
@ -303,7 +303,7 @@ class UrlsMixin:
|
||||
Urlpatterns for this plugin
|
||||
"""
|
||||
if self.has_urls:
|
||||
return url(f'^{self.slug}/', include((self.urls, self.slug)), name=self.slug)
|
||||
return re_path(f'^{self.slug}/', include((self.urls, self.slug)), name=self.slug)
|
||||
return None
|
||||
|
||||
@property
|
||||
|
@ -7,7 +7,7 @@ from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import transaction
|
||||
|
@ -11,7 +11,7 @@ import pathlib
|
||||
|
||||
from django.urls.base import reverse
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
import plugin.plugin as plugin_base
|
||||
from plugin.helpers import get_git_log, GitStatus
|
||||
|
@ -17,7 +17,7 @@ from importlib import reload
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.db.utils import OperationalError, ProgrammingError, IntegrityError
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
from django.urls import clear_url_caches
|
||||
from django.contrib import admin
|
||||
from django.utils.text import slugify
|
||||
@ -570,12 +570,12 @@ class PluginsRegistry:
|
||||
for index, a in enumerate(urlpatterns):
|
||||
if hasattr(a, 'app_name'):
|
||||
if a.app_name == 'admin':
|
||||
urlpatterns[index] = url(r'^admin/', admin.site.urls, name='inventree-admin')
|
||||
urlpatterns[index] = re_path(r'^admin/', admin.site.urls, name='inventree-admin')
|
||||
elif a.app_name == 'plugin':
|
||||
urlpatterns[index] = get_plugin_urls()
|
||||
|
||||
# replace frontendpatterns
|
||||
global_pattern[0] = url('', include(urlpatterns))
|
||||
global_pattern[0] = re_path('', include(urlpatterns))
|
||||
clear_url_caches()
|
||||
|
||||
def _reload_apps(self, force_reload: bool = False):
|
||||
|
@ -6,8 +6,8 @@ from plugin import IntegrationPluginBase
|
||||
from plugin.mixins import AppMixin, SettingsMixin, UrlsMixin, NavigationMixin
|
||||
|
||||
from django.http import HttpResponse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.conf.urls import url, include
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.urls import include, re_path
|
||||
|
||||
|
||||
class SampleIntegrationPlugin(AppMixin, SettingsMixin, UrlsMixin, NavigationMixin, IntegrationPluginBase):
|
||||
@ -28,13 +28,13 @@ class SampleIntegrationPlugin(AppMixin, SettingsMixin, UrlsMixin, NavigationMixi
|
||||
|
||||
def setup_urls(self):
|
||||
he_urls = [
|
||||
url(r'^he/', self.view_test, name='he'),
|
||||
url(r'^ha/', self.view_test, name='ha'),
|
||||
re_path(r'^he/', self.view_test, name='he'),
|
||||
re_path(r'^ha/', self.view_test, name='ha'),
|
||||
]
|
||||
|
||||
return [
|
||||
url(r'^hi/', self.view_test, name='hi'),
|
||||
url(r'^ho/', include(he_urls), name='ho'),
|
||||
re_path(r'^hi/', self.view_test, name='hi'),
|
||||
re_path(r'^ho/', include(he_urls), name='ho'),
|
||||
]
|
||||
|
||||
SETTINGS = {
|
||||
|
@ -10,7 +10,7 @@ import subprocess
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils import timezone
|
||||
|
||||
from rest_framework import serializers
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from django.test import TestCase
|
||||
from django.conf import settings
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from datetime import datetime
|
||||
@ -66,7 +66,7 @@ class UrlsMixinTest(BaseMixinDefinition, TestCase):
|
||||
class UrlsCls(UrlsMixin, IntegrationPluginBase):
|
||||
def test():
|
||||
return 'ccc'
|
||||
URLS = [url('testpath', test, name='test'), ]
|
||||
URLS = [re_path('testpath', test, name='test'), ]
|
||||
self.mixin = UrlsCls()
|
||||
|
||||
class NoUrlsCls(UrlsMixin, IntegrationPluginBase):
|
||||
@ -81,7 +81,7 @@ class UrlsMixinTest(BaseMixinDefinition, TestCase):
|
||||
self.assertEqual(self.mixin.base_url, target_url)
|
||||
|
||||
# urlpattern
|
||||
target_pattern = url(f'^{plg_name}/', include((self.mixin.urls, plg_name)), name=plg_name)
|
||||
target_pattern = re_path(f'^{plg_name}/', include((self.mixin.urls, plg_name)), name=plg_name)
|
||||
self.assertEqual(self.mixin.urlpatterns.reverse_dict, target_pattern.reverse_dict)
|
||||
|
||||
# resolve the view
|
||||
|
@ -2,7 +2,7 @@
|
||||
URL lookup for plugin app
|
||||
"""
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
|
||||
from plugin import registry
|
||||
|
||||
@ -21,4 +21,4 @@ def get_plugin_urls():
|
||||
if plugin.mixin_enabled('urls'):
|
||||
urls.append(plugin.urlpatterns)
|
||||
|
||||
return url(f'^{PLUGIN_BASE}/', include((urls, 'plugin')))
|
||||
return re_path(f'^{PLUGIN_BASE}/', include((urls, 'plugin')))
|
||||
|
@ -1,8 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.conf.urls import url, include
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.urls import include, path, re_path
|
||||
from django.core.exceptions import ValidationError, FieldError
|
||||
from django.http import HttpResponse
|
||||
|
||||
@ -730,62 +730,62 @@ class SalesOrderReportPrint(generics.RetrieveAPIView, OrderReportMixin, ReportPr
|
||||
report_api_urls = [
|
||||
|
||||
# Purchase order reports
|
||||
url(r'po/', include([
|
||||
re_path(r'po/', include([
|
||||
# Detail views
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'print/', PurchaseOrderReportPrint.as_view(), name='api-po-report-print'),
|
||||
url(r'^$', PurchaseOrderReportDetail.as_view(), name='api-po-report-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'print/', PurchaseOrderReportPrint.as_view(), name='api-po-report-print'),
|
||||
path('', PurchaseOrderReportDetail.as_view(), name='api-po-report-detail'),
|
||||
])),
|
||||
|
||||
# List view
|
||||
url(r'^$', PurchaseOrderReportList.as_view(), name='api-po-report-list'),
|
||||
path('', PurchaseOrderReportList.as_view(), name='api-po-report-list'),
|
||||
])),
|
||||
|
||||
# Sales order reports
|
||||
url(r'so/', include([
|
||||
re_path(r'so/', include([
|
||||
# Detail views
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'print/', SalesOrderReportPrint.as_view(), name='api-so-report-print'),
|
||||
url(r'^$', SalesOrderReportDetail.as_view(), name='api-so-report-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'print/', SalesOrderReportPrint.as_view(), name='api-so-report-print'),
|
||||
path('', SalesOrderReportDetail.as_view(), name='api-so-report-detail'),
|
||||
])),
|
||||
|
||||
url(r'^$', SalesOrderReportList.as_view(), name='api-so-report-list'),
|
||||
path('', SalesOrderReportList.as_view(), name='api-so-report-list'),
|
||||
])),
|
||||
|
||||
# Build reports
|
||||
url(r'build/', include([
|
||||
re_path(r'build/', include([
|
||||
# Detail views
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'print/?', BuildReportPrint.as_view(), name='api-build-report-print'),
|
||||
url(r'^.$', BuildReportDetail.as_view(), name='api-build-report-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'print/?', BuildReportPrint.as_view(), name='api-build-report-print'),
|
||||
re_path(r'^.$', BuildReportDetail.as_view(), name='api-build-report-detail'),
|
||||
])),
|
||||
|
||||
# List view
|
||||
url(r'^.*$', BuildReportList.as_view(), name='api-build-report-list'),
|
||||
re_path(r'^.*$', BuildReportList.as_view(), name='api-build-report-list'),
|
||||
])),
|
||||
|
||||
# Bill of Material reports
|
||||
url(r'bom/', include([
|
||||
re_path(r'bom/', include([
|
||||
|
||||
# Detail views
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'print/?', BOMReportPrint.as_view(), name='api-bom-report-print'),
|
||||
url(r'^.*$', BOMReportDetail.as_view(), name='api-bom-report-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'print/?', BOMReportPrint.as_view(), name='api-bom-report-print'),
|
||||
re_path(r'^.*$', BOMReportDetail.as_view(), name='api-bom-report-detail'),
|
||||
])),
|
||||
|
||||
# List view
|
||||
url(r'^.*$', BOMReportList.as_view(), name='api-bom-report-list'),
|
||||
re_path(r'^.*$', BOMReportList.as_view(), name='api-bom-report-list'),
|
||||
])),
|
||||
|
||||
# Stock item test reports
|
||||
url(r'test/', include([
|
||||
re_path(r'test/', include([
|
||||
# Detail views
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'print/?', StockItemTestReportPrint.as_view(), name='api-stockitem-testreport-print'),
|
||||
url(r'^.*$', StockItemTestReportDetail.as_view(), name='api-stockitem-testreport-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'print/?', StockItemTestReportPrint.as_view(), name='api-stockitem-testreport-print'),
|
||||
re_path(r'^.*$', StockItemTestReportDetail.as_view(), name='api-stockitem-testreport-detail'),
|
||||
])),
|
||||
|
||||
# List view
|
||||
url(r'^.*$', StockItemTestReportList.as_view(), name='api-stockitem-testreport-list'),
|
||||
re_path(r'^.*$', StockItemTestReportList.as_view(), name='api-stockitem-testreport-list'),
|
||||
])),
|
||||
]
|
||||
|
@ -9,11 +9,11 @@ from collections import OrderedDict
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from django.core.exceptions import ValidationError as DjangoValidationError
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, path, re_path
|
||||
from django.http import JsonResponse
|
||||
from django.db.models import Q, F
|
||||
from django.db import transaction
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from django_filters import rest_framework as rest_filters
|
||||
@ -1383,47 +1383,47 @@ class LocationDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
|
||||
|
||||
stock_api_urls = [
|
||||
url(r'^location/', include([
|
||||
re_path(r'^location/', include([
|
||||
|
||||
url(r'^tree/', StockLocationTree.as_view(), name='api-location-tree'),
|
||||
re_path(r'^tree/', StockLocationTree.as_view(), name='api-location-tree'),
|
||||
|
||||
url(r'^(?P<pk>\d+)/', LocationDetail.as_view(), name='api-location-detail'),
|
||||
url(r'^.*$', StockLocationList.as_view(), name='api-location-list'),
|
||||
re_path(r'^(?P<pk>\d+)/', LocationDetail.as_view(), name='api-location-detail'),
|
||||
re_path(r'^.*$', StockLocationList.as_view(), name='api-location-list'),
|
||||
])),
|
||||
|
||||
# Endpoints for bulk stock adjustment actions
|
||||
url(r'^count/', StockCount.as_view(), name='api-stock-count'),
|
||||
url(r'^add/', StockAdd.as_view(), name='api-stock-add'),
|
||||
url(r'^remove/', StockRemove.as_view(), name='api-stock-remove'),
|
||||
url(r'^transfer/', StockTransfer.as_view(), name='api-stock-transfer'),
|
||||
url(r'^assign/', StockAssign.as_view(), name='api-stock-assign'),
|
||||
url(r'^merge/', StockMerge.as_view(), name='api-stock-merge'),
|
||||
re_path(r'^count/', StockCount.as_view(), name='api-stock-count'),
|
||||
re_path(r'^add/', StockAdd.as_view(), name='api-stock-add'),
|
||||
re_path(r'^remove/', StockRemove.as_view(), name='api-stock-remove'),
|
||||
re_path(r'^transfer/', StockTransfer.as_view(), name='api-stock-transfer'),
|
||||
re_path(r'^assign/', StockAssign.as_view(), name='api-stock-assign'),
|
||||
re_path(r'^merge/', StockMerge.as_view(), name='api-stock-merge'),
|
||||
|
||||
# StockItemAttachment API endpoints
|
||||
url(r'^attachment/', include([
|
||||
url(r'^(?P<pk>\d+)/', StockAttachmentDetail.as_view(), name='api-stock-attachment-detail'),
|
||||
url(r'^$', StockAttachmentList.as_view(), name='api-stock-attachment-list'),
|
||||
re_path(r'^attachment/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', StockAttachmentDetail.as_view(), name='api-stock-attachment-detail'),
|
||||
path('', StockAttachmentList.as_view(), name='api-stock-attachment-list'),
|
||||
])),
|
||||
|
||||
# StockItemTestResult API endpoints
|
||||
url(r'^test/', include([
|
||||
url(r'^(?P<pk>\d+)/', StockItemTestResultDetail.as_view(), name='api-stock-test-result-detail'),
|
||||
url(r'^.*$', StockItemTestResultList.as_view(), name='api-stock-test-result-list'),
|
||||
re_path(r'^test/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', StockItemTestResultDetail.as_view(), name='api-stock-test-result-detail'),
|
||||
re_path(r'^.*$', StockItemTestResultList.as_view(), name='api-stock-test-result-list'),
|
||||
])),
|
||||
|
||||
# StockItemTracking API endpoints
|
||||
url(r'^track/', include([
|
||||
url(r'^(?P<pk>\d+)/', StockTrackingDetail.as_view(), name='api-stock-tracking-detail'),
|
||||
url(r'^.*$', StockTrackingList.as_view(), name='api-stock-tracking-list'),
|
||||
re_path(r'^track/', include([
|
||||
re_path(r'^(?P<pk>\d+)/', StockTrackingDetail.as_view(), name='api-stock-tracking-detail'),
|
||||
re_path(r'^.*$', StockTrackingList.as_view(), name='api-stock-tracking-list'),
|
||||
])),
|
||||
|
||||
# Detail views for a single stock item
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^serialize/', StockItemSerialize.as_view(), name='api-stock-item-serialize'),
|
||||
url(r'^install/', StockItemInstall.as_view(), name='api-stock-item-install'),
|
||||
url(r'^.*$', StockDetail.as_view(), name='api-stock-detail'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^serialize/', StockItemSerialize.as_view(), name='api-stock-item-serialize'),
|
||||
re_path(r'^install/', StockItemInstall.as_view(), name='api-stock-item-install'),
|
||||
re_path(r'^.*$', StockDetail.as_view(), name='api-stock-detail'),
|
||||
])),
|
||||
|
||||
# Anything else
|
||||
url(r'^.*$', StockList.as_view(), name='api-stock-list'),
|
||||
re_path(r'^.*$', StockList.as_view(), name='api-stock-list'),
|
||||
]
|
||||
|
@ -7,7 +7,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django import forms
|
||||
from django.forms.utils import ErrorDict
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from mptt.fields import TreeNodeChoiceField
|
||||
|
||||
|
@ -78,7 +78,7 @@ def update_history(apps, schema_editor):
|
||||
tracking_type = StockHistoryCode.STOCK_REMOVE
|
||||
|
||||
# Extract the number of removed items
|
||||
result = re.search("^removed ([\d\.]+) items", title)
|
||||
result = re.search(r"^removed ([\d\.]+) items", title)
|
||||
|
||||
if result:
|
||||
|
||||
@ -102,7 +102,7 @@ def update_history(apps, schema_editor):
|
||||
elif 'moved to' in title:
|
||||
tracking_type = StockHistoryCode.STOCK_MOVE
|
||||
|
||||
result = re.search('^Moved to (.*)( - )*(.*) \(from.*$', entry.title)
|
||||
result = re.search(r'^Moved to (.*)( - )*(.*) \(from.*$', entry.title)
|
||||
|
||||
if result:
|
||||
# Legacy tracking entries recorded the location in multiple ways, because.. why not?
|
||||
@ -157,7 +157,7 @@ def update_history(apps, schema_editor):
|
||||
tracking_type = StockHistoryCode.STOCK_ADD
|
||||
|
||||
# Extract the number of added items
|
||||
result = re.search("^added ([\d\.]+) items", title)
|
||||
result = re.search(r"^added ([\d\.]+) items", title)
|
||||
|
||||
if result:
|
||||
|
||||
|
@ -10,7 +10,7 @@ from datetime import datetime, timedelta
|
||||
from django.db import transaction
|
||||
|
||||
from django.core.exceptions import ValidationError as DjangoValidationError
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.db.models.functions import Coalesce
|
||||
from django.db.models import Case, When, Value
|
||||
from django.db.models import BooleanField
|
||||
|
@ -2,55 +2,55 @@
|
||||
URL lookup for Stock app
|
||||
"""
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, re_path
|
||||
|
||||
from stock import views
|
||||
|
||||
location_urls = [
|
||||
|
||||
url(r'^(?P<pk>\d+)/', include([
|
||||
url(r'^delete/?', views.StockLocationDelete.as_view(), name='stock-location-delete'),
|
||||
url(r'^qr_code/?', views.StockLocationQRCode.as_view(), name='stock-location-qr'),
|
||||
re_path(r'^(?P<pk>\d+)/', include([
|
||||
re_path(r'^delete/?', views.StockLocationDelete.as_view(), name='stock-location-delete'),
|
||||
re_path(r'^qr_code/?', views.StockLocationQRCode.as_view(), name='stock-location-qr'),
|
||||
|
||||
# Anything else
|
||||
url('^.*$', views.StockLocationDetail.as_view(), name='stock-location-detail'),
|
||||
re_path('^.*$', views.StockLocationDetail.as_view(), name='stock-location-detail'),
|
||||
])),
|
||||
|
||||
]
|
||||
|
||||
stock_item_detail_urls = [
|
||||
url(r'^convert/', views.StockItemConvert.as_view(), name='stock-item-convert'),
|
||||
url(r'^delete/', views.StockItemDelete.as_view(), name='stock-item-delete'),
|
||||
url(r'^qr_code/', views.StockItemQRCode.as_view(), name='stock-item-qr'),
|
||||
url(r'^delete_test_data/', views.StockItemDeleteTestData.as_view(), name='stock-item-delete-test-data'),
|
||||
url(r'^return/', views.StockItemReturnToStock.as_view(), name='stock-item-return'),
|
||||
re_path(r'^convert/', views.StockItemConvert.as_view(), name='stock-item-convert'),
|
||||
re_path(r'^delete/', views.StockItemDelete.as_view(), name='stock-item-delete'),
|
||||
re_path(r'^qr_code/', views.StockItemQRCode.as_view(), name='stock-item-qr'),
|
||||
re_path(r'^delete_test_data/', views.StockItemDeleteTestData.as_view(), name='stock-item-delete-test-data'),
|
||||
re_path(r'^return/', views.StockItemReturnToStock.as_view(), name='stock-item-return'),
|
||||
|
||||
url(r'^add_tracking/', views.StockItemTrackingCreate.as_view(), name='stock-tracking-create'),
|
||||
re_path(r'^add_tracking/', views.StockItemTrackingCreate.as_view(), name='stock-tracking-create'),
|
||||
|
||||
url('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'),
|
||||
re_path('^.*$', views.StockItemDetail.as_view(), name='stock-item-detail'),
|
||||
]
|
||||
|
||||
stock_tracking_urls = [
|
||||
|
||||
# edit
|
||||
url(r'^(?P<pk>\d+)/edit/', views.StockItemTrackingEdit.as_view(), name='stock-tracking-edit'),
|
||||
re_path(r'^(?P<pk>\d+)/edit/', views.StockItemTrackingEdit.as_view(), name='stock-tracking-edit'),
|
||||
|
||||
# delete
|
||||
url(r'^(?P<pk>\d+)/delete', views.StockItemTrackingDelete.as_view(), name='stock-tracking-delete'),
|
||||
re_path(r'^(?P<pk>\d+)/delete', views.StockItemTrackingDelete.as_view(), name='stock-tracking-delete'),
|
||||
]
|
||||
|
||||
stock_urls = [
|
||||
# Stock location
|
||||
url(r'^location/', include(location_urls)),
|
||||
re_path(r'^location/', include(location_urls)),
|
||||
|
||||
url(r'^item/uninstall/', views.StockItemUninstall.as_view(), name='stock-item-uninstall'),
|
||||
re_path(r'^item/uninstall/', views.StockItemUninstall.as_view(), name='stock-item-uninstall'),
|
||||
|
||||
url(r'^track/', include(stock_tracking_urls)),
|
||||
re_path(r'^track/', include(stock_tracking_urls)),
|
||||
|
||||
# Individual stock items
|
||||
url(r'^item/(?P<pk>\d+)/', include(stock_item_detail_urls)),
|
||||
re_path(r'^item/(?P<pk>\d+)/', include(stock_item_detail_urls)),
|
||||
|
||||
url(r'^sublocations/', views.StockIndex.as_view(template_name='stock/sublocation.html'), name='stock-sublocations'),
|
||||
re_path(r'^sublocations/', views.StockIndex.as_view(template_name='stock/sublocation.html'), name='stock-sublocations'),
|
||||
|
||||
url(r'^.*$', views.StockIndex.as_view(), name='stock-index'),
|
||||
re_path(r'^.*$', views.StockIndex.as_view(), name='stock-index'),
|
||||
]
|
||||
|
@ -15,7 +15,7 @@ from django.http import HttpResponseRedirect
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Group
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from moneyed import CURRENCIES
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from django.contrib import admin, messages
|
||||
from django import forms
|
||||
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
from django.conf.urls import url, include
|
||||
from django.urls import include, path, re_path
|
||||
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
|
||||
@ -174,14 +174,14 @@ class GetAuthToken(APIView):
|
||||
|
||||
user_urls = [
|
||||
|
||||
url(r'roles/?$', RoleDetails.as_view(), name='api-user-roles'),
|
||||
url(r'token/?$', GetAuthToken.as_view(), name='api-token'),
|
||||
re_path(r'roles/?$', RoleDetails.as_view(), name='api-user-roles'),
|
||||
re_path(r'token/?$', GetAuthToken.as_view(), name='api-token'),
|
||||
|
||||
url(r'^owner/', include([
|
||||
url(r'^(?P<pk>[0-9]+)/$', OwnerDetail.as_view(), name='api-owner-detail'),
|
||||
url(r'^.*$', OwnerList.as_view(), name='api-owner-list'),
|
||||
re_path(r'^owner/', include([
|
||||
path('<int:pk>/', OwnerDetail.as_view(), name='api-owner-detail'),
|
||||
re_path(r'^.*$', OwnerList.as_view(), name='api-owner-list'),
|
||||
])),
|
||||
|
||||
url(r'^(?P<pk>[0-9]+)/?$', UserDetail.as_view(), name='user-detail'),
|
||||
url(r'^$', UserList.as_view()),
|
||||
re_path(r'^(?P<pk>[0-9]+)/?$', UserDetail.as_view(), name='user-detail'),
|
||||
path('', UserList.as_view()),
|
||||
]
|
||||
|
@ -66,7 +66,7 @@ if __name__ == '__main__':
|
||||
|
||||
print("Checking development branch")
|
||||
|
||||
pattern = "^\d+(\.\d+)+ dev$"
|
||||
pattern = r"^\d+(\.\d+)+ dev$"
|
||||
|
||||
result = re.match(pattern, version)
|
||||
|
||||
@ -82,7 +82,7 @@ if __name__ == '__main__':
|
||||
|
||||
print("Checking release branch")
|
||||
|
||||
pattern = "^\d+(\.\d+)+$"
|
||||
pattern = r"^\d+(\.\d+)+$"
|
||||
|
||||
result = re.match(pattern, version)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user