2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-07-09 16:41:25 +00:00

Merge branch 'master' into custom-states

This commit is contained in:
Oliver
2024-11-11 09:56:14 +11:00
committed by GitHub
136 changed files with 10650 additions and 9666 deletions
+42 -4
View File
@@ -30,7 +30,6 @@ from .helpers_email import is_email_configured
from .mixins import ListAPI, RetrieveUpdateAPI
from .status import check_system_health, is_worker_running
from .version import inventreeApiText
from .views import AjaxView
logger = logging.getLogger('inventree')
@@ -196,8 +195,35 @@ class VersionTextView(ListAPI):
return JsonResponse(inventreeApiText())
class InfoView(AjaxView):
"""Simple JSON endpoint for InvenTree information.
class InfoApiSerializer(serializers.Serializer):
"""InvenTree server information - some information might be blanked if called without elevated credentials."""
server = serializers.CharField(read_only=True)
version = serializers.CharField(read_only=True)
instance = serializers.CharField(read_only=True)
apiVersion = serializers.IntegerField(read_only=True) # noqa: N815
worker_running = serializers.BooleanField(read_only=True)
worker_count = serializers.IntegerField(read_only=True)
worker_pending_tasks = serializers.IntegerField(read_only=True)
plugins_enabled = serializers.BooleanField(read_only=True)
plugins_install_disabled = serializers.BooleanField(read_only=True)
active_plugins = serializers.JSONField(read_only=True)
email_configured = serializers.BooleanField(read_only=True)
debug_mode = serializers.BooleanField(read_only=True)
docker_mode = serializers.BooleanField(read_only=True)
default_locale = serializers.ChoiceField(
choices=settings.LOCALE_CODES, read_only=True
)
system_health = serializers.BooleanField(read_only=True)
database = serializers.CharField(read_only=True)
platform = serializers.CharField(read_only=True)
installer = serializers.CharField(read_only=True)
target = serializers.CharField(read_only=True)
django_admin = serializers.CharField(read_only=True)
class InfoView(APIView):
"""JSON endpoint for InvenTree server information.
Use to confirm that the server is running, etc.
"""
@@ -208,6 +234,13 @@ class InfoView(AjaxView):
"""Return the current number of outstanding background tasks."""
return OrmQ.objects.count()
@extend_schema(
responses={
200: OpenApiResponse(
response=InfoApiSerializer, description='InvenTree server information'
)
}
)
def get(self, request, *args, **kwargs):
"""Serve current server information."""
is_staff = request.user.is_staff
@@ -261,7 +294,7 @@ class InfoView(AjaxView):
return False
class NotFoundView(AjaxView):
class NotFoundView(APIView):
"""Simple JSON view when accessing an invalid API view."""
permission_classes = [permissions.AllowAny]
@@ -280,22 +313,27 @@ class NotFoundView(AjaxView):
"""Return 404."""
return self.not_found(request)
@extend_schema(exclude=True)
def get(self, request, *args, **kwargs):
"""Return 404."""
return self.not_found(request)
@extend_schema(exclude=True)
def post(self, request, *args, **kwargs):
"""Return 404."""
return self.not_found(request)
@extend_schema(exclude=True)
def patch(self, request, *args, **kwargs):
"""Return 404."""
return self.not_found(request)
@extend_schema(exclude=True)
def put(self, request, *args, **kwargs):
"""Return 404."""
return self.not_found(request)
@extend_schema(exclude=True)
def delete(self, request, *args, **kwargs):
"""Return 404."""
return self.not_found(request)
+15 -1
View File
@@ -1,13 +1,27 @@
"""InvenTree API version information."""
# InvenTree API version
INVENTREE_API_VERSION = 277
INVENTREE_API_VERSION = 280
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
INVENTREE_API_TEXT = """
v280 - 2024-11-10 : https://github.com/inventree/InvenTree/pull/8461
- Makes schema for API information endpoint more informing
- Removes general not found endpoint
v279 - 2024-11-09 : https://github.com/inventree/InvenTree/pull/8458
- Adds "order_outstanding" and "part" filters to the BuildLine API endpoint
- Adds "order_outstanding" filter to the SalesOrderLineItem API endpoint
v278 - 2024-11-07 : https://github.com/inventree/InvenTree/pull/8445
- Updates to the SalesOrder API endpoints
- Add "shipment count" information to the SalesOrder API endpoints
- Allow null value for SalesOrderAllocation.shipment field
- Additional filtering options for allocation endpoints
v277 - 2024-11-01 : https://github.com/inventree/InvenTree/pull/8278
- Allow build order list to be filtered by "outstanding" (alias for "active")
+18 -17
View File
@@ -36,6 +36,24 @@ def get_token_from_request(request):
return None
# List of target URL endpoints where *do not* want to redirect to
urls = [
reverse_lazy('account_login'),
reverse_lazy('account_logout'),
reverse_lazy('admin:login'),
reverse_lazy('admin:logout'),
]
# Do not redirect requests to any of these paths
paths_ignore = [
'/api/',
'/auth/',
'/js/', # TODO - remove when CUI is removed
settings.MEDIA_URL,
settings.STATIC_URL,
]
class AuthRequiredMiddleware:
"""Check for user to be authenticated."""
@@ -108,23 +126,6 @@ class AuthRequiredMiddleware:
if not authorized:
path = request.path_info
# List of URL endpoints we *do not* want to redirect to
urls = [
reverse_lazy('account_login'),
reverse_lazy('account_logout'),
reverse_lazy('admin:login'),
reverse_lazy('admin:logout'),
]
# Do not redirect requests to any of these paths
paths_ignore = [
'/api/',
'/auth/',
'/js/',
settings.MEDIA_URL,
settings.STATIC_URL,
]
if path not in urls and not any(
path.startswith(p) for p in paths_ignore
):
@@ -2,7 +2,6 @@
from django.conf import settings
from django.http import Http404
from django.test import tag
from django.urls import reverse
from error_report.models import Error
@@ -11,8 +10,6 @@ from InvenTree.exceptions import log_error
from InvenTree.unit_test import InvenTreeTestCase
# TODO change test to not rely on CUI
@tag('cui')
class MiddlewareTests(InvenTreeTestCase):
"""Test for middleware functions."""
@@ -32,25 +29,17 @@ class MiddlewareTests(InvenTreeTestCase):
# logout
self.client.logout()
# check that static files go through
# TODO @matmair re-enable this check
# self.check_path('/static/css/inventree.css', 302)
# check that account things go through
self.check_path(reverse('account_login'))
# logout goes directly to login
self.check_path(reverse('account_logout'))
# check that frontend code is redirected to login
response = self.check_path(reverse('stats'), 302)
self.assertEqual(response.url, '/accounts/login/?next=/stats/')
# check that a 401 is raised
self.check_path(reverse('settings.js'), 401)
response = self.check_path(reverse('index'), 302)
self.assertEqual(response.url, '/accounts/login/?next=/')
def test_token_auth(self):
"""Test auth with token auth."""
target = reverse('settings.js') # for PUI only use 'api-license'
# get token
response = self.client.get(reverse('api-token'), format='json', data={})
token = response.data['token']
@@ -58,16 +47,17 @@ class MiddlewareTests(InvenTreeTestCase):
# logout
self.client.logout()
# this should raise a 401
self.check_path(reverse('settings.js'), 401)
# request with token
self.check_path(reverse('settings.js'), HTTP_Authorization=f'Token {token}')
self.check_path(target, 401)
# Request with broken token
self.check_path(reverse('settings.js'), 401, HTTP_Authorization='Token abcd123')
self.check_path(target, 401, HTTP_Authorization='Token abcd123')
# should still fail without token
self.check_path(reverse('settings.js'), 401)
self.check_path(target, 401)
# request with token
self.check_path(target, HTTP_Authorization=f'Token {token}')
def test_error_exceptions(self):
"""Test that ignored errors are not logged."""
@@ -80,7 +70,7 @@ class MiddlewareTests(InvenTreeTestCase):
# Test normal setup
check()
response = self.client.get(reverse('part-detail', kwargs={'pk': 9999}))
response = self.client.get(reverse('api-part-detail', kwargs={'pk': 9999}))
self.assertEqual(response.status_code, 404)
check()
@@ -92,13 +82,8 @@ class MiddlewareTests(InvenTreeTestCase):
# Test setup without ignored errors
settings.IGNORED_ERRORS = []
response = self.client.get(reverse('part-detail', kwargs={'pk': 9999}))
self.assertEqual(response.status_code, 404)
check(1)
# Test manual logging
try:
raise Http404
except Http404:
log_error('testpath')
check(2)
check(1)
+1 -3
View File
@@ -11,7 +11,7 @@ from django.conf import settings
from django.contrib.auth import get_user_model
from django.core import mail
from django.core.exceptions import ValidationError
from django.test import TestCase, override_settings, tag
from django.test import TestCase, override_settings
from django.urls import reverse
from django.utils import timezone
@@ -1493,8 +1493,6 @@ class MagicLoginTest(InvenTreeTestCase):
self.assertEqual(resp.wsgi_request.user, self.user)
# TODO - refactor to not use CUI
@tag('cui')
class MaintenanceModeTest(InvenTreeTestCase):
"""Unit tests for maintenance mode."""
+3 -1
View File
@@ -477,7 +477,9 @@ if settings.ENABLE_PLATFORM_FRONTEND:
frontendpatterns += [
path(
'accounts/login/',
RedirectView.as_view(url=settings.FRONTEND_URL_BASE, permanent=False),
RedirectView.as_view(
url=f'/{settings.FRONTEND_URL_BASE}', permanent=False
),
name='account_login',
)
]
+33
View File
@@ -357,6 +357,23 @@ class BuildLineFilter(rest_filters.FilterSet):
tracked = rest_filters.BooleanFilter(label=_('Tracked'), field_name='bom_item__sub_part__trackable')
testable = rest_filters.BooleanFilter(label=_('Testable'), field_name='bom_item__sub_part__testable')
part = rest_filters.ModelChoiceFilter(
queryset=part.models.Part.objects.all(),
label=_('Part'),
field_name='bom_item__sub_part',
)
order_outstanding = rest_filters.BooleanFilter(
label=_('Order Outstanding'),
method='filter_order_outstanding'
)
def filter_order_outstanding(self, queryset, name, value):
"""Filter by whether the associated BuildOrder is 'outstanding'."""
if str2bool(value):
return queryset.filter(build__status__in=BuildStatusGroups.ACTIVE_CODES)
return queryset.exclude(build__status__in=BuildStatusGroups.ACTIVE_CODES)
allocated = rest_filters.BooleanFilter(label=_('Allocated'), method='filter_allocated')
def filter_allocated(self, queryset, name, value):
@@ -383,12 +400,28 @@ class BuildLineFilter(rest_filters.FilterSet):
return queryset.exclude(flt)
class BuildLineEndpoint:
"""Mixin class for BuildLine API endpoints."""
queryset = BuildLine.objects.all()
serializer_class = build.serializers.BuildLineSerializer
def get_serializer(self, *args, **kwargs):
"""Return the serializer instance for this endpoint."""
kwargs['context'] = self.get_serializer_context()
try:
params = self.request.query_params
kwargs['part_detail'] = str2bool(params.get('part_detail', True))
kwargs['build_detail'] = str2bool(params.get('build_detail', False))
except AttributeError:
pass
return self.serializer_class(*args, **kwargs)
def get_source_build(self) -> Build:
"""Return the source Build object for the BuildLine queryset.
+23 -2
View File
@@ -1278,8 +1278,6 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali
'pk',
'build',
'bom_item',
'bom_item_detail',
'part_detail',
'quantity',
# Build detail fields
@@ -1315,6 +1313,11 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali
# Extra fields only for data export
'part_description',
'part_category_name',
# Extra detail (related field) serializers
'bom_item_detail',
'part_detail',
'build_detail',
]
read_only_fields = [
@@ -1323,6 +1326,19 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali
'allocations',
]
def __init__(self, *args, **kwargs):
"""Determine which extra details fields should be included"""
part_detail = kwargs.pop('part_detail', True)
build_detail = kwargs.pop('build_detail', False)
super().__init__(*args, **kwargs)
if not part_detail:
self.fields.pop('part_detail', None)
if not build_detail:
self.fields.pop('build_detail', None)
# Build info fields
build_reference = serializers.CharField(source='build.reference', label=_('Build Reference'), read_only=True)
@@ -1362,6 +1378,7 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali
)
part_detail = part_serializers.PartBriefSerializer(source='bom_item.sub_part', many=False, read_only=True, pricing=False)
build_detail = BuildSerializer(source='build', part_detail=False, many=False, read_only=True)
# Annotated (calculated) fields
@@ -1404,9 +1421,13 @@ class BuildLineSerializer(DataImportExportSerializerMixin, InvenTreeModelSeriali
"""
queryset = queryset.select_related(
'build',
'build__part',
'build__part__pricing_data',
'bom_item',
'bom_item__part',
'bom_item__part__pricing_data',
'bom_item__sub_part',
'bom_item__sub_part__pricing_data'
)
# Pre-fetch related fields
+2
View File
@@ -47,6 +47,8 @@ class BuildTestSimple(InvenTreeTestCase):
b1 = Build.objects.get(pk=1)
if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(b1.get_absolute_url(), '/build/1/')
else:
self.assertEqual(b1.get_absolute_url(), '/platform/manufacturing/build-order/1')
def test_is_complete(self):
"""Test build completion status"""
+4
View File
@@ -62,6 +62,10 @@ class CompanySimpleTest(TestCase):
c = Company.objects.get(pk=1)
if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(c.get_absolute_url(), '/company/1/')
else:
self.assertEqual(
c.get_absolute_url(), '/platform/purchasing/manufacturer/1'
)
def test_image_renamer(self):
"""Test the company image upload functionality."""
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Arabic\n"
"Language: ar_SA\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "نقطة نهاية API غير موجودة"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "المستخدم ليس لديه الصلاحية لعرض هذا النموذج"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Bulgarian\n"
"Language: bg_BG\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "Не е намерена крайна точка на API"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Потребителя няма нужното разрешение, за да вижда този модел"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Czech\n"
"Language: cs_CZ\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API endpoint nebyl nalezen"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Uživatel nemá právo zobrazit tento model"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Danish\n"
"Language: da_DK\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API endpoint ikke fundet"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Bruger har ikke tilladelse til at se denne model"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: German\n"
"Language: de_DE\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API-Endpunkt nicht gefunden"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Benutzer hat keine Berechtigung, dieses Modell anzuzeigen"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Greek\n"
"Language: el_GR\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "Το API endpoint δε βρέθηκε"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Δεν έχετε δικαιώματα να το δείτε αυτό"
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 10:24+0000\n"
"POT-Creation-Date: 2024-11-08 08:37+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,23 +18,23 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr ""
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr ""
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Spanish\n"
"Language: es_ES\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "endpoint API no encontrado"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "El usuario no tiene permiso para ver este modelo"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Spanish, Mexico\n"
"Language: es_MX\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "Endpoint de API no encontrado"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "El usuario no tiene permiso para ver este modelo"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Estonian\n"
"Language: et_EE\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr ""
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Teil ei ole selle lehe vaatamiseks luba"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Persian\n"
"Language: fa_IR\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "Address e API peida nashod"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "کاربر سطح دسترسی نمایش این مدل را ندارد"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Finnish\n"
"Language: fi_FI\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API-rajapintaa ei löydy"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Käyttäjän oikeudet eivät riitä kohteen tarkastelemiseen"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 10:27\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: French\n"
"Language: fr_FR\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "Point de terminaison de l'API introuvable"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "L'utilisateur n'a pas la permission de voir ce modèle"
@@ -2249,7 +2249,7 @@ msgstr "Utilisateur ou groupe responsable de ce projet"
#: common/models.py:783 common/models.py:2236 common/models.py:2613
msgid "Settings key"
msgstr ""
msgstr "Paramétrés des touches"
#: common/models.py:787
msgid "Settings value"
@@ -5979,7 +5979,7 @@ msgstr ""
#: order/serializers.py:93
msgid "Copy Lines"
msgstr ""
msgstr "Copier des lignes"
#: order/serializers.py:94
msgid "Copy line items from the original order"
@@ -5987,7 +5987,7 @@ msgstr ""
#: order/serializers.py:100
msgid "Copy Extra Lines"
msgstr ""
msgstr "Copier les lignes supplémentaires"
#: order/serializers.py:101
msgid "Copy extra line items from the original order"
@@ -6168,7 +6168,7 @@ msgstr "Aucune correspondance trouvée pour les numéros de série suivants"
#: order/serializers.py:1678
msgid "The following serial numbers are unavailable"
msgstr "Les numéros de série suivants ne sont pas disponibles"
msgstr "Les numéros de série suivants sont indisponibles"
#: order/serializers.py:1904
msgid "Return order line item"
@@ -7672,7 +7672,7 @@ msgstr ""
#: part/serializers.py:277
msgid "Model ID"
msgstr ""
msgstr "Identifiant du Modèle"
#: part/serializers.py:324
msgid "Number of parts using this template"
@@ -8917,11 +8917,11 @@ msgstr ""
#: plugin/base/ui/serializers.py:30
msgid "Plugin Name"
msgstr ""
msgstr "Nom de l'extension"
#: plugin/base/ui/serializers.py:34
msgid "Feature Type"
msgstr ""
msgstr "Type de fonctionnalité"
#: plugin/base/ui/serializers.py:39
msgid "Feature Label"
@@ -8929,27 +8929,27 @@ msgstr ""
#: plugin/base/ui/serializers.py:44
msgid "Feature Title"
msgstr ""
msgstr "Titre de la fonctionnalité"
#: plugin/base/ui/serializers.py:49
msgid "Feature Description"
msgstr ""
msgstr "Description de la fonctionnalité"
#: plugin/base/ui/serializers.py:54
msgid "Feature Icon"
msgstr ""
msgstr "Icône de fonctionnalité"
#: plugin/base/ui/serializers.py:58
msgid "Feature Options"
msgstr ""
msgstr "Options de fonctionnalité"
#: plugin/base/ui/serializers.py:61
msgid "Feature Context"
msgstr ""
msgstr "Contexte de la fonctionnalité"
#: plugin/base/ui/serializers.py:64
msgid "Feature Source (javascript)"
msgstr ""
msgstr "Source de la fonctionnalité (javascript)"
#: plugin/builtin/barcodes/inventree_barcode.py:27
msgid "InvenTree Barcodes"
@@ -9331,7 +9331,7 @@ msgstr ""
#: plugin/samples/integration/user_interface_sample.py:33
msgid "Enable Purchase Order Panels"
msgstr ""
msgstr "Activer les panneaux de commande"
#: plugin/samples/integration/user_interface_sample.py:34
msgid "Enable custom panels for Purchase Order views"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Hebrew\n"
"Language: he_IL\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr ""
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "למשתמש אין הרשאה לצפות במוזל הזה"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Hindi\n"
"Language: hi_IN\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr ""
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr ""
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Hungarian\n"
"Language: hu_HU\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API funkciót nem találom"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Nincs jogosultságod az adatok megtekintéséhez"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Indonesian\n"
"Language: id_ID\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API endpoint tidak ditemukan"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Pengguna tidak memiliki izin untuk melihat model ini"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Italian\n"
"Language: it_IT\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "Endpoint API non trovato"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "L'utente non ha i permessi per vedere questo modello"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Japanese\n"
"Language: ja_JP\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "APIエンドポイントが見つかりません"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "ユーザーにこのモデルを表示する権限がありません"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Korean\n"
"Language: ko_KR\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr ""
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr ""
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Lithuanian\n"
"Language: lt_LT\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr ""
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr ""
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Latvian\n"
"Language: lv_LV\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API galapunkts nav atrasts"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Lietotājam nav atļaujas, lai apskatītu šo modeli"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Dutch\n"
"Language: nl_NL\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API eindpunt niet gevonden"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr "Ongeldige items lijst verstrekt"
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr "Ongeldige filters opgegeven"
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr "Geen items gevonden om te verwijderen"
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Gebruiker heeft geen rechten om dit model te bekijken"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Norwegian\n"
"Language: no_NO\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API-endepunkt ikke funnet"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Brukeren har ikke rettigheter til å se denne modellen"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Polish\n"
"Language: pl_PL\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "Nie znaleziono punktu końcowego API"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Użytkownik nie ma uprawnień do przeglądania tego modelu"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Portuguese\n"
"Language: pt_PT\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API endpoint não encontrado"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Usuário não tem permissão para ver este modelo"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Portuguese, Brazilian\n"
"Language: pt_BR\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API endpoint não encontrado"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
msgstr "Lista de itens inválida fornecida"
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
msgstr "Filtros inválidos fornecidos"
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
msgstr "Nenhum item encontrado para excluir"
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr ""
@@ -150,7 +150,7 @@ msgstr ""
#: InvenTree/helpers.py:509
msgid "Cannot serialize more than 1000 items at once"
msgstr ""
msgstr "Não é possível serializar mais de 1000 itens de uma vez"
#: InvenTree/helpers.py:515
msgid "Empty serial number string"
@@ -164,7 +164,7 @@ msgstr ""
#: InvenTree/helpers.py:644 InvenTree/helpers.py:663
#, python-brace-format
msgid "Invalid group: {group}"
msgstr ""
msgstr "Grupo invalido:{group}"
#: InvenTree/helpers.py:607
#, python-brace-format
@@ -373,7 +373,7 @@ msgstr "Chinês (tradicional)"
#: InvenTree/magic_login.py:28
msgid "Log in to the app"
msgstr ""
msgstr "Entrar no aplicativo"
#: InvenTree/magic_login.py:38 InvenTree/serializers.py:416
#: company/models.py:133 company/templates/company/company_base.html:138
@@ -522,7 +522,7 @@ msgstr ""
#: InvenTree/models.py:1112
msgid "Task Failure"
msgstr ""
msgstr "Falha na Tarefa"
#: InvenTree/models.py:1114
#, python-brace-format
@@ -643,7 +643,7 @@ msgstr ""
#: InvenTree/serializers.py:632 common/files.py:63
msgid "Unsupported file format"
msgstr ""
msgstr "Formato de arquivo não suportado"
#: InvenTree/serializers.py:638
msgid "File is too large"
@@ -689,7 +689,7 @@ msgstr ""
#: InvenTree/serializers.py:917
msgid "Failed to download image from remote URL"
msgstr ""
msgstr "Falha ao baixar a imagem da URL remota"
#: InvenTree/templatetags/inventree_extras.py:184
msgid "Unknown database"
@@ -6136,7 +6136,7 @@ msgstr ""
#: order/serializers.py:1260
msgid "Allocated Items"
msgstr ""
msgstr "Itens Alocados"
#: order/serializers.py:1374
msgid "No shipment details provided"
@@ -6168,7 +6168,7 @@ msgstr ""
#: order/serializers.py:1678
msgid "The following serial numbers are unavailable"
msgstr ""
msgstr "Os seguintes números de série não estão disponíveis"
#: order/serializers.py:1904
msgid "Return order line item"
@@ -7346,7 +7346,7 @@ msgstr ""
#: part/models.py:3626
msgid "Test templates can only be created for testable parts"
msgstr ""
msgstr "Modelos de teste só podem ser criados para partes testáveis"
#: part/models.py:3637
msgid "Test template with the same key already exists for part"
@@ -7668,11 +7668,11 @@ msgstr ""
#: part/serializers.py:268
msgid "Speculative Quantity"
msgstr ""
msgstr "Quantidade Especulativa"
#: part/serializers.py:277
msgid "Model ID"
msgstr ""
msgstr "ID do modelo"
#: part/serializers.py:324
msgid "Number of parts using this template"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Romanian\n"
"Language: ro_RO\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr ""
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr ""
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Russian\n"
"Language: ru_RU\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "Конечная точка API не обнаружена"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "У пользователя недостаточно прав для просмотра этой модели!"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Slovak\n"
"Language: sk_SK\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr ""
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr ""
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Slovenian\n"
"Language: sl_SI\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API vmesnik ni najden"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Uporabnik nima dovoljenja pogleda tega modela"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Serbian (Latin)\n"
"Language: sr_CS\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API krajnja tačka nije pronađena"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Korisnik nema dozvolu za pregled ovog modela"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-07 00:24\n"
"Last-Translator: \n"
"Language-Team: Swedish\n"
"Language: sv_SE\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API-slutpunkt hittades inte"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Användaren har inte behörighet att se denna modell"
@@ -373,7 +373,7 @@ msgstr "Kinesiska (Traditionell)"
#: InvenTree/magic_login.py:28
msgid "Log in to the app"
msgstr ""
msgstr "Logga in på appen"
#: InvenTree/magic_login.py:38 InvenTree/serializers.py:416
#: company/models.py:133 company/templates/company/company_base.html:138
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Thai\n"
"Language: th_TH\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "ไม่พบ API endpoint"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr ""
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Turkish\n"
"Language: tr_TR\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API uç noktası bulunamadı"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Kullanıcının bu modeli görüntüleme izni yok"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-07 23:53\n"
"Last-Translator: \n"
"Language-Team: Ukrainian\n"
"Language: uk_UA\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "Кінцева точка API не знайдена"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "У користувача немає дозволу на перегляд цієї моделі"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-05 22:31\n"
"Last-Translator: \n"
"Language-Team: Vietnamese\n"
"Language: vi_VN\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "API endpoint không tồn tại"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr ""
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr ""
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr ""
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "Người dùng không được phân quyền xem mẫu này"
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 10:27\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-07 23:53\n"
"Last-Translator: \n"
"Language-Team: Chinese Simplified\n"
"Language: zh_CN\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "未找到 API 端点"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr "提供了无效的单位"
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr "提供了无效的过滤器"
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr "未找到要删除的项目"
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "用户没有权限查阅当前模型。"
@@ -905,7 +905,7 @@ msgstr "生产订单"
#: templates/InvenTree/settings/sidebar.html:55
#: templates/js/translated/search.js:186 users/models.py:207
msgid "Build Orders"
msgstr "生產工單"
msgstr "生产订单"
#: build/models.py:136
msgid "Assembly BOM has not been validated"
@@ -4926,7 +4926,7 @@ msgstr "新建采购订单"
#: templates/js/translated/search.js:219 templates/navbar.html:62
#: users/models.py:209
msgid "Sales Orders"
msgstr "銷售訂單"
msgstr "销售订单"
#: company/templates/company/detail.html:105
#: order/templates/order/sales_orders.html:20
@@ -2,8 +2,8 @@ msgid ""
msgstr ""
"Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-04 03:11+0000\n"
"PO-Revision-Date: 2024-11-04 03:14\n"
"POT-Creation-Date: 2024-11-05 22:28+0000\n"
"PO-Revision-Date: 2024-11-07 23:53\n"
"Last-Translator: \n"
"Language-Team: Chinese Traditional\n"
"Language: zh_TW\n"
@@ -17,23 +17,23 @@ msgstr ""
"X-Crowdin-File: /src/backend/InvenTree/locale/en/LC_MESSAGES/django.po\n"
"X-Crowdin-File-ID: 250\n"
#: InvenTree/api.py:270
#: InvenTree/api.py:273
msgid "API endpoint not found"
msgstr "未找到 API 端點"
#: InvenTree/api.py:387
#: InvenTree/api.py:390
msgid "Invalid items list provided"
msgstr "提供了無效的單位"
#: InvenTree/api.py:396
#: InvenTree/api.py:399
msgid "Invalid filters provided"
msgstr "提供了無效的過濾器"
#: InvenTree/api.py:401
#: InvenTree/api.py:404
msgid "No items found to delete"
msgstr "未找到要刪除的項目"
#: InvenTree/api.py:515
#: InvenTree/api.py:518
msgid "User does not have permission to view this model"
msgstr "用户沒有權限查閲當前模型。"
+38 -4
View File
@@ -816,6 +816,17 @@ class SalesOrderLineItemFilter(LineItemFilter):
return queryset.exclude(order__status__in=SalesOrderStatusGroups.COMPLETE)
order_outstanding = rest_filters.BooleanFilter(
label=_('Order Outstanding'), method='filter_order_outstanding'
)
def filter_order_outstanding(self, queryset, name, value):
"""Filter by whether the order is 'outstanding' or not."""
if str2bool(value):
return queryset.filter(order__status__in=SalesOrderStatusGroups.OPEN)
return queryset.exclude(order__status__in=SalesOrderStatusGroups.OPEN)
class SalesOrderLineItemMixin:
"""Mixin class for SalesOrderLineItem endpoints."""
@@ -978,7 +989,7 @@ class SalesOrderAllocationFilter(rest_filters.FilterSet):
"""Metaclass options."""
model = models.SalesOrderAllocation
fields = ['shipment', 'item']
fields = ['shipment', 'line', 'item']
order = rest_filters.ModelChoiceFilter(
queryset=models.SalesOrder.objects.all(),
@@ -1034,6 +1045,16 @@ class SalesOrderAllocationFilter(rest_filters.FilterSet):
line__order__status__in=SalesOrderStatusGroups.OPEN,
)
assigned_to_shipment = rest_filters.BooleanFilter(
label=_('Has Shipment'), method='filter_assigned_to_shipment'
)
def filter_assigned_to_shipment(self, queryset, name, value):
"""Filter by whether or not the allocation has been assigned to a shipment."""
if str2bool(value):
return queryset.exclude(shipment=None)
return queryset.filter(shipment=None)
class SalesOrderAllocationMixin:
"""Mixin class for SalesOrderAllocation endpoints."""
@@ -1049,12 +1070,16 @@ class SalesOrderAllocationMixin:
'item',
'item__sales_order',
'item__part',
'line__part',
'item__location',
'line__order',
'line__part',
'line__order__responsible',
'line__order__project_code',
'line__order__project_code__responsible',
'shipment',
'shipment__order',
)
'shipment__checked_by',
).select_related('line__part__pricing_data', 'item__part__pricing_data')
return queryset
@@ -1065,7 +1090,15 @@ class SalesOrderAllocationList(SalesOrderAllocationMixin, ListAPI):
filterset_class = SalesOrderAllocationFilter
filter_backends = SEARCH_ORDER_FILTER_ALIAS
ordering_fields = ['quantity', 'part', 'serial', 'batch', 'location', 'order']
ordering_fields = [
'quantity',
'part',
'serial',
'batch',
'location',
'order',
'shipment_date',
]
ordering_field_aliases = {
'part': 'item__part__name',
@@ -1073,6 +1106,7 @@ class SalesOrderAllocationList(SalesOrderAllocationMixin, ListAPI):
'batch': 'item__batch',
'location': 'item__location__name',
'order': 'line__order__reference',
'shipment_date': 'shipment__shipment_date',
}
search_fields = {'item__part__name', 'item__serial', 'item__batch'}
@@ -0,0 +1,19 @@
# Generated by Django 4.2.16 on 2024-11-06 04:46
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('order', '0102_purchaseorder_destination_and_more'),
]
operations = [
migrations.AlterField(
model_name='salesorderallocation',
name='shipment',
field=models.ForeignKey(blank=True, help_text='Sales order shipment reference', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='allocations', to='order.salesordershipment', verbose_name='Shipment'),
),
]
+30 -1
View File
@@ -1105,6 +1105,11 @@ class SalesOrder(TotalPriceMixin, Order):
_('Order cannot be completed as there are incomplete shipments')
)
if self.pending_allocation_count > 0:
raise ValidationError(
_('Order cannot be completed as there are incomplete allocations')
)
if not allow_incomplete_lines and self.pending_line_count > 0:
raise ValidationError(
_('Order cannot be completed as there are incomplete line items')
@@ -1297,6 +1302,23 @@ class SalesOrder(TotalPriceMixin, Order):
"""Return a queryset of the pending shipments for this order."""
return self.shipments.filter(shipment_date=None)
def allocations(self):
"""Return a queryset of all allocations for this order."""
return SalesOrderAllocation.objects.filter(line__order=self)
def pending_allocations(self):
"""Return a queryset of any pending allocations for this order.
Allocations are pending if:
a) They are not associated with a SalesOrderShipment
b) The linked SalesOrderShipment has not been shipped
"""
Q1 = Q(shipment=None)
Q2 = Q(shipment__shipment_date=None)
return self.allocations().filter(Q1 | Q2).distinct()
@property
def shipment_count(self):
"""Return the total number of shipments associated with this order."""
@@ -1312,6 +1334,11 @@ class SalesOrder(TotalPriceMixin, Order):
"""Return the number of pending shipments associated with this order."""
return self.pending_shipments().count()
@property
def pending_allocation_count(self):
"""Return the number of pending (non-shipped) allocations."""
return self.pending_allocations().count()
@receiver(post_save, sender=SalesOrder, dispatch_uid='sales_order_post_save')
def after_save_sales_order(sender, instance: SalesOrder, created: bool, **kwargs):
@@ -2030,7 +2057,7 @@ class SalesOrderAllocation(models.Model):
if self.item.serial and self.quantity != 1:
errors['quantity'] = _('Quantity must be 1 for serialized stock item')
if self.line.order != self.shipment.order:
if self.shipment and self.line.order != self.shipment.order:
errors['line'] = _('Sales order does not match shipment')
errors['shipment'] = _('Shipment does not match sales order')
@@ -2047,6 +2074,8 @@ class SalesOrderAllocation(models.Model):
shipment = models.ForeignKey(
SalesOrderShipment,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name='allocations',
verbose_name=_('Shipment'),
help_text=_('Sales order shipment reference'),
+48 -19
View File
@@ -990,6 +990,8 @@ class SalesOrderSerializer(
'shipment_date',
'total_price',
'order_currency',
'shipments_count',
'completed_shipments_count',
])
read_only_fields = ['status', 'creation_date', 'shipment_date']
@@ -1035,12 +1037,26 @@ class SalesOrderSerializer(
)
)
# Annotate shipment details
queryset = queryset.annotate(
shipments_count=SubqueryCount('shipments'),
completed_shipments_count=SubqueryCount(
'shipments', filter=Q(shipment_date__isnull=False)
),
)
return queryset
customer_detail = CompanyBriefSerializer(
source='customer', many=False, read_only=True
)
shipments_count = serializers.IntegerField(read_only=True, label=_('Shipments'))
completed_shipments_count = serializers.IntegerField(
read_only=True, label=_('Completed Shipments')
)
class SalesOrderIssueSerializer(OrderAdjustSerializer):
"""Serializer for issuing a SalesOrder."""
@@ -1246,6 +1262,15 @@ class SalesOrderShipmentSerializer(NotesFieldMixin, InvenTreeModelSerializer):
'notes',
]
def __init__(self, *args, **kwargs):
"""Initialization routine for the serializer."""
order_detail = kwargs.pop('order_detail', True)
super().__init__(*args, **kwargs)
if not order_detail:
self.fields.pop('order_detail', None)
@staticmethod
def annotate_queryset(queryset):
"""Annotate the queryset with extra information."""
@@ -1276,22 +1301,26 @@ class SalesOrderAllocationSerializer(InvenTreeModelSerializer):
fields = [
'pk',
'line',
'customer_detail',
'serial',
'quantity',
'location',
'location_detail',
'item',
'item_detail',
'order',
'order_detail',
'part',
'part_detail',
'quantity',
'shipment',
# Annotated read-only fields
'line',
'part',
'order',
'serial',
'location',
# Extra detail fields
'item_detail',
'part_detail',
'order_detail',
'customer_detail',
'location_detail',
'shipment_detail',
]
read_only_fields = ['line', '']
def __init__(self, *args, **kwargs):
"""Initialization routine for the serializer."""
order_detail = kwargs.pop('order_detail', False)
@@ -1341,7 +1370,7 @@ class SalesOrderAllocationSerializer(InvenTreeModelSerializer):
)
shipment_detail = SalesOrderShipmentSerializer(
source='shipment', many=False, read_only=True
source='shipment', order_detail=False, many=False, read_only=True
)
@@ -1596,8 +1625,8 @@ class SalesOrderSerialAllocationSerializer(serializers.Serializer):
shipment = serializers.PrimaryKeyRelatedField(
queryset=order.models.SalesOrderShipment.objects.all(),
many=False,
allow_null=False,
required=True,
required=False,
allow_null=True,
label=_('Shipment'),
)
@@ -1609,10 +1638,10 @@ class SalesOrderSerialAllocationSerializer(serializers.Serializer):
"""
order = self.context['order']
if shipment.shipment_date is not None:
if shipment and shipment.shipment_date is not None:
raise ValidationError(_('Shipment has already been shipped'))
if shipment.order != order:
if shipment and shipment.order != order:
raise ValidationError(_('Shipment is not associated with this order'))
return shipment
@@ -1720,8 +1749,8 @@ class SalesOrderShipmentAllocationSerializer(serializers.Serializer):
shipment = serializers.PrimaryKeyRelatedField(
queryset=order.models.SalesOrderShipment.objects.all(),
many=False,
allow_null=False,
required=True,
required=False,
allow_null=True,
label=_('Shipment'),
)
@@ -1756,7 +1785,7 @@ class SalesOrderShipmentAllocationSerializer(serializers.Serializer):
data = self.validated_data
items = data['items']
shipment = data['shipment']
shipment = data.get('shipment')
with transaction.atomic():
for entry in items:
-1
View File
@@ -1877,7 +1877,6 @@ class SalesOrderAllocateTest(OrderTest):
response = self.post(self.url, {}, expected_code=400)
self.assertIn('This field is required', str(response.data['items']))
self.assertIn('This field is required', str(response.data['shipment']))
# Test with a single line items
line = self.order.lines.first()
+5
View File
@@ -46,6 +46,11 @@ class OrderTest(TestCase):
self.assertEqual(
order.get_absolute_url(), f'/order/purchase-order/{pk}/'
)
else:
self.assertEqual(
order.get_absolute_url(),
f'/platform/purchasing/purchase-order/{pk}',
)
self.assertEqual(order.reference, f'PO-{pk:04d}')
@@ -130,6 +130,10 @@ class CategoryTest(TestCase):
"""Test that the PartCategory URL works."""
if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(self.capacitors.get_absolute_url(), '/part/category/3/')
else:
self.assertEqual(
self.capacitors.get_absolute_url(), '/platform/part/category/3'
)
def test_part_count(self):
"""Test that the Category part count works."""
+2
View File
@@ -246,6 +246,8 @@ class PartTest(TestCase):
self.assertEqual(self.r1.name, 'R_2K2_0805')
if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(self.r1.get_absolute_url(), '/part/3/')
else:
self.assertEqual(self.r1.get_absolute_url(), '/platform/part/3')
def test_category(self):
"""Test PartCategory path."""
@@ -289,6 +289,10 @@ class TestInvenTreeBarcode(InvenTreeAPITestCase):
self.assertEqual(
response.data['stocklocation']['web_url'], '/stock/location/5/'
)
else:
self.assertEqual(
response.data['stocklocation']['web_url'], '/platform/stock/location/5'
)
self.assertEqual(response.data['plugin'], 'InvenTreeBarcode')
# Scan a Part object
@@ -332,6 +336,10 @@ class TestInvenTreeBarcode(InvenTreeAPITestCase):
self.assertEqual(
response.data['stocklocation']['web_url'], '/stock/location/5/'
)
else:
self.assertEqual(
response.data['stocklocation']['web_url'], '/platform/stock/location/5'
)
self.assertEqual(response.data['plugin'], 'InvenTreeBarcode')
# Scan a Part object
+77 -124
View File
@@ -50,7 +50,7 @@ from InvenTree.mixins import (
RetrieveAPI,
RetrieveUpdateDestroyAPI,
)
from order.models import PurchaseOrder, ReturnOrder, SalesOrder, SalesOrderAllocation
from order.models import PurchaseOrder, ReturnOrder, SalesOrder
from order.serializers import (
PurchaseOrderSerializer,
ReturnOrderSerializer,
@@ -101,55 +101,6 @@ class GenerateSerialNumber(GenericAPIView):
return Response(data, status=status.HTTP_201_CREATED)
class StockDetail(RetrieveUpdateDestroyAPI):
"""API detail endpoint for Stock object.
get:
Return a single StockItem object
post:
Update a StockItem
delete:
Remove a StockItem
"""
queryset = StockItem.objects.all()
serializer_class = StockSerializers.StockItemSerializer
def get_queryset(self, *args, **kwargs):
"""Annotate queryset."""
queryset = super().get_queryset(*args, **kwargs)
queryset = StockSerializers.StockItemSerializer.annotate_queryset(queryset)
return queryset
def get_serializer_context(self):
"""Extend serializer context."""
ctx = super().get_serializer_context()
ctx['user'] = getattr(self.request, 'user', None)
return ctx
def get_serializer(self, *args, **kwargs):
"""Set context before returning serializer."""
kwargs['context'] = self.get_serializer_context()
try:
params = self.request.query_params
kwargs['part_detail'] = str2bool(params.get('part_detail', True))
kwargs['location_detail'] = str2bool(params.get('location_detail', True))
kwargs['supplier_part_detail'] = str2bool(
params.get('supplier_part_detail', True)
)
kwargs['path_detail'] = str2bool(params.get('path_detail', False))
except AttributeError: # pragma: no cover
pass
return self.serializer_class(*args, **kwargs)
class StockItemContextMixin:
"""Mixin class for adding StockItem object to serializer context."""
@@ -531,54 +482,88 @@ class StockFilter(rest_filters.FilterSet):
)
supplier = rest_filters.ModelChoiceFilter(
label='Supplier',
label=_('Supplier'),
queryset=Company.objects.filter(is_supplier=True),
field_name='supplier_part__supplier',
)
include_variants = rest_filters.BooleanFilter(
label=_('Include Variants'), method='filter_include_variants'
)
def filter_include_variants(self, queryset, name, value):
"""Filter by whether or not to include variants of the selected part.
Note:
- This filter does nothing by itself, and requires the 'part' filter to be set.
- Refer to the 'filter_part' method for more information.
"""
return queryset
part = rest_filters.ModelChoiceFilter(
label=_('Part'), queryset=Part.objects.all(), method='filter_part'
)
def filter_part(self, queryset, name, part):
"""Filter StockItem list by provided Part instance.
Note:
- If "part" is a variant, include all variants of the selected part
- Otherwise, filter by the selected part
"""
include_variants = str2bool(self.data.get('include_variants', True))
if include_variants:
return queryset.filter(part__in=part.get_descendants(include_self=True))
else:
return queryset.filter(part=part)
# Part name filters
name = rest_filters.CharFilter(
label='Part name (case insensitive)',
label=_('Part name (case insensitive)'),
field_name='part__name',
lookup_expr='iexact',
)
name_contains = rest_filters.CharFilter(
label='Part name contains (case insensitive)',
label=_('Part name contains (case insensitive)'),
field_name='part__name',
lookup_expr='icontains',
)
name_regex = rest_filters.CharFilter(
label='Part name (regex)', field_name='part__name', lookup_expr='iregex'
label=_('Part name (regex)'), field_name='part__name', lookup_expr='iregex'
)
# Part IPN filters
IPN = rest_filters.CharFilter(
label='Part IPN (case insensitive)',
label=_('Part IPN (case insensitive)'),
field_name='part__IPN',
lookup_expr='iexact',
)
IPN_contains = rest_filters.CharFilter(
label='Part IPN contains (case insensitive)',
label=_('Part IPN contains (case insensitive)'),
field_name='part__IPN',
lookup_expr='icontains',
)
IPN_regex = rest_filters.CharFilter(
label='Part IPN (regex)', field_name='part__IPN', lookup_expr='iregex'
label=_('Part IPN (regex)'), field_name='part__IPN', lookup_expr='iregex'
)
# Part attribute filters
assembly = rest_filters.BooleanFilter(label='Assembly', field_name='part__assembly')
active = rest_filters.BooleanFilter(label='Active', field_name='part__active')
salable = rest_filters.BooleanFilter(label='Salable', field_name='part__salable')
assembly = rest_filters.BooleanFilter(
label=_('Assembly'), field_name='part__assembly'
)
active = rest_filters.BooleanFilter(label=_('Active'), field_name='part__active')
salable = rest_filters.BooleanFilter(label=_('Salable'), field_name='part__salable')
min_stock = rest_filters.NumberFilter(
label='Minimum stock', field_name='quantity', lookup_expr='gte'
label=_('Minimum stock'), field_name='quantity', lookup_expr='gte'
)
max_stock = rest_filters.NumberFilter(
label='Maximum stock', field_name='quantity', lookup_expr='lte'
label=_('Maximum stock'), field_name='quantity', lookup_expr='lte'
)
status = rest_filters.NumberFilter(label='Status Code', method='filter_status')
status = rest_filters.NumberFilter(label=_('Status Code'), method='filter_status')
def filter_status(self, queryset, name, value):
"""Filter by integer status code."""
@@ -860,17 +845,25 @@ class StockFilter(rest_filters.FilterSet):
return queryset.exclude(stale_filter)
class StockList(DataExportViewMixin, ListCreateDestroyAPIView):
"""API endpoint for list view of Stock objects.
- GET: Return a list of all StockItem objects (with optional query filters)
- POST: Create a new StockItem
- DELETE: Delete multiple StockItem objects
"""
class StockApiMixin:
"""Mixin class for StockItem API endpoints."""
serializer_class = StockSerializers.StockItemSerializer
queryset = StockItem.objects.all()
filterset_class = StockFilter
def get_queryset(self, *args, **kwargs):
"""Annotate queryset."""
queryset = super().get_queryset(*args, **kwargs)
queryset = StockSerializers.StockItemSerializer.annotate_queryset(queryset)
return queryset
def get_serializer_context(self):
"""Extend serializer context."""
ctx = super().get_serializer_context()
ctx['user'] = getattr(self.request, 'user', None)
return ctx
def get_serializer(self, *args, **kwargs):
"""Set context before returning serializer.
@@ -899,12 +892,16 @@ class StockList(DataExportViewMixin, ListCreateDestroyAPIView):
return self.serializer_class(*args, **kwargs)
def get_serializer_context(self):
"""Extend serializer context."""
ctx = super().get_serializer_context()
ctx['user'] = getattr(self.request, 'user', None)
return ctx
class StockList(DataExportViewMixin, StockApiMixin, ListCreateDestroyAPIView):
"""API endpoint for list view of Stock objects.
- GET: Return a list of all StockItem objects (with optional query filters)
- POST: Create a new StockItem
- DELETE: Delete multiple StockItem objects
"""
filterset_class = StockFilter
def create(self, request, *args, **kwargs):
"""Create a new StockItem object via the API.
@@ -1079,14 +1076,6 @@ class StockList(DataExportViewMixin, ListCreateDestroyAPIView):
headers=self.get_success_headers(serializer.data),
)
def get_queryset(self, *args, **kwargs):
"""Annotate queryset before returning."""
queryset = super().get_queryset(*args, **kwargs)
queryset = StockSerializers.StockItemSerializer.annotate_queryset(queryset)
return queryset
def filter_queryset(self, queryset):
"""Custom filtering for the StockItem queryset."""
params = self.request.query_params
@@ -1107,46 +1096,6 @@ class StockList(DataExportViewMixin, ListCreateDestroyAPIView):
except (ValueError, StockItem.DoesNotExist): # pragma: no cover
pass
# Exclude StockItems which are already allocated to a particular SalesOrder
exclude_so_allocation = params.get('exclude_so_allocation', None)
if exclude_so_allocation is not None:
try:
order = SalesOrder.objects.get(pk=exclude_so_allocation)
# Grab all the active SalesOrderAllocations for this order
allocations = SalesOrderAllocation.objects.filter(
line__pk__in=[line.pk for line in order.lines.all()]
)
# Exclude any stock item which is already allocated to the sales order
queryset = queryset.exclude(pk__in=[a.item.pk for a in allocations])
except (ValueError, SalesOrder.DoesNotExist): # pragma: no cover
pass
# Does the client wish to filter by the Part ID?
part_id = params.get('part', None)
if part_id:
try:
part = Part.objects.get(pk=part_id)
# Do we wish to filter *just* for this part, or also for parts *under* this one?
include_variants = str2bool(params.get('include_variants', True))
if include_variants:
# Filter by any parts "under" the given part
parts = part.get_descendants(include_self=True)
queryset = queryset.filter(part__in=parts)
else:
queryset = queryset.filter(part=part)
except (ValueError, Part.DoesNotExist):
raise ValidationError({'part': 'Invalid Part ID specified'})
# Does the client wish to filter by stock location?
loc_id = params.get('location', None)
@@ -1212,6 +1161,10 @@ class StockList(DataExportViewMixin, ListCreateDestroyAPIView):
]
class StockDetail(StockApiMixin, RetrieveUpdateDestroyAPI):
"""API detail endpoint for a single StockItem instance."""
class StockItemTestResultMixin:
"""Mixin class for the StockItemTestResult API endpoints."""
+3
View File
@@ -266,6 +266,9 @@ class StockTest(StockTestBase):
if settings.ENABLE_CLASSIC_FRONTEND:
self.assertEqual(it.get_absolute_url(), '/stock/item/2/')
self.assertEqual(self.home.get_absolute_url(), '/stock/location/1/')
else:
self.assertEqual(it.get_absolute_url(), '/platform/stock/item/2')
self.assertEqual(self.home.get_absolute_url(), '/platform/stock/location/1')
def test_strings(self):
"""Test str function."""
@@ -11,6 +11,8 @@
constructField,
constructForm,
constructOrderTableButtons,
disableFormInput,
enableFormInput,
endDate,
formatCurrency,
FullCalendar,
@@ -1559,17 +1561,35 @@ function showAllocationSubTable(index, row, element, options) {
// Add callbacks for 'edit' buttons
table.find('.button-allocation-edit').click(function() {
var pk = $(this).attr('pk');
let pk = $(this).attr('pk');
let allocation = table.bootstrapTable('getRowByUniqueId', pk);
let disableShipment = allocation && allocation.shipment_detail?.shipment_date;
// Edit the sales order allocation
constructForm(
`/api/order/so-allocation/${pk}/`,
{
fields: {
item: {},
quantity: {},
shipment: {
filters: {
order: allocation.order,
shipped: false,
}
}
},
title: '{% trans "Edit Stock Allocation" %}',
refreshTable: options.table,
afterRender: function(fields, opts) {
disableFormInput('item', opts);
if (disableShipment) {
disableFormInput('shipment', opts);
} else {
enableFormInput('shipment', opts);
}
}
},
);
});
@@ -1593,6 +1613,8 @@ function showAllocationSubTable(index, row, element, options) {
table.bootstrapTable({
url: '{% url "api-so-allocation-list" %}',
onPostBody: setupCallbacks,
uniqueId: 'pk',
idField: 'pk',
queryParams: {
...options.queryParams,
part_detail: true,
@@ -1614,7 +1636,11 @@ function showAllocationSubTable(index, row, element, options) {
field: 'shipment',
title: '{% trans "Shipment" %}',
formatter: function(value, row) {
return row.shipment_detail.reference;
if (row.shipment_detail) {
return row.shipment_detail.reference;
} else {
return '{% trans "No shipment" %}';
}
}
},
{
+1 -3
View File
@@ -2,7 +2,7 @@
from django.apps import apps
from django.contrib.auth.models import Group
from django.test import TestCase, tag
from django.test import TestCase
from django.urls import reverse
from common.settings import set_global_setting
@@ -166,8 +166,6 @@ class OwnerModelTest(InvenTreeTestCase):
self.assertEqual(response.status_code, status_code)
return response.data
# TODO: Find out why this depends on CUI
@tag('cui')
def test_owner(self):
"""Tests for the 'owner' model."""
# Check that owner was created for user