2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-29 20:16:44 +00:00

Merge branch 'inventree:master' into matmair/issue2279

This commit is contained in:
Matthias Mair 2022-02-28 00:45:58 +01:00 committed by GitHub
commit 86ba69eeaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 3473 additions and 3366 deletions

View File

@ -258,6 +258,7 @@ class StockHistoryCode(StatusCode):
# Build order codes # Build order codes
BUILD_OUTPUT_CREATED = 50 BUILD_OUTPUT_CREATED = 50
BUILD_OUTPUT_COMPLETED = 55 BUILD_OUTPUT_COMPLETED = 55
BUILD_CONSUMED = 57
# Sales order codes # Sales order codes
@ -298,6 +299,7 @@ class StockHistoryCode(StatusCode):
BUILD_OUTPUT_CREATED: _('Build order output created'), BUILD_OUTPUT_CREATED: _('Build order output created'),
BUILD_OUTPUT_COMPLETED: _('Build order output completed'), BUILD_OUTPUT_COMPLETED: _('Build order output completed'),
BUILD_CONSUMED: _('Consumed by build order'),
RECEIVED_AGAINST_PURCHASE_ORDER: _('Received against purchase order') RECEIVED_AGAINST_PURCHASE_ORDER: _('Received against purchase order')

View File

@ -30,8 +30,6 @@ from InvenTree.helpers import increment, getSetting, normalize, MakeBarcode
from InvenTree.models import InvenTreeAttachment, ReferenceIndexingMixin from InvenTree.models import InvenTreeAttachment, ReferenceIndexingMixin
from InvenTree.validators import validate_build_order_reference from InvenTree.validators import validate_build_order_reference
import common.models
import InvenTree.fields import InvenTree.fields
import InvenTree.helpers import InvenTree.helpers
import InvenTree.tasks import InvenTree.tasks
@ -479,8 +477,6 @@ class Build(MPTTModel, ReferenceIndexingMixin):
outputs = self.get_build_outputs(complete=True) outputs = self.get_build_outputs(complete=True)
# TODO - Ordering?
return outputs return outputs
@property @property
@ -491,8 +487,6 @@ class Build(MPTTModel, ReferenceIndexingMixin):
outputs = self.get_build_outputs(complete=False) outputs = self.get_build_outputs(complete=False)
# TODO - Order by how "complete" they are?
return outputs return outputs
@property @property
@ -563,7 +557,7 @@ class Build(MPTTModel, ReferenceIndexingMixin):
if self.remaining > 0: if self.remaining > 0:
return False return False
if not self.areUntrackedPartsFullyAllocated(): if not self.are_untracked_parts_allocated():
return False return False
# No issues! # No issues!
@ -584,7 +578,7 @@ class Build(MPTTModel, ReferenceIndexingMixin):
self.save() self.save()
# Remove untracked allocated stock # Remove untracked allocated stock
self.subtractUntrackedStock(user) self.subtract_allocated_stock(user)
# Ensure that there are no longer any BuildItem objects # Ensure that there are no longer any BuildItem objects
# which point to thisFcan Build Order # which point to thisFcan Build Order
@ -768,7 +762,7 @@ class Build(MPTTModel, ReferenceIndexingMixin):
output.delete() output.delete()
@transaction.atomic @transaction.atomic
def subtractUntrackedStock(self, user): def subtract_allocated_stock(self, user):
""" """
Called when the Build is marked as "complete", Called when the Build is marked as "complete",
this function removes the allocated untracked items from stock. this function removes the allocated untracked items from stock.
@ -831,7 +825,7 @@ class Build(MPTTModel, ReferenceIndexingMixin):
self.save() self.save()
def requiredQuantity(self, part, output): def required_quantity(self, bom_item, output=None):
""" """
Get the quantity of a part required to complete the particular build output. Get the quantity of a part required to complete the particular build output.
@ -840,12 +834,7 @@ class Build(MPTTModel, ReferenceIndexingMixin):
output - The particular build output (StockItem) output - The particular build output (StockItem)
""" """
# Extract the BOM line item from the database
try:
bom_item = PartModels.BomItem.objects.get(part=self.part.pk, sub_part=part.pk)
quantity = bom_item.quantity quantity = bom_item.quantity
except (PartModels.BomItem.DoesNotExist):
quantity = 0
if output: if output:
quantity *= output.quantity quantity *= output.quantity
@ -854,32 +843,32 @@ class Build(MPTTModel, ReferenceIndexingMixin):
return quantity return quantity
def allocatedItems(self, part, output): def allocated_bom_items(self, bom_item, output=None):
""" """
Return all BuildItem objects which allocate stock of <part> to <output> Return all BuildItem objects which allocate stock of <bom_item> to <output>
Note that the bom_item may allow variants, or direct substitutes,
making things difficult.
Args: Args:
part - The part object bom_item - The BomItem object
output - Build output (StockItem). output - Build output (StockItem).
""" """
# Remember, if 'variant' stock is allowed to be allocated, it becomes more complicated!
variants = part.get_descendants(include_self=True)
allocations = BuildItem.objects.filter( allocations = BuildItem.objects.filter(
build=self, build=self,
stock_item__part__pk__in=[p.pk for p in variants], bom_item=bom_item,
install_into=output, install_into=output,
) )
return allocations return allocations
def allocatedQuantity(self, part, output): def allocated_quantity(self, bom_item, output=None):
""" """
Return the total quantity of given part allocated to a given build output. Return the total quantity of given part allocated to a given build output.
""" """
allocations = self.allocatedItems(part, output) allocations = self.allocated_bom_items(bom_item, output)
allocated = allocations.aggregate( allocated = allocations.aggregate(
q=Coalesce( q=Coalesce(
@ -891,24 +880,24 @@ class Build(MPTTModel, ReferenceIndexingMixin):
return allocated['q'] return allocated['q']
def unallocatedQuantity(self, part, output): def unallocated_quantity(self, bom_item, output=None):
""" """
Return the total unallocated (remaining) quantity of a part against a particular output. Return the total unallocated (remaining) quantity of a part against a particular output.
""" """
required = self.requiredQuantity(part, output) required = self.required_quantity(bom_item, output)
allocated = self.allocatedQuantity(part, output) allocated = self.allocated_quantity(bom_item, output)
return max(required - allocated, 0) return max(required - allocated, 0)
def isPartFullyAllocated(self, part, output): def is_bom_item_allocated(self, bom_item, output=None):
""" """
Returns True if the part has been fully allocated to the particular build output Test if the supplied BomItem has been fully allocated!
""" """
return self.unallocatedQuantity(part, output) == 0 return self.unallocated_quantity(bom_item, output) == 0
def isFullyAllocated(self, output, verbose=False): def is_fully_allocated(self, output):
""" """
Returns True if the particular build output is fully allocated. Returns True if the particular build output is fully allocated.
""" """
@ -919,53 +908,24 @@ class Build(MPTTModel, ReferenceIndexingMixin):
else: else:
bom_items = self.tracked_bom_items bom_items = self.tracked_bom_items
fully_allocated = True
for bom_item in bom_items: for bom_item in bom_items:
part = bom_item.sub_part
if not self.isPartFullyAllocated(part, output): if not self.is_bom_item_allocated(bom_item, output):
fully_allocated = False return False
if verbose:
print(f"Part {part} is not fully allocated for output {output}")
else:
break
# All parts must be fully allocated! # All parts must be fully allocated!
return fully_allocated return True
def areUntrackedPartsFullyAllocated(self): def are_untracked_parts_allocated(self):
""" """
Returns True if the un-tracked parts are fully allocated for this BuildOrder Returns True if the un-tracked parts are fully allocated for this BuildOrder
""" """
return self.isFullyAllocated(None) return self.is_fully_allocated(None)
def allocatedParts(self, output): def unallocated_bom_items(self, output):
""" """
Return a list of parts which have been fully allocated against a particular output Return a list of bom items which have *not* been fully allocated against a particular output
"""
allocated = []
# If output is not specified, we are talking about "untracked" items
if output is None:
bom_items = self.untracked_bom_items
else:
bom_items = self.tracked_bom_items
for bom_item in bom_items:
part = bom_item.sub_part
if self.isPartFullyAllocated(part, output):
allocated.append(part)
return allocated
def unallocatedParts(self, output):
"""
Return a list of parts which have *not* been fully allocated against a particular output
""" """
unallocated = [] unallocated = []
@ -977,10 +937,9 @@ class Build(MPTTModel, ReferenceIndexingMixin):
bom_items = self.tracked_bom_items bom_items = self.tracked_bom_items
for bom_item in bom_items: for bom_item in bom_items:
part = bom_item.sub_part
if not self.isPartFullyAllocated(part, output): if not self.is_bom_item_allocated(bom_item, output):
unallocated.append(part) unallocated.append(bom_item)
return unallocated return unallocated
@ -1008,57 +967,6 @@ class Build(MPTTModel, ReferenceIndexingMixin):
return parts return parts
def availableStockItems(self, part, output):
"""
Returns stock items which are available for allocation to this build.
Args:
part - Part object
output - The particular build output
"""
# Grab initial query for items which are "in stock" and match the part
items = StockModels.StockItem.objects.filter(
StockModels.StockItem.IN_STOCK_FILTER
)
# Check if variants are allowed for this part
try:
bom_item = PartModels.BomItem.objects.get(part=self.part, sub_part=part)
allow_part_variants = bom_item.allow_variants
except PartModels.BomItem.DoesNotExist:
allow_part_variants = False
if allow_part_variants:
parts = part.get_descendants(include_self=True)
items = items.filter(part__pk__in=[p.pk for p in parts])
else:
items = items.filter(part=part)
# Exclude any items which have already been allocated
allocated = BuildItem.objects.filter(
build=self,
stock_item__part=part,
install_into=output,
)
items = items.exclude(
id__in=[item.stock_item.id for item in allocated.all()]
)
# Limit query to stock items which are "downstream" of the source location
if self.take_from is not None:
items = items.filter(
location__in=[loc for loc in self.take_from.getUniqueChildren()]
)
# Exclude expired stock items
if not common.models.InvenTreeSetting.get_setting('STOCK_ALLOW_EXPIRED_BUILD'):
items = items.exclude(StockModels.StockItem.EXPIRED_FILTER)
return items
@property @property
def is_active(self): def is_active(self):
""" Is this build active? An active build is either: """ Is this build active? An active build is either:
@ -1257,7 +1165,12 @@ class BuildItem(models.Model):
if item.part.trackable: if item.part.trackable:
# Split the allocated stock if there are more available than allocated # Split the allocated stock if there are more available than allocated
if item.quantity > self.quantity: if item.quantity > self.quantity:
item = item.splitStock(self.quantity, None, user) item = item.splitStock(
self.quantity,
None,
user,
code=StockHistoryCode.BUILD_CONSUMED,
)
# Make sure we are pointing to the new item # Make sure we are pointing to the new item
self.stock_item = item self.stock_item = item
@ -1268,7 +1181,11 @@ class BuildItem(models.Model):
item.save() item.save()
else: else:
# Simply remove the items from stock # Simply remove the items from stock
item.take_stock(self.quantity, user) item.take_stock(
self.quantity,
user,
code=StockHistoryCode.BUILD_CONSUMED
)
def getStockItemThumbnail(self): def getStockItemThumbnail(self):
""" """

View File

@ -160,7 +160,7 @@ class BuildOutputSerializer(serializers.Serializer):
if to_complete: if to_complete:
# The build output must have all tracked parts allocated # The build output must have all tracked parts allocated
if not build.isFullyAllocated(output): if not build.is_fully_allocated(output):
raise ValidationError(_("This build output is not fully allocated")) raise ValidationError(_("This build output is not fully allocated"))
return output return output
@ -236,6 +236,7 @@ class BuildOutputCreateSerializer(serializers.Serializer):
auto_allocate = serializers.BooleanField( auto_allocate = serializers.BooleanField(
required=False, required=False,
default=False, default=False,
allow_null=True,
label=_('Auto Allocate Serial Numbers'), label=_('Auto Allocate Serial Numbers'),
help_text=_('Automatically allocate required items with matching serial numbers'), help_text=_('Automatically allocate required items with matching serial numbers'),
) )
@ -403,6 +404,10 @@ class BuildOutputCompleteSerializer(serializers.Serializer):
data = self.validated_data data = self.validated_data
location = data['location']
status = data['status']
notes = data.get('notes', '')
outputs = data.get('outputs', []) outputs = data.get('outputs', [])
# Mark the specified build outputs as "complete" # Mark the specified build outputs as "complete"
@ -414,8 +419,9 @@ class BuildOutputCompleteSerializer(serializers.Serializer):
build.complete_build_output( build.complete_build_output(
output, output,
request.user, request.user,
status=data['status'], location=location,
notes=data.get('notes', '') status=status,
notes=notes,
) )
@ -435,7 +441,7 @@ class BuildCompleteSerializer(serializers.Serializer):
build = self.context['build'] build = self.context['build']
if not build.areUntrackedPartsFullyAllocated() and not value: if not build.are_untracked_parts_allocated() and not value:
raise ValidationError(_('Required stock has not been fully allocated')) raise ValidationError(_('Required stock has not been fully allocated'))
return value return value

View File

@ -125,7 +125,7 @@ src="{% static 'img/blank_image.png' %}"
{% trans "Required build quantity has not yet been completed" %} {% trans "Required build quantity has not yet been completed" %}
</div> </div>
{% endif %} {% endif %}
{% if not build.areUntrackedPartsFullyAllocated %} {% if not build.are_untracked_parts_allocated %}
<div class='alert alert-block alert-warning'> <div class='alert alert-block alert-warning'>
{% trans "Stock has not been fully allocated to this Build Order" %} {% trans "Stock has not been fully allocated to this Build Order" %}
</div> </div>
@ -234,7 +234,7 @@ src="{% static 'img/blank_image.png' %}"
{% else %} {% else %}
completeBuildOrder({{ build.pk }}, { completeBuildOrder({{ build.pk }}, {
allocated: {% if build.areUntrackedPartsFullyAllocated %}true{% else %}false{% endif %}, allocated: {% if build.are_untracked_parts_allocated %}true{% else %}false{% endif %},
completed: {% if build.remaining == 0 %}true{% else %}false{% endif %}, completed: {% if build.remaining == 0 %}true{% else %}false{% endif %},
}); });
{% endif %} {% endif %}

View File

@ -192,7 +192,7 @@
<div class='panel-content'> <div class='panel-content'>
{% if build.has_untracked_bom_items %} {% if build.has_untracked_bom_items %}
{% if build.active %} {% if build.active %}
{% if build.areUntrackedPartsFullyAllocated %} {% if build.are_untracked_parts_allocated %}
<div class='alert alert-block alert-success'> <div class='alert alert-block alert-success'>
{% trans "Untracked stock has been fully allocated for this Build Order" %} {% trans "Untracked stock has been fully allocated for this Build Order" %}
</div> </div>

View File

@ -62,20 +62,20 @@ class BuildTest(TestCase):
) )
# Create BOM item links for the parts # Create BOM item links for the parts
BomItem.objects.create( self.bom_item_1 = BomItem.objects.create(
part=self.assembly, part=self.assembly,
sub_part=self.sub_part_1, sub_part=self.sub_part_1,
quantity=5 quantity=5
) )
BomItem.objects.create( self.bom_item_2 = BomItem.objects.create(
part=self.assembly, part=self.assembly,
sub_part=self.sub_part_2, sub_part=self.sub_part_2,
quantity=3 quantity=3
) )
# sub_part_3 is trackable! # sub_part_3 is trackable!
BomItem.objects.create( self.bom_item_3 = BomItem.objects.create(
part=self.assembly, part=self.assembly,
sub_part=self.sub_part_3, sub_part=self.sub_part_3,
quantity=2 quantity=2
@ -147,15 +147,15 @@ class BuildTest(TestCase):
# None of the build outputs have been completed # None of the build outputs have been completed
for output in self.build.get_build_outputs().all(): for output in self.build.get_build_outputs().all():
self.assertFalse(self.build.isFullyAllocated(output)) self.assertFalse(self.build.is_fully_allocated(output))
self.assertFalse(self.build.isPartFullyAllocated(self.sub_part_1, self.output_1)) self.assertFalse(self.build.is_bom_item_allocated(self.bom_item_1, self.output_1))
self.assertFalse(self.build.isPartFullyAllocated(self.sub_part_2, self.output_2)) self.assertFalse(self.build.is_bom_item_allocated(self.bom_item_2, self.output_2))
self.assertEqual(self.build.unallocatedQuantity(self.sub_part_1, self.output_1), 15) self.assertEqual(self.build.unallocated_quantity(self.bom_item_1, self.output_1), 15)
self.assertEqual(self.build.unallocatedQuantity(self.sub_part_1, self.output_2), 35) self.assertEqual(self.build.unallocated_quantity(self.bom_item_1, self.output_2), 35)
self.assertEqual(self.build.unallocatedQuantity(self.sub_part_2, self.output_1), 9) self.assertEqual(self.build.unallocated_quantity(self.bom_item_2, self.output_1), 9)
self.assertEqual(self.build.unallocatedQuantity(self.sub_part_2, self.output_2), 21) self.assertEqual(self.build.unallocated_quantity(self.bom_item_2, self.output_2), 21)
self.assertFalse(self.build.is_complete) self.assertFalse(self.build.is_complete)
@ -226,7 +226,7 @@ class BuildTest(TestCase):
} }
) )
self.assertTrue(self.build.isFullyAllocated(self.output_1)) self.assertTrue(self.build.is_fully_allocated(self.output_1))
# Partially allocate tracked stock against build output 2 # Partially allocate tracked stock against build output 2
self.allocate_stock( self.allocate_stock(
@ -236,7 +236,7 @@ class BuildTest(TestCase):
} }
) )
self.assertFalse(self.build.isFullyAllocated(self.output_2)) self.assertFalse(self.build.is_fully_allocated(self.output_2))
# Partially allocate untracked stock against build # Partially allocate untracked stock against build
self.allocate_stock( self.allocate_stock(
@ -247,9 +247,9 @@ class BuildTest(TestCase):
} }
) )
self.assertFalse(self.build.isFullyAllocated(None, verbose=True)) self.assertFalse(self.build.is_fully_allocated(None))
unallocated = self.build.unallocatedParts(None) unallocated = self.build.unallocated_bom_items(None)
self.assertEqual(len(unallocated), 2) self.assertEqual(len(unallocated), 2)
@ -260,19 +260,19 @@ class BuildTest(TestCase):
} }
) )
self.assertFalse(self.build.isFullyAllocated(None, verbose=True)) self.assertFalse(self.build.is_fully_allocated(None))
unallocated = self.build.unallocatedParts(None) unallocated = self.build.unallocated_bom_items(None)
self.assertEqual(len(unallocated), 1) self.assertEqual(len(unallocated), 1)
self.build.unallocateStock() self.build.unallocateStock()
unallocated = self.build.unallocatedParts(None) unallocated = self.build.unallocated_bom_items(None)
self.assertEqual(len(unallocated), 2) self.assertEqual(len(unallocated), 2)
self.assertFalse(self.build.areUntrackedPartsFullyAllocated()) self.assertFalse(self.build.are_untracked_parts_allocated())
# Now we "fully" allocate the untracked untracked items # Now we "fully" allocate the untracked untracked items
self.allocate_stock( self.allocate_stock(
@ -283,7 +283,7 @@ class BuildTest(TestCase):
} }
) )
self.assertTrue(self.build.areUntrackedPartsFullyAllocated()) self.assertTrue(self.build.are_untracked_parts_allocated())
def test_cancel(self): def test_cancel(self):
""" """
@ -331,9 +331,9 @@ class BuildTest(TestCase):
} }
) )
self.assertTrue(self.build.isFullyAllocated(None, verbose=True)) self.assertTrue(self.build.is_fully_allocated(None))
self.assertTrue(self.build.isFullyAllocated(self.output_1)) self.assertTrue(self.build.is_fully_allocated(self.output_1))
self.assertTrue(self.build.isFullyAllocated(self.output_2)) self.assertTrue(self.build.is_fully_allocated(self.output_2))
self.build.complete_build_output(self.output_1, None) self.build.complete_build_output(self.output_1, None)

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 23:03\n" "PO-Revision-Date: 2022-02-22 11:36\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: German\n" "Language-Team: German\n"
"Language: de_DE\n" "Language: de_DE\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "Hebräisch" msgstr "Hebräisch"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr "Ungarisch"
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "Italienisch" msgstr "Italienisch"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "Japanisch" msgstr "Japanisch"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "Koreanisch" msgstr "Koreanisch"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "Niederländisch" msgstr "Niederländisch"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "Norwegisch" msgstr "Norwegisch"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "Polnisch" msgstr "Polnisch"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "Portugiesisch" msgstr "Portugiesisch"
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "Russisch" msgstr "Russisch"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "Schwedisch" msgstr "Schwedisch"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "Thailändisch" msgstr "Thailändisch"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "Türkisch" msgstr "Türkisch"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "Vietnamesisch" msgstr "Vietnamesisch"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "Chinesisch" msgstr "Chinesisch"

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Greek\n" "Language-Team: Greek\n"
"Language: el_GR\n" "Language: el_GR\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "" msgstr ""
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Italian" msgid "Hungarian"
msgstr "" msgstr ""
#: InvenTree/settings.py:663 #: InvenTree/settings.py:663
msgid "Japanese" msgid "Italian"
msgstr "" msgstr ""
#: InvenTree/settings.py:664 #: InvenTree/settings.py:664
msgid "Korean" msgid "Japanese"
msgstr "" msgstr ""
#: InvenTree/settings.py:665 #: InvenTree/settings.py:665
msgid "Dutch" msgid "Korean"
msgstr "" msgstr ""
#: InvenTree/settings.py:666 #: InvenTree/settings.py:666
msgid "Norwegian" msgid "Dutch"
msgstr "" msgstr ""
#: InvenTree/settings.py:667 #: InvenTree/settings.py:667
msgid "Polish" msgid "Norwegian"
msgstr "" msgstr ""
#: InvenTree/settings.py:668 #: InvenTree/settings.py:668
msgid "Portugese" msgid "Polish"
msgstr "" msgstr ""
#: InvenTree/settings.py:669 #: InvenTree/settings.py:669
msgid "Russian" msgid "Portugese"
msgstr "" msgstr ""
#: InvenTree/settings.py:670 #: InvenTree/settings.py:670
msgid "Swedish" msgid "Russian"
msgstr "" msgstr ""
#: InvenTree/settings.py:671 #: InvenTree/settings.py:671
msgid "Thai" msgid "Swedish"
msgstr "" msgstr ""
#: InvenTree/settings.py:672 #: InvenTree/settings.py:672
msgid "Turkish" msgid "Thai"
msgstr "" msgstr ""
#: InvenTree/settings.py:673 #: InvenTree/settings.py:673
msgid "Vietnamese" msgid "Turkish"
msgstr "" msgstr ""
#: InvenTree/settings.py:674 #: InvenTree/settings.py:674
msgid "Vietnamese"
msgstr ""
#: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "" msgstr ""

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: French\n" "Language-Team: French\n"
"Language: fr_FR\n" "Language: fr_FR\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "Hebrew" msgstr "Hebrew"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "Italian" msgstr "Italian"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "Japanese" msgstr "Japanese"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "Korean" msgstr "Korean"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "Dutch" msgstr "Dutch"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "Norwegian" msgstr "Norwegian"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "Polonais" msgstr "Polonais"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "Portugais" msgstr "Portugais"
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "Russian" msgstr "Russian"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "Swedish" msgstr "Swedish"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "Thai" msgstr "Thai"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "Turc" msgstr "Turc"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "Vietnamese" msgstr "Vietnamese"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "Chinese" msgstr "Chinese"

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Hebrew\n" "Language-Team: Hebrew\n"
"Language: he_IL\n" "Language: he_IL\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "עברית" msgstr "עברית"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "איטלקית" msgstr "איטלקית"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "יפנית" msgstr "יפנית"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "קוריאנית" msgstr "קוריאנית"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "הולנדית" msgstr "הולנדית"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "נורווגית" msgstr "נורווגית"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "פולנית" msgstr "פולנית"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "פורטוגזית" msgstr "פורטוגזית"
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "רוסית" msgstr "רוסית"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "שוודית" msgstr "שוודית"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "תאילנדית" msgstr "תאילנדית"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "טורקית" msgstr "טורקית"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "ווייטנאמית" msgstr "ווייטנאמית"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "סינית" msgstr "סינית"

