mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge branch 'master' of https://github.com/inventree/InvenTree into plugin-2037
This commit is contained in:
commit
6eee332da8
@ -46,7 +46,7 @@ class InvenTreeAPITestCase(APITestCase):
|
|||||||
self.user.is_staff = True
|
self.user.is_staff = True
|
||||||
|
|
||||||
self.user.save()
|
self.user.save()
|
||||||
|
|
||||||
for role in self.roles:
|
for role in self.roles:
|
||||||
self.assignRole(role)
|
self.assignRole(role)
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
Pull rendered copies of the templated
|
Pull rendered copies of the templated
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.http import response
|
from django.test import TestCase
|
||||||
from django.test import TestCase, testcases
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -53,7 +53,7 @@ class InvenTreeModelMoneyField(ModelMoneyField):
|
|||||||
"""
|
"""
|
||||||
Custom MoneyField for clean migrations while using dynamic currency settings
|
Custom MoneyField for clean migrations while using dynamic currency settings
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
# detect if creating migration
|
# detect if creating migration
|
||||||
if 'migrate' in sys.argv or 'makemigrations' in sys.argv:
|
if 'migrate' in sys.argv or 'makemigrations' in sys.argv:
|
||||||
|
@ -38,7 +38,7 @@ class InvenTreeOrderingFilter(OrderingFilter):
|
|||||||
ordering = []
|
ordering = []
|
||||||
|
|
||||||
for field in ordering_initial:
|
for field in ordering_initial:
|
||||||
|
|
||||||
reverse = field.startswith('-')
|
reverse = field.startswith('-')
|
||||||
|
|
||||||
if reverse:
|
if reverse:
|
||||||
@ -52,7 +52,7 @@ class InvenTreeOrderingFilter(OrderingFilter):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
Potentially, a single field could be "aliased" to multiple field,
|
Potentially, a single field could be "aliased" to multiple field,
|
||||||
|
|
||||||
(For example to enforce a particular ordering sequence)
|
(For example to enforce a particular ordering sequence)
|
||||||
|
|
||||||
e.g. to filter first by the integer value...
|
e.g. to filter first by the integer value...
|
||||||
|
@ -36,7 +36,7 @@ class Command(BaseCommand):
|
|||||||
img = model.image
|
img = model.image
|
||||||
url = img.thumbnail.name
|
url = img.thumbnail.name
|
||||||
loc = os.path.join(settings.MEDIA_ROOT, url)
|
loc = os.path.join(settings.MEDIA_ROOT, url)
|
||||||
|
|
||||||
if not os.path.exists(loc):
|
if not os.path.exists(loc):
|
||||||
logger.info(f"Generating thumbnail image for '{img}'")
|
logger.info(f"Generating thumbnail image for '{img}'")
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class InvenTreeMetadata(SimpleMetadata):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def determine_metadata(self, request, view):
|
def determine_metadata(self, request, view):
|
||||||
|
|
||||||
self.request = request
|
self.request = request
|
||||||
self.view = view
|
self.view = view
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ class InvenTreeMetadata(SimpleMetadata):
|
|||||||
Override get_serializer_info so that we can add 'default' values
|
Override get_serializer_info so that we can add 'default' values
|
||||||
to any fields whose Meta.model specifies a default value
|
to any fields whose Meta.model specifies a default value
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_info = super().get_serializer_info(serializer)
|
serializer_info = super().get_serializer_info(serializer)
|
||||||
|
|
||||||
model_class = None
|
model_class = None
|
||||||
@ -174,7 +174,7 @@ class InvenTreeMetadata(SimpleMetadata):
|
|||||||
# Extract extra information if an instance is available
|
# Extract extra information if an instance is available
|
||||||
if hasattr(serializer, 'instance'):
|
if hasattr(serializer, 'instance'):
|
||||||
instance = serializer.instance
|
instance = serializer.instance
|
||||||
|
|
||||||
if instance is None and model_class is not None:
|
if instance is None and model_class is not None:
|
||||||
# Attempt to find the instance based on kwargs lookup
|
# Attempt to find the instance based on kwargs lookup
|
||||||
kwargs = getattr(self.view, 'kwargs', None)
|
kwargs = getattr(self.view, 'kwargs', None)
|
||||||
@ -240,7 +240,7 @@ class InvenTreeMetadata(SimpleMetadata):
|
|||||||
|
|
||||||
# Introspect writable related fields
|
# Introspect writable related fields
|
||||||
if field_info['type'] == 'field' and not field_info['read_only']:
|
if field_info['type'] == 'field' and not field_info['read_only']:
|
||||||
|
|
||||||
# If the field is a PrimaryKeyRelatedField, we can extract the model from the queryset
|
# If the field is a PrimaryKeyRelatedField, we can extract the model from the queryset
|
||||||
if isinstance(field, serializers.PrimaryKeyRelatedField):
|
if isinstance(field, serializers.PrimaryKeyRelatedField):
|
||||||
model = field.queryset.model
|
model = field.queryset.model
|
||||||
|
@ -66,7 +66,7 @@ class InvenTreeMoneySerializer(MoneyField):
|
|||||||
|
|
||||||
if currency and amount is not None and not isinstance(amount, MONEY_CLASSES) and amount is not empty:
|
if currency and amount is not None and not isinstance(amount, MONEY_CLASSES) and amount is not empty:
|
||||||
return Money(amount, currency)
|
return Money(amount, currency)
|
||||||
|
|
||||||
return amount
|
return amount
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ def offload_task(taskname, *args, force_sync=False, **kwargs):
|
|||||||
except NameError:
|
except NameError:
|
||||||
logger.warning(f"WARNING: '{taskname}' not started - No function named '{func}'")
|
logger.warning(f"WARNING: '{taskname}' not started - No function named '{func}'")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Workers are not running: run it as synchronous task
|
# Workers are not running: run it as synchronous task
|
||||||
_func(*args, **kwargs)
|
_func(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ from base64 import b64encode
|
|||||||
class HTMLAPITests(TestCase):
|
class HTMLAPITests(TestCase):
|
||||||
"""
|
"""
|
||||||
Test that we can access the REST API endpoints via the HTML interface.
|
Test that we can access the REST API endpoints via the HTML interface.
|
||||||
|
|
||||||
History: Discovered on 2021-06-28 a bug in InvenTreeModelSerializer,
|
History: Discovered on 2021-06-28 a bug in InvenTreeModelSerializer,
|
||||||
which raised an AssertionError when using the HTML API interface,
|
which raised an AssertionError when using the HTML API interface,
|
||||||
while the regular JSON interface continued to work as expected.
|
while the regular JSON interface continued to work as expected.
|
||||||
@ -280,7 +280,7 @@ class APITests(InvenTreeAPITestCase):
|
|||||||
"""
|
"""
|
||||||
Tests for detail API endpoint actions
|
Tests for detail API endpoint actions
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.basicAuth()
|
self.basicAuth()
|
||||||
|
|
||||||
url = reverse('api-part-detail', kwargs={'pk': 1})
|
url = reverse('api-part-detail', kwargs={'pk': 1})
|
||||||
|
@ -80,7 +80,7 @@ apipatterns = [
|
|||||||
settings_urls = [
|
settings_urls = [
|
||||||
|
|
||||||
url(r'^i18n/?', include('django.conf.urls.i18n')),
|
url(r'^i18n/?', include('django.conf.urls.i18n')),
|
||||||
|
|
||||||
url(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'),
|
url(r'^appearance/?', AppearanceSelectView.as_view(), name='settings-appearance'),
|
||||||
url(r'^currencies-refresh/', CurrencyRefreshView.as_view(), name='settings-currencies-refresh'),
|
url(r'^currencies-refresh/', CurrencyRefreshView.as_view(), name='settings-currencies-refresh'),
|
||||||
|
|
||||||
|
@ -120,10 +120,10 @@ def isInvenTreeDevelopmentVersion():
|
|||||||
def inventreeDocsVersion():
|
def inventreeDocsVersion():
|
||||||
"""
|
"""
|
||||||
Return the version string matching the latest documentation.
|
Return the version string matching the latest documentation.
|
||||||
|
|
||||||
Development -> "latest"
|
Development -> "latest"
|
||||||
Release -> "major.minor.sub" e.g. "0.5.2"
|
Release -> "major.minor.sub" e.g. "0.5.2"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isInvenTreeDevelopmentVersion():
|
if isInvenTreeDevelopmentVersion():
|
||||||
|
@ -198,7 +198,7 @@ class BuildUnallocate(generics.CreateAPIView):
|
|||||||
queryset = Build.objects.none()
|
queryset = Build.objects.none()
|
||||||
|
|
||||||
serializer_class = BuildUnallocationSerializer
|
serializer_class = BuildUnallocationSerializer
|
||||||
|
|
||||||
def get_serializer_context(self):
|
def get_serializer_context(self):
|
||||||
|
|
||||||
ctx = super().get_serializer_context()
|
ctx = super().get_serializer_context()
|
||||||
@ -231,7 +231,7 @@ class BuildComplete(generics.CreateAPIView):
|
|||||||
ctx['build'] = Build.objects.get(pk=self.kwargs.get('pk', None))
|
ctx['build'] = Build.objects.get(pk=self.kwargs.get('pk', None))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
@ -296,7 +296,7 @@ class BuildItemList(generics.ListCreateAPIView):
|
|||||||
kwargs['location_detail'] = str2bool(params.get('location_detail', False))
|
kwargs['location_detail'] = str2bool(params.get('location_detail', False))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return self.serializer_class(*args, **kwargs)
|
return self.serializer_class(*args, **kwargs)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
@ -66,7 +66,7 @@ def get_next_build_number():
|
|||||||
attempts.add(reference)
|
attempts.add(reference)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
return reference
|
return reference
|
||||||
|
|
||||||
|
|
||||||
@ -94,13 +94,13 @@ class Build(MPTTModel, ReferenceIndexingMixin):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
OVERDUE_FILTER = Q(status__in=BuildStatus.ACTIVE_CODES) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date())
|
OVERDUE_FILTER = Q(status__in=BuildStatus.ACTIVE_CODES) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date())
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_api_url():
|
def get_api_url():
|
||||||
return reverse('api-build-list')
|
return reverse('api-build-list')
|
||||||
|
|
||||||
def api_instance_filters(self):
|
def api_instance_filters(self):
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'parent': {
|
'parent': {
|
||||||
'exclude_tree': self.pk,
|
'exclude_tree': self.pk,
|
||||||
@ -1178,7 +1178,7 @@ class BuildItem(models.Model):
|
|||||||
bom_item = PartModels.BomItem.objects.get(part=self.build.part, sub_part=ancestor)
|
bom_item = PartModels.BomItem.objects.get(part=self.build.part, sub_part=ancestor)
|
||||||
except PartModels.BomItem.DoesNotExist:
|
except PartModels.BomItem.DoesNotExist:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# A matching BOM item has been found!
|
# A matching BOM item has been found!
|
||||||
if idx == 0 or bom_item.allow_variants:
|
if idx == 0 or bom_item.allow_variants:
|
||||||
bom_item_valid = True
|
bom_item_valid = True
|
||||||
@ -1234,7 +1234,7 @@ class BuildItem(models.Model):
|
|||||||
thumb_url = self.stock_item.part.image.thumbnail.url
|
thumb_url = self.stock_item.part.image.thumbnail.url
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if thumb_url is None and self.bom_item and self.bom_item.sub_part:
|
if thumb_url is None and self.bom_item and self.bom_item.sub_part:
|
||||||
try:
|
try:
|
||||||
thumb_url = self.bom_item.sub_part.image.thumbnail.url
|
thumb_url = self.bom_item.sub_part.image.thumbnail.url
|
||||||
|
@ -309,7 +309,7 @@ class BuildAllocationItemSerializer(serializers.Serializer):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def validate_bom_item(self, bom_item):
|
def validate_bom_item(self, bom_item):
|
||||||
|
|
||||||
# TODO: Fix this validation - allow for variants and substitutes!
|
# TODO: Fix this validation - allow for variants and substitutes!
|
||||||
|
|
||||||
build = self.context['build']
|
build = self.context['build']
|
||||||
@ -332,7 +332,7 @@ class BuildAllocationItemSerializer(serializers.Serializer):
|
|||||||
|
|
||||||
if not stock_item.in_stock:
|
if not stock_item.in_stock:
|
||||||
raise ValidationError(_("Item must be in stock"))
|
raise ValidationError(_("Item must be in stock"))
|
||||||
|
|
||||||
return stock_item
|
return stock_item
|
||||||
|
|
||||||
quantity = serializers.DecimalField(
|
quantity = serializers.DecimalField(
|
||||||
@ -398,7 +398,7 @@ class BuildAllocationItemSerializer(serializers.Serializer):
|
|||||||
|
|
||||||
# Output *cannot* be set for un-tracked parts
|
# Output *cannot* be set for un-tracked parts
|
||||||
if output is not None and not bom_item.sub_part.trackable:
|
if output is not None and not bom_item.sub_part.trackable:
|
||||||
|
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'output': _('Build output cannot be specified for allocation of untracked parts')
|
'output': _('Build output cannot be specified for allocation of untracked parts')
|
||||||
})
|
})
|
||||||
@ -422,14 +422,14 @@ class BuildAllocationSerializer(serializers.Serializer):
|
|||||||
"""
|
"""
|
||||||
Validation
|
Validation
|
||||||
"""
|
"""
|
||||||
|
|
||||||
super().validate(data)
|
super().validate(data)
|
||||||
|
|
||||||
items = data.get('items', [])
|
items = data.get('items', [])
|
||||||
|
|
||||||
if len(items) == 0:
|
if len(items) == 0:
|
||||||
raise ValidationError(_('Allocation items must be provided'))
|
raise ValidationError(_('Allocation items must be provided'))
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
|
@ -2,14 +2,21 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load inventree_extras %}
|
{% load inventree_extras %}
|
||||||
|
|
||||||
{% include "sidebar_item.html" with label='details' text="Build Order Details" icon="fa-info-circle" %}
|
{% trans "Build Order Details" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='details' text=text icon="fa-info-circle" %}
|
||||||
{% if build.active %}
|
{% if build.active %}
|
||||||
{% include "sidebar_item.html" with label='allocate' text="Allocate Stock" icon="fa-tasks" %}
|
{% trans "Allocate Stock" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='allocate' text=text icon="fa-tasks" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not build.is_complete %}
|
{% if not build.is_complete %}
|
||||||
{% include "sidebar_item.html" with label='outputs' text="Pending Items" icon="fa-tools" %}
|
{% trans "Pending Items" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='outputs' text=text icon="fa-tools" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include "sidebar_item.html" with label='completed' text="Completed Items" icon="fa-boxes" %}
|
{% trans "Completed Items" as text %}
|
||||||
{% include "sidebar_item.html" with label='children' text="Child Build Orders" icon="fa-sitemap" %}
|
{% include "sidebar_item.html" with label='completed' text=text icon="fa-boxes" %}
|
||||||
{% include "sidebar_item.html" with label='attachments' text="Attachments" icon="fa-paperclip" %}
|
{% trans "Child Build Orders" as text %}
|
||||||
{% include "sidebar_item.html" with label='notes' text="Notes" icon="fa-clipboard" %}
|
{% include "sidebar_item.html" with label='children' text=text icon="fa-sitemap" %}
|
||||||
|
{% trans "Attachments" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='attachments' text=text icon="fa-paperclip" %}
|
||||||
|
{% trans "Notes" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='notes' text=text icon="fa-clipboard" %}
|
||||||
|
@ -73,7 +73,7 @@ class GlobalSettingsDetail(generics.RetrieveUpdateAPIView):
|
|||||||
permission_classes = [
|
permission_classes = [
|
||||||
GlobalSettingsPermissions,
|
GlobalSettingsPermissions,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class UserSettingsList(SettingsList):
|
class UserSettingsList(SettingsList):
|
||||||
"""
|
"""
|
||||||
@ -124,7 +124,7 @@ class UserSettingsDetail(generics.RetrieveUpdateAPIView):
|
|||||||
|
|
||||||
queryset = common.models.InvenTreeUserSetting.objects.all()
|
queryset = common.models.InvenTreeUserSetting.objects.all()
|
||||||
serializer_class = common.serializers.UserSettingsSerializer
|
serializer_class = common.serializers.UserSettingsSerializer
|
||||||
|
|
||||||
permission_classes = [
|
permission_classes = [
|
||||||
UserSettingsPermissions,
|
UserSettingsPermissions,
|
||||||
]
|
]
|
||||||
|
@ -12,7 +12,7 @@ class CommonConfig(AppConfig):
|
|||||||
name = 'common'
|
name = 'common'
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
|
|
||||||
self.clear_restart_flag()
|
self.clear_restart_flag()
|
||||||
|
|
||||||
def clear_restart_flag(self):
|
def clear_restart_flag(self):
|
||||||
@ -22,7 +22,7 @@ class CommonConfig(AppConfig):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import common.models
|
import common.models
|
||||||
|
|
||||||
if common.models.InvenTreeSetting.get_setting('SERVER_RESTART_REQUIRED'):
|
if common.models.InvenTreeSetting.get_setting('SERVER_RESTART_REQUIRED'):
|
||||||
logger.info("Clearing SERVER_RESTART_REQUIRED flag")
|
logger.info("Clearing SERVER_RESTART_REQUIRED flag")
|
||||||
common.models.InvenTreeSetting.set_setting('SERVER_RESTART_REQUIRED', False, None)
|
common.models.InvenTreeSetting.set_setting('SERVER_RESTART_REQUIRED', False, None)
|
||||||
|
@ -487,7 +487,7 @@ class BaseInvenTreeSetting(models.Model):
|
|||||||
|
|
||||||
elif self.is_int():
|
elif self.is_int():
|
||||||
return 'integer'
|
return 'integer'
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return 'string'
|
return 'string'
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ class ManufacturerPartParameterList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
queryset = ManufacturerPartParameter.objects.all()
|
queryset = ManufacturerPartParameter.objects.all()
|
||||||
serializer_class = ManufacturerPartParameterSerializer
|
serializer_class = ManufacturerPartParameterSerializer
|
||||||
|
|
||||||
def get_serializer(self, *args, **kwargs):
|
def get_serializer(self, *args, **kwargs):
|
||||||
|
|
||||||
# Do we wish to include any extra detail?
|
# Do we wish to include any extra detail?
|
||||||
|
@ -477,7 +477,7 @@ class SupplierPart(models.Model):
|
|||||||
return reverse('supplier-part-detail', kwargs={'pk': self.id})
|
return reverse('supplier-part-detail', kwargs={'pk': self.id})
|
||||||
|
|
||||||
def api_instance_filters(self):
|
def api_instance_filters(self):
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'manufacturer_part': {
|
'manufacturer_part': {
|
||||||
'part': self.part.pk
|
'part': self.part.pk
|
||||||
|
@ -187,7 +187,7 @@ class SupplierPartSerializer(InvenTreeModelSerializer):
|
|||||||
part_detail = kwargs.pop('part_detail', True)
|
part_detail = kwargs.pop('part_detail', True)
|
||||||
supplier_detail = kwargs.pop('supplier_detail', True)
|
supplier_detail = kwargs.pop('supplier_detail', True)
|
||||||
manufacturer_detail = kwargs.pop('manufacturer_detail', True)
|
manufacturer_detail = kwargs.pop('manufacturer_detail', True)
|
||||||
|
|
||||||
prettify = kwargs.pop('pretty', False)
|
prettify = kwargs.pop('pretty', False)
|
||||||
|
|
||||||
super(SupplierPartSerializer, self).__init__(*args, **kwargs)
|
super(SupplierPartSerializer, self).__init__(*args, **kwargs)
|
||||||
|
@ -2,5 +2,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load inventree_extras %}
|
{% load inventree_extras %}
|
||||||
|
|
||||||
{% include "sidebar_item.html" with label='parameters' text="Parameters" icon="fa-th-list" %}
|
{% trans "Parameters" as text %}
|
||||||
{% include "sidebar_item.html" with label='supplier-parts' text="Supplier Parts" icon="fa-building" %}
|
{% include "sidebar_item.html" with label='parameters' text=text icon="fa-th-list" %}
|
||||||
|
{% trans "Supplier Parts" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='supplier-parts' text=text icon="fa-building" %}
|
@ -3,17 +3,24 @@
|
|||||||
{% load inventree_extras %}
|
{% load inventree_extras %}
|
||||||
|
|
||||||
{% if company.is_manufacturer %}
|
{% if company.is_manufacturer %}
|
||||||
{% include "sidebar_item.html" with label='manufacturer-parts' text="Manufactured Parts" icon="fa-industry" %}
|
{% trans "Manufactured Parts" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='manufacturer-parts' text=text icon="fa-industry" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if company.is_supplier %}
|
{% if company.is_supplier %}
|
||||||
{% include "sidebar_item.html" with label='supplier-parts' text="Supplied Parts" icon="fa-building" %}
|
{% trans "Supplied Parts" as text %}
|
||||||
{% include "sidebar_item.html" with label='purchase-orders' text="Purchase Orders" icon="fa-shopping-cart" %}
|
{% include "sidebar_item.html" with label='supplier-parts' text=text icon="fa-building" %}
|
||||||
|
{% trans "Purchase Orders" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='purchase-orders' text=text icon="fa-shopping-cart" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if company.is_manufacturer or company.is_supplier %}
|
{% if company.is_manufacturer or company.is_supplier %}
|
||||||
{% include "sidebar_item.html" with label='company-stock' text="Supplied Stock Items" icon="fa-boxes" %}
|
{% trans "Supplied Stock Items" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='company-stock' text=text icon="fa-boxes" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if company.is_customer %}
|
{% if company.is_customer %}
|
||||||
{% include "sidebar_item.html" with label='sales-orders' text="Sales Orders" icon="fa-truck" %}
|
{% trans "Sales Orders" as text %}
|
||||||
{% include "sidebar_item.html" with label='assigned-stock' text="Assigned Stock Items" icon="fa-sign-out-alt" %}
|
{% include "sidebar_item.html" with label='sales-orders' text=text icon="fa-truck" %}
|
||||||
|
{% trans "Assigned Stock Items" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='assigned-stock' text=text icon="fa-sign-out-alt" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include "sidebar_item.html" with label='company-notes' text="Notes" icon="fa-clipboard" %}
|
{% trans "Notes" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='company-notes' text=text icon="fa-clipboard" %}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load inventree_extras %}
|
{% load inventree_extras %}
|
||||||
|
|
||||||
{% include "sidebar_item.html" with label='stock' text="Stock Items" icon="fa-boxes" %}
|
{% trans "Stock Items" as text %}
|
||||||
{% include "sidebar_item.html" with label='purchase-orders' text="Purchase Orders" icon="fa-shopping-cart" %}
|
{% include "sidebar_item.html" with label='stock' text=text icon="fa-boxes" %}
|
||||||
{% include "sidebar_item.html" with label='pricing' text="Supplier Part Pricing" icon="fa-dollar-sign" %}
|
{% trans "Purchase Orders" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='purchase-orders' text=text icon="fa-shopping-cart" %}
|
||||||
|
{% trans "Supplier Part Pricing" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='pricing' text=text icon="fa-dollar-sign" %}
|
||||||
|
@ -202,7 +202,7 @@ class ManufacturerTest(InvenTreeAPITestCase):
|
|||||||
data = {
|
data = {
|
||||||
'MPN': 'MPN-TEST-123',
|
'MPN': 'MPN-TEST-123',
|
||||||
}
|
}
|
||||||
|
|
||||||
response = self.client.patch(url, data, format='json')
|
response = self.client.patch(url, data, format='json')
|
||||||
|
|
||||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||||
|
@ -29,7 +29,7 @@ company_urls = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
manufacturer_part_urls = [
|
manufacturer_part_urls = [
|
||||||
|
|
||||||
url(r'^(?P<pk>\d+)/', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part.html'), name='manufacturer-part-detail'),
|
url(r'^(?P<pk>\d+)/', views.ManufacturerPartDetail.as_view(template_name='company/manufacturer_part.html'), name='manufacturer-part-detail'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ class PartLabelMixin:
|
|||||||
if key in params:
|
if key in params:
|
||||||
parts = params.getlist(key, [])
|
parts = params.getlist(key, [])
|
||||||
break
|
break
|
||||||
|
|
||||||
valid_ids = []
|
valid_ids = []
|
||||||
|
|
||||||
for part in parts:
|
for part in parts:
|
||||||
|
@ -186,7 +186,7 @@ class LabelTemplate(models.Model):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
template_string = Template(self.filename_pattern)
|
template_string = Template(self.filename_pattern)
|
||||||
|
|
||||||
ctx = self.context(request)
|
ctx = self.context(request)
|
||||||
|
|
||||||
context = Context(ctx)
|
context = Context(ctx)
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
InvenTree/locale/el/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/el/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-11-19 07:42+1100\n"
|
"POT-Creation-Date: 2021-11-22 22:08+0000\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -131,8 +131,8 @@ msgstr ""
|
|||||||
msgid "File comment"
|
msgid "File comment"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: InvenTree/models.py:118 InvenTree/models.py:119 common/models.py:1170
|
#: InvenTree/models.py:118 InvenTree/models.py:119 common/models.py:1185
|
||||||
#: common/models.py:1171 part/models.py:2205 part/models.py:2225
|
#: common/models.py:1186 part/models.py:2205 part/models.py:2225
|
||||||
#: report/templates/report/inventree_test_report_base.html:96
|
#: report/templates/report/inventree_test_report_base.html:96
|
||||||
#: templates/js/translated/stock.js:2054
|
#: templates/js/translated/stock.js:2054
|
||||||
msgid "User"
|
msgid "User"
|
||||||
@ -234,7 +234,7 @@ msgid "Spanish"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: InvenTree/settings.py:667
|
#: InvenTree/settings.py:667
|
||||||
msgid "Spanish (Mexican"
|
msgid "Spanish (Mexican)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: InvenTree/settings.py:668
|
#: InvenTree/settings.py:668
|
||||||
@ -544,7 +544,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: build/forms.py:36 build/models.py:1283
|
#: build/forms.py:36 build/models.py:1283
|
||||||
#: build/templates/build/build_base.html:124
|
#: build/templates/build/build_base.html:124
|
||||||
#: build/templates/build/detail.html:35 common/models.py:1210
|
#: build/templates/build/detail.html:35 common/models.py:1225
|
||||||
#: company/forms.py:42 company/templates/company/supplier_part.html:251
|
#: company/forms.py:42 company/templates/company/supplier_part.html:251
|
||||||
#: order/forms.py:102 order/models.py:729 order/models.py:991
|
#: order/forms.py:102 order/models.py:729 order/models.py:991
|
||||||
#: order/templates/order/order_wizard/match_parts.html:30
|
#: order/templates/order/order_wizard/match_parts.html:30
|
||||||
@ -1454,688 +1454,688 @@ msgstr ""
|
|||||||
msgid "Select {name} file to upload"
|
msgid "Select {name} file to upload"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:338 common/models.py:955 common/models.py:1163
|
#: common/models.py:340 common/models.py:970 common/models.py:1178
|
||||||
msgid "Settings key (must be unique - case insensitive"
|
msgid "Settings key (must be unique - case insensitive"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:340
|
#: common/models.py:342
|
||||||
msgid "Settings value"
|
msgid "Settings value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:375
|
#: common/models.py:377
|
||||||
msgid "Must be an integer value"
|
msgid "Must be an integer value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:380
|
#: common/models.py:382
|
||||||
msgid "Chosen value is not a valid option"
|
msgid "Chosen value is not a valid option"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:403
|
#: common/models.py:405
|
||||||
msgid "Value must be a boolean value"
|
msgid "Value must be a boolean value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:414
|
#: common/models.py:416
|
||||||
msgid "Value must be an integer value"
|
msgid "Value must be an integer value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:437
|
#: common/models.py:439
|
||||||
msgid "Key string must be unique"
|
msgid "Key string must be unique"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:544
|
#: common/models.py:559
|
||||||
msgid "No group"
|
msgid "No group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:586
|
#: common/models.py:601
|
||||||
msgid "Restart required"
|
msgid "Restart required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:587
|
#: common/models.py:602
|
||||||
msgid "A setting has been changed which requires a server restart"
|
msgid "A setting has been changed which requires a server restart"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:594
|
#: common/models.py:609
|
||||||
msgid "InvenTree Instance Name"
|
msgid "InvenTree Instance Name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:596
|
#: common/models.py:611
|
||||||
msgid "String descriptor for the server instance"
|
msgid "String descriptor for the server instance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:600
|
#: common/models.py:615
|
||||||
msgid "Use instance name"
|
msgid "Use instance name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:601
|
#: common/models.py:616
|
||||||
msgid "Use the instance name in the title-bar"
|
msgid "Use the instance name in the title-bar"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:607 company/models.py:100 company/models.py:101
|
#: common/models.py:622 company/models.py:100 company/models.py:101
|
||||||
msgid "Company name"
|
msgid "Company name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:608
|
#: common/models.py:623
|
||||||
msgid "Internal company name"
|
msgid "Internal company name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:613
|
#: common/models.py:628
|
||||||
msgid "Base URL"
|
msgid "Base URL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:614
|
#: common/models.py:629
|
||||||
msgid "Base URL for server instance"
|
msgid "Base URL for server instance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:620
|
#: common/models.py:635
|
||||||
msgid "Default Currency"
|
msgid "Default Currency"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:621
|
#: common/models.py:636
|
||||||
msgid "Default currency"
|
msgid "Default currency"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:627
|
#: common/models.py:642
|
||||||
msgid "Download from URL"
|
msgid "Download from URL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:628
|
#: common/models.py:643
|
||||||
msgid "Allow download of remote images and files from external URL"
|
msgid "Allow download of remote images and files from external URL"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:634
|
#: common/models.py:649
|
||||||
msgid "Barcode Support"
|
msgid "Barcode Support"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:635
|
#: common/models.py:650
|
||||||
msgid "Enable barcode scanner support"
|
msgid "Enable barcode scanner support"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:641
|
#: common/models.py:656
|
||||||
msgid "IPN Regex"
|
msgid "IPN Regex"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:642
|
#: common/models.py:657
|
||||||
msgid "Regular expression pattern for matching Part IPN"
|
msgid "Regular expression pattern for matching Part IPN"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:646
|
#: common/models.py:661
|
||||||
msgid "Allow Duplicate IPN"
|
msgid "Allow Duplicate IPN"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:647
|
#: common/models.py:662
|
||||||
msgid "Allow multiple parts to share the same IPN"
|
msgid "Allow multiple parts to share the same IPN"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:653
|
#: common/models.py:668
|
||||||
msgid "Allow Editing IPN"
|
msgid "Allow Editing IPN"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:654
|
#: common/models.py:669
|
||||||
msgid "Allow changing the IPN value while editing a part"
|
msgid "Allow changing the IPN value while editing a part"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:660
|
#: common/models.py:675
|
||||||
msgid "Copy Part BOM Data"
|
msgid "Copy Part BOM Data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:661
|
#: common/models.py:676
|
||||||
msgid "Copy BOM data by default when duplicating a part"
|
msgid "Copy BOM data by default when duplicating a part"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:667
|
#: common/models.py:682
|
||||||
msgid "Copy Part Parameter Data"
|
msgid "Copy Part Parameter Data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:668
|
#: common/models.py:683
|
||||||
msgid "Copy parameter data by default when duplicating a part"
|
msgid "Copy parameter data by default when duplicating a part"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:674
|
#: common/models.py:689
|
||||||
msgid "Copy Part Test Data"
|
msgid "Copy Part Test Data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:675
|
#: common/models.py:690
|
||||||
msgid "Copy test data by default when duplicating a part"
|
msgid "Copy test data by default when duplicating a part"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:681
|
#: common/models.py:696
|
||||||
msgid "Copy Category Parameter Templates"
|
msgid "Copy Category Parameter Templates"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:682
|
#: common/models.py:697
|
||||||
msgid "Copy category parameter templates when creating a part"
|
msgid "Copy category parameter templates when creating a part"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:688 part/models.py:2429 report/models.py:187
|
#: common/models.py:703 part/models.py:2429 report/models.py:187
|
||||||
#: templates/js/translated/table_filters.js:38
|
#: templates/js/translated/table_filters.js:38
|
||||||
#: templates/js/translated/table_filters.js:367
|
#: templates/js/translated/table_filters.js:367
|
||||||
msgid "Template"
|
msgid "Template"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:689
|
#: common/models.py:704
|
||||||
msgid "Parts are templates by default"
|
msgid "Parts are templates by default"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:695 part/models.py:888 templates/js/translated/bom.js:954
|
#: common/models.py:710 part/models.py:888 templates/js/translated/bom.js:954
|
||||||
#: templates/js/translated/table_filters.js:162
|
#: templates/js/translated/table_filters.js:162
|
||||||
#: templates/js/translated/table_filters.js:379
|
#: templates/js/translated/table_filters.js:379
|
||||||
msgid "Assembly"
|
msgid "Assembly"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:696
|
#: common/models.py:711
|
||||||
msgid "Parts can be assembled from other components by default"
|
msgid "Parts can be assembled from other components by default"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:702 part/models.py:894
|
#: common/models.py:717 part/models.py:894
|
||||||
#: templates/js/translated/table_filters.js:383
|
#: templates/js/translated/table_filters.js:383
|
||||||
msgid "Component"
|
msgid "Component"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:703
|
#: common/models.py:718
|
||||||
msgid "Parts can be used as sub-components by default"
|
msgid "Parts can be used as sub-components by default"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:709 part/models.py:905
|
#: common/models.py:724 part/models.py:905
|
||||||
msgid "Purchaseable"
|
msgid "Purchaseable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:710
|
#: common/models.py:725
|
||||||
msgid "Parts are purchaseable by default"
|
msgid "Parts are purchaseable by default"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:716 part/models.py:910
|
#: common/models.py:731 part/models.py:910
|
||||||
#: templates/js/translated/table_filters.js:391
|
#: templates/js/translated/table_filters.js:391
|
||||||
msgid "Salable"
|
msgid "Salable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:717
|
#: common/models.py:732
|
||||||
msgid "Parts are salable by default"
|
msgid "Parts are salable by default"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:723 part/models.py:900
|
#: common/models.py:738 part/models.py:900
|
||||||
#: templates/js/translated/table_filters.js:46
|
#: templates/js/translated/table_filters.js:46
|
||||||
#: templates/js/translated/table_filters.js:94
|
#: templates/js/translated/table_filters.js:94
|
||||||
#: templates/js/translated/table_filters.js:395
|
#: templates/js/translated/table_filters.js:395
|
||||||
msgid "Trackable"
|
msgid "Trackable"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:724
|
#: common/models.py:739
|
||||||
msgid "Parts are trackable by default"
|
msgid "Parts are trackable by default"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:730 part/models.py:920
|
#: common/models.py:745 part/models.py:920
|
||||||
#: part/templates/part/part_base.html:144
|
#: part/templates/part/part_base.html:144
|
||||||
#: templates/js/translated/table_filters.js:42
|
#: templates/js/translated/table_filters.js:42
|
||||||
msgid "Virtual"
|
msgid "Virtual"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:731
|
#: common/models.py:746
|
||||||
msgid "Parts are virtual by default"
|
msgid "Parts are virtual by default"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:737
|
#: common/models.py:752
|
||||||
msgid "Show Import in Views"
|
msgid "Show Import in Views"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:738
|
#: common/models.py:753
|
||||||
msgid "Display the import wizard in some part views"
|
msgid "Display the import wizard in some part views"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:744
|
#: common/models.py:759
|
||||||
msgid "Show Price in Forms"
|
msgid "Show Price in Forms"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:745
|
#: common/models.py:760
|
||||||
msgid "Display part price in some forms"
|
msgid "Display part price in some forms"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:756
|
#: common/models.py:771
|
||||||
msgid "Show Price in BOM"
|
msgid "Show Price in BOM"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:757
|
#: common/models.py:772
|
||||||
msgid "Include pricing information in BOM tables"
|
msgid "Include pricing information in BOM tables"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:763
|
#: common/models.py:778
|
||||||
msgid "Show related parts"
|
msgid "Show related parts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:764
|
#: common/models.py:779
|
||||||
msgid "Display related parts for a part"
|
msgid "Display related parts for a part"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:770
|
#: common/models.py:785
|
||||||
msgid "Create initial stock"
|
msgid "Create initial stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:771
|
#: common/models.py:786
|
||||||
msgid "Create initial stock on part creation"
|
msgid "Create initial stock on part creation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:777
|
#: common/models.py:792
|
||||||
msgid "Internal Prices"
|
msgid "Internal Prices"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:778
|
#: common/models.py:793
|
||||||
msgid "Enable internal prices for parts"
|
msgid "Enable internal prices for parts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:784
|
#: common/models.py:799
|
||||||
msgid "Internal Price as BOM-Price"
|
msgid "Internal Price as BOM-Price"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:785
|
#: common/models.py:800
|
||||||
msgid "Use the internal price (if set) in BOM-price calculations"
|
msgid "Use the internal price (if set) in BOM-price calculations"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:791
|
#: common/models.py:806
|
||||||
msgid "Part Name Display Format"
|
msgid "Part Name Display Format"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:792
|
#: common/models.py:807
|
||||||
msgid "Format to display the part name"
|
msgid "Format to display the part name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:799
|
#: common/models.py:814
|
||||||
msgid "Enable Reports"
|
msgid "Enable Reports"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:800
|
#: common/models.py:815
|
||||||
msgid "Enable generation of reports"
|
msgid "Enable generation of reports"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:806 templates/stats.html:25
|
#: common/models.py:821 templates/stats.html:25
|
||||||
msgid "Debug Mode"
|
msgid "Debug Mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:807
|
#: common/models.py:822
|
||||||
msgid "Generate reports in debug mode (HTML output)"
|
msgid "Generate reports in debug mode (HTML output)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:813
|
#: common/models.py:828
|
||||||
msgid "Page Size"
|
msgid "Page Size"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:814
|
#: common/models.py:829
|
||||||
msgid "Default page size for PDF reports"
|
msgid "Default page size for PDF reports"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:824
|
#: common/models.py:839
|
||||||
msgid "Test Reports"
|
msgid "Test Reports"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:825
|
#: common/models.py:840
|
||||||
msgid "Enable generation of test reports"
|
msgid "Enable generation of test reports"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:831
|
#: common/models.py:846
|
||||||
msgid "Stock Expiry"
|
msgid "Stock Expiry"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:832
|
#: common/models.py:847
|
||||||
msgid "Enable stock expiry functionality"
|
msgid "Enable stock expiry functionality"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:838
|
#: common/models.py:853
|
||||||
msgid "Sell Expired Stock"
|
msgid "Sell Expired Stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:839
|
#: common/models.py:854
|
||||||
msgid "Allow sale of expired stock"
|
msgid "Allow sale of expired stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:845
|
#: common/models.py:860
|
||||||
msgid "Stock Stale Time"
|
msgid "Stock Stale Time"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:846
|
#: common/models.py:861
|
||||||
msgid "Number of days stock items are considered stale before expiring"
|
msgid "Number of days stock items are considered stale before expiring"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:848
|
#: common/models.py:863
|
||||||
msgid "days"
|
msgid "days"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:853
|
#: common/models.py:868
|
||||||
msgid "Build Expired Stock"
|
msgid "Build Expired Stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:854
|
#: common/models.py:869
|
||||||
msgid "Allow building with expired stock"
|
msgid "Allow building with expired stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:860
|
#: common/models.py:875
|
||||||
msgid "Stock Ownership Control"
|
msgid "Stock Ownership Control"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:861
|
#: common/models.py:876
|
||||||
msgid "Enable ownership control over stock locations and items"
|
msgid "Enable ownership control over stock locations and items"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:867
|
#: common/models.py:882
|
||||||
msgid "Group by Part"
|
msgid "Group by Part"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:868
|
#: common/models.py:883
|
||||||
msgid "Group stock items by part reference in table views"
|
msgid "Group stock items by part reference in table views"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:874
|
#: common/models.py:889
|
||||||
msgid "Build Order Reference Prefix"
|
msgid "Build Order Reference Prefix"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:875
|
#: common/models.py:890
|
||||||
msgid "Prefix value for build order reference"
|
msgid "Prefix value for build order reference"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:880
|
#: common/models.py:895
|
||||||
msgid "Build Order Reference Regex"
|
msgid "Build Order Reference Regex"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:881
|
#: common/models.py:896
|
||||||
msgid "Regular expression pattern for matching build order reference"
|
msgid "Regular expression pattern for matching build order reference"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:885
|
#: common/models.py:900
|
||||||
msgid "Sales Order Reference Prefix"
|
msgid "Sales Order Reference Prefix"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:886
|
#: common/models.py:901
|
||||||
msgid "Prefix value for sales order reference"
|
msgid "Prefix value for sales order reference"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:891
|
#: common/models.py:906
|
||||||
msgid "Purchase Order Reference Prefix"
|
msgid "Purchase Order Reference Prefix"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:892
|
#: common/models.py:907
|
||||||
msgid "Prefix value for purchase order reference"
|
msgid "Prefix value for purchase order reference"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:898
|
#: common/models.py:913
|
||||||
msgid "Enable password forgot"
|
msgid "Enable password forgot"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:899
|
#: common/models.py:914
|
||||||
msgid "Enable password forgot function on the login pages"
|
msgid "Enable password forgot function on the login pages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:904
|
#: common/models.py:919
|
||||||
msgid "Enable registration"
|
msgid "Enable registration"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:905
|
#: common/models.py:920
|
||||||
msgid "Enable self-registration for users on the login pages"
|
msgid "Enable self-registration for users on the login pages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:910
|
#: common/models.py:925
|
||||||
msgid "Enable SSO"
|
msgid "Enable SSO"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:911
|
#: common/models.py:926
|
||||||
msgid "Enable SSO on the login pages"
|
msgid "Enable SSO on the login pages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:916
|
#: common/models.py:931
|
||||||
msgid "Email required"
|
msgid "Email required"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:917
|
#: common/models.py:932
|
||||||
msgid "Require user to supply mail on signup"
|
msgid "Require user to supply mail on signup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:922
|
#: common/models.py:937
|
||||||
msgid "Auto-fill SSO users"
|
msgid "Auto-fill SSO users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:923
|
#: common/models.py:938
|
||||||
msgid "Automatically fill out user-details from SSO account-data"
|
msgid "Automatically fill out user-details from SSO account-data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:928
|
#: common/models.py:943
|
||||||
msgid "Mail twice"
|
msgid "Mail twice"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:929
|
#: common/models.py:944
|
||||||
msgid "On signup ask users twice for their mail"
|
msgid "On signup ask users twice for their mail"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:934
|
#: common/models.py:949
|
||||||
msgid "Password twice"
|
msgid "Password twice"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:935
|
#: common/models.py:950
|
||||||
msgid "On signup ask users twice for their password"
|
msgid "On signup ask users twice for their password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:940
|
#: common/models.py:955
|
||||||
msgid "Group on signup"
|
msgid "Group on signup"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:941
|
#: common/models.py:956
|
||||||
msgid "Group to which new users are assigned on registration"
|
msgid "Group to which new users are assigned on registration"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:986
|
#: common/models.py:1001
|
||||||
msgid "Show subscribed parts"
|
msgid "Show subscribed parts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:987
|
#: common/models.py:1002
|
||||||
msgid "Show subscribed parts on the homepage"
|
msgid "Show subscribed parts on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:992
|
#: common/models.py:1007
|
||||||
msgid "Show subscribed categories"
|
msgid "Show subscribed categories"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:993
|
#: common/models.py:1008
|
||||||
msgid "Show subscribed part categories on the homepage"
|
msgid "Show subscribed part categories on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:998
|
#: common/models.py:1013
|
||||||
msgid "Show latest parts"
|
msgid "Show latest parts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:999
|
#: common/models.py:1014
|
||||||
msgid "Show latest parts on the homepage"
|
msgid "Show latest parts on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1004
|
#: common/models.py:1019
|
||||||
msgid "Recent Part Count"
|
msgid "Recent Part Count"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1005
|
#: common/models.py:1020
|
||||||
msgid "Number of recent parts to display on index page"
|
msgid "Number of recent parts to display on index page"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1011
|
#: common/models.py:1026
|
||||||
msgid "Show unvalidated BOMs"
|
msgid "Show unvalidated BOMs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1012
|
#: common/models.py:1027
|
||||||
msgid "Show BOMs that await validation on the homepage"
|
msgid "Show BOMs that await validation on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1017
|
#: common/models.py:1032
|
||||||
msgid "Show recent stock changes"
|
msgid "Show recent stock changes"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1018
|
#: common/models.py:1033
|
||||||
msgid "Show recently changed stock items on the homepage"
|
msgid "Show recently changed stock items on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1023
|
#: common/models.py:1038
|
||||||
msgid "Recent Stock Count"
|
msgid "Recent Stock Count"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1024
|
#: common/models.py:1039
|
||||||
msgid "Number of recent stock items to display on index page"
|
msgid "Number of recent stock items to display on index page"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1029
|
#: common/models.py:1044
|
||||||
msgid "Show low stock"
|
msgid "Show low stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1030
|
#: common/models.py:1045
|
||||||
msgid "Show low stock items on the homepage"
|
msgid "Show low stock items on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1035
|
#: common/models.py:1050
|
||||||
msgid "Show depleted stock"
|
msgid "Show depleted stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1036
|
#: common/models.py:1051
|
||||||
msgid "Show depleted stock items on the homepage"
|
msgid "Show depleted stock items on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1041
|
#: common/models.py:1056
|
||||||
msgid "Show needed stock"
|
msgid "Show needed stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1042
|
#: common/models.py:1057
|
||||||
msgid "Show stock items needed for builds on the homepage"
|
msgid "Show stock items needed for builds on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1047
|
#: common/models.py:1062
|
||||||
msgid "Show expired stock"
|
msgid "Show expired stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1048
|
#: common/models.py:1063
|
||||||
msgid "Show expired stock items on the homepage"
|
msgid "Show expired stock items on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1053
|
#: common/models.py:1068
|
||||||
msgid "Show stale stock"
|
msgid "Show stale stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1054
|
#: common/models.py:1069
|
||||||
msgid "Show stale stock items on the homepage"
|
msgid "Show stale stock items on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1059
|
#: common/models.py:1074
|
||||||
msgid "Show pending builds"
|
msgid "Show pending builds"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1060
|
#: common/models.py:1075
|
||||||
msgid "Show pending builds on the homepage"
|
msgid "Show pending builds on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1065
|
#: common/models.py:1080
|
||||||
msgid "Show overdue builds"
|
msgid "Show overdue builds"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1066
|
#: common/models.py:1081
|
||||||
msgid "Show overdue builds on the homepage"
|
msgid "Show overdue builds on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1071
|
#: common/models.py:1086
|
||||||
msgid "Show outstanding POs"
|
msgid "Show outstanding POs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1072
|
#: common/models.py:1087
|
||||||
msgid "Show outstanding POs on the homepage"
|
msgid "Show outstanding POs on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1077
|
#: common/models.py:1092
|
||||||
msgid "Show overdue POs"
|
msgid "Show overdue POs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1078
|
#: common/models.py:1093
|
||||||
msgid "Show overdue POs on the homepage"
|
msgid "Show overdue POs on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1083
|
#: common/models.py:1098
|
||||||
msgid "Show outstanding SOs"
|
msgid "Show outstanding SOs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1084
|
#: common/models.py:1099
|
||||||
msgid "Show outstanding SOs on the homepage"
|
msgid "Show outstanding SOs on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1089
|
#: common/models.py:1104
|
||||||
msgid "Show overdue SOs"
|
msgid "Show overdue SOs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1090
|
#: common/models.py:1105
|
||||||
msgid "Show overdue SOs on the homepage"
|
msgid "Show overdue SOs on the homepage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1096
|
#: common/models.py:1111
|
||||||
msgid "Inline label display"
|
msgid "Inline label display"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1097
|
#: common/models.py:1112
|
||||||
msgid "Display PDF labels in the browser, instead of downloading as a file"
|
msgid "Display PDF labels in the browser, instead of downloading as a file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1103
|
#: common/models.py:1118
|
||||||
msgid "Inline report display"
|
msgid "Inline report display"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1104
|
#: common/models.py:1119
|
||||||
msgid "Display PDF reports in the browser, instead of downloading as a file"
|
msgid "Display PDF reports in the browser, instead of downloading as a file"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1110
|
#: common/models.py:1125
|
||||||
msgid "Search Preview Results"
|
msgid "Search Preview Results"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1111
|
#: common/models.py:1126
|
||||||
msgid "Number of results to show in search preview window"
|
msgid "Number of results to show in search preview window"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1117
|
#: common/models.py:1132
|
||||||
msgid "Search Show Stock"
|
msgid "Search Show Stock"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1118
|
#: common/models.py:1133
|
||||||
msgid "Display stock levels in search preview window"
|
msgid "Display stock levels in search preview window"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1124
|
#: common/models.py:1139
|
||||||
msgid "Hide Inactive Parts"
|
msgid "Hide Inactive Parts"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1125
|
#: common/models.py:1140
|
||||||
msgid "Hide inactive parts in search preview window"
|
msgid "Hide inactive parts in search preview window"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1131
|
#: common/models.py:1146
|
||||||
msgid "Show Quantity in Forms"
|
msgid "Show Quantity in Forms"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1132
|
#: common/models.py:1147
|
||||||
msgid "Display available part quantity in some forms"
|
msgid "Display available part quantity in some forms"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1138
|
#: common/models.py:1153
|
||||||
msgid "Escape Key Closes Forms"
|
msgid "Escape Key Closes Forms"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1139
|
#: common/models.py:1154
|
||||||
msgid "Use the escape key to close modal forms"
|
msgid "Use the escape key to close modal forms"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1145
|
#: common/models.py:1160
|
||||||
msgid "Fixed Navbar"
|
msgid "Fixed Navbar"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1146
|
#: common/models.py:1161
|
||||||
msgid "InvenTree navbar position is fixed to the top of the screen"
|
msgid "InvenTree navbar position is fixed to the top of the screen"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1211 company/forms.py:43
|
#: common/models.py:1226 company/forms.py:43
|
||||||
msgid "Price break quantity"
|
msgid "Price break quantity"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1218 company/serializers.py:264
|
#: common/models.py:1233 company/serializers.py:264
|
||||||
#: company/templates/company/supplier_part.html:256
|
#: company/templates/company/supplier_part.html:256
|
||||||
#: templates/js/translated/part.js:1508
|
#: templates/js/translated/part.js:1508
|
||||||
msgid "Price"
|
msgid "Price"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: common/models.py:1219
|
#: common/models.py:1234
|
||||||
msgid "Unit price at specified quantity"
|
msgid "Unit price at specified quantity"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
InvenTree/locale/he/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/he/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
InvenTree/locale/id/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/id/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
InvenTree/locale/ko/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/ko/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
InvenTree/locale/nl/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/nl/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
InvenTree/locale/no/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/no/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
InvenTree/locale/sv/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/sv/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
InvenTree/locale/th/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/th/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
InvenTree/locale/vi/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/vi/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -49,7 +49,7 @@ class POList(generics.ListCreateAPIView):
|
|||||||
"""
|
"""
|
||||||
serializer = self.get_serializer(data=request.data)
|
serializer = self.get_serializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
item = serializer.save()
|
item = serializer.save()
|
||||||
item.created_by = request.user
|
item.created_by = request.user
|
||||||
item.save()
|
item.save()
|
||||||
@ -404,7 +404,7 @@ class SOList(generics.ListCreateAPIView):
|
|||||||
"""
|
"""
|
||||||
serializer = self.get_serializer(data=request.data)
|
serializer = self.get_serializer(data=request.data)
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
|
|
||||||
item = serializer.save()
|
item = serializer.save()
|
||||||
item.created_by = request.user
|
item.created_by = request.user
|
||||||
item.save()
|
item.save()
|
||||||
|
@ -772,7 +772,7 @@ class PurchaseOrderLineItem(OrderLineItem):
|
|||||||
def get_base_part(self):
|
def get_base_part(self):
|
||||||
"""
|
"""
|
||||||
Return the base part.Part object for the line item
|
Return the base part.Part object for the line item
|
||||||
|
|
||||||
Note: Returns None if the SupplierPart is not set!
|
Note: Returns None if the SupplierPart is not set!
|
||||||
"""
|
"""
|
||||||
if self.part is None:
|
if self.part is None:
|
||||||
|
@ -553,10 +553,10 @@ class SOLineItemSerializer(InvenTreeModelSerializer):
|
|||||||
allocations = SalesOrderAllocationSerializer(many=True, read_only=True, location_detail=True)
|
allocations = SalesOrderAllocationSerializer(many=True, read_only=True, location_detail=True)
|
||||||
|
|
||||||
quantity = InvenTreeDecimalField()
|
quantity = InvenTreeDecimalField()
|
||||||
|
|
||||||
allocated = serializers.FloatField(source='allocated_quantity', read_only=True)
|
allocated = serializers.FloatField(source='allocated_quantity', read_only=True)
|
||||||
fulfilled = serializers.FloatField(source='fulfilled_quantity', read_only=True)
|
fulfilled = serializers.FloatField(source='fulfilled_quantity', read_only=True)
|
||||||
|
|
||||||
sale_price = InvenTreeMoneySerializer(
|
sale_price = InvenTreeMoneySerializer(
|
||||||
allow_null=True
|
allow_null=True
|
||||||
)
|
)
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
{% url "po-detail" order.id as url %}
|
{% url "po-detail" order.id as url %}
|
||||||
{% include "sidebar_item.html" with url=url text="Return to Orders" icon="fa-undo" %}
|
{% trans "Return to Orders" as text %}
|
||||||
|
{% include "sidebar_item.html" with url=url text=text icon="fa-undo" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load inventree_extras %}
|
{% load inventree_extras %}
|
||||||
|
|
||||||
{% include "sidebar_item.html" with label='order-items' text="Line Items" icon="fa-list-ol" %}
|
{% trans "Line Items" as text %}
|
||||||
{% include "sidebar_item.html" with label='received-items' text="Received Stock" icon="fa-sign-in-alt" %}
|
{% include "sidebar_item.html" with label='order-items' text=text icon="fa-list-ol" %}
|
||||||
{% include "sidebar_item.html" with label='order-attachments' text="Attachments" icon="fa-paperclip" %}
|
{% trans "Received Stock" as text %}
|
||||||
{% include "sidebar_item.html" with label='order-notes' text="Notes" icon="fa-clipboard" %}
|
{% include "sidebar_item.html" with label='received-items' text=text icon="fa-sign-in-alt" %}
|
||||||
|
{% trans "Attachments" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='order-attachments' text=text icon="fa-paperclip" %}
|
||||||
|
{% trans "Notes" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='order-notes' text=text icon="fa-clipboard" %}
|
@ -2,7 +2,11 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load inventree_extras %}
|
{% load inventree_extras %}
|
||||||
|
|
||||||
{% include "sidebar_item.html" with label='order-items' text="Line Items" icon="fa-list-ol" %}
|
{% trans "Line Items" as text %}
|
||||||
{% include "sidebar_item.html" with label='order-builds' text="Build Orders" icon="fa-tools" %}
|
{% include "sidebar_item.html" with label='order-items' text=text icon="fa-list-ol" %}
|
||||||
{% include "sidebar_item.html" with label='order-attachments' text="Attachments" icon="fa-paperclip" %}
|
{% trans "Build Orders" as text %}
|
||||||
{% include "sidebar_item.html" with label='order-notes' text="Notes" icon="fa-clipboard" %}
|
{% include "sidebar_item.html" with label='order-builds' text=text icon="fa-tools" %}
|
||||||
|
{% trans "Attachments" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='order-attachments' text=text icon="fa-paperclip" %}
|
||||||
|
{% trans "Notes" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='order-notes' text=text icon="fa-clipboard" %}
|
||||||
|
@ -228,7 +228,7 @@ class PurchaseOrderReceiveTest(OrderTest):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|
||||||
self.assignRole('purchase_order.add')
|
self.assignRole('purchase_order.add')
|
||||||
|
|
||||||
self.url = reverse('api-po-receive', kwargs={'pk': 1})
|
self.url = reverse('api-po-receive', kwargs={'pk': 1})
|
||||||
|
@ -406,7 +406,7 @@ class PurchaseOrderUpload(FileManagementFormView):
|
|||||||
|
|
||||||
def done(self, form_list, **kwargs):
|
def done(self, form_list, **kwargs):
|
||||||
""" Once all the data is in, process it to add PurchaseOrderLineItem instances to the order """
|
""" Once all the data is in, process it to add PurchaseOrderLineItem instances to the order """
|
||||||
|
|
||||||
order = self.get_order()
|
order = self.get_order()
|
||||||
items = self.get_clean_items()
|
items = self.get_clean_items()
|
||||||
|
|
||||||
@ -432,7 +432,7 @@ class PurchaseOrderUpload(FileManagementFormView):
|
|||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
# PurchaseOrderLineItem already exists
|
# PurchaseOrderLineItem already exists
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return HttpResponseRedirect(reverse('po-detail', kwargs={'pk': self.kwargs['pk']}))
|
return HttpResponseRedirect(reverse('po-detail', kwargs={'pk': self.kwargs['pk']}))
|
||||||
|
|
||||||
|
|
||||||
@ -449,7 +449,7 @@ class SalesOrderExport(AjaxView):
|
|||||||
role_required = 'sales_order.view'
|
role_required = 'sales_order.view'
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
|
||||||
order = get_object_or_404(SalesOrder, pk=self.kwargs.get('pk', None))
|
order = get_object_or_404(SalesOrder, pk=self.kwargs.get('pk', None))
|
||||||
|
|
||||||
export_format = request.GET.get('format', 'csv')
|
export_format = request.GET.get('format', 'csv')
|
||||||
|
@ -205,7 +205,7 @@ class BomItemResource(ModelResource):
|
|||||||
|
|
||||||
# If we are not generating an "import" template,
|
# If we are not generating an "import" template,
|
||||||
# just return the complete list of fields
|
# just return the complete list of fields
|
||||||
if not self.is_importing:
|
if not getattr(self, 'is_importing', False):
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
# Otherwise, remove some fields we are not interested in
|
# Otherwise, remove some fields we are not interested in
|
||||||
|
@ -169,7 +169,7 @@ class CategoryDetail(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
"""
|
"""
|
||||||
API endpoint for detail view of a single PartCategory object
|
API endpoint for detail view of a single PartCategory object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = part_serializers.CategorySerializer
|
serializer_class = part_serializers.CategorySerializer
|
||||||
queryset = PartCategory.objects.all()
|
queryset = PartCategory.objects.all()
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ class CategoryParameterList(generics.ListAPIView):
|
|||||||
|
|
||||||
if category is not None:
|
if category is not None:
|
||||||
try:
|
try:
|
||||||
|
|
||||||
category = PartCategory.objects.get(pk=category)
|
category = PartCategory.objects.get(pk=category)
|
||||||
|
|
||||||
fetch_parent = str2bool(params.get('fetch_parent', True))
|
fetch_parent = str2bool(params.get('fetch_parent', True))
|
||||||
@ -734,7 +734,7 @@ class PartList(generics.ListCreateAPIView):
|
|||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'initial_stock_quantity': [_('Must be a valid quantity')],
|
'initial_stock_quantity': [_('Must be a valid quantity')],
|
||||||
})
|
})
|
||||||
|
|
||||||
initial_stock_location = request.data.get('initial_stock_location', None)
|
initial_stock_location = request.data.get('initial_stock_location', None)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -850,7 +850,7 @@ class PartList(generics.ListCreateAPIView):
|
|||||||
id_values.append(val)
|
id_values.append(val)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
queryset = queryset.exclude(pk__in=id_values)
|
queryset = queryset.exclude(pk__in=id_values)
|
||||||
|
|
||||||
# Exclude part variant tree?
|
# Exclude part variant tree?
|
||||||
@ -1096,7 +1096,7 @@ class BomFilter(rest_filters.FilterSet):
|
|||||||
queryset = queryset.filter(pk__in=pks)
|
queryset = queryset.filter(pk__in=pks)
|
||||||
else:
|
else:
|
||||||
queryset = queryset.exclude(pk__in=pks)
|
queryset = queryset.exclude(pk__in=pks)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
# Filters for linked 'part'
|
# Filters for linked 'part'
|
||||||
@ -1257,7 +1257,7 @@ class BomList(generics.ListCreateAPIView):
|
|||||||
queryset = self.annotate_pricing(queryset)
|
queryset = self.annotate_pricing(queryset)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def include_pricing(self):
|
def include_pricing(self):
|
||||||
"""
|
"""
|
||||||
Determine if pricing information should be included in the response
|
Determine if pricing information should be included in the response
|
||||||
@ -1291,7 +1291,7 @@ class BomList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
# Get default currency from settings
|
# Get default currency from settings
|
||||||
default_currency = InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY')
|
default_currency = InvenTreeSetting.get_setting('INVENTREE_DEFAULT_CURRENCY')
|
||||||
|
|
||||||
if price:
|
if price:
|
||||||
if currency and default_currency:
|
if currency and default_currency:
|
||||||
try:
|
try:
|
||||||
@ -1381,7 +1381,7 @@ class BomItemSubstituteList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
serializer_class = part_serializers.BomItemSubstituteSerializer
|
serializer_class = part_serializers.BomItemSubstituteSerializer
|
||||||
queryset = BomItemSubstitute.objects.all()
|
queryset = BomItemSubstitute.objects.all()
|
||||||
|
|
||||||
filter_backends = [
|
filter_backends = [
|
||||||
DjangoFilterBackend,
|
DjangoFilterBackend,
|
||||||
filters.SearchFilter,
|
filters.SearchFilter,
|
||||||
|
@ -172,7 +172,7 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None, parameter_data=Fa
|
|||||||
|
|
||||||
# Filter manufacturer parts
|
# Filter manufacturer parts
|
||||||
manufacturer_parts = ManufacturerPart.objects.filter(part__pk=b_part.pk).prefetch_related('supplier_parts')
|
manufacturer_parts = ManufacturerPart.objects.filter(part__pk=b_part.pk).prefetch_related('supplier_parts')
|
||||||
|
|
||||||
for mp_idx, mp_part in enumerate(manufacturer_parts):
|
for mp_idx, mp_part in enumerate(manufacturer_parts):
|
||||||
|
|
||||||
# Extract the "name" field of the Manufacturer (Company)
|
# Extract the "name" field of the Manufacturer (Company)
|
||||||
@ -190,7 +190,7 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None, parameter_data=Fa
|
|||||||
# Generate a column name for this manufacturer
|
# Generate a column name for this manufacturer
|
||||||
k_man = f'{_("Manufacturer")}_{mp_idx}'
|
k_man = f'{_("Manufacturer")}_{mp_idx}'
|
||||||
k_mpn = f'{_("MPN")}_{mp_idx}'
|
k_mpn = f'{_("MPN")}_{mp_idx}'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
manufacturer_cols[k_man].update({bom_idx: manufacturer_name})
|
manufacturer_cols[k_man].update({bom_idx: manufacturer_name})
|
||||||
manufacturer_cols[k_mpn].update({bom_idx: manufacturer_mpn})
|
manufacturer_cols[k_mpn].update({bom_idx: manufacturer_mpn})
|
||||||
@ -200,7 +200,7 @@ def ExportBom(part, fmt='csv', cascade=False, max_levels=None, parameter_data=Fa
|
|||||||
|
|
||||||
# We wish to include supplier data for this manufacturer part
|
# We wish to include supplier data for this manufacturer part
|
||||||
if supplier_data:
|
if supplier_data:
|
||||||
|
|
||||||
for sp_idx, sp_part in enumerate(mp_part.supplier_parts.all()):
|
for sp_idx, sp_part in enumerate(mp_part.supplier_parts.all()):
|
||||||
|
|
||||||
supplier_parts_used.add(sp_part)
|
supplier_parts_used.add(sp_part)
|
||||||
|
@ -2118,7 +2118,7 @@ class Part(MPTTModel):
|
|||||||
"""
|
"""
|
||||||
Returns True if the total stock for this part is less than the minimum stock level
|
Returns True if the total stock for this part is less than the minimum stock level
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return self.get_stock_count() < self.minimum_stock
|
return self.get_stock_count() < self.minimum_stock
|
||||||
|
|
||||||
|
|
||||||
@ -2155,7 +2155,7 @@ class PartSellPriceBreak(common.models.PriceBreak):
|
|||||||
"""
|
"""
|
||||||
Represents a price break for selling this part
|
Represents a price break for selling this part
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_api_url():
|
def get_api_url():
|
||||||
return reverse('api-part-sale-price-list')
|
return reverse('api-part-sale-price-list')
|
||||||
|
@ -446,9 +446,9 @@ class BomItemSerializer(InvenTreeModelSerializer):
|
|||||||
purchase_price_min = MoneyField(max_digits=10, decimal_places=6, read_only=True)
|
purchase_price_min = MoneyField(max_digits=10, decimal_places=6, read_only=True)
|
||||||
|
|
||||||
purchase_price_max = MoneyField(max_digits=10, decimal_places=6, read_only=True)
|
purchase_price_max = MoneyField(max_digits=10, decimal_places=6, read_only=True)
|
||||||
|
|
||||||
purchase_price_avg = serializers.SerializerMethodField()
|
purchase_price_avg = serializers.SerializerMethodField()
|
||||||
|
|
||||||
purchase_price_range = serializers.SerializerMethodField()
|
purchase_price_range = serializers.SerializerMethodField()
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@ -520,7 +520,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
|
|||||||
|
|
||||||
def get_purchase_price_avg(self, obj):
|
def get_purchase_price_avg(self, obj):
|
||||||
""" Return purchase price average """
|
""" Return purchase price average """
|
||||||
|
|
||||||
try:
|
try:
|
||||||
purchase_price_avg = obj.purchase_price_avg
|
purchase_price_avg = obj.purchase_price_avg
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -62,7 +62,7 @@ def notify_low_stock(part: part.models.Part):
|
|||||||
def notify_low_stock_if_required(part: part.models.Part):
|
def notify_low_stock_if_required(part: part.models.Part):
|
||||||
"""
|
"""
|
||||||
Check if the stock quantity has fallen below the minimum threshold of part.
|
Check if the stock quantity has fallen below the minimum threshold of part.
|
||||||
|
|
||||||
If true, notify the users who have subscribed to the part
|
If true, notify the users who have subscribed to the part
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
{% url "part-detail" part.id as url %}
|
{% url "part-detail" part.id as url %}
|
||||||
{% include "sidebar_link.html" with url=url text="Return to BOM" icon="fa-undo" %}
|
{% trans "Return to BOM" as text %}
|
||||||
|
{% include "sidebar_link.html" with url=url text=text icon="fa-undo" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block heading %}
|
{% block heading %}
|
||||||
|
@ -4,12 +4,16 @@
|
|||||||
|
|
||||||
{% settings_value 'PART_SHOW_IMPORT' as show_import %}
|
{% settings_value 'PART_SHOW_IMPORT' as show_import %}
|
||||||
|
|
||||||
{% include "sidebar_item.html" with label="subcategories" text="Subcategories" icon="fa-sitemap" %}
|
{% trans "Subcategories" as text %}
|
||||||
{% include "sidebar_item.html" with label="parts" text="Parts" icon="fa-shapes" %}
|
{% include "sidebar_item.html" with label="subcategories" text=text icon="fa-sitemap" %}
|
||||||
|
{% trans "Parts" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="parts" text=text icon="fa-shapes" %}
|
||||||
{% if show_import and user.is_staff and roles.part.add %}
|
{% if show_import and user.is_staff and roles.part.add %}
|
||||||
{% url "part-import" as url %}
|
{% url "part-import" as url %}
|
||||||
{% include "sidebar_link.html" with url=url text="Import Parts" icon="fa-file-upload" %}
|
{% trans "Import Parts" as text %}
|
||||||
|
{% include "sidebar_link.html" with url=url text=text icon="fa-file-upload" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if category %}
|
{% if category %}
|
||||||
{% include "sidebar_item.html" with label="parameters" text="Parameters" icon="fa-tasks" %}
|
{% trans "Parameters" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="parameters" text=text icon="fa-tasks" %}
|
||||||
{% endif %}
|
{% endif %}
|
@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
{% block sidebar %}
|
{% block sidebar %}
|
||||||
{% url 'part-index' as url %}
|
{% url 'part-index' as url %}
|
||||||
{% include "sidebar_link.html" with url=url text="Return to Parts" icon="fa-undo" %}
|
{% trans "Return to Parts" as text %}
|
||||||
|
{% include "sidebar_link.html" with url=url text=text icon="fa-undo" %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
@ -5,34 +5,49 @@
|
|||||||
{% settings_value "PART_INTERNAL_PRICE" as show_internal_price %}
|
{% settings_value "PART_INTERNAL_PRICE" as show_internal_price %}
|
||||||
{% settings_value 'PART_SHOW_RELATED' as show_related %}
|
{% settings_value 'PART_SHOW_RELATED' as show_related %}
|
||||||
|
|
||||||
{% include "sidebar_item.html" with label="part-details" text="Details" icon="fa-shapes" %}
|
{% trans "Details" as text %}
|
||||||
{% include "sidebar_item.html" with label="part-parameters" text="Parameters" icon="fa-th-list" %}
|
{% include "sidebar_item.html" with label="part-details" text=text icon="fa-shapes" %}
|
||||||
|
{% trans "Parameters" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="part-parameters" text=text icon="fa-th-list" %}
|
||||||
{% if part.is_template %}
|
{% if part.is_template %}
|
||||||
{% include "sidebar_item.html" with label="variants" text="Variants" icon="fa-shapes" %}
|
{% trans "Variants" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="variants" text=text icon="fa-shapes" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include "sidebar_item.html" with label="part-stock" text="Stock" icon="fa-boxes" %}
|
{% trans "Stock" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="part-stock" text=text icon="fa-boxes" %}
|
||||||
{% if part.assembly %}
|
{% if part.assembly %}
|
||||||
{% include "sidebar_item.html" with label="bom" text="Bill of Materials" icon="fa-list" %}
|
{% trans "Bill of Materials" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="bom" text=text icon="fa-list" %}
|
||||||
{% if roles.build.view %}
|
{% if roles.build.view %}
|
||||||
{% include "sidebar_item.html" with label="build-orders" text="Build Orders" icon="fa-tools" %}
|
{% trans "Build Orders" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="build-orders" text=text icon="fa-tools" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if part.component %}
|
{% if part.component %}
|
||||||
{% include "sidebar_item.html" with label="used-in" text="Used In" icon="fa-layer-group" %}
|
{% trans "Used In" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="used-in" text=text icon="fa-layer-group" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include "sidebar_item.html" with label="pricing" text="Pricing" icon="fa-dollar-sign" %}
|
{% trans "Pricing" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="pricing" text=text icon="fa-dollar-sign" %}
|
||||||
{% if part.purchaseable and roles.purchase_order.view %}
|
{% if part.purchaseable and roles.purchase_order.view %}
|
||||||
{% include "sidebar_item.html" with label="suppliers" text="Suppliers" icon="fa-building" %}
|
{% trans "Suppliers" as text %}
|
||||||
{% include "sidebar_item.html" with label="purchase-orders" text="Purchase Orders" icon="fa-shopping-cart" %}
|
{% include "sidebar_item.html" with label="suppliers" text=text icon="fa-building" %}
|
||||||
|
{% trans "Purchase Orders" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="purchase-orders" text=text icon="fa-shopping-cart" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if part.salable and roles.sales_order.view %}
|
{% if part.salable and roles.sales_order.view %}
|
||||||
{% include "sidebar_item.html" with label="sales-orders" text="Sales Orders" icon="fa-truck" %}
|
{% trans "Sales Orders" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="sales-orders" text=text icon="fa-truck" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if part.trackable %}
|
{% if part.trackable %}
|
||||||
{% include "sidebar_item.html" with label="test-templates" text="Test Templates" icon="fa-vial" %}
|
{% trans "Test Templates" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="test-templates" text=text icon="fa-vial" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if show_related %}
|
{% if show_related %}
|
||||||
{% include "sidebar_item.html" with label="related-parts" text="Related Parts" icon="fa-random" %}
|
{% trans "Related Parts" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="related-parts" text=text icon="fa-random" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include "sidebar_item.html" with label="part-attachments" text="Attachments" icon="fa-paperclip" %}
|
{% trans "Attachments" as text %}
|
||||||
{% include "sidebar_item.html" with label="part-notes" text="Notes" icon="fa-clipboard" %}
|
{% include "sidebar_item.html" with label="part-attachments" text=text icon="fa-paperclip" %}
|
||||||
|
{% trans "Notes" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="part-notes" text=text icon="fa-clipboard" %}
|
||||||
|
@ -236,7 +236,7 @@ def settings_value(key, *args, **kwargs):
|
|||||||
|
|
||||||
if 'user' in kwargs:
|
if 'user' in kwargs:
|
||||||
return InvenTreeUserSetting.get_setting(key, user=kwargs['user'])
|
return InvenTreeUserSetting.get_setting(key, user=kwargs['user'])
|
||||||
|
|
||||||
return InvenTreeSetting.get_setting(key)
|
return InvenTreeSetting.get_setting(key)
|
||||||
|
|
||||||
|
|
||||||
@ -384,7 +384,7 @@ def keyvalue(dict, key):
|
|||||||
def call_method(obj, method_name, *args):
|
def call_method(obj, method_name, *args):
|
||||||
"""
|
"""
|
||||||
enables calling model methods / functions from templates with arguments
|
enables calling model methods / functions from templates with arguments
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
{% call_method model_object 'fnc_name' argument1 %}
|
{% call_method model_object 'fnc_name' argument1 %}
|
||||||
"""
|
"""
|
||||||
|
@ -542,7 +542,7 @@ class PartAPITest(InvenTreeAPITestCase):
|
|||||||
# Check that there is a new manufacturer part *and* a new supplier part
|
# Check that there is a new manufacturer part *and* a new supplier part
|
||||||
self.assertEqual(new_part.supplier_parts.count(), 1)
|
self.assertEqual(new_part.supplier_parts.count(), 1)
|
||||||
self.assertEqual(new_part.manufacturer_parts.count(), 1)
|
self.assertEqual(new_part.manufacturer_parts.count(), 1)
|
||||||
|
|
||||||
def test_strange_chars(self):
|
def test_strange_chars(self):
|
||||||
"""
|
"""
|
||||||
Test that non-standard ASCII chars are accepted
|
Test that non-standard ASCII chars are accepted
|
||||||
@ -911,7 +911,7 @@ class BomItemTest(InvenTreeAPITestCase):
|
|||||||
|
|
||||||
# How many BOM items currently exist in the database?
|
# How many BOM items currently exist in the database?
|
||||||
n = BomItem.objects.count()
|
n = BomItem.objects.count()
|
||||||
|
|
||||||
url = reverse('api-bom-list')
|
url = reverse('api-bom-list')
|
||||||
response = self.get(url, expected_code=200)
|
response = self.get(url, expected_code=200)
|
||||||
self.assertEqual(len(response.data), n)
|
self.assertEqual(len(response.data), n)
|
||||||
@ -962,7 +962,7 @@ class BomItemTest(InvenTreeAPITestCase):
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.post(url, data, expected_code=201)
|
self.post(url, data, expected_code=201)
|
||||||
|
|
||||||
# Now try to create a BomItem which references itself
|
# Now try to create a BomItem which references itself
|
||||||
data['part'] = 100
|
data['part'] = 100
|
||||||
data['sub_part'] = 100
|
data['sub_part'] = 100
|
||||||
@ -1003,7 +1003,7 @@ class BomItemTest(InvenTreeAPITestCase):
|
|||||||
|
|
||||||
# Now we will create some variant parts and stock
|
# Now we will create some variant parts and stock
|
||||||
for ii in range(5):
|
for ii in range(5):
|
||||||
|
|
||||||
# Create a variant part!
|
# Create a variant part!
|
||||||
variant = Part.objects.create(
|
variant = Part.objects.create(
|
||||||
name=f"Variant_{ii}",
|
name=f"Variant_{ii}",
|
||||||
|
@ -153,7 +153,7 @@ class BomItemTest(TestCase):
|
|||||||
subs = []
|
subs = []
|
||||||
|
|
||||||
for ii in range(5):
|
for ii in range(5):
|
||||||
|
|
||||||
# Create a new part
|
# Create a new part
|
||||||
sub_part = Part.objects.create(
|
sub_part = Part.objects.create(
|
||||||
name=f"Orphan {ii}",
|
name=f"Orphan {ii}",
|
||||||
@ -181,7 +181,7 @@ class BomItemTest(TestCase):
|
|||||||
|
|
||||||
# There should be now 5 substitute parts available
|
# There should be now 5 substitute parts available
|
||||||
self.assertEqual(bom_item.substitutes.count(), 5)
|
self.assertEqual(bom_item.substitutes.count(), 5)
|
||||||
|
|
||||||
# Try to create a substitute which points to the same sub-part (should fail)
|
# Try to create a substitute which points to the same sub-part (should fail)
|
||||||
with self.assertRaises(django_exceptions.ValidationError):
|
with self.assertRaises(django_exceptions.ValidationError):
|
||||||
BomItemSubstitute.objects.create(
|
BomItemSubstitute.objects.create(
|
||||||
|
@ -370,7 +370,7 @@ class PartSubscriptionTests(TestCase):
|
|||||||
|
|
||||||
# electronics / IC / MCU
|
# electronics / IC / MCU
|
||||||
self.category = PartCategory.objects.get(pk=4)
|
self.category = PartCategory.objects.get(pk=4)
|
||||||
|
|
||||||
self.part = Part.objects.create(
|
self.part = Part.objects.create(
|
||||||
category=self.category,
|
category=self.category,
|
||||||
name='STM32F103',
|
name='STM32F103',
|
||||||
@ -382,7 +382,7 @@ class PartSubscriptionTests(TestCase):
|
|||||||
"""
|
"""
|
||||||
Test basic subscription against a part
|
Test basic subscription against a part
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# First check that the user is *not* subscribed to the part
|
# First check that the user is *not* subscribed to the part
|
||||||
self.assertFalse(self.part.is_starred_by(self.user))
|
self.assertFalse(self.part.is_starred_by(self.user))
|
||||||
|
|
||||||
@ -450,7 +450,7 @@ class PartSubscriptionTests(TestCase):
|
|||||||
"""
|
"""
|
||||||
Check that a parent category can be subscribed to
|
Check that a parent category can be subscribed to
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Top-level "electronics" category
|
# Top-level "electronics" category
|
||||||
cat = PartCategory.objects.get(pk=1)
|
cat = PartCategory.objects.get(pk=1)
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ part_detail_urls = [
|
|||||||
url(r'^bom-export/?', views.BomExport.as_view(), name='bom-export'),
|
url(r'^bom-export/?', views.BomExport.as_view(), name='bom-export'),
|
||||||
url(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'),
|
url(r'^bom-download/?', views.BomDownload.as_view(), name='bom-download'),
|
||||||
url(r'^validate-bom/', views.BomValidate.as_view(), name='bom-validate'),
|
url(r'^validate-bom/', views.BomValidate.as_view(), name='bom-validate'),
|
||||||
|
|
||||||
url(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'),
|
url(r'^pricing/', views.PartPricing.as_view(), name='part-pricing'),
|
||||||
|
|
||||||
url(r'^bom-upload/?', views.BomUpload.as_view(), name='upload-bom'),
|
url(r'^bom-upload/?', views.BomUpload.as_view(), name='upload-bom'),
|
||||||
|
@ -459,7 +459,7 @@ class PartDetail(InvenTreeRoleMixin, DetailView):
|
|||||||
part = self.get_object()
|
part = self.get_object()
|
||||||
|
|
||||||
ctx = part.get_context_data(self.request)
|
ctx = part.get_context_data(self.request)
|
||||||
|
|
||||||
context.update(**ctx)
|
context.update(**ctx)
|
||||||
|
|
||||||
# Pricing information
|
# Pricing information
|
||||||
@ -1056,7 +1056,7 @@ class BomUpload(InvenTreeRoleMixin, FileManagementFormView):
|
|||||||
matches = sorted(matches, key=lambda item: item['match'], reverse=True)
|
matches = sorted(matches, key=lambda item: item['match'], reverse=True)
|
||||||
|
|
||||||
part_options = [m['part'] for m in matches]
|
part_options = [m['part'] for m in matches]
|
||||||
|
|
||||||
# Supply list of part options for each row, sorted by how closely they match the part name
|
# Supply list of part options for each row, sorted by how closely they match the part name
|
||||||
row['item_options'] = part_options
|
row['item_options'] = part_options
|
||||||
|
|
||||||
@ -1520,11 +1520,11 @@ class CategoryDetail(InvenTreeRoleMixin, DetailView):
|
|||||||
|
|
||||||
# Prefetch parts parameters
|
# Prefetch parts parameters
|
||||||
parts_parameters = category.prefetch_parts_parameters(cascade=cascade)
|
parts_parameters = category.prefetch_parts_parameters(cascade=cascade)
|
||||||
|
|
||||||
# Get table headers (unique parameters names)
|
# Get table headers (unique parameters names)
|
||||||
context['headers'] = category.get_unique_parameters(cascade=cascade,
|
context['headers'] = category.get_unique_parameters(cascade=cascade,
|
||||||
prefetch=parts_parameters)
|
prefetch=parts_parameters)
|
||||||
|
|
||||||
# Insert part information
|
# Insert part information
|
||||||
context['headers'].insert(0, 'description')
|
context['headers'].insert(0, 'description')
|
||||||
context['headers'].insert(0, 'part')
|
context['headers'].insert(0, 'part')
|
||||||
|
@ -247,7 +247,7 @@ class ReportTemplateBase(ReportBase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
template_string = Template(self.filename_pattern)
|
template_string = Template(self.filename_pattern)
|
||||||
|
|
||||||
ctx = self.context(request)
|
ctx = self.context(request)
|
||||||
|
|
||||||
context = Context(ctx)
|
context = Context(ctx)
|
||||||
|
@ -106,7 +106,7 @@ class ReportTest(InvenTreeAPITestCase):
|
|||||||
# Filter by "enabled" status
|
# Filter by "enabled" status
|
||||||
response = self.get(url, {'enabled': True})
|
response = self.get(url, {'enabled': True})
|
||||||
self.assertEqual(len(response.data), n)
|
self.assertEqual(len(response.data), n)
|
||||||
|
|
||||||
response = self.get(url, {'enabled': False})
|
response = self.get(url, {'enabled': False})
|
||||||
self.assertEqual(len(response.data), 0)
|
self.assertEqual(len(response.data), 0)
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ class ReportTest(InvenTreeAPITestCase):
|
|||||||
# Filter by "enabled" status
|
# Filter by "enabled" status
|
||||||
response = self.get(url, {'enabled': True})
|
response = self.get(url, {'enabled': True})
|
||||||
self.assertEqual(len(response.data), 0)
|
self.assertEqual(len(response.data), 0)
|
||||||
|
|
||||||
response = self.get(url, {'enabled': False})
|
response = self.get(url, {'enabled': False})
|
||||||
self.assertEqual(len(response.data), n)
|
self.assertEqual(len(response.data), n)
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ class BuildReportTest(ReportTest):
|
|||||||
build = Build.objects.first()
|
build = Build.objects.first()
|
||||||
|
|
||||||
response = self.get(url, {'build': build.pk})
|
response = self.get(url, {'build': build.pk})
|
||||||
|
|
||||||
self.assertEqual(type(response), StreamingHttpResponse)
|
self.assertEqual(type(response), StreamingHttpResponse)
|
||||||
|
|
||||||
headers = response.headers
|
headers = response.headers
|
||||||
|
@ -91,7 +91,7 @@ class StockDetail(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
Instead of "deleting" the StockItem
|
Instead of "deleting" the StockItem
|
||||||
(which may take a long time)
|
(which may take a long time)
|
||||||
we instead schedule it for deletion at a later date.
|
we instead schedule it for deletion at a later date.
|
||||||
|
|
||||||
The background worker will delete these in the future
|
The background worker will delete these in the future
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ class StockAdjustView(generics.CreateAPIView):
|
|||||||
queryset = StockItem.objects.none()
|
queryset = StockItem.objects.none()
|
||||||
|
|
||||||
def get_serializer_context(self):
|
def get_serializer_context(self):
|
||||||
|
|
||||||
context = super().get_serializer_context()
|
context = super().get_serializer_context()
|
||||||
|
|
||||||
context['request'] = self.request
|
context['request'] = self.request
|
||||||
@ -348,7 +348,7 @@ class StockFilter(rest_filters.FilterSet):
|
|||||||
queryset = queryset.exclude(customer=None)
|
queryset = queryset.exclude(customer=None)
|
||||||
else:
|
else:
|
||||||
queryset = queryset.filter(customer=None)
|
queryset = queryset.filter(customer=None)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
depleted = rest_filters.BooleanFilter(label='Depleted', method='filter_depleted')
|
depleted = rest_filters.BooleanFilter(label='Depleted', method='filter_depleted')
|
||||||
@ -437,7 +437,7 @@ class StockList(generics.ListCreateAPIView):
|
|||||||
})
|
})
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
|
|
||||||
# Create an initial stock item
|
# Create an initial stock item
|
||||||
item = serializer.save()
|
item = serializer.save()
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ class ConvertStockItemForm(HelperForm):
|
|||||||
class CreateStockItemForm(HelperForm):
|
class CreateStockItemForm(HelperForm):
|
||||||
"""
|
"""
|
||||||
Form for creating a new StockItem
|
Form for creating a new StockItem
|
||||||
|
|
||||||
TODO: Migrate this form to the modern API forms interface
|
TODO: Migrate this form to the modern API forms interface
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ class CreateStockItemForm(HelperForm):
|
|||||||
class SerializeStockForm(HelperForm):
|
class SerializeStockForm(HelperForm):
|
||||||
"""
|
"""
|
||||||
Form for serializing a StockItem.
|
Form for serializing a StockItem.
|
||||||
|
|
||||||
TODO: Migrate this form to the modern API forms interface
|
TODO: Migrate this form to the modern API forms interface
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -272,7 +272,7 @@ class StockItem(MPTTModel):
|
|||||||
add_note = kwargs.pop('add_note', True)
|
add_note = kwargs.pop('add_note', True)
|
||||||
|
|
||||||
notes = kwargs.pop('notes', '')
|
notes = kwargs.pop('notes', '')
|
||||||
|
|
||||||
if self.pk:
|
if self.pk:
|
||||||
# StockItem has already been saved
|
# StockItem has already been saved
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ class StockItemSerializerBrief(InvenTree.serializers.InvenTreeModelSerializer):
|
|||||||
|
|
||||||
location_name = serializers.CharField(source='location', read_only=True)
|
location_name = serializers.CharField(source='location', read_only=True)
|
||||||
part_name = serializers.CharField(source='part.full_name', read_only=True)
|
part_name = serializers.CharField(source='part.full_name', read_only=True)
|
||||||
|
|
||||||
quantity = InvenTreeDecimalField()
|
quantity = InvenTreeDecimalField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -615,7 +615,7 @@ class StockCountSerializer(StockAdjustmentSerializer):
|
|||||||
|
|
||||||
stock_item = item['pk']
|
stock_item = item['pk']
|
||||||
quantity = item['quantity']
|
quantity = item['quantity']
|
||||||
|
|
||||||
stock_item.stocktake(
|
stock_item.stocktake(
|
||||||
quantity,
|
quantity,
|
||||||
request.user,
|
request.user,
|
||||||
@ -654,7 +654,7 @@ class StockRemoveSerializer(StockAdjustmentSerializer):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
|
|
||||||
request = self.context['request']
|
request = self.context['request']
|
||||||
|
|
||||||
data = self.validated_data
|
data = self.validated_data
|
||||||
@ -707,7 +707,7 @@ class StockTransferSerializer(StockAdjustmentSerializer):
|
|||||||
request = self.context['request']
|
request = self.context['request']
|
||||||
|
|
||||||
data = self.validated_data
|
data = self.validated_data
|
||||||
|
|
||||||
items = data['items']
|
items = data['items']
|
||||||
notes = data.get('notes', '')
|
notes = data.get('notes', '')
|
||||||
location = data['location']
|
location = data['location']
|
||||||
|
@ -2,5 +2,7 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load inventree_extras %}
|
{% load inventree_extras %}
|
||||||
|
|
||||||
{% include "sidebar_item.html" with label='sublocations' text="Sublocations" icon="fa-sitemap" %}
|
{% trans "Sublocations" as text %}
|
||||||
{% include "sidebar_item.html" with label='stock' text="Stock Items" icon="fa-boxes" %}
|
{% include "sidebar_item.html" with label='sublocations' text=text icon="fa-sitemap" %}
|
||||||
|
{% trans "Stock Items" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='stock' text=text icon="fa-boxes" %}
|
||||||
|
@ -2,15 +2,21 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load inventree_extras %}
|
{% load inventree_extras %}
|
||||||
|
|
||||||
{% include "sidebar_item.html" with label='history' text="Stock Tracking" icon="fa-history" %}
|
{% trans "Stock Tracking" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='history' text=text icon="fa-history" %}
|
||||||
{% if item.part.trackable %}
|
{% if item.part.trackable %}
|
||||||
{% include "sidebar_item.html" with label='test-data' text="Test Data" icon="fa-vial" %}
|
{% trans "Test Data" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='test-data' text=text icon="fa-vial" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if item.part.assembly %}
|
{% if item.part.assembly %}
|
||||||
{% include "sidebar_item.html" with label='installed-items' text="Installed Items" icon="fa-sign-in-alt" %}
|
{% trans "Installed Items" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='installed-items' text=text icon="fa-sign-in-alt" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if item.child_count > 0 %}
|
{% if item.child_count > 0 %}
|
||||||
{% include "sidebar_item.html" with label='children' text="Child Items" icon="fa-sitemap" %}
|
{% trans "Child Items" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='children' text=text icon="fa-sitemap" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include "sidebar_item.html" with label='attachments' text="Attachments" icon="fa-paperclip" %}
|
{% trans "Attachments" as text %}
|
||||||
{% include "sidebar_item.html" with label='notes' text="Notes" icon="fa-clipboard" %}
|
{% include "sidebar_item.html" with label='attachments' text=text icon="fa-paperclip" %}
|
||||||
|
{% trans "Notes" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='notes' text=text icon="fa-clipboard" %}
|
||||||
|
@ -368,7 +368,7 @@ class StockItemTest(StockAPITestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self.assertIn('Quantity is required', str(response.data))
|
self.assertIn('Quantity is required', str(response.data))
|
||||||
|
|
||||||
# POST with quantity and part and location
|
# POST with quantity and part and location
|
||||||
response = self.post(
|
response = self.post(
|
||||||
self.list_url,
|
self.list_url,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user