File diff suppressed because it is too large Load Diff

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Indonesian\n" "Language-Team: Indonesian\n"
"Language: id_ID\n" "Language: id_ID\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "" msgstr ""
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Italian" msgid "Hungarian"
msgstr "" msgstr ""
#: InvenTree/settings.py:663 #: InvenTree/settings.py:663
msgid "Japanese" msgid "Italian"
msgstr "" msgstr ""
#: InvenTree/settings.py:664 #: InvenTree/settings.py:664
msgid "Korean" msgid "Japanese"
msgstr "" msgstr ""
#: InvenTree/settings.py:665 #: InvenTree/settings.py:665
msgid "Dutch" msgid "Korean"
msgstr "" msgstr ""
#: InvenTree/settings.py:666 #: InvenTree/settings.py:666
msgid "Norwegian" msgid "Dutch"
msgstr "" msgstr ""
#: InvenTree/settings.py:667 #: InvenTree/settings.py:667
msgid "Polish" msgid "Norwegian"
msgstr "" msgstr ""
#: InvenTree/settings.py:668 #: InvenTree/settings.py:668
msgid "Portugese" msgid "Polish"
msgstr "" msgstr ""
#: InvenTree/settings.py:669 #: InvenTree/settings.py:669
msgid "Russian" msgid "Portugese"
msgstr "" msgstr ""
#: InvenTree/settings.py:670 #: InvenTree/settings.py:670
msgid "Swedish" msgid "Russian"
msgstr "" msgstr ""
#: InvenTree/settings.py:671 #: InvenTree/settings.py:671
msgid "Thai" msgid "Swedish"
msgstr "" msgstr ""
#: InvenTree/settings.py:672 #: InvenTree/settings.py:672
msgid "Turkish" msgid "Thai"
msgstr "" msgstr ""
#: InvenTree/settings.py:673 #: InvenTree/settings.py:673
msgid "Vietnamese" msgid "Turkish"
msgstr "" msgstr ""
#: InvenTree/settings.py:674 #: InvenTree/settings.py:674
msgid "Vietnamese"
msgstr ""
#: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "" msgstr ""

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:03\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Italian\n" "Language-Team: Italian\n"
"Language: it_IT\n" "Language: it_IT\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "Ebraico" msgstr "Ebraico"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "Italiano" msgstr "Italiano"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "Giapponese" msgstr "Giapponese"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "Coreano" msgstr "Coreano"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "Olandese" msgstr "Olandese"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "Norvegese" msgstr "Norvegese"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "Polacco" msgstr "Polacco"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "Portoghese" msgstr "Portoghese"
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "Russo" msgstr "Russo"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "Svedese" msgstr "Svedese"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "Thailandese" msgstr "Thailandese"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "Turco" msgstr "Turco"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "Vietnamita" msgstr "Vietnamita"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "Cinese" msgstr "Cinese"

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:03\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Japanese\n" "Language-Team: Japanese\n"
"Language: ja_JP\n" "Language: ja_JP\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "" msgstr ""
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Italian" msgid "Hungarian"
msgstr "" msgstr ""
#: InvenTree/settings.py:663 #: InvenTree/settings.py:663
msgid "Japanese" msgid "Italian"
msgstr "" msgstr ""
#: InvenTree/settings.py:664 #: InvenTree/settings.py:664
msgid "Korean" msgid "Japanese"
msgstr "" msgstr ""
#: InvenTree/settings.py:665 #: InvenTree/settings.py:665
msgid "Dutch" msgid "Korean"
msgstr "" msgstr ""
#: InvenTree/settings.py:666 #: InvenTree/settings.py:666
msgid "Norwegian" msgid "Dutch"
msgstr "" msgstr ""
#: InvenTree/settings.py:667 #: InvenTree/settings.py:667
msgid "Norwegian"
msgstr ""
#: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "ポーランド語" msgstr "ポーランド語"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "" msgstr ""
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "" msgstr ""
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "" msgstr ""
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "" msgstr ""
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "トルコ語" msgstr "トルコ語"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "" msgstr ""
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "" msgstr ""

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Korean\n" "Language-Team: Korean\n"
"Language: ko_KR\n" "Language: ko_KR\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "히브리어" msgstr "히브리어"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "이탈리아어" msgstr "이탈리아어"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "일본어" msgstr "일본어"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "한국어" msgstr "한국어"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "네덜란드어" msgstr "네덜란드어"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "노르웨이어" msgstr "노르웨이어"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "폴란드어" msgstr "폴란드어"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "포르투갈어" msgstr "포르투갈어"
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "러시아어" msgstr "러시아어"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "스웨덴어" msgstr "스웨덴어"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "태국어" msgstr "태국어"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "터키어" msgstr "터키어"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "베트남어" msgstr "베트남어"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "중국어" msgstr "중국어"

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Dutch\n" "Language-Team: Dutch\n"
"Language: nl_NL\n" "Language: nl_NL\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "Hebreeuws" msgstr "Hebreeuws"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "Italiaans" msgstr "Italiaans"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "Japans" msgstr "Japans"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "Koreaans" msgstr "Koreaans"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "Nederlands" msgstr "Nederlands"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "Noors" msgstr "Noors"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "Pools" msgstr "Pools"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "Portugees" msgstr "Portugees"
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "Russisch" msgstr "Russisch"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "Zweeds" msgstr "Zweeds"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "Thais" msgstr "Thais"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "Turks" msgstr "Turks"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "Vietnamees" msgstr "Vietnamees"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "Chinees" msgstr "Chinees"

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Norwegian\n" "Language-Team: Norwegian\n"
"Language: no_NO\n" "Language: no_NO\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "Hebraisk" msgstr "Hebraisk"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "Italiensk" msgstr "Italiensk"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "Japansk" msgstr "Japansk"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "Koreansk" msgstr "Koreansk"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "Nederlandsk" msgstr "Nederlandsk"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "Norsk" msgstr "Norsk"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "Polsk" msgstr "Polsk"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "Portugesisk" msgstr "Portugesisk"
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "Russisk" msgstr "Russisk"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "Svensk" msgstr "Svensk"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "Thailandsk" msgstr "Thailandsk"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "Tyrkisk" msgstr "Tyrkisk"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "Vietnamesisk" msgstr "Vietnamesisk"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "Kinesisk" msgstr "Kinesisk"

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:03\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Polish\n" "Language-Team: Polish\n"
"Language: pl_PL\n" "Language: pl_PL\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "Hebrajski" msgstr "Hebrajski"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "Włoski" msgstr "Włoski"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "Japoński" msgstr "Japoński"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "Koreański" msgstr "Koreański"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "Holenderski" msgstr "Holenderski"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "Norweski" msgstr "Norweski"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "Polski" msgstr "Polski"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "Portugalski" msgstr "Portugalski"
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "Rosyjski" msgstr "Rosyjski"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "Szwedzki" msgstr "Szwedzki"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "Tajski" msgstr "Tajski"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "Turecki" msgstr "Turecki"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "Wietnamski" msgstr "Wietnamski"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "Chiński" msgstr "Chiński"

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Portuguese\n" "Language-Team: Portuguese\n"
"Language: pt_PT\n" "Language: pt_PT\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "" msgstr ""
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Italian" msgid "Hungarian"
msgstr "" msgstr ""
#: InvenTree/settings.py:663 #: InvenTree/settings.py:663
msgid "Japanese" msgid "Italian"
msgstr "" msgstr ""
#: InvenTree/settings.py:664 #: InvenTree/settings.py:664
msgid "Korean" msgid "Japanese"
msgstr "" msgstr ""
#: InvenTree/settings.py:665 #: InvenTree/settings.py:665
msgid "Dutch" msgid "Korean"
msgstr "" msgstr ""
#: InvenTree/settings.py:666 #: InvenTree/settings.py:666
msgid "Norwegian" msgid "Dutch"
msgstr "" msgstr ""
#: InvenTree/settings.py:667 #: InvenTree/settings.py:667
msgid "Polish" msgid "Norwegian"
msgstr "" msgstr ""
#: InvenTree/settings.py:668 #: InvenTree/settings.py:668
msgid "Portugese" msgid "Polish"
msgstr "" msgstr ""
#: InvenTree/settings.py:669 #: InvenTree/settings.py:669
msgid "Russian" msgid "Portugese"
msgstr "" msgstr ""
#: InvenTree/settings.py:670 #: InvenTree/settings.py:670
msgid "Swedish" msgid "Russian"
msgstr "" msgstr ""
#: InvenTree/settings.py:671 #: InvenTree/settings.py:671
msgid "Thai" msgid "Swedish"
msgstr "" msgstr ""
#: InvenTree/settings.py:672 #: InvenTree/settings.py:672
msgid "Turkish" msgid "Thai"
msgstr "" msgstr ""
#: InvenTree/settings.py:673 #: InvenTree/settings.py:673
msgid "Vietnamese" msgid "Turkish"
msgstr "" msgstr ""
#: InvenTree/settings.py:674 #: InvenTree/settings.py:674
msgid "Vietnamese"
msgstr ""
#: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "" msgstr ""

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:03\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Russian\n" "Language-Team: Russian\n"
"Language: ru_RU\n" "Language: ru_RU\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "Иврит" msgstr "Иврит"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "Итальянский" msgstr "Итальянский"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "Японский" msgstr "Японский"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "Корейский" msgstr "Корейский"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "Голландский" msgstr "Голландский"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "Норвежский" msgstr "Норвежский"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "Польский" msgstr "Польский"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "Португальский" msgstr "Португальский"
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "Русский" msgstr "Русский"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "Шведский" msgstr "Шведский"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "Тайский" msgstr "Тайский"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "Турецкий" msgstr "Турецкий"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "Вьетнамский" msgstr "Вьетнамский"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "Китайский" msgstr "Китайский"

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Swedish\n" "Language-Team: Swedish\n"
"Language: sv_SE\n" "Language: sv_SE\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "Hebreiska" msgstr "Hebreiska"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "Italienska" msgstr "Italienska"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "Japanska" msgstr "Japanska"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "Koreanska" msgstr "Koreanska"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "Nederländska" msgstr "Nederländska"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "Norska" msgstr "Norska"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "Polska" msgstr "Polska"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "" msgstr ""
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "Ryska" msgstr "Ryska"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "Svenska" msgstr "Svenska"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "Thailändska" msgstr "Thailändska"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "Turkiska" msgstr "Turkiska"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "Vietnamesiska" msgstr "Vietnamesiska"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "Kinesiska" msgstr "Kinesiska"

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:03\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Thai\n" "Language-Team: Thai\n"
"Language: th_TH\n" "Language: th_TH\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "" msgstr ""
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Italian" msgid "Hungarian"
msgstr "" msgstr ""
#: InvenTree/settings.py:663 #: InvenTree/settings.py:663
msgid "Japanese" msgid "Italian"
msgstr "" msgstr ""
#: InvenTree/settings.py:664 #: InvenTree/settings.py:664
msgid "Korean" msgid "Japanese"
msgstr "" msgstr ""
#: InvenTree/settings.py:665 #: InvenTree/settings.py:665
msgid "Dutch" msgid "Korean"
msgstr "" msgstr ""
#: InvenTree/settings.py:666 #: InvenTree/settings.py:666
msgid "Norwegian" msgid "Dutch"
msgstr "" msgstr ""
#: InvenTree/settings.py:667 #: InvenTree/settings.py:667
msgid "Polish" msgid "Norwegian"
msgstr "" msgstr ""
#: InvenTree/settings.py:668 #: InvenTree/settings.py:668
msgid "Portugese" msgid "Polish"
msgstr "" msgstr ""
#: InvenTree/settings.py:669 #: InvenTree/settings.py:669
msgid "Russian" msgid "Portugese"
msgstr "" msgstr ""
#: InvenTree/settings.py:670 #: InvenTree/settings.py:670
msgid "Swedish" msgid "Russian"
msgstr "" msgstr ""
#: InvenTree/settings.py:671 #: InvenTree/settings.py:671
msgid "Thai" msgid "Swedish"
msgstr "" msgstr ""
#: InvenTree/settings.py:672 #: InvenTree/settings.py:672
msgid "Turkish" msgid "Thai"
msgstr "" msgstr ""
#: InvenTree/settings.py:673 #: InvenTree/settings.py:673
msgid "Vietnamese" msgid "Turkish"
msgstr "" msgstr ""
#: InvenTree/settings.py:674 #: InvenTree/settings.py:674
msgid "Vietnamese"
msgstr ""
#: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "" msgstr ""

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:03\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Turkish\n" "Language-Team: Turkish\n"
"Language: tr_TR\n" "Language: tr_TR\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "İbranice" msgstr "İbranice"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "İtalyanca" msgstr "İtalyanca"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "Japonca" msgstr "Japonca"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "Korece" msgstr "Korece"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "Flemenkçe" msgstr "Flemenkçe"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "Norveççe" msgstr "Norveççe"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "Polonyaca" msgstr "Polonyaca"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "" msgstr ""
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "Rusça" msgstr "Rusça"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "İsveççe" msgstr "İsveççe"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "Tay dili" msgstr "Tay dili"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "Türkçe" msgstr "Türkçe"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "" msgstr ""
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "Çince" msgstr "Çince"

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Vietnamese\n" "Language-Team: Vietnamese\n"
"Language: vi_VN\n" "Language: vi_VN\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "" msgstr ""
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Italian" msgid "Hungarian"
msgstr "" msgstr ""
#: InvenTree/settings.py:663 #: InvenTree/settings.py:663
msgid "Japanese" msgid "Italian"
msgstr "" msgstr ""
#: InvenTree/settings.py:664 #: InvenTree/settings.py:664
msgid "Korean" msgid "Japanese"
msgstr "" msgstr ""
#: InvenTree/settings.py:665 #: InvenTree/settings.py:665
msgid "Dutch" msgid "Korean"
msgstr "" msgstr ""
#: InvenTree/settings.py:666 #: InvenTree/settings.py:666
msgid "Norwegian" msgid "Dutch"
msgstr "" msgstr ""
#: InvenTree/settings.py:667 #: InvenTree/settings.py:667
msgid "Polish" msgid "Norwegian"
msgstr "" msgstr ""
#: InvenTree/settings.py:668 #: InvenTree/settings.py:668
msgid "Portugese" msgid "Polish"
msgstr "" msgstr ""
#: InvenTree/settings.py:669 #: InvenTree/settings.py:669
msgid "Russian" msgid "Portugese"
msgstr "" msgstr ""
#: InvenTree/settings.py:670 #: InvenTree/settings.py:670
msgid "Swedish" msgid "Russian"
msgstr "" msgstr ""
#: InvenTree/settings.py:671 #: InvenTree/settings.py:671
msgid "Thai" msgid "Swedish"
msgstr "" msgstr ""
#: InvenTree/settings.py:672 #: InvenTree/settings.py:672
msgid "Turkish" msgid "Thai"
msgstr "" msgstr ""
#: InvenTree/settings.py:673 #: InvenTree/settings.py:673
msgid "Vietnamese" msgid "Turkish"
msgstr "" msgstr ""
#: InvenTree/settings.py:674 #: InvenTree/settings.py:674
msgid "Vietnamese"
msgstr ""
#: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "" msgstr ""

View File

@ -3,8 +3,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: inventree\n" "Project-Id-Version: inventree\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-20 22:01+0000\n" "POT-Creation-Date: 2022-02-22 01:07+0000\n"
"PO-Revision-Date: 2022-02-20 22:02\n" "PO-Revision-Date: 2022-02-22 01:18\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: Chinese Simplified\n" "Language-Team: Chinese Simplified\n"
"Language: zh_CN\n" "Language: zh_CN\n"
@ -328,54 +328,58 @@ msgid "Hebrew"
msgstr "希伯来语" msgstr "希伯来语"
#: InvenTree/settings.py:662 #: InvenTree/settings.py:662
msgid "Hungarian"
msgstr ""
#: InvenTree/settings.py:663
msgid "Italian" msgid "Italian"
msgstr "意大利语" msgstr "意大利语"
#: InvenTree/settings.py:663 #: InvenTree/settings.py:664
msgid "Japanese" msgid "Japanese"
msgstr "日语" msgstr "日语"
#: InvenTree/settings.py:664 #: InvenTree/settings.py:665
msgid "Korean" msgid "Korean"
msgstr "韩语" msgstr "韩语"
#: InvenTree/settings.py:665 #: InvenTree/settings.py:666
msgid "Dutch" msgid "Dutch"
msgstr "荷兰语" msgstr "荷兰语"
#: InvenTree/settings.py:666 #: InvenTree/settings.py:667
msgid "Norwegian" msgid "Norwegian"
msgstr "挪威语" msgstr "挪威语"
#: InvenTree/settings.py:667 #: InvenTree/settings.py:668
msgid "Polish" msgid "Polish"
msgstr "波兰语" msgstr "波兰语"
#: InvenTree/settings.py:668 #: InvenTree/settings.py:669
msgid "Portugese" msgid "Portugese"
msgstr "" msgstr ""
#: InvenTree/settings.py:669 #: InvenTree/settings.py:670
msgid "Russian" msgid "Russian"
msgstr "俄语" msgstr "俄语"
#: InvenTree/settings.py:670 #: InvenTree/settings.py:671
msgid "Swedish" msgid "Swedish"
msgstr "瑞典语" msgstr "瑞典语"
#: InvenTree/settings.py:671 #: InvenTree/settings.py:672
msgid "Thai" msgid "Thai"
msgstr "泰语" msgstr "泰语"
#: InvenTree/settings.py:672 #: InvenTree/settings.py:673
msgid "Turkish" msgid "Turkish"
msgstr "土耳其语" msgstr "土耳其语"
#: InvenTree/settings.py:673 #: InvenTree/settings.py:674
msgid "Vietnamese" msgid "Vietnamese"
msgstr "越南语" msgstr "越南语"
#: InvenTree/settings.py:674 #: InvenTree/settings.py:675
msgid "Chinese" msgid "Chinese"
msgstr "中文(简体)" msgstr "中文(简体)"

View File

@ -1,5 +1,7 @@
# Generated by Django 3.0.7 on 2020-11-10 11:25 # Generated by Django 3.0.7 on 2020-11-10 11:25
import logging
from django.db import migrations from django.db import migrations
from moneyed import CURRENCIES from moneyed import CURRENCIES
@ -7,6 +9,9 @@ from django.db import migrations, connection
from company.models import SupplierPriceBreak from company.models import SupplierPriceBreak
logger = logging.getLogger('inventree')
def migrate_currencies(apps, schema_editor): def migrate_currencies(apps, schema_editor):
""" """
Migrate from the 'old' method of handling currencies, Migrate from the 'old' method of handling currencies,
@ -19,7 +24,7 @@ def migrate_currencies(apps, schema_editor):
for the SupplierPriceBreak model, to a new django-money compatible currency. for the SupplierPriceBreak model, to a new django-money compatible currency.
""" """
print("Updating currency references for SupplierPriceBreak model...") logger.info("Updating currency references for SupplierPriceBreak model...")
# A list of available currency codes # A list of available currency codes
currency_codes = CURRENCIES.keys() currency_codes = CURRENCIES.keys()

View File

@ -63,6 +63,43 @@ class StockLocation(InvenTreeTree):
help_text=_('Select Owner'), help_text=_('Select Owner'),
related_name='stock_locations') related_name='stock_locations')
def get_location_owner(self):
"""
Get the closest "owner" for this location.
Start at this location, and traverse "up" the location tree until we find an owner
"""
for loc in self.get_ancestors(include_self=True, ascending=True):
if loc.owner is not None:
return loc.owner
return None
def check_ownership(self, user):
"""
Check if the user "owns" (is one of the owners of) the location.
"""
# Superuser accounts automatically "own" everything
if user.is_superuser:
return True
ownership_enabled = common.models.InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL')
if not ownership_enabled:
# Location ownership function is not enabled, so return True
return True
owner = self.get_location_owner()
if owner is None:
# No owner set, for this location or any location above
# So, no ownership checks to perform!
return True
return user in owner.get_related_owners(include_group=True)
def get_absolute_url(self): def get_absolute_url(self):
return reverse('stock-location-detail', kwargs={'pk': self.id}) return reverse('stock-location-detail', kwargs={'pk': self.id})
@ -614,6 +651,48 @@ class StockItem(MPTTModel):
help_text=_('Select Owner'), help_text=_('Select Owner'),
related_name='stock_items') related_name='stock_items')
def get_item_owner(self):
"""
Return the closest "owner" for this StockItem.
- If the item has an owner set, return that
- If the item is "in stock", check the StockLocation
- Otherwise, return None
"""
if self.owner is not None:
return self.owner
if self.in_stock and self.location is not None:
loc_owner = self.location.get_location_owner()
if loc_owner:
return loc_owner
return None
def check_ownership(self, user):
"""
Check if the user "owns" (or is one of the owners of) the item
"""
# Superuser accounts automatically "own" everything
if user.is_superuser:
return True
ownership_enabled = common.models.InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL')
if not ownership_enabled:
# Location ownership function is not enabled, so return True
return True
owner = self.get_item_owner()
if owner is None:
return True
return user in owner.get_related_owners(include_group=True)
def is_stale(self): def is_stale(self):
""" """
Returns True if this Stock item is "stale". Returns True if this Stock item is "stale".
@ -1311,6 +1390,7 @@ class StockItem(MPTTModel):
""" """
notes = kwargs.get('notes', '') notes = kwargs.get('notes', '')
code = kwargs.get('code', StockHistoryCode.SPLIT_FROM_PARENT)
# Do not split a serialized part # Do not split a serialized part
if self.serialized: if self.serialized:
@ -1352,7 +1432,7 @@ class StockItem(MPTTModel):
# Add a new tracking item for the new stock item # Add a new tracking item for the new stock item
new_stock.add_tracking_entry( new_stock.add_tracking_entry(
StockHistoryCode.SPLIT_FROM_PARENT, code,
user, user,
notes=notes, notes=notes,
deltas={ deltas={
@ -1530,7 +1610,7 @@ class StockItem(MPTTModel):
return True return True
@transaction.atomic @transaction.atomic
def take_stock(self, quantity, user, notes=''): def take_stock(self, quantity, user, notes='', code=StockHistoryCode.STOCK_REMOVE):
""" """
Remove items from stock Remove items from stock
""" """
@ -1550,7 +1630,7 @@ class StockItem(MPTTModel):
if self.updateQuantity(self.quantity - quantity): if self.updateQuantity(self.quantity - quantity):
self.add_tracking_entry( self.add_tracking_entry(
StockHistoryCode.STOCK_REMOVE, code,
user, user,
notes=notes, notes=notes,
deltas={ deltas={

View File

@ -18,18 +18,11 @@
<h4>{% trans "Stock Tracking Information" %}</h4> <h4>{% trans "Stock Tracking Information" %}</h4>
{% include "spacer.html" %} {% include "spacer.html" %}
<div class='btn-group' role='group'> <div class='btn-group' role='group'>
{% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %} {% if user_owns_item and roles.stock.change and not item.is_building %}
{% if owner_control.value == "True" %}
{% authorized_owners item.owner as owners %}
{% endif %}
<!-- Check permissions and owner -->
{% if owner_control.value == "False" or owner_control.value == "True" and user in owners %}
{% if roles.stock.change and not item.is_building %}
<button class='btn btn-success' type='button' title='New tracking entry' id='new-entry'> <button class='btn btn-success' type='button' title='New tracking entry' id='new-entry'>
<span class='fas fa-plus-circle'></span> {% trans "New Entry" %} <span class='fas fa-plus-circle'></span> {% trans "New Entry" %}
</button> </button>
{% endif %} {% endif %}
{% endif %}
</div> </div>
</div> </div>
</div> </div>

View File

@ -59,14 +59,7 @@
</ul> </ul>
</div> </div>
<!-- Stock adjustment menu --> <!-- Stock adjustment menu -->
<!-- Check permissions and owner --> {% if user_owns_item %}
{% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %}
{% if owner_control.value == "True" %}
{% authorized_owners item.owner as owners %}
{% endif %}
{% if owner_control.value == "False" or owner_control.value == "True" and user in owners or user.is_superuser %}
{% if roles.stock.change and not item.is_building %} {% if roles.stock.change and not item.is_building %}
<div class='btn-group'> <div class='btn-group'>
<button id='stock-actions' title='{% trans "Stock adjustment actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'><span class='fas fa-boxes'></span> <span class='caret'></span></button> <button id='stock-actions' title='{% trans "Stock adjustment actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'><span class='fas fa-boxes'></span> <span class='caret'></span></button>
@ -219,24 +212,8 @@
</tr> </tr>
</table> </table>
{% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %}
{% if owner_control.value == "True" %}
{% authorized_owners item.owner as owners %}
{% endif %}
<div class='info-messages'> <div class='info-messages'>
{% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %}
{% if owner_control.value == "True" %}
{% authorized_owners item.owner as owners %}
{% if not user in owners and not user.is_superuser %}
<div class='alert alert-block alert-info'>
{% trans "You are not in the list of owners of this item. This stock item cannot be edited." %}<br>
</div>
{% endif %}
{% endif %}
{% if item.is_building %} {% if item.is_building %}
<div class='alert alert-block alert-info'> <div class='alert alert-block alert-info'>
{% trans "This stock item is in production and cannot be edited." %}<br> {% trans "This stock item is in production and cannot be edited." %}<br>
@ -409,14 +386,28 @@
<tr> <tr>
<td><span class='fas fa-vial'></span></td> <td><span class='fas fa-vial'></span></td>
<td>{% trans "Tests" %}</td> <td>{% trans "Tests" %}</td>
<td>{{ item.requiredTestStatus.passed }} / {{ item.requiredTestStatus.total }}</td> <td>
{{ item.requiredTestStatus.passed }} / {{ item.requiredTestStatus.total }}
{% if item.passedAllRequiredTests %}
<span class='fas fa-check-circle float-right icon-green'></span>
{% else %}
<span class='fas fa-times-circle float-right icon-red'></span>
{% endif %}
</td>
</tr> </tr>
{% endif %} {% endif %}
{% if item.owner %} {% if ownership_enabled and item_owner %}
<tr> <tr>
<td><span class='fas fa-users'></span></td> <td><span class='fas fa-users'></span></td>
<td>{% trans "Owner" %}</td> <td>{% trans "Owner" %}</td>
<td>{{ item.owner }}</td> <td>
{{ item_owner }}
{% if not user_owns_item %}
<span class='badge rounded-pill bg-warning badge-right' title='{% trans "You are not in the list of owners of this item. This stock item cannot be edited." %}'>
{% trans "Read only" %}
</span>
{% endif %}
</td>
</tr> </tr>
{% endif %} {% endif %}
</table> </table>

View File

@ -20,6 +20,7 @@
{% endblock %} {% endblock %}
{% block actions %} {% block actions %}
<!-- Admin view --> <!-- Admin view -->
{% if location and user.is_staff and roles.stock_location.change %} {% if location and user.is_staff and roles.stock_location.change %}
{% url 'admin:stock_stocklocation_change' location.pk as url %} {% url 'admin:stock_stocklocation_change' location.pk as url %}
@ -38,7 +39,7 @@
</ul> </ul>
</div> </div>
<!-- Check permissions and owner --> <!-- Check permissions and owner -->
{% if owner_control.value == "False" or owner_control.value == "True" and user in owners or user.is_superuser %} {% if user_owns_location %}
{% if roles.stock.change %} {% if roles.stock.change %}
<div class='btn-group' role='group'> <div class='btn-group' role='group'>
<button id='stock-actions' title='{% trans "Stock actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'> <button id='stock-actions' title='{% trans "Stock actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'>
@ -74,13 +75,11 @@
{% endif %} {% endif %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if owner_control.value == "False" or owner_control.value == "True" and user in owners or user.is_superuser or not location %} {% if user_owns_location and roles.stock_location.add %}
{% if roles.stock_location.add %}
<button class='btn btn-success' id='location-create' type='button' title='{% trans "Create new stock location" %}'> <button class='btn btn-success' id='location-create' type='button' title='{% trans "Create new stock location" %}'>
<span class='fas fa-plus-circle'></span> {% trans "New Location" %} <span class='fas fa-plus-circle'></span> {% trans "New Location" %}
</button> </button>
{% endif %} {% endif %}
{% endif %}
{% endblock %} {% endblock %}
{% block details_left %} {% block details_left %}
@ -106,23 +105,23 @@
<td><em>{% trans "Top level stock location" %}</em></td> <td><em>{% trans "Top level stock location" %}</em></td>
</tr> </tr>
{% endif %} {% endif %}
{% if ownership_enabled and location_owner %}
<tr>
<td><span class='fas fa-users'></span></td>
<td>{% trans "Location Owner" %}</td>
<td>
{{ location_owner }}
{% if not user_owns_location %}
<span class='badge rounded-pill bg-warning badge-right' title='{% trans "You are not in the list of owners of this location. This stock location cannot be edited." %}'>
{% trans "Read only" %}
</span>
{% endif %}
</td>
</tr>
{% endif %}
</table> </table>
{% endblock details_left %} {% endblock details_left %}
{% block details_below %}
{% setting_object 'STOCK_OWNERSHIP_CONTROL' as owner_control %}
{% if owner_control.value == "True" %}
{% authorized_owners location.owner as owners %}
{% if location and not user in owners and not user.is_superuser %}
<div class='alert alert-block alert-info'>
{% trans "You are not in the list of owners of this location. This stock location cannot be edited." %}<br>
</div>
{% endif %}
{% endif %}
{% endblock details_below %}
{% block details_right %} {% block details_right %}
{% if location %} {% if location %}
<table class='table table-striped table-condensed'> <table class='table table-striped table-condensed'>

View File

@ -63,6 +63,11 @@ class StockIndex(InvenTreeRoleMixin, ListView):
context['loc_count'] = StockLocation.objects.count() context['loc_count'] = StockLocation.objects.count()
context['stock_count'] = StockItem.objects.count() context['stock_count'] = StockItem.objects.count()
# No 'ownership' checks are necessary for the top-level StockLocation view
context['user_owns_location'] = True
context['location_owner'] = None
context['ownership_enabled'] = common.models.InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL')
return context return context
@ -76,6 +81,16 @@ class StockLocationDetail(InvenTreeRoleMixin, DetailView):
queryset = StockLocation.objects.all() queryset = StockLocation.objects.all()
model = StockLocation model = StockLocation
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['ownership_enabled'] = common.models.InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL')
context['location_owner'] = context['location'].get_location_owner()
context['user_owns_location'] = context['location'].check_ownership(self.request.user)
return context
class StockItemDetail(InvenTreeRoleMixin, DetailView): class StockItemDetail(InvenTreeRoleMixin, DetailView):
""" """
@ -126,6 +141,10 @@ class StockItemDetail(InvenTreeRoleMixin, DetailView):
# We only support integer serial number progression # We only support integer serial number progression
pass pass
data['ownership_enabled'] = common.models.InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL')
data['item_owner'] = self.object.get_item_owner()
data['user_owns_item'] = self.object.check_ownership(self.request.user)
return data return data
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):

View File

@ -1554,11 +1554,11 @@ function locationDetail(row, showLink=true) {
} else if (row.belongs_to) { } else if (row.belongs_to) {
// StockItem is installed inside a different StockItem // StockItem is installed inside a different StockItem
text = `{% trans "Installed in Stock Item" %} ${row.belongs_to}`; text = `{% trans "Installed in Stock Item" %} ${row.belongs_to}`;
url = `/stock/item/${row.belongs_to}/installed/`; url = `/stock/item/${row.belongs_to}/?display=installed-items`;
} else if (row.customer) { } else if (row.customer) {
// StockItem has been assigned to a customer // StockItem has been assigned to a customer
text = '{% trans "Shipped to customer" %}'; text = '{% trans "Shipped to customer" %}';
url = `/company/${row.customer}/assigned-stock/`; url = `/company/${row.customer}/?display=assigned-stock`;
} else if (row.sales_order) { } else if (row.sales_order) {
// StockItem has been assigned to a sales order // StockItem has been assigned to a sales order
text = '{% trans "Assigned to Sales Order" %}'; text = '{% trans "Assigned to Sales Order" %}';

View File

@ -452,7 +452,7 @@ def update_group_roles(group, debug=False):
group.permissions.add(permission) group.permissions.add(permission)
if debug: # pragma: no cover if debug: # pragma: no cover
print(f"Adding permission {perm} to group {group.name}") logger.info(f"Adding permission {perm} to group {group.name}")
# Remove any extra permissions from the group # Remove any extra permissions from the group
for perm in permissions_to_delete: for perm in permissions_to_delete:
@ -467,7 +467,7 @@ def update_group_roles(group, debug=False):
group.permissions.remove(permission) group.permissions.remove(permission)
if debug: # pragma: no cover if debug: # pragma: no cover
print(f"Removing permission {perm} from group {group.name}") logger.info(f"Removing permission {perm} from group {group.name}")
# Enable all action permissions for certain children models # Enable all action permissions for certain children models
# if parent model has 'change' permission # if parent model has 'change' permission
@ -489,7 +489,7 @@ def update_group_roles(group, debug=False):
permission = get_permission_object(child_perm) permission = get_permission_object(child_perm)
if permission: if permission:
group.permissions.add(permission) group.permissions.add(permission)
print(f"Adding permission {child_perm} to group {group.name}") logger.info(f"Adding permission {child_perm} to group {group.name}")
@receiver(post_save, sender=Group, dispatch_uid='create_missing_rule_sets') @receiver(post_save, sender=Group, dispatch_uid='create_missing_rule_sets')

View File

@ -37,6 +37,9 @@ InvenTree is supported by a [companion mobile app](https://inventree.readthedocs
- [**Download InvenTree from the Apple App Store**](https://apps.apple.com/au/app/inventree/id1581731101#?platform=iphone) - [**Download InvenTree from the Apple App Store**](https://apps.apple.com/au/app/inventree/id1581731101#?platform=iphone)
# Deploy to DigitalOcean
[![Deploy to DO](https://www.deploytodo.com/do-btn-blue-ghost.svg)](https://marketplace.digitalocean.com/apps/inventree?refcode=d6172576d014)
# Documentation # Documentation
For InvenTree documentation, refer to the [InvenTree documentation website](https://inventree.readthedocs.io/en/latest/). For InvenTree documentation, refer to the [InvenTree documentation website](https://inventree.readthedocs.io/en/latest/).