diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py index a60935b4b6..d2a5c5daa6 100644 --- a/InvenTree/InvenTree/models.py +++ b/InvenTree/InvenTree/models.py @@ -4,8 +4,11 @@ Generic models which provide extra functionality over base Django model types. from __future__ import unicode_literals +import os + from django.db import models from django.contrib.contenttypes.models import ContentType +from django.utils.translation import gettext_lazy as _ from django.db.models.signals import pre_delete from django.dispatch import receiver @@ -15,6 +18,51 @@ from mptt.models import MPTTModel, TreeForeignKey from .validators import validate_tree_name +def rename_attachment(instance, filename): + """ + Function for renaming an attachment file. + The subdirectory for the uploaded file is determined by the implementing class. + + Args: + instance: Instance of a PartAttachment object + filename: name of uploaded file + + Returns: + path to store file, format: '//filename' + """ + + # Construct a path to store a file attachment for a given model type + return os.path.join(instance.getSubdir(), filename) + + +class InvenTreeAttachment(models.Model): + """ Provides an abstracted class for managing file attachments. + + Attributes: + attachment: File + comment: String descriptor for the attachment + """ + def getSubdir(self): + """ + Return the subdirectory under which attachments should be stored. + Note: Re-implement this for each subclass of InvenTreeAttachment + """ + + return "attachments" + + attachment = models.FileField(upload_to=rename_attachment, + help_text=_('Select file to attach')) + + comment = models.CharField(max_length=100, help_text=_('File comment')) + + @property + def basename(self): + return os.path.basename(self.attachment.name) + + class Meta: + abstract = True + + class InvenTreeTree(MPTTModel): """ Provides an abstracted self-referencing tree model for data categories. diff --git a/InvenTree/InvenTree/version.py b/InvenTree/InvenTree/version.py index f5329effba..76f0cabdd6 100644 --- a/InvenTree/InvenTree/version.py +++ b/InvenTree/InvenTree/version.py @@ -4,7 +4,7 @@ Provides information on the current InvenTree version import subprocess -INVENTREE_SW_VERSION = "0.0.8" +INVENTREE_SW_VERSION = "0.0.9" def inventreeVersion(): diff --git a/InvenTree/company/templates/company/company_base.html b/InvenTree/company/templates/company/company_base.html index 1080f01445..9e849e5a47 100644 --- a/InvenTree/company/templates/company/company_base.html +++ b/InvenTree/company/templates/company/company_base.html @@ -100,7 +100,7 @@ InvenTree | {% trans "Company" %} - {{ company.name }} }); $("#company-order-2").click(function() { - launchModalForm("{% url 'purchase-order-create' %}", + launchModalForm("{% url 'po-create' %}", { data: { supplier: {{ company.id }}, diff --git a/InvenTree/company/templates/company/detail_purchase_orders.html b/InvenTree/company/templates/company/detail_purchase_orders.html index fcba26e2af..c3878eec6d 100644 --- a/InvenTree/company/templates/company/detail_purchase_orders.html +++ b/InvenTree/company/templates/company/detail_purchase_orders.html @@ -28,7 +28,7 @@ function newOrder() { - launchModalForm("{% url 'purchase-order-create' %}", + launchModalForm("{% url 'po-create' %}", { data: { supplier: {{ company.id }}, diff --git a/InvenTree/locale/de/LC_MESSAGES/django.po b/InvenTree/locale/de/LC_MESSAGES/django.po index 06afa0b14d..d850c50f0f 100644 --- a/InvenTree/locale/de/LC_MESSAGES/django.po +++ b/InvenTree/locale/de/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-02-12 00:31+0000\n" +"POT-Creation-Date: 2020-03-22 08:55+0000\n" "PO-Revision-Date: 2020-02-02 08:07+0100\n" "Last-Translator: Christian Schlüter \n" "Language-Team: C \n" @@ -17,7 +17,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Lokalize 19.12.0\n" -#: InvenTree/helpers.py:186 order/models.py:161 order/models.py:212 +#: InvenTree/helpers.py:186 order/models.py:163 order/models.py:214 msgid "Invalid quantity provided" msgstr "Keine gültige Menge" @@ -47,6 +47,14 @@ msgstr "" "Anzahl der eindeutigen Seriennummern ({s}) muss mit der Anzahl ({q}) " "übereinstimmen" +#: InvenTree/models.py:54 +msgid "Select file to attach" +msgstr "Datei zum Anhängen auswählen" + +#: InvenTree/models.py:56 +msgid "File comment" +msgstr "Datei-Kommentar" + #: InvenTree/settings.py:270 msgid "English" msgstr "Englisch" @@ -154,11 +162,11 @@ msgstr "Bau-Fertigstellung bestätigen" msgid "Brief description of the build" msgstr "Kurze Beschreibung des Baus" -#: build/models.py:63 +#: build/models.py:64 msgid "Select part to build" msgstr "Teil für den Bau wählen" -#: build/models.py:69 +#: build/models.py:70 msgid "" "Select location to take stock from for this build (leave blank to take from " "any stock location)" @@ -166,46 +174,46 @@ msgstr "" "Lager-Entnahmestandort für diesen Bau wählen (oder leer lassen für einen " "beliebigen Lager-Standort)" -#: build/models.py:75 +#: build/models.py:76 msgid "Number of parts to build" msgstr "Anzahl der zu bauenden Teile" -#: build/models.py:81 +#: build/models.py:82 msgid "Build status" msgstr "Bau-Status" -#: build/models.py:84 +#: build/models.py:85 msgid "Batch code for this build output" msgstr "Chargennummer für diese Bau-Ausgabe" -#: build/models.py:96 +#: build/models.py:97 msgid "Link to external URL" msgstr "Link zu einer externen URL" -#: build/models.py:98 +#: build/models.py:99 msgid "Extra build notes" msgstr "Notizen für den Bau" -#: build/models.py:383 +#: build/models.py:388 #, python-brace-format msgid "Selected stock item not found in BOM for part '{p}'" msgstr "Ausgewähltes Lagerobjekt nicht in BOM für Teil '{p}' gefunden" -#: build/models.py:386 +#: build/models.py:391 #, python-brace-format msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" "zugewiesene Anzahl ({n}) darf nicht die verfügbare ({q}) Anzahl überschreiten" -#: build/models.py:404 +#: build/models.py:409 msgid "Build to allocate parts" msgstr "Bau starten um Teile zuzuweisen" -#: build/models.py:411 +#: build/models.py:416 msgid "Stock Item to allocate to build" msgstr "Lagerobjekt dem Bau zuweisen" -#: build/models.py:419 +#: build/models.py:424 msgid "Stock quantity to allocate to build" msgstr "Lagerobjekt-Anzahl dem Bau zuweisen" @@ -248,12 +256,13 @@ msgid "Allocate" msgstr "zuweisen" #: build/templates/build/allocate_view.html:10 -#: company/templates/company/detail_part.html:18 order/views.py:448 +#: company/templates/company/detail_part.html:18 order/views.py:526 msgid "Order Parts" msgstr "Teile bestellen" #: build/templates/build/allocate_view.html:18 #: company/templates/company/index.html:54 +#: company/templates/company/supplier_part_base.html:50 #: company/templates/company/supplier_part_detail.html:27 #: order/templates/order/purchase_order_detail.html:26 #: part/templates/part/detail.html:33 @@ -265,6 +274,12 @@ msgstr "Beschreibung" msgid "On Order" msgstr "bestellt" +#: build/templates/build/build_output.html:9 +#, fuzzy +#| msgid "Build status" +msgid "Build Outputs" +msgstr "Bau-Status" + #: build/templates/build/delete_build_item.html:6 #, fuzzy #| msgid "Are you sure you want to delete the following Supplier Parts?" @@ -283,7 +298,7 @@ msgstr "Titel" #: build/templates/build/detail.html:20 #: company/templates/company/supplier_part_pricing.html:27 #: order/templates/order/purchase_order_detail.html:29 -#: stock/templates/stock/item_base.html:90 +#: stock/templates/stock/item_base.html:101 #: stock/templates/stock/stock_adjust.html:18 msgid "Quantity" msgstr "Anzahl" @@ -298,19 +313,21 @@ msgstr "Bestand kann jedem verfügbaren Lagerort entnommen werden." #: build/templates/build/detail.html:33 #: order/templates/order/order_base.html:71 -#: stock/templates/stock/item_base.html:147 +#: stock/templates/stock/item_base.html:158 msgid "Status" msgstr "Status" -#: build/templates/build/detail.html:37 stock/templates/stock/item_base.html:96 +#: build/templates/build/detail.html:37 +#: stock/templates/stock/item_base.html:107 msgid "Batch" msgstr "Los" #: build/templates/build/detail.html:42 #: company/templates/company/detail_part.html:90 +#: company/templates/company/supplier_part_base.html:47 #: company/templates/company/supplier_part_detail.html:24 #: part/templates/part/detail.html:50 part/templates/part/part_base.html:81 -#: stock/templates/stock/item_base.html:120 +#: stock/templates/stock/item_base.html:131 msgid "URL" msgstr "URL" @@ -351,19 +368,22 @@ msgstr "Speichern" msgid "Edit notes" msgstr "Bermerkungen bearbeiten" -#: build/templates/build/tabs.html:5 -#: company/templates/company/supplier_part_tabs.html:5 -#: company/templates/company/tabs.html:5 part/templates/part/tabs.html:6 +#: build/templates/build/tabs.html:5 company/templates/company/tabs.html:5 +#: part/templates/part/tabs.html:6 msgid "Details" msgstr "Details" -#: build/templates/build/tabs.html:8 company/models.py:248 -#: company/templates/company/tabs.html:26 order/templates/order/tabs.html:8 -#: part/templates/part/tabs.html:58 stock/templates/stock/tabs.html:14 +#: build/templates/build/tabs.html:8 +msgid "Outputs" +msgstr "" + +#: build/templates/build/tabs.html:11 company/models.py:248 +#: company/templates/company/tabs.html:26 order/templates/order/tabs.html:11 +#: part/templates/part/tabs.html:58 stock/templates/stock/tabs.html:17 msgid "Notes" msgstr "Notizen" -#: build/templates/build/tabs.html:11 +#: build/templates/build/tabs.html:14 msgid "Assign Parts" msgstr "Teile zuweisen" @@ -601,6 +621,7 @@ msgid "Supplier stock keeping unit" msgstr "Stock Keeping Units (SKU) des Zulieferers" #: company/models.py:240 company/templates/company/detail_part.html:81 +#: company/templates/company/supplier_part_base.html:53 #: company/templates/company/supplier_part_detail.html:30 msgid "Manufacturer" msgstr "Hersteller" @@ -625,7 +646,7 @@ msgstr "Mindestpreis" msgid "Part packaging" msgstr "Teile-Packaging" -#: company/templates/company/company_base.html:7 order/models.py:128 +#: company/templates/company/company_base.html:7 order/models.py:130 msgid "Company" msgstr "Firma" @@ -657,15 +678,16 @@ msgid "Company Details" msgstr "Firmenbemerkungen" #: company/templates/company/detail.html:13 -#: stock/templates/stock/item_base.html:114 +#: stock/templates/stock/item_base.html:125 msgid "Customer" msgstr "Kunde" #: company/templates/company/detail.html:17 #: company/templates/company/index.html:46 +#: company/templates/company/supplier_part_base.html:44 #: company/templates/company/supplier_part_detail.html:21 #: order/templates/order/order_base.html:67 -#: stock/templates/stock/item_base.html:126 +#: stock/templates/stock/item_base.html:137 msgid "Supplier" msgstr "Zulieferer" @@ -692,6 +714,7 @@ msgid "Delete Parts" msgstr "Anhang löschen" #: company/templates/company/detail_part.html:73 +#: company/templates/company/supplier_part_base.html:45 #: company/templates/company/supplier_part_detail.html:22 msgid "SKU" msgstr "" @@ -753,28 +776,32 @@ msgstr "" #: company/templates/company/supplier_part_base.html:6 #: company/templates/company/supplier_part_base.html:13 -#: stock/templates/stock/item_base.html:130 +#: stock/templates/stock/item_base.html:141 msgid "Supplier Part" msgstr "Zulieferer-Teil" +#: company/templates/company/supplier_part_base.html:34 #: company/templates/company/supplier_part_detail.html:11 #, fuzzy #| msgid "Supplier Parts" msgid "Supplier Part Details" msgstr "Zulieferer-Teile" +#: company/templates/company/supplier_part_base.html:37 #: company/templates/company/supplier_part_detail.html:14 #, fuzzy #| msgid "Internal Part Number" msgid "Internal Part" msgstr "Interne Teilenummer" +#: company/templates/company/supplier_part_base.html:54 #: company/templates/company/supplier_part_detail.html:31 #, fuzzy #| msgid "IPN" msgid "MPN" msgstr "IPN (Interne Produktnummer)" +#: company/templates/company/supplier_part_base.html:57 #: company/templates/company/supplier_part_detail.html:34 #: order/templates/order/purchase_order_detail.html:33 msgid "Note" @@ -838,19 +865,19 @@ msgstr "Standort" msgid "Create New Location" msgstr "Neuen Lager-Standort erstellen" -#: company/templates/company/supplier_part_tabs.html:8 +#: company/templates/company/supplier_part_tabs.html:5 #, fuzzy #| msgid "Part packaging" msgid "Pricing" msgstr "Teile-Packaging" -#: company/templates/company/supplier_part_tabs.html:11 +#: company/templates/company/supplier_part_tabs.html:8 #: company/templates/company/tabs.html:12 part/templates/part/tabs.html:17 #: templates/navbar.html:11 msgid "Stock" msgstr "Lagerbestand" -#: company/templates/company/supplier_part_tabs.html:14 +#: company/templates/company/supplier_part_tabs.html:11 #: templates/navbar.html:14 #, fuzzy #| msgid "On Order" @@ -955,56 +982,56 @@ msgstr "Bestellung stornieren" msgid "Receive parts to this location" msgstr "Teile in diesen Ort empfangen" -#: order/models.py:65 +#: order/models.py:67 msgid "Order reference" msgstr "Bestell-Referenz" -#: order/models.py:67 +#: order/models.py:69 msgid "Order description" msgstr "Bestellungs-Beschreibung" -#: order/models.py:69 +#: order/models.py:71 msgid "Link to external page" msgstr "Link auf externe Seite" -#: order/models.py:86 +#: order/models.py:88 msgid "Order notes" msgstr "Bestell-Notizen" -#: order/models.py:159 order/models.py:210 part/views.py:1109 -#: stock/models.py:440 +#: order/models.py:161 order/models.py:212 part/views.py:1119 +#: stock/models.py:463 msgid "Quantity must be greater than zero" msgstr "Anzahl muss größer Null sein" -#: order/models.py:164 +#: order/models.py:166 msgid "Part supplier must match PO supplier" msgstr "Teile-Zulieferer muss dem Zulieferer des Kaufvertrags entsprechen" -#: order/models.py:205 +#: order/models.py:207 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "Nur Teile aufgegebener Bestllungen können empfangen werden" -#: order/models.py:254 +#: order/models.py:267 msgid "Item quantity" msgstr "Anzahl" -#: order/models.py:256 +#: order/models.py:269 msgid "Line item reference" msgstr "Position - Referenz" -#: order/models.py:258 +#: order/models.py:271 msgid "Line item notes" msgstr "Position - Notizen" -#: order/models.py:284 stock/templates/stock/item_base.html:108 +#: order/models.py:297 stock/templates/stock/item_base.html:119 msgid "Purchase Order" msgstr "Kaufvertrag" -#: order/models.py:293 +#: order/models.py:306 msgid "Supplier part" msgstr "Zulieferer-Teil" -#: order/models.py:296 +#: order/models.py:309 msgid "Number of items received" msgstr "Empfangene Objekt-Anzahl" @@ -1026,7 +1053,46 @@ msgstr "Empfangen" msgid "Order Notes" msgstr "Bestellungsbemerkungen" -#: order/templates/order/purchase_order_detail.html:15 order/views.py:747 +#: order/templates/order/po_attachments.html:11 +#, fuzzy +#| msgid "Purchase Order Details" +msgid "Purchase Order Attachments" +msgstr "Bestelldetails" + +#: order/templates/order/po_attachments.html:17 +#: part/templates/part/attachments.html:14 +msgid "Add Attachment" +msgstr "Anhang hinzufügen" + +#: order/templates/order/po_attachments.html:24 +#: part/templates/part/attachments.html:22 +msgid "File" +msgstr "Datei" + +#: order/templates/order/po_attachments.html:25 +#: part/templates/part/attachments.html:23 +msgid "Comment" +msgstr "Kommentar" + +#: order/templates/order/po_attachments.html:36 +#: part/templates/part/attachments.html:34 part/views.py:119 +msgid "Edit attachment" +msgstr "Anhang bearbeiten" + +#: order/templates/order/po_attachments.html:39 +#: part/templates/part/attachments.html:37 +msgid "Delete attachment" +msgstr "Anhang löschen" + +#: order/templates/order/po_delete.html:5 +#: part/templates/part/attachment_delete.html:5 +#, fuzzy +#| msgid "Are you sure you want to delete the following Supplier Parts?" +msgid "Are you sure you want to delete this attachment?" +msgstr "" +"Sind Sie sicher, dass sie die folgenden Zulieferer-Teile löschen möchten?" + +#: order/templates/order/purchase_order_detail.html:15 order/views.py:825 msgid "Add Line Item" msgstr "Position hinzufügen" @@ -1050,95 +1116,135 @@ msgstr "Referenz" msgid "Items" msgstr "Positionen" -#: order/views.py:99 +#: order/templates/order/tabs.html:8 part/templates/part/tabs.html:55 +msgid "Attachments" +msgstr "Anhänge" + +#: order/views.py:80 +#, fuzzy +#| msgid "Purchase Order Details" +msgid "Add Purchase Order Attachment" +msgstr "Bestelldetails" + +#: order/views.py:85 part/views.py:80 +#, fuzzy +#| msgid "Add Attachment" +msgid "Added attachment" +msgstr "Anhang hinzufügen" + +#: order/views.py:121 +#, fuzzy +#| msgid "Edit attachment" +msgid "Edit Attachment" +msgstr "Anhang bearbeiten" + +#: order/views.py:125 +#, fuzzy +#| msgid "Part Attachments" +msgid "Attachment updated" +msgstr "Anhänge" + +#: order/views.py:141 +#, fuzzy +#| msgid "Delete attachment" +msgid "Delete Attachment" +msgstr "Anhang löschen" + +#: order/views.py:147 +#, fuzzy +#| msgid "Delete attachment" +msgid "Deleted attachment" +msgstr "Anhang löschen" + +#: order/views.py:177 #, fuzzy #| msgid "Purchase Order" msgid "Create Purchase Order" msgstr "Kaufvertrag" -#: order/views.py:129 +#: order/views.py:207 #, fuzzy #| msgid "Purchase Order" msgid "Edit Purchase Order" msgstr "Kaufvertrag" -#: order/views.py:149 +#: order/views.py:227 #, fuzzy #| msgid "Cancel order" msgid "Cancel Order" msgstr "Bestellung stornieren" -#: order/views.py:164 +#: order/views.py:242 msgid "Confirm order cancellation" msgstr "Bestell-Stornierung bestätigen" -#: order/views.py:182 +#: order/views.py:260 #, fuzzy #| msgid "Issued" msgid "Issue Order" msgstr "Aufgegeben" -#: order/views.py:197 +#: order/views.py:275 msgid "Confirm order placement" msgstr "Bestellungstätigung bestätigen" -#: order/views.py:218 +#: order/views.py:296 #, fuzzy #| msgid "Completed" msgid "Complete Order" msgstr "Fertig" -#: order/views.py:284 +#: order/views.py:362 #, fuzzy #| msgid "Required Parts" msgid "Receive Parts" msgstr "benötigte Teile" -#: order/views.py:351 +#: order/views.py:429 msgid "Items received" msgstr "Anzahl empfangener Positionen" -#: order/views.py:365 +#: order/views.py:443 msgid "No destination set" msgstr "Kein Ziel gesetzt" -#: order/views.py:396 +#: order/views.py:474 msgid "Error converting quantity to number" msgstr "Fehler beim Konvertieren zu Zahl" -#: order/views.py:402 +#: order/views.py:480 msgid "Receive quantity less than zero" msgstr "Anzahl kleiner null empfangen" -#: order/views.py:408 +#: order/views.py:486 msgid "No lines specified" msgstr "Keine Zeilen angegeben" -#: order/views.py:767 +#: order/views.py:845 msgid "Invalid Purchase Order" msgstr "Ungültige Bestellung" -#: order/views.py:775 +#: order/views.py:853 msgid "Supplier must match for Part and Order" msgstr "Zulieferer muss zum Teil und zur Bestellung passen" -#: order/views.py:780 +#: order/views.py:858 msgid "Invalid SupplierPart selection" msgstr "Ungültige Wahl des Zulieferer-Teils" -#: order/views.py:862 +#: order/views.py:940 #, fuzzy #| msgid "Add Line Item" msgid "Edit Line Item" msgstr "Position hinzufügen" -#: order/views.py:878 +#: order/views.py:956 #, fuzzy #| msgid "Delete Stock Item" msgid "Delete Line Item" msgstr "Lagerobjekt löschen" -#: order/views.py:883 +#: order/views.py:961 #, fuzzy #| msgid "Deleted {n} stock items" msgid "Deleted line item" @@ -1203,149 +1309,141 @@ msgstr "Eintragsmenge zur Preisberechnung" msgid "Select currency for price calculation" msgstr "Währung zur Preisberechnung wählen" -#: part/models.py:59 +#: part/models.py:60 msgid "Default location for parts in this category" msgstr "Standard-Standort für Teile dieser Kategorie" -#: part/models.py:62 +#: part/models.py:63 msgid "Default keywords for parts in this category" msgstr "Standard-Stichworte für Teile dieser Kategorie" -#: part/models.py:323 +#: part/models.py:327 msgid "Part must be unique for name, IPN and revision" msgstr "Namen, Teile- und Revisionsnummern müssen eindeutig sein" -#: part/models.py:337 +#: part/models.py:341 msgid "Part cannot be a template part if it is a variant of another part" msgstr "Teil kann keine Vorlage sein wenn es Variante eines anderen Teils ist" -#: part/models.py:338 +#: part/models.py:342 msgid "Part cannot be a variant of another part if it is already a template" msgstr "" "Teil kann keine Variante eines anderen Teils sein wenn es bereits eine " "Vorlage ist" -#: part/models.py:342 part/templates/part/detail.html:17 +#: part/models.py:346 part/templates/part/detail.html:17 msgid "Part name" msgstr "Name des Teils" -#: part/models.py:346 +#: part/models.py:350 msgid "Is this part a template part?" msgstr "Ist dieses Teil eine Vorlage?" -#: part/models.py:355 +#: part/models.py:359 msgid "Is this part a variant of another part?" msgstr "Ist dieses Teil eine Variante eines anderen Teils?" -#: part/models.py:357 +#: part/models.py:361 msgid "Part description" msgstr "Beschreibung des Teils" -#: part/models.py:359 +#: part/models.py:363 msgid "Part keywords to improve visibility in search results" msgstr "Schlüsselworte um die Sichtbarkeit in Suchergebnissen zu verbessern" -#: part/models.py:364 +#: part/models.py:368 msgid "Part category" msgstr "Teile-Kategorie" -#: part/models.py:366 +#: part/models.py:370 msgid "Internal Part Number" msgstr "Interne Teilenummer" -#: part/models.py:368 +#: part/models.py:372 msgid "Part revision or version number" msgstr "Revisions- oder Versionsnummer" -#: part/models.py:370 +#: part/models.py:374 msgid "Link to extenal URL" msgstr "Link zu einer Externen URL" -#: part/models.py:376 +#: part/models.py:380 msgid "Where is this item normally stored?" msgstr "Wo wird dieses Teil normalerweise gelagert?" -#: part/models.py:420 +#: part/models.py:424 msgid "Default supplier part" msgstr "Standard-Zulieferer?" -#: part/models.py:423 +#: part/models.py:427 msgid "Minimum allowed stock level" msgstr "Minimal zulässiger Lagerbestand" -#: part/models.py:425 +#: part/models.py:429 msgid "Stock keeping units for this part" msgstr "Stock Keeping Units (SKU) für dieses Teil" -#: part/models.py:427 +#: part/models.py:431 msgid "Can this part be built from other parts?" msgstr "Kann dieses Teil aus anderen Teilen angefertigt werden?" -#: part/models.py:429 +#: part/models.py:433 msgid "Can this part be used to build other parts?" msgstr "Kann dieses Teil zum Bau von anderen genutzt werden?" -#: part/models.py:431 +#: part/models.py:435 msgid "Does this part have tracking for unique items?" msgstr "Hat dieses Teil Tracking für einzelne Objekte?" -#: part/models.py:433 +#: part/models.py:437 msgid "Can this part be purchased from external suppliers?" msgstr "Kann dieses Teil von externen Zulieferern gekauft werden?" -#: part/models.py:435 +#: part/models.py:439 msgid "Can this part be sold to customers?" msgstr "Kann dieses Teil an Kunden verkauft werden?" -#: part/models.py:437 +#: part/models.py:441 msgid "Is this part active?" msgstr "Ist dieses Teil aktiv?" -#: part/models.py:439 +#: part/models.py:443 msgid "Is this a virtual part, such as a software product or license?" msgstr "Ist dieses Teil virtuell, wie zum Beispiel eine Software oder Lizenz?" -#: part/models.py:441 +#: part/models.py:445 msgid "Part notes - supports Markdown formatting" msgstr "Bemerkungen - unterstüzt Markdown-Formatierung" -#: part/models.py:443 +#: part/models.py:447 msgid "Stored BOM checksum" msgstr "Prüfsumme der Stückliste gespeichert" -#: part/models.py:948 -msgid "Select file to attach" -msgstr "Datei zum Anhängen auswählen" - -#: part/models.py:950 -msgid "File comment" -msgstr "Datei-Kommentar" - -#: part/models.py:1005 +#: part/models.py:1004 msgid "Parameter template name must be unique" msgstr "Vorlagen-Name des Parameters muss eindeutig sein" -#: part/models.py:1010 +#: part/models.py:1009 msgid "Parameter Name" msgstr "Name des Parameters" -#: part/models.py:1012 +#: part/models.py:1011 msgid "Parameter Units" msgstr "Parameter Einheit" -#: part/models.py:1038 +#: part/models.py:1037 msgid "Parent Part" msgstr "Ausgangsteil" -#: part/models.py:1040 +#: part/models.py:1039 msgid "Parameter Template" msgstr "Parameter Vorlage" -#: part/models.py:1042 +#: part/models.py:1041 msgid "Parameter Value" msgstr "Parameter Wert" -#: part/models.py:1066 +#: part/models.py:1065 msgid "Select parent part" msgstr "Ausgangsteil auswählen" @@ -1353,31 +1451,31 @@ msgstr "Ausgangsteil auswählen" msgid "Select part to be used in BOM" msgstr "Teil für die Nutzung in der Stückliste auswählen" -#: part/models.py:1080 +#: part/models.py:1081 msgid "BOM quantity for this BOM item" msgstr "Stücklisten-Anzahl für dieses Stücklisten-Teil" -#: part/models.py:1083 +#: part/models.py:1084 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "Geschätzter Ausschuss (absolut oder prozentual)" -#: part/models.py:1086 +#: part/models.py:1087 msgid "BOM item reference" msgstr "Referenz des Objekts auf der Stückliste" -#: part/models.py:1089 +#: part/models.py:1090 msgid "BOM item notes" msgstr "Notizen zum Stücklisten-Objekt" -#: part/models.py:1091 +#: part/models.py:1092 msgid "BOM line checksum" msgstr "Prüfsumme der Stückliste" -#: part/models.py:1154 +#: part/models.py:1155 msgid "Part cannot be added to its own Bill of Materials" msgstr "Teil kann nicht zu seiner eigenen Stückliste hinzugefügt werden" -#: part/models.py:1161 +#: part/models.py:1162 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "Teil '{p1}' wird in Stückliste für Teil '{p2}' benutzt (rekursiv)" @@ -1386,26 +1484,6 @@ msgstr "Teil '{p1}' wird in Stückliste für Teil '{p2}' benutzt (rekursiv)" msgid "Part Attachments" msgstr "Anhänge" -#: part/templates/part/attachments.html:14 -msgid "Add Attachment" -msgstr "Anhang hinzufügen" - -#: part/templates/part/attachments.html:22 -msgid "File" -msgstr "Datei" - -#: part/templates/part/attachments.html:23 -msgid "Comment" -msgstr "Kommentar" - -#: part/templates/part/attachments.html:34 part/views.py:118 -msgid "Edit attachment" -msgstr "Anhang bearbeiten" - -#: part/templates/part/attachments.html:37 -msgid "Delete attachment" -msgstr "Anhang löschen" - #: part/templates/part/category.html:13 part/templates/part/category.html:69 #: templates/stats.html:14 msgid "Part Categories" @@ -1475,71 +1553,87 @@ msgstr "Einheiten" msgid "Minimum Stock" msgstr "Minimaler Lagerbestand" -#: part/templates/part/detail.html:91 +#: part/templates/part/detail.html:87 +#, fuzzy +#| msgid "Create new Stock Item" +msgid "Creation Date" +msgstr "Neues Lagerobjekt hinzufügen" + +#: part/templates/part/detail.html:92 +#, fuzzy +#| msgid "Created" +msgid "Created By" +msgstr "Erstellt" + +#: part/templates/part/detail.html:98 +msgid "Responsible User" +msgstr "" + +#: part/templates/part/detail.html:107 msgid "Virtual" msgstr "Virtuell" -#: part/templates/part/detail.html:94 +#: part/templates/part/detail.html:110 msgid "Part is virtual (not a physical part)" msgstr "Teil ist virtuell (kein physisches Teil)" -#: part/templates/part/detail.html:96 +#: part/templates/part/detail.html:112 msgid "Part is not a virtual part" msgstr "Teil ist nicht virtuell" -#: part/templates/part/detail.html:100 +#: part/templates/part/detail.html:116 msgid "Assembly" msgstr "Baugruppe" -#: part/templates/part/detail.html:103 +#: part/templates/part/detail.html:119 msgid "Part can be assembled from other parts" msgstr "Teil kann aus anderen Teilen angefertigt werden" -#: part/templates/part/detail.html:105 +#: part/templates/part/detail.html:121 msgid "Part cannot be assembled from other parts" msgstr "Teil kann nicht aus anderen Teilen angefertigt werden" -#: part/templates/part/detail.html:109 +#: part/templates/part/detail.html:125 msgid "Component" msgstr "Komponente" -#: part/templates/part/detail.html:112 +#: part/templates/part/detail.html:128 msgid "Part can be used in assemblies" msgstr "Teil kann in Baugruppen benutzt werden" -#: part/templates/part/detail.html:114 +#: part/templates/part/detail.html:130 msgid "Part cannot be used in assemblies" msgstr "Teil kann nicht in Baugruppen benutzt werden" -#: part/templates/part/detail.html:118 +#: part/templates/part/detail.html:134 msgid "Trackable" msgstr "nachverfolgbar" -#: part/templates/part/detail.html:121 +#: part/templates/part/detail.html:137 msgid "Part stock is tracked by serial number" msgstr "Teilebestand in der Seriennummer hinterlegt" -#: part/templates/part/detail.html:123 +#: part/templates/part/detail.html:139 msgid "Part stock is not tracked by serial number" msgstr "Teilebestand ist nicht in der Seriennummer hinterlegt" -#: part/templates/part/detail.html:127 +#: part/templates/part/detail.html:143 msgid "Purchaseable" msgstr "Kaufbar" -#: part/templates/part/detail.html:130 part/templates/part/detail.html:132 +#: part/templates/part/detail.html:146 part/templates/part/detail.html:148 msgid "Part can be purchased from external suppliers" msgstr "Teil kann von externen Zulieferern gekauft werden" -#: part/templates/part/detail.html:137 +#: part/templates/part/detail.html:153 msgid "Sellable" msgstr "Verkaufbar" -#: part/templates/part/detail.html:140 +#: part/templates/part/detail.html:156 msgid "Part can be sold to customers" msgstr "Teil kann an Kunden verkauft werden" -#: part/templates/part/detail.html:142 +#: part/templates/part/detail.html:158 msgid "Part cannot be sold to customers" msgstr "Teil kann nicht an Kunden verkauft werden" @@ -1613,7 +1707,7 @@ msgstr "Varianten" msgid "BOM" msgstr "Stückliste" -#: part/templates/part/tabs.html:28 stock/templates/stock/item_base.html:102 +#: part/templates/part/tabs.html:28 stock/templates/stock/item_base.html:113 #: templates/navbar.html:12 msgid "Build" msgstr "Bau" @@ -1630,230 +1724,220 @@ msgstr "Zulieferer" msgid "Tracking" msgstr "Tracking" -#: part/templates/part/tabs.html:55 -msgid "Attachments" -msgstr "Anhänge" - #: part/views.py:75 #, fuzzy #| msgid "Add Attachment" msgid "Add part attachment" msgstr "Anhang hinzufügen" -#: part/views.py:80 -#, fuzzy -#| msgid "Add Attachment" -msgid "Added attachment" -msgstr "Anhang hinzufügen" - -#: part/views.py:122 +#: part/views.py:123 #, fuzzy #| msgid "Part Attachments" msgid "Part attachment updated" msgstr "Anhänge" -#: part/views.py:137 +#: part/views.py:138 #, fuzzy #| msgid "Delete attachment" msgid "Delete Part Attachment" msgstr "Anhang löschen" -#: part/views.py:143 +#: part/views.py:144 #, fuzzy #| msgid "Delete attachment" msgid "Deleted part attachment" msgstr "Anhang löschen" -#: part/views.py:151 +#: part/views.py:152 #, fuzzy #| msgid "Select part category" msgid "Set Part Category" msgstr "Teilekategorie wählen" -#: part/views.py:199 +#: part/views.py:200 #, python-brace-format msgid "Set category for {n} parts" msgstr "Kategorie für {n} Teile setzen" -#: part/views.py:234 +#: part/views.py:235 #, fuzzy #| msgid "Create new Stock Item" msgid "Create Variant" msgstr "Neues Lagerobjekt hinzufügen" -#: part/views.py:304 +#: part/views.py:305 #, fuzzy #| msgid "Supplier Part" msgid "Duplicate Part" msgstr "Zulieferer-Teil" -#: part/views.py:309 +#: part/views.py:310 #, fuzzy #| msgid "Supplier part" msgid "Copied part" msgstr "Zulieferer-Teil" -#: part/views.py:417 +#: part/views.py:421 #, fuzzy #| msgid "Create new Stock Item" msgid "Create new part" msgstr "Neues Lagerobjekt hinzufügen" -#: part/views.py:422 +#: part/views.py:426 #, fuzzy #| msgid "Created new stock item" msgid "Created new part" msgstr "Neues Lagerobjekt erstellt" -#: part/views.py:595 +#: part/views.py:605 #, fuzzy #| msgid "Part Notes" msgid "Part QR Code" msgstr "Teil-Bemerkungen" -#: part/views.py:612 +#: part/views.py:622 msgid "Upload Part Image" msgstr "" -#: part/views.py:617 part/views.py:652 +#: part/views.py:627 part/views.py:662 msgid "Updated part image" msgstr "" -#: part/views.py:626 +#: part/views.py:636 #, fuzzy #| msgid "Select part" msgid "Select Part Image" msgstr "Teil auswählen" -#: part/views.py:655 +#: part/views.py:665 msgid "Part image not found" msgstr "" -#: part/views.py:666 +#: part/views.py:676 #, fuzzy #| msgid "Edit notes" msgid "Edit Part Properties" msgstr "Bermerkungen bearbeiten" -#: part/views.py:688 +#: part/views.py:698 msgid "Validate BOM" msgstr "" -#: part/views.py:850 +#: part/views.py:860 msgid "No BOM file provided" msgstr "Keine Stückliste angegeben" -#: part/views.py:1111 +#: part/views.py:1121 msgid "Enter a valid quantity" msgstr "Bitte eine gültige Anzahl eingeben" -#: part/views.py:1135 part/views.py:1138 +#: part/views.py:1145 part/views.py:1148 msgid "Select valid part" msgstr "Bitte ein gültiges Teil auswählen" -#: part/views.py:1144 +#: part/views.py:1154 msgid "Duplicate part selected" msgstr "Teil doppelt ausgewählt" -#: part/views.py:1172 +#: part/views.py:1182 msgid "Select a part" msgstr "Teil auswählen" -#: part/views.py:1176 +#: part/views.py:1186 msgid "Specify quantity" msgstr "Anzahl angeben" -#: part/views.py:1356 +#: part/views.py:1366 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1396 +#: part/views.py:1406 #, fuzzy #| msgid "Confirm part creation" msgid "Confirm Part Deletion" msgstr "Erstellen des Teils bestätigen" -#: part/views.py:1403 +#: part/views.py:1413 msgid "Part was deleted" msgstr "" -#: part/views.py:1412 +#: part/views.py:1422 #, fuzzy #| msgid "Part packaging" msgid "Part Pricing" msgstr "Teile-Packaging" -#: part/views.py:1534 +#: part/views.py:1544 #, fuzzy #| msgid "Parameter Template" msgid "Create Part Parameter Template" msgstr "Parameter Vorlage" -#: part/views.py:1542 +#: part/views.py:1552 #, fuzzy #| msgid "Parameter Template" msgid "Edit Part Parameter Template" msgstr "Parameter Vorlage" -#: part/views.py:1549 +#: part/views.py:1559 #, fuzzy #| msgid "Parameter Template" msgid "Delete Part Parameter Template" msgstr "Parameter Vorlage" -#: part/views.py:1557 +#: part/views.py:1567 msgid "Create Part Parameter" msgstr "" -#: part/views.py:1607 +#: part/views.py:1617 #, fuzzy #| msgid "Edit attachment" msgid "Edit Part Parameter" msgstr "Anhang bearbeiten" -#: part/views.py:1621 +#: part/views.py:1631 #, fuzzy #| msgid "Delete attachment" msgid "Delete Part Parameter" msgstr "Anhang löschen" -#: part/views.py:1637 +#: part/views.py:1647 #, fuzzy #| msgid "Part category" msgid "Edit Part Category" msgstr "Teile-Kategorie" -#: part/views.py:1672 +#: part/views.py:1682 #, fuzzy #| msgid "Select part category" msgid "Delete Part Category" msgstr "Teilekategorie wählen" -#: part/views.py:1678 +#: part/views.py:1688 #, fuzzy #| msgid "Part category" msgid "Part category was deleted" msgstr "Teile-Kategorie" -#: part/views.py:1686 +#: part/views.py:1696 #, fuzzy #| msgid "Select part category" msgid "Create new part category" msgstr "Teilekategorie wählen" -#: part/views.py:1737 +#: part/views.py:1747 #, fuzzy #| msgid "Created new stock item" msgid "Create BOM item" msgstr "Neues Lagerobjekt erstellt" -#: part/views.py:1803 +#: part/views.py:1813 #, fuzzy #| msgid "Edit Stock Item" msgid "Edit BOM item" msgstr "Lagerobjekt bearbeiten" -#: part/views.py:1851 +#: part/views.py:1861 #, fuzzy #| msgid "Confirm build completion" msgid "Confim BOM item deletion" @@ -1875,7 +1959,7 @@ msgstr "Bewegung der Lagerobjekte bestätigen" msgid "Set the destination as the default location for selected parts" msgstr "Setze das Ziel als Standard-Ziel für ausgewählte Teile" -#: stock/models.py:204 +#: stock/models.py:205 #, python-brace-format msgid "" "A stock item with this serial number already exists for template part {part}" @@ -1883,116 +1967,116 @@ msgstr "" "Ein Teil mit dieser Seriennummer existiert bereits für die Teilevorlage " "{part}" -#: stock/models.py:209 +#: stock/models.py:210 msgid "A stock item with this serial number already exists" msgstr "Ein Teil mit dieser Seriennummer existiert bereits" -#: stock/models.py:228 +#: stock/models.py:229 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "Teile-Typ ('{pf}') muss {pe} sein" -#: stock/models.py:238 stock/models.py:247 +#: stock/models.py:239 stock/models.py:248 msgid "Quantity must be 1 for item with a serial number" msgstr "Anzahl muss für Objekte mit Seriennummer \"1\" sein" -#: stock/models.py:239 +#: stock/models.py:240 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" "Seriennummer kann nicht gesetzt werden wenn die Anzahl größer als \"1\" ist" -#: stock/models.py:255 +#: stock/models.py:256 msgid "Stock item cannot be created for a template Part" msgstr "Lagerobjekt kann nicht für Vorlagen-Teile angelegt werden" -#: stock/models.py:264 +#: stock/models.py:265 msgid "Item cannot belong to itself" msgstr "Teil kann nicht zu sich selbst gehören" -#: stock/models.py:300 +#: stock/models.py:306 msgid "Base part" msgstr "Basis-Teil" -#: stock/models.py:307 +#: stock/models.py:314 msgid "Select a matching supplier part for this stock item" msgstr "Passenden Zulieferer für dieses Lagerobjekt auswählen" -#: stock/models.py:311 +#: stock/models.py:318 msgid "Where is this stock item located?" msgstr "Wo wird dieses Teil normalerweise gelagert?" -#: stock/models.py:315 +#: stock/models.py:322 msgid "Is this item installed in another item?" msgstr "Ist dieses Teil in einem anderen verbaut?" -#: stock/models.py:319 +#: stock/models.py:326 msgid "Item assigned to customer?" msgstr "Ist dieses Objekt einem Kunden zugeteilt?" -#: stock/models.py:322 +#: stock/models.py:329 msgid "Serial number for this item" msgstr "Seriennummer für dieses Teil" -#: stock/models.py:327 +#: stock/models.py:334 msgid "Batch code for this stock item" msgstr "Losnummer für dieses Lagerobjekt" -#: stock/models.py:336 +#: stock/models.py:343 msgid "Build for this stock item" msgstr "Bau für dieses Lagerobjekt" -#: stock/models.py:345 +#: stock/models.py:352 msgid "Purchase order for this stock item" msgstr "Bestellung für dieses Teil" -#: stock/models.py:356 +#: stock/models.py:363 msgid "Delete this Stock Item when stock is depleted" msgstr "Objekt löschen wenn Lagerbestand aufgebraucht" -#: stock/models.py:363 stock/templates/stock/item_notes.html:13 +#: stock/models.py:370 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/item_notes.html:29 msgid "Stock Item Notes" msgstr "Lagerobjekt-Notizen" -#: stock/models.py:437 +#: stock/models.py:460 msgid "Quantity must be integer" msgstr "Anzahl muss eine Ganzzahl sein" -#: stock/models.py:443 +#: stock/models.py:466 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "Anzahl darf nicht die verfügbare Anzahl überschreiten ({n})" -#: stock/models.py:446 stock/models.py:449 +#: stock/models.py:469 stock/models.py:472 msgid "Serial numbers must be a list of integers" msgstr "Seriennummern muss eine Liste von Ganzzahlen sein" -#: stock/models.py:452 +#: stock/models.py:475 msgid "Quantity does not match serial numbers" msgstr "Anzahl stimmt nicht mit den Seriennummern überein" -#: stock/models.py:462 +#: stock/models.py:485 msgid "Serial numbers already exist: " msgstr "Seriennummern existieren bereits:" -#: stock/models.py:483 +#: stock/models.py:507 msgid "Add serial number" msgstr "Seriennummer hinzufügen" -#: stock/models.py:486 +#: stock/models.py:510 #, python-brace-format msgid "Serialized {n} items" msgstr "{n} Teile serialisiert" -#: stock/models.py:752 +#: stock/models.py:810 msgid "Tracking entry title" msgstr "Name des Eintrags-Trackings" -#: stock/models.py:754 +#: stock/models.py:812 msgid "Entry notes" msgstr "Eintrags-Notizen" -#: stock/models.py:756 +#: stock/models.py:814 msgid "Link to external page for further information" msgstr "Link auf externe Seite für weitere Informationen" @@ -2004,7 +2088,7 @@ msgstr "Informationen zum Lagerbestands-Tracking" msgid "Stock Item Details" msgstr "Lagerbestands-Details" -#: stock/templates/stock/item_base.html:53 +#: stock/templates/stock/item_base.html:55 msgid "" "This stock item is serialized - it has a unique serial number and the " "quantity cannot be adjusted." @@ -2012,38 +2096,58 @@ msgstr "" "Dieses Lagerobjekt ist serialisiert. Es hat eine eindeutige Seriennummer und " "die Anzahl kann nicht angepasst werden." -#: stock/templates/stock/item_base.html:57 +#: stock/templates/stock/item_base.html:59 +#, fuzzy +#| msgid "Stock item cannot be created for a template Part" +msgid "This stock item cannot be deleted as it has child items" +msgstr "Lagerobjekt kann nicht für Vorlagen-Teile angelegt werden" + +#: stock/templates/stock/item_base.html:63 msgid "" "This stock item will be automatically deleted when all stock is depleted." msgstr "" "Dieses Lagerobjekt wird automatisch gelöscht wenn der Lagerbestand " "aufgebraucht ist." -#: stock/templates/stock/item_base.html:74 +#: stock/templates/stock/item_base.html:68 +msgid "This stock item was split from " +msgstr "" + +#: stock/templates/stock/item_base.html:85 msgid "Belongs To" msgstr "Gehört zu" -#: stock/templates/stock/item_base.html:79 +#: stock/templates/stock/item_base.html:90 #: stock/templates/stock/stock_adjust.html:17 msgid "Location" msgstr "Standort" -#: stock/templates/stock/item_base.html:85 +#: stock/templates/stock/item_base.html:96 msgid "Serial Number" msgstr "Seriennummer" -#: stock/templates/stock/item_base.html:135 +#: stock/templates/stock/item_base.html:146 msgid "Last Updated" msgstr "Zuletzt aktualisiert" -#: stock/templates/stock/item_base.html:139 +#: stock/templates/stock/item_base.html:150 msgid "Last Stocktake" msgstr "Letzte Inventur" -#: stock/templates/stock/item_base.html:143 +#: stock/templates/stock/item_base.html:154 msgid "No stocktake performed" msgstr "Keine Inventur ausgeführt" +#: stock/templates/stock/item_childs.html:12 +#, fuzzy +#| msgid "Add Stock Items" +msgid "Child Stock Items" +msgstr "Lagerobjekte hinzufügen" + +#: stock/templates/stock/item_childs.html:18 +msgid "This stock item does not have any child items" +msgstr "" + #: stock/templates/stock/location.html:37 msgid "Location Details" msgstr "Standort-Details" @@ -2079,7 +2183,11 @@ msgstr "Lagerobjekt-Standorte" msgid "Stock Item" msgstr "Lagerobjekt" -#: stock/templates/stock/tabs.html:10 +#: stock/templates/stock/tabs.html:8 +msgid "Children" +msgstr "" + +#: stock/templates/stock/tabs.html:13 msgid "Builds" msgstr "Baue" @@ -2289,7 +2397,7 @@ msgstr "" msgid "Statistics" msgstr "Status" -#: templates/stock_table.html:7 +#: templates/stock_table.html:8 #, fuzzy #| msgid "Stock Item" msgid "New Stock Item" diff --git a/InvenTree/locale/en/LC_MESSAGES/django.po b/InvenTree/locale/en/LC_MESSAGES/django.po index 99c6de1be1..9b717613f0 100644 --- a/InvenTree/locale/en/LC_MESSAGES/django.po +++ b/InvenTree/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-02-12 00:31+0000\n" +"POT-Creation-Date: 2020-03-22 08:55+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,7 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: InvenTree/helpers.py:186 order/models.py:161 order/models.py:212 +#: InvenTree/helpers.py:186 order/models.py:163 order/models.py:214 msgid "Invalid quantity provided" msgstr "" @@ -46,6 +46,14 @@ msgstr "" msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" +#: InvenTree/models.py:54 +msgid "Select file to attach" +msgstr "" + +#: InvenTree/models.py:56 +msgid "File comment" +msgstr "" + #: InvenTree/settings.py:270 msgid "English" msgstr "" @@ -153,55 +161,55 @@ msgstr "" msgid "Brief description of the build" msgstr "" -#: build/models.py:63 +#: build/models.py:64 msgid "Select part to build" msgstr "" -#: build/models.py:69 +#: build/models.py:70 msgid "" "Select location to take stock from for this build (leave blank to take from " "any stock location)" msgstr "" -#: build/models.py:75 +#: build/models.py:76 msgid "Number of parts to build" msgstr "" -#: build/models.py:81 +#: build/models.py:82 msgid "Build status" msgstr "" -#: build/models.py:84 +#: build/models.py:85 msgid "Batch code for this build output" msgstr "" -#: build/models.py:96 +#: build/models.py:97 msgid "Link to external URL" msgstr "" -#: build/models.py:98 +#: build/models.py:99 msgid "Extra build notes" msgstr "" -#: build/models.py:383 +#: build/models.py:388 #, python-brace-format msgid "Selected stock item not found in BOM for part '{p}'" msgstr "" -#: build/models.py:386 +#: build/models.py:391 #, python-brace-format msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:404 +#: build/models.py:409 msgid "Build to allocate parts" msgstr "" -#: build/models.py:411 +#: build/models.py:416 msgid "Stock Item to allocate to build" msgstr "" -#: build/models.py:419 +#: build/models.py:424 msgid "Stock quantity to allocate to build" msgstr "" @@ -244,12 +252,13 @@ msgid "Allocate" msgstr "" #: build/templates/build/allocate_view.html:10 -#: company/templates/company/detail_part.html:18 order/views.py:448 +#: company/templates/company/detail_part.html:18 order/views.py:526 msgid "Order Parts" msgstr "" #: build/templates/build/allocate_view.html:18 #: company/templates/company/index.html:54 +#: company/templates/company/supplier_part_base.html:50 #: company/templates/company/supplier_part_detail.html:27 #: order/templates/order/purchase_order_detail.html:26 #: part/templates/part/detail.html:33 @@ -261,6 +270,10 @@ msgstr "" msgid "On Order" msgstr "" +#: build/templates/build/build_output.html:9 +msgid "Build Outputs" +msgstr "" + #: build/templates/build/delete_build_item.html:6 msgid "Are you sure you want to unallocate these parts?" msgstr "" @@ -276,7 +289,7 @@ msgstr "" #: build/templates/build/detail.html:20 #: company/templates/company/supplier_part_pricing.html:27 #: order/templates/order/purchase_order_detail.html:29 -#: stock/templates/stock/item_base.html:90 +#: stock/templates/stock/item_base.html:101 #: stock/templates/stock/stock_adjust.html:18 msgid "Quantity" msgstr "" @@ -291,19 +304,21 @@ msgstr "" #: build/templates/build/detail.html:33 #: order/templates/order/order_base.html:71 -#: stock/templates/stock/item_base.html:147 +#: stock/templates/stock/item_base.html:158 msgid "Status" msgstr "" -#: build/templates/build/detail.html:37 stock/templates/stock/item_base.html:96 +#: build/templates/build/detail.html:37 +#: stock/templates/stock/item_base.html:107 msgid "Batch" msgstr "" #: build/templates/build/detail.html:42 #: company/templates/company/detail_part.html:90 +#: company/templates/company/supplier_part_base.html:47 #: company/templates/company/supplier_part_detail.html:24 #: part/templates/part/detail.html:50 part/templates/part/part_base.html:81 -#: stock/templates/stock/item_base.html:120 +#: stock/templates/stock/item_base.html:131 msgid "URL" msgstr "" @@ -344,19 +359,22 @@ msgstr "" msgid "Edit notes" msgstr "" -#: build/templates/build/tabs.html:5 -#: company/templates/company/supplier_part_tabs.html:5 -#: company/templates/company/tabs.html:5 part/templates/part/tabs.html:6 +#: build/templates/build/tabs.html:5 company/templates/company/tabs.html:5 +#: part/templates/part/tabs.html:6 msgid "Details" msgstr "" -#: build/templates/build/tabs.html:8 company/models.py:248 -#: company/templates/company/tabs.html:26 order/templates/order/tabs.html:8 -#: part/templates/part/tabs.html:58 stock/templates/stock/tabs.html:14 +#: build/templates/build/tabs.html:8 +msgid "Outputs" +msgstr "" + +#: build/templates/build/tabs.html:11 company/models.py:248 +#: company/templates/company/tabs.html:26 order/templates/order/tabs.html:11 +#: part/templates/part/tabs.html:58 stock/templates/stock/tabs.html:17 msgid "Notes" msgstr "" -#: build/templates/build/tabs.html:11 +#: build/templates/build/tabs.html:14 msgid "Assign Parts" msgstr "" @@ -562,6 +580,7 @@ msgid "Supplier stock keeping unit" msgstr "" #: company/models.py:240 company/templates/company/detail_part.html:81 +#: company/templates/company/supplier_part_base.html:53 #: company/templates/company/supplier_part_detail.html:30 msgid "Manufacturer" msgstr "" @@ -586,7 +605,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/templates/company/company_base.html:7 order/models.py:128 +#: company/templates/company/company_base.html:7 order/models.py:130 msgid "Company" msgstr "" @@ -616,15 +635,16 @@ msgid "Company Details" msgstr "" #: company/templates/company/detail.html:13 -#: stock/templates/stock/item_base.html:114 +#: stock/templates/stock/item_base.html:125 msgid "Customer" msgstr "" #: company/templates/company/detail.html:17 #: company/templates/company/index.html:46 +#: company/templates/company/supplier_part_base.html:44 #: company/templates/company/supplier_part_detail.html:21 #: order/templates/order/order_base.html:67 -#: stock/templates/stock/item_base.html:126 +#: stock/templates/stock/item_base.html:137 msgid "Supplier" msgstr "" @@ -647,6 +667,7 @@ msgid "Delete Parts" msgstr "" #: company/templates/company/detail_part.html:73 +#: company/templates/company/supplier_part_base.html:45 #: company/templates/company/supplier_part_detail.html:22 msgid "SKU" msgstr "" @@ -699,22 +720,26 @@ msgstr "" #: company/templates/company/supplier_part_base.html:6 #: company/templates/company/supplier_part_base.html:13 -#: stock/templates/stock/item_base.html:130 +#: stock/templates/stock/item_base.html:141 msgid "Supplier Part" msgstr "" +#: company/templates/company/supplier_part_base.html:34 #: company/templates/company/supplier_part_detail.html:11 msgid "Supplier Part Details" msgstr "" +#: company/templates/company/supplier_part_base.html:37 #: company/templates/company/supplier_part_detail.html:14 msgid "Internal Part" msgstr "" +#: company/templates/company/supplier_part_base.html:54 #: company/templates/company/supplier_part_detail.html:31 msgid "MPN" msgstr "" +#: company/templates/company/supplier_part_base.html:57 #: company/templates/company/supplier_part_detail.html:34 #: order/templates/order/purchase_order_detail.html:33 msgid "Note" @@ -766,17 +791,17 @@ msgstr "" msgid "Create New Location" msgstr "" -#: company/templates/company/supplier_part_tabs.html:8 +#: company/templates/company/supplier_part_tabs.html:5 msgid "Pricing" msgstr "" -#: company/templates/company/supplier_part_tabs.html:11 +#: company/templates/company/supplier_part_tabs.html:8 #: company/templates/company/tabs.html:12 part/templates/part/tabs.html:17 #: templates/navbar.html:11 msgid "Stock" msgstr "" -#: company/templates/company/supplier_part_tabs.html:14 +#: company/templates/company/supplier_part_tabs.html:11 #: templates/navbar.html:14 msgid "Orders" msgstr "" @@ -857,56 +882,56 @@ msgstr "" msgid "Receive parts to this location" msgstr "" -#: order/models.py:65 +#: order/models.py:67 msgid "Order reference" msgstr "" -#: order/models.py:67 +#: order/models.py:69 msgid "Order description" msgstr "" -#: order/models.py:69 +#: order/models.py:71 msgid "Link to external page" msgstr "" -#: order/models.py:86 +#: order/models.py:88 msgid "Order notes" msgstr "" -#: order/models.py:159 order/models.py:210 part/views.py:1109 -#: stock/models.py:440 +#: order/models.py:161 order/models.py:212 part/views.py:1119 +#: stock/models.py:463 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:164 +#: order/models.py:166 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:205 +#: order/models.py:207 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:254 +#: order/models.py:267 msgid "Item quantity" msgstr "" -#: order/models.py:256 +#: order/models.py:269 msgid "Line item reference" msgstr "" -#: order/models.py:258 +#: order/models.py:271 msgid "Line item notes" msgstr "" -#: order/models.py:284 stock/templates/stock/item_base.html:108 +#: order/models.py:297 stock/templates/stock/item_base.html:119 msgid "Purchase Order" msgstr "" -#: order/models.py:293 +#: order/models.py:306 msgid "Supplier part" msgstr "" -#: order/models.py:296 +#: order/models.py:309 msgid "Number of items received" msgstr "" @@ -928,7 +953,41 @@ msgstr "" msgid "Order Notes" msgstr "" -#: order/templates/order/purchase_order_detail.html:15 order/views.py:747 +#: order/templates/order/po_attachments.html:11 +msgid "Purchase Order Attachments" +msgstr "" + +#: order/templates/order/po_attachments.html:17 +#: part/templates/part/attachments.html:14 +msgid "Add Attachment" +msgstr "" + +#: order/templates/order/po_attachments.html:24 +#: part/templates/part/attachments.html:22 +msgid "File" +msgstr "" + +#: order/templates/order/po_attachments.html:25 +#: part/templates/part/attachments.html:23 +msgid "Comment" +msgstr "" + +#: order/templates/order/po_attachments.html:36 +#: part/templates/part/attachments.html:34 part/views.py:119 +msgid "Edit attachment" +msgstr "" + +#: order/templates/order/po_attachments.html:39 +#: part/templates/part/attachments.html:37 +msgid "Delete attachment" +msgstr "" + +#: order/templates/order/po_delete.html:5 +#: part/templates/part/attachment_delete.html:5 +msgid "Are you sure you want to delete this attachment?" +msgstr "" + +#: order/templates/order/purchase_order_detail.html:15 order/views.py:825 msgid "Add Line Item" msgstr "" @@ -952,79 +1011,107 @@ msgstr "" msgid "Items" msgstr "" -#: order/views.py:99 +#: order/templates/order/tabs.html:8 part/templates/part/tabs.html:55 +msgid "Attachments" +msgstr "" + +#: order/views.py:80 +msgid "Add Purchase Order Attachment" +msgstr "" + +#: order/views.py:85 part/views.py:80 +msgid "Added attachment" +msgstr "" + +#: order/views.py:121 +msgid "Edit Attachment" +msgstr "" + +#: order/views.py:125 +msgid "Attachment updated" +msgstr "" + +#: order/views.py:141 +msgid "Delete Attachment" +msgstr "" + +#: order/views.py:147 +msgid "Deleted attachment" +msgstr "" + +#: order/views.py:177 msgid "Create Purchase Order" msgstr "" -#: order/views.py:129 +#: order/views.py:207 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:149 +#: order/views.py:227 msgid "Cancel Order" msgstr "" -#: order/views.py:164 +#: order/views.py:242 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:182 +#: order/views.py:260 msgid "Issue Order" msgstr "" -#: order/views.py:197 +#: order/views.py:275 msgid "Confirm order placement" msgstr "" -#: order/views.py:218 +#: order/views.py:296 msgid "Complete Order" msgstr "" -#: order/views.py:284 +#: order/views.py:362 msgid "Receive Parts" msgstr "" -#: order/views.py:351 +#: order/views.py:429 msgid "Items received" msgstr "" -#: order/views.py:365 +#: order/views.py:443 msgid "No destination set" msgstr "" -#: order/views.py:396 +#: order/views.py:474 msgid "Error converting quantity to number" msgstr "" -#: order/views.py:402 +#: order/views.py:480 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:408 +#: order/views.py:486 msgid "No lines specified" msgstr "" -#: order/views.py:767 +#: order/views.py:845 msgid "Invalid Purchase Order" msgstr "" -#: order/views.py:775 +#: order/views.py:853 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:780 +#: order/views.py:858 msgid "Invalid SupplierPart selection" msgstr "" -#: order/views.py:862 +#: order/views.py:940 msgid "Edit Line Item" msgstr "" -#: order/views.py:878 +#: order/views.py:956 msgid "Delete Line Item" msgstr "" -#: order/views.py:883 +#: order/views.py:961 msgid "Deleted line item" msgstr "" @@ -1085,147 +1172,139 @@ msgstr "" msgid "Select currency for price calculation" msgstr "" -#: part/models.py:59 +#: part/models.py:60 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:62 +#: part/models.py:63 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:323 +#: part/models.py:327 msgid "Part must be unique for name, IPN and revision" msgstr "" -#: part/models.py:337 +#: part/models.py:341 msgid "Part cannot be a template part if it is a variant of another part" msgstr "" -#: part/models.py:338 +#: part/models.py:342 msgid "Part cannot be a variant of another part if it is already a template" msgstr "" -#: part/models.py:342 part/templates/part/detail.html:17 +#: part/models.py:346 part/templates/part/detail.html:17 msgid "Part name" msgstr "" -#: part/models.py:346 +#: part/models.py:350 msgid "Is this part a template part?" msgstr "" -#: part/models.py:355 +#: part/models.py:359 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:357 +#: part/models.py:361 msgid "Part description" msgstr "" -#: part/models.py:359 +#: part/models.py:363 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:364 +#: part/models.py:368 msgid "Part category" msgstr "" -#: part/models.py:366 +#: part/models.py:370 msgid "Internal Part Number" msgstr "" -#: part/models.py:368 +#: part/models.py:372 msgid "Part revision or version number" msgstr "" -#: part/models.py:370 +#: part/models.py:374 msgid "Link to extenal URL" msgstr "" -#: part/models.py:376 +#: part/models.py:380 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:420 +#: part/models.py:424 msgid "Default supplier part" msgstr "" -#: part/models.py:423 +#: part/models.py:427 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:425 +#: part/models.py:429 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:427 +#: part/models.py:431 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:429 +#: part/models.py:433 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:431 +#: part/models.py:435 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:433 +#: part/models.py:437 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:435 +#: part/models.py:439 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:437 +#: part/models.py:441 msgid "Is this part active?" msgstr "" -#: part/models.py:439 +#: part/models.py:443 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:441 +#: part/models.py:445 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:443 +#: part/models.py:447 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:948 -msgid "Select file to attach" -msgstr "" - -#: part/models.py:950 -msgid "File comment" -msgstr "" - -#: part/models.py:1005 +#: part/models.py:1004 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:1010 +#: part/models.py:1009 msgid "Parameter Name" msgstr "" -#: part/models.py:1012 +#: part/models.py:1011 msgid "Parameter Units" msgstr "" -#: part/models.py:1038 +#: part/models.py:1037 msgid "Parent Part" msgstr "" -#: part/models.py:1040 +#: part/models.py:1039 msgid "Parameter Template" msgstr "" -#: part/models.py:1042 +#: part/models.py:1041 msgid "Parameter Value" msgstr "" -#: part/models.py:1066 +#: part/models.py:1065 msgid "Select parent part" msgstr "" @@ -1233,31 +1312,31 @@ msgstr "" msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:1080 +#: part/models.py:1081 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:1083 +#: part/models.py:1084 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:1086 +#: part/models.py:1087 msgid "BOM item reference" msgstr "" -#: part/models.py:1089 +#: part/models.py:1090 msgid "BOM item notes" msgstr "" -#: part/models.py:1091 +#: part/models.py:1092 msgid "BOM line checksum" msgstr "" -#: part/models.py:1154 +#: part/models.py:1155 msgid "Part cannot be added to its own Bill of Materials" msgstr "" -#: part/models.py:1161 +#: part/models.py:1162 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" @@ -1266,26 +1345,6 @@ msgstr "" msgid "Part Attachments" msgstr "" -#: part/templates/part/attachments.html:14 -msgid "Add Attachment" -msgstr "" - -#: part/templates/part/attachments.html:22 -msgid "File" -msgstr "" - -#: part/templates/part/attachments.html:23 -msgid "Comment" -msgstr "" - -#: part/templates/part/attachments.html:34 part/views.py:118 -msgid "Edit attachment" -msgstr "" - -#: part/templates/part/attachments.html:37 -msgid "Delete attachment" -msgstr "" - #: part/templates/part/category.html:13 part/templates/part/category.html:69 #: templates/stats.html:14 msgid "Part Categories" @@ -1355,71 +1414,83 @@ msgstr "" msgid "Minimum Stock" msgstr "" -#: part/templates/part/detail.html:91 +#: part/templates/part/detail.html:87 +msgid "Creation Date" +msgstr "" + +#: part/templates/part/detail.html:92 +msgid "Created By" +msgstr "" + +#: part/templates/part/detail.html:98 +msgid "Responsible User" +msgstr "" + +#: part/templates/part/detail.html:107 msgid "Virtual" msgstr "" -#: part/templates/part/detail.html:94 +#: part/templates/part/detail.html:110 msgid "Part is virtual (not a physical part)" msgstr "" -#: part/templates/part/detail.html:96 +#: part/templates/part/detail.html:112 msgid "Part is not a virtual part" msgstr "" -#: part/templates/part/detail.html:100 +#: part/templates/part/detail.html:116 msgid "Assembly" msgstr "" -#: part/templates/part/detail.html:103 +#: part/templates/part/detail.html:119 msgid "Part can be assembled from other parts" msgstr "" -#: part/templates/part/detail.html:105 +#: part/templates/part/detail.html:121 msgid "Part cannot be assembled from other parts" msgstr "" -#: part/templates/part/detail.html:109 +#: part/templates/part/detail.html:125 msgid "Component" msgstr "" -#: part/templates/part/detail.html:112 +#: part/templates/part/detail.html:128 msgid "Part can be used in assemblies" msgstr "" -#: part/templates/part/detail.html:114 +#: part/templates/part/detail.html:130 msgid "Part cannot be used in assemblies" msgstr "" -#: part/templates/part/detail.html:118 +#: part/templates/part/detail.html:134 msgid "Trackable" msgstr "" -#: part/templates/part/detail.html:121 +#: part/templates/part/detail.html:137 msgid "Part stock is tracked by serial number" msgstr "" -#: part/templates/part/detail.html:123 +#: part/templates/part/detail.html:139 msgid "Part stock is not tracked by serial number" msgstr "" -#: part/templates/part/detail.html:127 +#: part/templates/part/detail.html:143 msgid "Purchaseable" msgstr "" -#: part/templates/part/detail.html:130 part/templates/part/detail.html:132 +#: part/templates/part/detail.html:146 part/templates/part/detail.html:148 msgid "Part can be purchased from external suppliers" msgstr "" -#: part/templates/part/detail.html:137 +#: part/templates/part/detail.html:153 msgid "Sellable" msgstr "" -#: part/templates/part/detail.html:140 +#: part/templates/part/detail.html:156 msgid "Part can be sold to customers" msgstr "" -#: part/templates/part/detail.html:142 +#: part/templates/part/detail.html:158 msgid "Part cannot be sold to customers" msgstr "" @@ -1487,7 +1558,7 @@ msgstr "" msgid "BOM" msgstr "" -#: part/templates/part/tabs.html:28 stock/templates/stock/item_base.html:102 +#: part/templates/part/tabs.html:28 stock/templates/stock/item_base.html:113 #: templates/navbar.html:12 msgid "Build" msgstr "" @@ -1504,176 +1575,168 @@ msgstr "" msgid "Tracking" msgstr "" -#: part/templates/part/tabs.html:55 -msgid "Attachments" -msgstr "" - #: part/views.py:75 msgid "Add part attachment" msgstr "" -#: part/views.py:80 -msgid "Added attachment" -msgstr "" - -#: part/views.py:122 +#: part/views.py:123 msgid "Part attachment updated" msgstr "" -#: part/views.py:137 +#: part/views.py:138 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:143 +#: part/views.py:144 msgid "Deleted part attachment" msgstr "" -#: part/views.py:151 +#: part/views.py:152 msgid "Set Part Category" msgstr "" -#: part/views.py:199 +#: part/views.py:200 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:234 +#: part/views.py:235 msgid "Create Variant" msgstr "" -#: part/views.py:304 +#: part/views.py:305 msgid "Duplicate Part" msgstr "" -#: part/views.py:309 +#: part/views.py:310 msgid "Copied part" msgstr "" -#: part/views.py:417 +#: part/views.py:421 msgid "Create new part" msgstr "" -#: part/views.py:422 +#: part/views.py:426 msgid "Created new part" msgstr "" -#: part/views.py:595 +#: part/views.py:605 msgid "Part QR Code" msgstr "" -#: part/views.py:612 +#: part/views.py:622 msgid "Upload Part Image" msgstr "" -#: part/views.py:617 part/views.py:652 +#: part/views.py:627 part/views.py:662 msgid "Updated part image" msgstr "" -#: part/views.py:626 +#: part/views.py:636 msgid "Select Part Image" msgstr "" -#: part/views.py:655 +#: part/views.py:665 msgid "Part image not found" msgstr "" -#: part/views.py:666 +#: part/views.py:676 msgid "Edit Part Properties" msgstr "" -#: part/views.py:688 +#: part/views.py:698 msgid "Validate BOM" msgstr "" -#: part/views.py:850 +#: part/views.py:860 msgid "No BOM file provided" msgstr "" -#: part/views.py:1111 +#: part/views.py:1121 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1135 part/views.py:1138 +#: part/views.py:1145 part/views.py:1148 msgid "Select valid part" msgstr "" -#: part/views.py:1144 +#: part/views.py:1154 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1172 +#: part/views.py:1182 msgid "Select a part" msgstr "" -#: part/views.py:1176 +#: part/views.py:1186 msgid "Specify quantity" msgstr "" -#: part/views.py:1356 +#: part/views.py:1366 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1396 +#: part/views.py:1406 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1403 +#: part/views.py:1413 msgid "Part was deleted" msgstr "" -#: part/views.py:1412 +#: part/views.py:1422 msgid "Part Pricing" msgstr "" -#: part/views.py:1534 +#: part/views.py:1544 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1542 +#: part/views.py:1552 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1549 +#: part/views.py:1559 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1557 +#: part/views.py:1567 msgid "Create Part Parameter" msgstr "" -#: part/views.py:1607 +#: part/views.py:1617 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:1621 +#: part/views.py:1631 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:1637 +#: part/views.py:1647 msgid "Edit Part Category" msgstr "" -#: part/views.py:1672 +#: part/views.py:1682 msgid "Delete Part Category" msgstr "" -#: part/views.py:1678 +#: part/views.py:1688 msgid "Part category was deleted" msgstr "" -#: part/views.py:1686 +#: part/views.py:1696 msgid "Create new part category" msgstr "" -#: part/views.py:1737 +#: part/views.py:1747 msgid "Create BOM item" msgstr "" -#: part/views.py:1803 +#: part/views.py:1813 msgid "Edit BOM item" msgstr "" -#: part/views.py:1851 +#: part/views.py:1861 msgid "Confim BOM item deletion" msgstr "" @@ -1693,121 +1756,121 @@ msgstr "" msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:204 +#: stock/models.py:205 #, python-brace-format msgid "" "A stock item with this serial number already exists for template part {part}" msgstr "" -#: stock/models.py:209 +#: stock/models.py:210 msgid "A stock item with this serial number already exists" msgstr "" -#: stock/models.py:228 +#: stock/models.py:229 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:238 stock/models.py:247 +#: stock/models.py:239 stock/models.py:248 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:239 +#: stock/models.py:240 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:255 +#: stock/models.py:256 msgid "Stock item cannot be created for a template Part" msgstr "" -#: stock/models.py:264 +#: stock/models.py:265 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:300 +#: stock/models.py:306 msgid "Base part" msgstr "" -#: stock/models.py:307 +#: stock/models.py:314 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:311 +#: stock/models.py:318 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:315 +#: stock/models.py:322 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:319 +#: stock/models.py:326 msgid "Item assigned to customer?" msgstr "" -#: stock/models.py:322 +#: stock/models.py:329 msgid "Serial number for this item" msgstr "" -#: stock/models.py:327 +#: stock/models.py:334 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:336 +#: stock/models.py:343 msgid "Build for this stock item" msgstr "" -#: stock/models.py:345 +#: stock/models.py:352 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:356 +#: stock/models.py:363 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:363 stock/templates/stock/item_notes.html:13 +#: stock/models.py:370 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/item_notes.html:29 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:437 +#: stock/models.py:460 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:443 +#: stock/models.py:466 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:446 stock/models.py:449 +#: stock/models.py:469 stock/models.py:472 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:452 +#: stock/models.py:475 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:462 +#: stock/models.py:485 msgid "Serial numbers already exist: " msgstr "" -#: stock/models.py:483 +#: stock/models.py:507 msgid "Add serial number" msgstr "" -#: stock/models.py:486 +#: stock/models.py:510 #, python-brace-format msgid "Serialized {n} items" msgstr "" -#: stock/models.py:752 +#: stock/models.py:810 msgid "Tracking entry title" msgstr "" -#: stock/models.py:754 +#: stock/models.py:812 msgid "Entry notes" msgstr "" -#: stock/models.py:756 +#: stock/models.py:814 msgid "Link to external page for further information" msgstr "" @@ -1819,42 +1882,58 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:53 +#: stock/templates/stock/item_base.html:55 msgid "" "This stock item is serialized - it has a unique serial number and the " "quantity cannot be adjusted." msgstr "" -#: stock/templates/stock/item_base.html:57 +#: stock/templates/stock/item_base.html:59 +msgid "This stock item cannot be deleted as it has child items" +msgstr "" + +#: stock/templates/stock/item_base.html:63 msgid "" "This stock item will be automatically deleted when all stock is depleted." msgstr "" -#: stock/templates/stock/item_base.html:74 +#: stock/templates/stock/item_base.html:68 +msgid "This stock item was split from " +msgstr "" + +#: stock/templates/stock/item_base.html:85 msgid "Belongs To" msgstr "" -#: stock/templates/stock/item_base.html:79 +#: stock/templates/stock/item_base.html:90 #: stock/templates/stock/stock_adjust.html:17 msgid "Location" msgstr "" -#: stock/templates/stock/item_base.html:85 +#: stock/templates/stock/item_base.html:96 msgid "Serial Number" msgstr "" -#: stock/templates/stock/item_base.html:135 +#: stock/templates/stock/item_base.html:146 msgid "Last Updated" msgstr "" -#: stock/templates/stock/item_base.html:139 +#: stock/templates/stock/item_base.html:150 msgid "Last Stocktake" msgstr "" -#: stock/templates/stock/item_base.html:143 +#: stock/templates/stock/item_base.html:154 msgid "No stocktake performed" msgstr "" +#: stock/templates/stock/item_childs.html:12 +msgid "Child Stock Items" +msgstr "" + +#: stock/templates/stock/item_childs.html:18 +msgid "This stock item does not have any child items" +msgstr "" + #: stock/templates/stock/location.html:37 msgid "Location Details" msgstr "" @@ -1890,7 +1969,11 @@ msgstr "" msgid "Stock Item" msgstr "" -#: stock/templates/stock/tabs.html:10 +#: stock/templates/stock/tabs.html:8 +msgid "Children" +msgstr "" + +#: stock/templates/stock/tabs.html:13 msgid "Builds" msgstr "" @@ -2093,7 +2176,7 @@ msgstr "" msgid "Statistics" msgstr "" -#: templates/stock_table.html:7 +#: templates/stock_table.html:8 msgid "New Stock Item" msgstr "" diff --git a/InvenTree/locale/es/LC_MESSAGES/django.po b/InvenTree/locale/es/LC_MESSAGES/django.po index 99c6de1be1..9b717613f0 100644 --- a/InvenTree/locale/es/LC_MESSAGES/django.po +++ b/InvenTree/locale/es/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2020-02-12 00:31+0000\n" +"POT-Creation-Date: 2020-03-22 08:55+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,7 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: InvenTree/helpers.py:186 order/models.py:161 order/models.py:212 +#: InvenTree/helpers.py:186 order/models.py:163 order/models.py:214 msgid "Invalid quantity provided" msgstr "" @@ -46,6 +46,14 @@ msgstr "" msgid "Number of unique serial number ({s}) must match quantity ({q})" msgstr "" +#: InvenTree/models.py:54 +msgid "Select file to attach" +msgstr "" + +#: InvenTree/models.py:56 +msgid "File comment" +msgstr "" + #: InvenTree/settings.py:270 msgid "English" msgstr "" @@ -153,55 +161,55 @@ msgstr "" msgid "Brief description of the build" msgstr "" -#: build/models.py:63 +#: build/models.py:64 msgid "Select part to build" msgstr "" -#: build/models.py:69 +#: build/models.py:70 msgid "" "Select location to take stock from for this build (leave blank to take from " "any stock location)" msgstr "" -#: build/models.py:75 +#: build/models.py:76 msgid "Number of parts to build" msgstr "" -#: build/models.py:81 +#: build/models.py:82 msgid "Build status" msgstr "" -#: build/models.py:84 +#: build/models.py:85 msgid "Batch code for this build output" msgstr "" -#: build/models.py:96 +#: build/models.py:97 msgid "Link to external URL" msgstr "" -#: build/models.py:98 +#: build/models.py:99 msgid "Extra build notes" msgstr "" -#: build/models.py:383 +#: build/models.py:388 #, python-brace-format msgid "Selected stock item not found in BOM for part '{p}'" msgstr "" -#: build/models.py:386 +#: build/models.py:391 #, python-brace-format msgid "Allocated quantity ({n}) must not exceed available quantity ({q})" msgstr "" -#: build/models.py:404 +#: build/models.py:409 msgid "Build to allocate parts" msgstr "" -#: build/models.py:411 +#: build/models.py:416 msgid "Stock Item to allocate to build" msgstr "" -#: build/models.py:419 +#: build/models.py:424 msgid "Stock quantity to allocate to build" msgstr "" @@ -244,12 +252,13 @@ msgid "Allocate" msgstr "" #: build/templates/build/allocate_view.html:10 -#: company/templates/company/detail_part.html:18 order/views.py:448 +#: company/templates/company/detail_part.html:18 order/views.py:526 msgid "Order Parts" msgstr "" #: build/templates/build/allocate_view.html:18 #: company/templates/company/index.html:54 +#: company/templates/company/supplier_part_base.html:50 #: company/templates/company/supplier_part_detail.html:27 #: order/templates/order/purchase_order_detail.html:26 #: part/templates/part/detail.html:33 @@ -261,6 +270,10 @@ msgstr "" msgid "On Order" msgstr "" +#: build/templates/build/build_output.html:9 +msgid "Build Outputs" +msgstr "" + #: build/templates/build/delete_build_item.html:6 msgid "Are you sure you want to unallocate these parts?" msgstr "" @@ -276,7 +289,7 @@ msgstr "" #: build/templates/build/detail.html:20 #: company/templates/company/supplier_part_pricing.html:27 #: order/templates/order/purchase_order_detail.html:29 -#: stock/templates/stock/item_base.html:90 +#: stock/templates/stock/item_base.html:101 #: stock/templates/stock/stock_adjust.html:18 msgid "Quantity" msgstr "" @@ -291,19 +304,21 @@ msgstr "" #: build/templates/build/detail.html:33 #: order/templates/order/order_base.html:71 -#: stock/templates/stock/item_base.html:147 +#: stock/templates/stock/item_base.html:158 msgid "Status" msgstr "" -#: build/templates/build/detail.html:37 stock/templates/stock/item_base.html:96 +#: build/templates/build/detail.html:37 +#: stock/templates/stock/item_base.html:107 msgid "Batch" msgstr "" #: build/templates/build/detail.html:42 #: company/templates/company/detail_part.html:90 +#: company/templates/company/supplier_part_base.html:47 #: company/templates/company/supplier_part_detail.html:24 #: part/templates/part/detail.html:50 part/templates/part/part_base.html:81 -#: stock/templates/stock/item_base.html:120 +#: stock/templates/stock/item_base.html:131 msgid "URL" msgstr "" @@ -344,19 +359,22 @@ msgstr "" msgid "Edit notes" msgstr "" -#: build/templates/build/tabs.html:5 -#: company/templates/company/supplier_part_tabs.html:5 -#: company/templates/company/tabs.html:5 part/templates/part/tabs.html:6 +#: build/templates/build/tabs.html:5 company/templates/company/tabs.html:5 +#: part/templates/part/tabs.html:6 msgid "Details" msgstr "" -#: build/templates/build/tabs.html:8 company/models.py:248 -#: company/templates/company/tabs.html:26 order/templates/order/tabs.html:8 -#: part/templates/part/tabs.html:58 stock/templates/stock/tabs.html:14 +#: build/templates/build/tabs.html:8 +msgid "Outputs" +msgstr "" + +#: build/templates/build/tabs.html:11 company/models.py:248 +#: company/templates/company/tabs.html:26 order/templates/order/tabs.html:11 +#: part/templates/part/tabs.html:58 stock/templates/stock/tabs.html:17 msgid "Notes" msgstr "" -#: build/templates/build/tabs.html:11 +#: build/templates/build/tabs.html:14 msgid "Assign Parts" msgstr "" @@ -562,6 +580,7 @@ msgid "Supplier stock keeping unit" msgstr "" #: company/models.py:240 company/templates/company/detail_part.html:81 +#: company/templates/company/supplier_part_base.html:53 #: company/templates/company/supplier_part_detail.html:30 msgid "Manufacturer" msgstr "" @@ -586,7 +605,7 @@ msgstr "" msgid "Part packaging" msgstr "" -#: company/templates/company/company_base.html:7 order/models.py:128 +#: company/templates/company/company_base.html:7 order/models.py:130 msgid "Company" msgstr "" @@ -616,15 +635,16 @@ msgid "Company Details" msgstr "" #: company/templates/company/detail.html:13 -#: stock/templates/stock/item_base.html:114 +#: stock/templates/stock/item_base.html:125 msgid "Customer" msgstr "" #: company/templates/company/detail.html:17 #: company/templates/company/index.html:46 +#: company/templates/company/supplier_part_base.html:44 #: company/templates/company/supplier_part_detail.html:21 #: order/templates/order/order_base.html:67 -#: stock/templates/stock/item_base.html:126 +#: stock/templates/stock/item_base.html:137 msgid "Supplier" msgstr "" @@ -647,6 +667,7 @@ msgid "Delete Parts" msgstr "" #: company/templates/company/detail_part.html:73 +#: company/templates/company/supplier_part_base.html:45 #: company/templates/company/supplier_part_detail.html:22 msgid "SKU" msgstr "" @@ -699,22 +720,26 @@ msgstr "" #: company/templates/company/supplier_part_base.html:6 #: company/templates/company/supplier_part_base.html:13 -#: stock/templates/stock/item_base.html:130 +#: stock/templates/stock/item_base.html:141 msgid "Supplier Part" msgstr "" +#: company/templates/company/supplier_part_base.html:34 #: company/templates/company/supplier_part_detail.html:11 msgid "Supplier Part Details" msgstr "" +#: company/templates/company/supplier_part_base.html:37 #: company/templates/company/supplier_part_detail.html:14 msgid "Internal Part" msgstr "" +#: company/templates/company/supplier_part_base.html:54 #: company/templates/company/supplier_part_detail.html:31 msgid "MPN" msgstr "" +#: company/templates/company/supplier_part_base.html:57 #: company/templates/company/supplier_part_detail.html:34 #: order/templates/order/purchase_order_detail.html:33 msgid "Note" @@ -766,17 +791,17 @@ msgstr "" msgid "Create New Location" msgstr "" -#: company/templates/company/supplier_part_tabs.html:8 +#: company/templates/company/supplier_part_tabs.html:5 msgid "Pricing" msgstr "" -#: company/templates/company/supplier_part_tabs.html:11 +#: company/templates/company/supplier_part_tabs.html:8 #: company/templates/company/tabs.html:12 part/templates/part/tabs.html:17 #: templates/navbar.html:11 msgid "Stock" msgstr "" -#: company/templates/company/supplier_part_tabs.html:14 +#: company/templates/company/supplier_part_tabs.html:11 #: templates/navbar.html:14 msgid "Orders" msgstr "" @@ -857,56 +882,56 @@ msgstr "" msgid "Receive parts to this location" msgstr "" -#: order/models.py:65 +#: order/models.py:67 msgid "Order reference" msgstr "" -#: order/models.py:67 +#: order/models.py:69 msgid "Order description" msgstr "" -#: order/models.py:69 +#: order/models.py:71 msgid "Link to external page" msgstr "" -#: order/models.py:86 +#: order/models.py:88 msgid "Order notes" msgstr "" -#: order/models.py:159 order/models.py:210 part/views.py:1109 -#: stock/models.py:440 +#: order/models.py:161 order/models.py:212 part/views.py:1119 +#: stock/models.py:463 msgid "Quantity must be greater than zero" msgstr "" -#: order/models.py:164 +#: order/models.py:166 msgid "Part supplier must match PO supplier" msgstr "" -#: order/models.py:205 +#: order/models.py:207 msgid "Lines can only be received against an order marked as 'Placed'" msgstr "" -#: order/models.py:254 +#: order/models.py:267 msgid "Item quantity" msgstr "" -#: order/models.py:256 +#: order/models.py:269 msgid "Line item reference" msgstr "" -#: order/models.py:258 +#: order/models.py:271 msgid "Line item notes" msgstr "" -#: order/models.py:284 stock/templates/stock/item_base.html:108 +#: order/models.py:297 stock/templates/stock/item_base.html:119 msgid "Purchase Order" msgstr "" -#: order/models.py:293 +#: order/models.py:306 msgid "Supplier part" msgstr "" -#: order/models.py:296 +#: order/models.py:309 msgid "Number of items received" msgstr "" @@ -928,7 +953,41 @@ msgstr "" msgid "Order Notes" msgstr "" -#: order/templates/order/purchase_order_detail.html:15 order/views.py:747 +#: order/templates/order/po_attachments.html:11 +msgid "Purchase Order Attachments" +msgstr "" + +#: order/templates/order/po_attachments.html:17 +#: part/templates/part/attachments.html:14 +msgid "Add Attachment" +msgstr "" + +#: order/templates/order/po_attachments.html:24 +#: part/templates/part/attachments.html:22 +msgid "File" +msgstr "" + +#: order/templates/order/po_attachments.html:25 +#: part/templates/part/attachments.html:23 +msgid "Comment" +msgstr "" + +#: order/templates/order/po_attachments.html:36 +#: part/templates/part/attachments.html:34 part/views.py:119 +msgid "Edit attachment" +msgstr "" + +#: order/templates/order/po_attachments.html:39 +#: part/templates/part/attachments.html:37 +msgid "Delete attachment" +msgstr "" + +#: order/templates/order/po_delete.html:5 +#: part/templates/part/attachment_delete.html:5 +msgid "Are you sure you want to delete this attachment?" +msgstr "" + +#: order/templates/order/purchase_order_detail.html:15 order/views.py:825 msgid "Add Line Item" msgstr "" @@ -952,79 +1011,107 @@ msgstr "" msgid "Items" msgstr "" -#: order/views.py:99 +#: order/templates/order/tabs.html:8 part/templates/part/tabs.html:55 +msgid "Attachments" +msgstr "" + +#: order/views.py:80 +msgid "Add Purchase Order Attachment" +msgstr "" + +#: order/views.py:85 part/views.py:80 +msgid "Added attachment" +msgstr "" + +#: order/views.py:121 +msgid "Edit Attachment" +msgstr "" + +#: order/views.py:125 +msgid "Attachment updated" +msgstr "" + +#: order/views.py:141 +msgid "Delete Attachment" +msgstr "" + +#: order/views.py:147 +msgid "Deleted attachment" +msgstr "" + +#: order/views.py:177 msgid "Create Purchase Order" msgstr "" -#: order/views.py:129 +#: order/views.py:207 msgid "Edit Purchase Order" msgstr "" -#: order/views.py:149 +#: order/views.py:227 msgid "Cancel Order" msgstr "" -#: order/views.py:164 +#: order/views.py:242 msgid "Confirm order cancellation" msgstr "" -#: order/views.py:182 +#: order/views.py:260 msgid "Issue Order" msgstr "" -#: order/views.py:197 +#: order/views.py:275 msgid "Confirm order placement" msgstr "" -#: order/views.py:218 +#: order/views.py:296 msgid "Complete Order" msgstr "" -#: order/views.py:284 +#: order/views.py:362 msgid "Receive Parts" msgstr "" -#: order/views.py:351 +#: order/views.py:429 msgid "Items received" msgstr "" -#: order/views.py:365 +#: order/views.py:443 msgid "No destination set" msgstr "" -#: order/views.py:396 +#: order/views.py:474 msgid "Error converting quantity to number" msgstr "" -#: order/views.py:402 +#: order/views.py:480 msgid "Receive quantity less than zero" msgstr "" -#: order/views.py:408 +#: order/views.py:486 msgid "No lines specified" msgstr "" -#: order/views.py:767 +#: order/views.py:845 msgid "Invalid Purchase Order" msgstr "" -#: order/views.py:775 +#: order/views.py:853 msgid "Supplier must match for Part and Order" msgstr "" -#: order/views.py:780 +#: order/views.py:858 msgid "Invalid SupplierPart selection" msgstr "" -#: order/views.py:862 +#: order/views.py:940 msgid "Edit Line Item" msgstr "" -#: order/views.py:878 +#: order/views.py:956 msgid "Delete Line Item" msgstr "" -#: order/views.py:883 +#: order/views.py:961 msgid "Deleted line item" msgstr "" @@ -1085,147 +1172,139 @@ msgstr "" msgid "Select currency for price calculation" msgstr "" -#: part/models.py:59 +#: part/models.py:60 msgid "Default location for parts in this category" msgstr "" -#: part/models.py:62 +#: part/models.py:63 msgid "Default keywords for parts in this category" msgstr "" -#: part/models.py:323 +#: part/models.py:327 msgid "Part must be unique for name, IPN and revision" msgstr "" -#: part/models.py:337 +#: part/models.py:341 msgid "Part cannot be a template part if it is a variant of another part" msgstr "" -#: part/models.py:338 +#: part/models.py:342 msgid "Part cannot be a variant of another part if it is already a template" msgstr "" -#: part/models.py:342 part/templates/part/detail.html:17 +#: part/models.py:346 part/templates/part/detail.html:17 msgid "Part name" msgstr "" -#: part/models.py:346 +#: part/models.py:350 msgid "Is this part a template part?" msgstr "" -#: part/models.py:355 +#: part/models.py:359 msgid "Is this part a variant of another part?" msgstr "" -#: part/models.py:357 +#: part/models.py:361 msgid "Part description" msgstr "" -#: part/models.py:359 +#: part/models.py:363 msgid "Part keywords to improve visibility in search results" msgstr "" -#: part/models.py:364 +#: part/models.py:368 msgid "Part category" msgstr "" -#: part/models.py:366 +#: part/models.py:370 msgid "Internal Part Number" msgstr "" -#: part/models.py:368 +#: part/models.py:372 msgid "Part revision or version number" msgstr "" -#: part/models.py:370 +#: part/models.py:374 msgid "Link to extenal URL" msgstr "" -#: part/models.py:376 +#: part/models.py:380 msgid "Where is this item normally stored?" msgstr "" -#: part/models.py:420 +#: part/models.py:424 msgid "Default supplier part" msgstr "" -#: part/models.py:423 +#: part/models.py:427 msgid "Minimum allowed stock level" msgstr "" -#: part/models.py:425 +#: part/models.py:429 msgid "Stock keeping units for this part" msgstr "" -#: part/models.py:427 +#: part/models.py:431 msgid "Can this part be built from other parts?" msgstr "" -#: part/models.py:429 +#: part/models.py:433 msgid "Can this part be used to build other parts?" msgstr "" -#: part/models.py:431 +#: part/models.py:435 msgid "Does this part have tracking for unique items?" msgstr "" -#: part/models.py:433 +#: part/models.py:437 msgid "Can this part be purchased from external suppliers?" msgstr "" -#: part/models.py:435 +#: part/models.py:439 msgid "Can this part be sold to customers?" msgstr "" -#: part/models.py:437 +#: part/models.py:441 msgid "Is this part active?" msgstr "" -#: part/models.py:439 +#: part/models.py:443 msgid "Is this a virtual part, such as a software product or license?" msgstr "" -#: part/models.py:441 +#: part/models.py:445 msgid "Part notes - supports Markdown formatting" msgstr "" -#: part/models.py:443 +#: part/models.py:447 msgid "Stored BOM checksum" msgstr "" -#: part/models.py:948 -msgid "Select file to attach" -msgstr "" - -#: part/models.py:950 -msgid "File comment" -msgstr "" - -#: part/models.py:1005 +#: part/models.py:1004 msgid "Parameter template name must be unique" msgstr "" -#: part/models.py:1010 +#: part/models.py:1009 msgid "Parameter Name" msgstr "" -#: part/models.py:1012 +#: part/models.py:1011 msgid "Parameter Units" msgstr "" -#: part/models.py:1038 +#: part/models.py:1037 msgid "Parent Part" msgstr "" -#: part/models.py:1040 +#: part/models.py:1039 msgid "Parameter Template" msgstr "" -#: part/models.py:1042 +#: part/models.py:1041 msgid "Parameter Value" msgstr "" -#: part/models.py:1066 +#: part/models.py:1065 msgid "Select parent part" msgstr "" @@ -1233,31 +1312,31 @@ msgstr "" msgid "Select part to be used in BOM" msgstr "" -#: part/models.py:1080 +#: part/models.py:1081 msgid "BOM quantity for this BOM item" msgstr "" -#: part/models.py:1083 +#: part/models.py:1084 msgid "Estimated build wastage quantity (absolute or percentage)" msgstr "" -#: part/models.py:1086 +#: part/models.py:1087 msgid "BOM item reference" msgstr "" -#: part/models.py:1089 +#: part/models.py:1090 msgid "BOM item notes" msgstr "" -#: part/models.py:1091 +#: part/models.py:1092 msgid "BOM line checksum" msgstr "" -#: part/models.py:1154 +#: part/models.py:1155 msgid "Part cannot be added to its own Bill of Materials" msgstr "" -#: part/models.py:1161 +#: part/models.py:1162 #, python-brace-format msgid "Part '{p1}' is used in BOM for '{p2}' (recursive)" msgstr "" @@ -1266,26 +1345,6 @@ msgstr "" msgid "Part Attachments" msgstr "" -#: part/templates/part/attachments.html:14 -msgid "Add Attachment" -msgstr "" - -#: part/templates/part/attachments.html:22 -msgid "File" -msgstr "" - -#: part/templates/part/attachments.html:23 -msgid "Comment" -msgstr "" - -#: part/templates/part/attachments.html:34 part/views.py:118 -msgid "Edit attachment" -msgstr "" - -#: part/templates/part/attachments.html:37 -msgid "Delete attachment" -msgstr "" - #: part/templates/part/category.html:13 part/templates/part/category.html:69 #: templates/stats.html:14 msgid "Part Categories" @@ -1355,71 +1414,83 @@ msgstr "" msgid "Minimum Stock" msgstr "" -#: part/templates/part/detail.html:91 +#: part/templates/part/detail.html:87 +msgid "Creation Date" +msgstr "" + +#: part/templates/part/detail.html:92 +msgid "Created By" +msgstr "" + +#: part/templates/part/detail.html:98 +msgid "Responsible User" +msgstr "" + +#: part/templates/part/detail.html:107 msgid "Virtual" msgstr "" -#: part/templates/part/detail.html:94 +#: part/templates/part/detail.html:110 msgid "Part is virtual (not a physical part)" msgstr "" -#: part/templates/part/detail.html:96 +#: part/templates/part/detail.html:112 msgid "Part is not a virtual part" msgstr "" -#: part/templates/part/detail.html:100 +#: part/templates/part/detail.html:116 msgid "Assembly" msgstr "" -#: part/templates/part/detail.html:103 +#: part/templates/part/detail.html:119 msgid "Part can be assembled from other parts" msgstr "" -#: part/templates/part/detail.html:105 +#: part/templates/part/detail.html:121 msgid "Part cannot be assembled from other parts" msgstr "" -#: part/templates/part/detail.html:109 +#: part/templates/part/detail.html:125 msgid "Component" msgstr "" -#: part/templates/part/detail.html:112 +#: part/templates/part/detail.html:128 msgid "Part can be used in assemblies" msgstr "" -#: part/templates/part/detail.html:114 +#: part/templates/part/detail.html:130 msgid "Part cannot be used in assemblies" msgstr "" -#: part/templates/part/detail.html:118 +#: part/templates/part/detail.html:134 msgid "Trackable" msgstr "" -#: part/templates/part/detail.html:121 +#: part/templates/part/detail.html:137 msgid "Part stock is tracked by serial number" msgstr "" -#: part/templates/part/detail.html:123 +#: part/templates/part/detail.html:139 msgid "Part stock is not tracked by serial number" msgstr "" -#: part/templates/part/detail.html:127 +#: part/templates/part/detail.html:143 msgid "Purchaseable" msgstr "" -#: part/templates/part/detail.html:130 part/templates/part/detail.html:132 +#: part/templates/part/detail.html:146 part/templates/part/detail.html:148 msgid "Part can be purchased from external suppliers" msgstr "" -#: part/templates/part/detail.html:137 +#: part/templates/part/detail.html:153 msgid "Sellable" msgstr "" -#: part/templates/part/detail.html:140 +#: part/templates/part/detail.html:156 msgid "Part can be sold to customers" msgstr "" -#: part/templates/part/detail.html:142 +#: part/templates/part/detail.html:158 msgid "Part cannot be sold to customers" msgstr "" @@ -1487,7 +1558,7 @@ msgstr "" msgid "BOM" msgstr "" -#: part/templates/part/tabs.html:28 stock/templates/stock/item_base.html:102 +#: part/templates/part/tabs.html:28 stock/templates/stock/item_base.html:113 #: templates/navbar.html:12 msgid "Build" msgstr "" @@ -1504,176 +1575,168 @@ msgstr "" msgid "Tracking" msgstr "" -#: part/templates/part/tabs.html:55 -msgid "Attachments" -msgstr "" - #: part/views.py:75 msgid "Add part attachment" msgstr "" -#: part/views.py:80 -msgid "Added attachment" -msgstr "" - -#: part/views.py:122 +#: part/views.py:123 msgid "Part attachment updated" msgstr "" -#: part/views.py:137 +#: part/views.py:138 msgid "Delete Part Attachment" msgstr "" -#: part/views.py:143 +#: part/views.py:144 msgid "Deleted part attachment" msgstr "" -#: part/views.py:151 +#: part/views.py:152 msgid "Set Part Category" msgstr "" -#: part/views.py:199 +#: part/views.py:200 #, python-brace-format msgid "Set category for {n} parts" msgstr "" -#: part/views.py:234 +#: part/views.py:235 msgid "Create Variant" msgstr "" -#: part/views.py:304 +#: part/views.py:305 msgid "Duplicate Part" msgstr "" -#: part/views.py:309 +#: part/views.py:310 msgid "Copied part" msgstr "" -#: part/views.py:417 +#: part/views.py:421 msgid "Create new part" msgstr "" -#: part/views.py:422 +#: part/views.py:426 msgid "Created new part" msgstr "" -#: part/views.py:595 +#: part/views.py:605 msgid "Part QR Code" msgstr "" -#: part/views.py:612 +#: part/views.py:622 msgid "Upload Part Image" msgstr "" -#: part/views.py:617 part/views.py:652 +#: part/views.py:627 part/views.py:662 msgid "Updated part image" msgstr "" -#: part/views.py:626 +#: part/views.py:636 msgid "Select Part Image" msgstr "" -#: part/views.py:655 +#: part/views.py:665 msgid "Part image not found" msgstr "" -#: part/views.py:666 +#: part/views.py:676 msgid "Edit Part Properties" msgstr "" -#: part/views.py:688 +#: part/views.py:698 msgid "Validate BOM" msgstr "" -#: part/views.py:850 +#: part/views.py:860 msgid "No BOM file provided" msgstr "" -#: part/views.py:1111 +#: part/views.py:1121 msgid "Enter a valid quantity" msgstr "" -#: part/views.py:1135 part/views.py:1138 +#: part/views.py:1145 part/views.py:1148 msgid "Select valid part" msgstr "" -#: part/views.py:1144 +#: part/views.py:1154 msgid "Duplicate part selected" msgstr "" -#: part/views.py:1172 +#: part/views.py:1182 msgid "Select a part" msgstr "" -#: part/views.py:1176 +#: part/views.py:1186 msgid "Specify quantity" msgstr "" -#: part/views.py:1356 +#: part/views.py:1366 msgid "Export Bill of Materials" msgstr "" -#: part/views.py:1396 +#: part/views.py:1406 msgid "Confirm Part Deletion" msgstr "" -#: part/views.py:1403 +#: part/views.py:1413 msgid "Part was deleted" msgstr "" -#: part/views.py:1412 +#: part/views.py:1422 msgid "Part Pricing" msgstr "" -#: part/views.py:1534 +#: part/views.py:1544 msgid "Create Part Parameter Template" msgstr "" -#: part/views.py:1542 +#: part/views.py:1552 msgid "Edit Part Parameter Template" msgstr "" -#: part/views.py:1549 +#: part/views.py:1559 msgid "Delete Part Parameter Template" msgstr "" -#: part/views.py:1557 +#: part/views.py:1567 msgid "Create Part Parameter" msgstr "" -#: part/views.py:1607 +#: part/views.py:1617 msgid "Edit Part Parameter" msgstr "" -#: part/views.py:1621 +#: part/views.py:1631 msgid "Delete Part Parameter" msgstr "" -#: part/views.py:1637 +#: part/views.py:1647 msgid "Edit Part Category" msgstr "" -#: part/views.py:1672 +#: part/views.py:1682 msgid "Delete Part Category" msgstr "" -#: part/views.py:1678 +#: part/views.py:1688 msgid "Part category was deleted" msgstr "" -#: part/views.py:1686 +#: part/views.py:1696 msgid "Create new part category" msgstr "" -#: part/views.py:1737 +#: part/views.py:1747 msgid "Create BOM item" msgstr "" -#: part/views.py:1803 +#: part/views.py:1813 msgid "Edit BOM item" msgstr "" -#: part/views.py:1851 +#: part/views.py:1861 msgid "Confim BOM item deletion" msgstr "" @@ -1693,121 +1756,121 @@ msgstr "" msgid "Set the destination as the default location for selected parts" msgstr "" -#: stock/models.py:204 +#: stock/models.py:205 #, python-brace-format msgid "" "A stock item with this serial number already exists for template part {part}" msgstr "" -#: stock/models.py:209 +#: stock/models.py:210 msgid "A stock item with this serial number already exists" msgstr "" -#: stock/models.py:228 +#: stock/models.py:229 #, python-brace-format msgid "Part type ('{pf}') must be {pe}" msgstr "" -#: stock/models.py:238 stock/models.py:247 +#: stock/models.py:239 stock/models.py:248 msgid "Quantity must be 1 for item with a serial number" msgstr "" -#: stock/models.py:239 +#: stock/models.py:240 msgid "Serial number cannot be set if quantity greater than 1" msgstr "" -#: stock/models.py:255 +#: stock/models.py:256 msgid "Stock item cannot be created for a template Part" msgstr "" -#: stock/models.py:264 +#: stock/models.py:265 msgid "Item cannot belong to itself" msgstr "" -#: stock/models.py:300 +#: stock/models.py:306 msgid "Base part" msgstr "" -#: stock/models.py:307 +#: stock/models.py:314 msgid "Select a matching supplier part for this stock item" msgstr "" -#: stock/models.py:311 +#: stock/models.py:318 msgid "Where is this stock item located?" msgstr "" -#: stock/models.py:315 +#: stock/models.py:322 msgid "Is this item installed in another item?" msgstr "" -#: stock/models.py:319 +#: stock/models.py:326 msgid "Item assigned to customer?" msgstr "" -#: stock/models.py:322 +#: stock/models.py:329 msgid "Serial number for this item" msgstr "" -#: stock/models.py:327 +#: stock/models.py:334 msgid "Batch code for this stock item" msgstr "" -#: stock/models.py:336 +#: stock/models.py:343 msgid "Build for this stock item" msgstr "" -#: stock/models.py:345 +#: stock/models.py:352 msgid "Purchase order for this stock item" msgstr "" -#: stock/models.py:356 +#: stock/models.py:363 msgid "Delete this Stock Item when stock is depleted" msgstr "" -#: stock/models.py:363 stock/templates/stock/item_notes.html:13 +#: stock/models.py:370 stock/templates/stock/item_notes.html:13 #: stock/templates/stock/item_notes.html:29 msgid "Stock Item Notes" msgstr "" -#: stock/models.py:437 +#: stock/models.py:460 msgid "Quantity must be integer" msgstr "" -#: stock/models.py:443 +#: stock/models.py:466 #, python-brace-format msgid "Quantity must not exceed available stock quantity ({n})" msgstr "" -#: stock/models.py:446 stock/models.py:449 +#: stock/models.py:469 stock/models.py:472 msgid "Serial numbers must be a list of integers" msgstr "" -#: stock/models.py:452 +#: stock/models.py:475 msgid "Quantity does not match serial numbers" msgstr "" -#: stock/models.py:462 +#: stock/models.py:485 msgid "Serial numbers already exist: " msgstr "" -#: stock/models.py:483 +#: stock/models.py:507 msgid "Add serial number" msgstr "" -#: stock/models.py:486 +#: stock/models.py:510 #, python-brace-format msgid "Serialized {n} items" msgstr "" -#: stock/models.py:752 +#: stock/models.py:810 msgid "Tracking entry title" msgstr "" -#: stock/models.py:754 +#: stock/models.py:812 msgid "Entry notes" msgstr "" -#: stock/models.py:756 +#: stock/models.py:814 msgid "Link to external page for further information" msgstr "" @@ -1819,42 +1882,58 @@ msgstr "" msgid "Stock Item Details" msgstr "" -#: stock/templates/stock/item_base.html:53 +#: stock/templates/stock/item_base.html:55 msgid "" "This stock item is serialized - it has a unique serial number and the " "quantity cannot be adjusted." msgstr "" -#: stock/templates/stock/item_base.html:57 +#: stock/templates/stock/item_base.html:59 +msgid "This stock item cannot be deleted as it has child items" +msgstr "" + +#: stock/templates/stock/item_base.html:63 msgid "" "This stock item will be automatically deleted when all stock is depleted." msgstr "" -#: stock/templates/stock/item_base.html:74 +#: stock/templates/stock/item_base.html:68 +msgid "This stock item was split from " +msgstr "" + +#: stock/templates/stock/item_base.html:85 msgid "Belongs To" msgstr "" -#: stock/templates/stock/item_base.html:79 +#: stock/templates/stock/item_base.html:90 #: stock/templates/stock/stock_adjust.html:17 msgid "Location" msgstr "" -#: stock/templates/stock/item_base.html:85 +#: stock/templates/stock/item_base.html:96 msgid "Serial Number" msgstr "" -#: stock/templates/stock/item_base.html:135 +#: stock/templates/stock/item_base.html:146 msgid "Last Updated" msgstr "" -#: stock/templates/stock/item_base.html:139 +#: stock/templates/stock/item_base.html:150 msgid "Last Stocktake" msgstr "" -#: stock/templates/stock/item_base.html:143 +#: stock/templates/stock/item_base.html:154 msgid "No stocktake performed" msgstr "" +#: stock/templates/stock/item_childs.html:12 +msgid "Child Stock Items" +msgstr "" + +#: stock/templates/stock/item_childs.html:18 +msgid "This stock item does not have any child items" +msgstr "" + #: stock/templates/stock/location.html:37 msgid "Location Details" msgstr "" @@ -1890,7 +1969,11 @@ msgstr "" msgid "Stock Item" msgstr "" -#: stock/templates/stock/tabs.html:10 +#: stock/templates/stock/tabs.html:8 +msgid "Children" +msgstr "" + +#: stock/templates/stock/tabs.html:13 msgid "Builds" msgstr "" @@ -2093,7 +2176,7 @@ msgstr "" msgid "Statistics" msgstr "" -#: templates/stock_table.html:7 +#: templates/stock_table.html:8 msgid "New Stock Item" msgstr "" diff --git a/InvenTree/order/forms.py b/InvenTree/order/forms.py index 97e0f0bdd9..fead5d0496 100644 --- a/InvenTree/order/forms.py +++ b/InvenTree/order/forms.py @@ -13,7 +13,7 @@ from mptt.fields import TreeNodeChoiceField from InvenTree.forms import HelperForm from stock.models import StockLocation -from .models import PurchaseOrder, PurchaseOrderLineItem +from .models import PurchaseOrder, PurchaseOrderLineItem, PurchaseOrderAttachment class IssuePurchaseOrderForm(HelperForm): @@ -74,6 +74,18 @@ class EditPurchaseOrderForm(HelperForm): ] +class EditPurchaseOrderAttachmentForm(HelperForm): + """ Form for editing a PurchaseOrderAttachment object """ + + class Meta: + model = PurchaseOrderAttachment + fields = [ + 'order', + 'attachment', + 'comment' + ] + + class EditPurchaseOrderLineItemForm(HelperForm): """ Form for editing a PurchaseOrderLineItem object """ diff --git a/InvenTree/order/migrations/0016_purchaseorderattachment.py b/InvenTree/order/migrations/0016_purchaseorderattachment.py new file mode 100644 index 0000000000..25b43e222d --- /dev/null +++ b/InvenTree/order/migrations/0016_purchaseorderattachment.py @@ -0,0 +1,27 @@ +# Generated by Django 2.2.9 on 2020-03-22 07:01 + +import InvenTree.models +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('order', '0015_auto_20200201_2346'), + ] + + operations = [ + migrations.CreateModel( + name='PurchaseOrderAttachment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('attachment', models.FileField(help_text='Select file to attach', upload_to=InvenTree.models.rename_attachment)), + ('comment', models.CharField(help_text='File comment', max_length=100)), + ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='order.PurchaseOrder')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py index b5538c6040..f14065973e 100644 --- a/InvenTree/order/models.py +++ b/InvenTree/order/models.py @@ -14,6 +14,7 @@ from django.utils.translation import ugettext as _ from markdownx.models import MarkdownxField +import os from datetime import datetime from stock.models import StockItem @@ -21,6 +22,7 @@ from company.models import Company, SupplierPart from InvenTree.helpers import decimal2string from InvenTree.status_codes import OrderStatus +from InvenTree.models import InvenTreeAttachment class Order(models.Model): @@ -136,7 +138,7 @@ class PurchaseOrder(Order): ) def get_absolute_url(self): - return reverse('purchase-order-detail', kwargs={'pk': self.id}) + return reverse('po-detail', kwargs={'pk': self.id}) @transaction.atomic def add_line_item(self, supplier_part, quantity, group=True, reference=''): @@ -239,6 +241,17 @@ class PurchaseOrder(Order): self.complete_order() # This will save the model +class PurchaseOrderAttachment(InvenTreeAttachment): + """ + Model for storing file attachments against a PurchaseOrder object + """ + + def getSubdir(self): + return os.path.join("po_files", str(self.order.id)) + + order = models.ForeignKey(PurchaseOrder, on_delete=models.CASCADE, related_name="attachments") + + class OrderLineItem(models.Model): """ Abstract model for an order line item diff --git a/InvenTree/order/templates/order/order_base.html b/InvenTree/order/templates/order/order_base.html index 2cefeb6465..80a33fbfa8 100644 --- a/InvenTree/order/templates/order/order_base.html +++ b/InvenTree/order/templates/order/order_base.html @@ -107,7 +107,7 @@ InvenTree | {{ order }} {% if order.status == OrderStatus.PENDING and order.lines.count > 0 %} $("#place-order").click(function() { - launchModalForm("{% url 'purchase-order-issue' order.id %}", + launchModalForm("{% url 'po-issue' order.id %}", { reload: true, }); @@ -115,7 +115,7 @@ $("#place-order").click(function() { {% endif %} $("#edit-order").click(function() { - launchModalForm("{% url 'purchase-order-edit' order.id %}", + launchModalForm("{% url 'po-edit' order.id %}", { reload: true, } @@ -123,7 +123,7 @@ $("#edit-order").click(function() { }); $("#cancel-order").click(function() { - launchModalForm("{% url 'purchase-order-cancel' order.id %}", { + launchModalForm("{% url 'po-cancel' order.id %}", { reload: true, }); }); diff --git a/InvenTree/order/templates/order/order_notes.html b/InvenTree/order/templates/order/order_notes.html index 9077108510..de4f18ba6b 100644 --- a/InvenTree/order/templates/order/order_notes.html +++ b/InvenTree/order/templates/order/order_notes.html @@ -50,7 +50,7 @@ {% if editing %} {% else %} $("#edit-notes").click(function() { - location.href = "{% url 'purchase-order-notes' order.id %}?edit=1"; + location.href = "{% url 'po-notes' order.id %}?edit=1"; }); {% endif %} diff --git a/InvenTree/order/templates/order/po_attachments.html b/InvenTree/order/templates/order/po_attachments.html new file mode 100644 index 0000000000..173b0e1fb6 --- /dev/null +++ b/InvenTree/order/templates/order/po_attachments.html @@ -0,0 +1,81 @@ +{% extends "order/order_base.html" %} + +{% load inventree_extras %} +{% load i18n %} +{% load static %} + +{% block details %} + +{% include 'order/tabs.html' with tab='attachments' %} + +

{% trans "Purchase Order Attachments" %} + +
+ +
+
+ +
+
+ + + + + + + + + + + {% for attachment in order.attachments.all %} + + + + + + {% endfor %} + +
{% trans "File" %}{% trans "Comment" %}
{{ attachment.basename }}{{ attachment.comment }} +
+ + +
+
+ +{% endblock %} + +{% block js_ready %} +{{ block.super }} + +$("#new-attachment").click(function() { + launchModalForm("{% url 'po-attachment-create' %}?order={{ order.id }}", + { + reload: true, + } + ); +}); + +$("#attachment-table").on('click', '.attachment-edit-button', function() { + var button = $(this); + + launchModalForm(button.attr('url'), { + reload: true, + }); +}); + +$("#attachment-table").on('click', '.attachment-delete-button', function() { + var button = $(this); + + launchModalForm(button.attr('url'), { + reload: true, + }); +}); + +$("#attachment-table").inventreeTable({ +}); + +{% endblock %} \ No newline at end of file diff --git a/InvenTree/order/templates/order/po_delete.html b/InvenTree/order/templates/order/po_delete.html new file mode 100644 index 0000000000..4ee7f03cb1 --- /dev/null +++ b/InvenTree/order/templates/order/po_delete.html @@ -0,0 +1,7 @@ +{% extends "modal_delete_form.html" %} +{% load i18n %} + +{% block pre_form_content %} +{% trans "Are you sure you want to delete this attachment?" %} +
+{% endblock %} \ No newline at end of file diff --git a/InvenTree/order/templates/order/po_table.html b/InvenTree/order/templates/order/po_table.html index 0fe41e8efa..712553e866 100644 --- a/InvenTree/order/templates/order/po_table.html +++ b/InvenTree/order/templates/order/po_table.html @@ -12,7 +12,7 @@ {% for order in orders %} {% include "hover_image.html" with image=order.supplier.image hover=True %}{{ order.supplier.name }} - {{ order }} + {{ order }} {{ order.description }} {% include "order/order_status.html" %} {{ order.lines.count }} diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html index 15bc55a3d8..d2930cb8d1 100644 --- a/InvenTree/order/templates/order/purchase_order_detail.html +++ b/InvenTree/order/templates/order/purchase_order_detail.html @@ -92,7 +92,7 @@ $("#po-lines-table").on('click', ".line-receive", function() { console.log('clicked! ' + button.attr('pk')); - launchModalForm("{% url 'purchase-order-receive' order.id %}", { + launchModalForm("{% url 'po-receive' order.id %}", { reload: true, data: { line: button.attr('pk') @@ -109,7 +109,7 @@ $("#po-lines-table").on('click', ".line-receive", function() { }); $("#receive-order").click(function() { - launchModalForm("{% url 'purchase-order-receive' order.id %}", { + launchModalForm("{% url 'po-receive' order.id %}", { reload: true, secondary: [ { @@ -123,13 +123,13 @@ $("#receive-order").click(function() { }); $("#complete-order").click(function() { - launchModalForm("{% url 'purchase-order-complete' order.id %}", { + launchModalForm("{% url 'po-complete' order.id %}", { reload: true, }); }); $("#export-order").click(function() { - location.href = "{% url 'purchase-order-export' order.id %}"; + location.href = "{% url 'po-export' order.id %}"; }); {% if order.status == OrderStatus.PENDING %} diff --git a/InvenTree/order/templates/order/purchase_orders.html b/InvenTree/order/templates/order/purchase_orders.html index 17f3115c75..644e6418fa 100644 --- a/InvenTree/order/templates/order/purchase_orders.html +++ b/InvenTree/order/templates/order/purchase_orders.html @@ -18,7 +18,7 @@ InvenTree | Purchase Orders - +
{% endblock %} @@ -27,7 +27,7 @@ InvenTree | Purchase Orders {{ block.super }} $("#po-create").click(function() { - launchModalForm("{% url 'purchase-order-create' %}", + launchModalForm("{% url 'po-create' %}", { follow: true, } diff --git a/InvenTree/order/templates/order/tabs.html b/InvenTree/order/templates/order/tabs.html index e673a3271e..a04c97eba5 100644 --- a/InvenTree/order/templates/order/tabs.html +++ b/InvenTree/order/templates/order/tabs.html @@ -2,9 +2,16 @@ diff --git a/InvenTree/order/test_views.py b/InvenTree/order/test_views.py index de478cc665..bf3608e2b0 100644 --- a/InvenTree/order/test_views.py +++ b/InvenTree/order/test_views.py @@ -40,7 +40,7 @@ class OrderViewTestCase(TestCase): class OrderListTest(OrderViewTestCase): def test_order_list(self): - response = self.client.get(reverse('purchase-order-index')) + response = self.client.get(reverse('po-index')) self.assertEqual(response.status_code, 200) @@ -50,14 +50,14 @@ class POTests(OrderViewTestCase): def test_detail_view(self): """ Retrieve PO detail view """ - response = self.client.get(reverse('purchase-order-detail', args=(1,))) + response = self.client.get(reverse('po-detail', args=(1,))) self.assertEqual(response.status_code, 200) keys = response.context.keys() self.assertIn('OrderStatus', keys) def test_po_create(self): """ Launch forms to create new PurchaseOrder""" - url = reverse('purchase-order-create') + url = reverse('po-create') # Without a supplier ID response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest') @@ -74,13 +74,13 @@ class POTests(OrderViewTestCase): def test_po_edit(self): """ Launch form to edit a PurchaseOrder """ - response = self.client.get(reverse('purchase-order-edit', args=(1,)), HTTP_X_REQUESTED_WITH='XMLHttpRequest') + response = self.client.get(reverse('po-edit', args=(1,)), HTTP_X_REQUESTED_WITH='XMLHttpRequest') self.assertEqual(response.status_code, 200) def test_po_export(self): """ Export PurchaseOrder """ - response = self.client.get(reverse('purchase-order-export', args=(1,)), HTTP_X_REQUESTED_WITH='XMLHttpRequest') + response = self.client.get(reverse('po-export', args=(1,)), HTTP_X_REQUESTED_WITH='XMLHttpRequest') # Response should be streaming-content (file download) self.assertIn('streaming_content', dir(response)) @@ -88,7 +88,7 @@ class POTests(OrderViewTestCase): def test_po_issue(self): """ Test PurchaseOrderIssue view """ - url = reverse('purchase-order-issue', args=(1,)) + url = reverse('po-issue', args=(1,)) order = PurchaseOrder.objects.get(pk=1) self.assertEqual(order.status, OrderStatus.PENDING) @@ -183,7 +183,7 @@ class TestPOReceive(OrderViewTestCase): self.po = PurchaseOrder.objects.get(pk=1) self.po.status = OrderStatus.PLACED self.po.save() - self.url = reverse('purchase-order-receive', args=(1,)) + self.url = reverse('po-receive', args=(1,)) def post(self, data, validate=None): diff --git a/InvenTree/order/urls.py b/InvenTree/order/urls.py index d1d7d7f5f7..3346d7c44d 100644 --- a/InvenTree/order/urls.py +++ b/InvenTree/order/urls.py @@ -9,19 +9,26 @@ from django.conf.urls import url, include from . import views +purchase_order_attachment_urls = [ + url(r'^new/', views.PurchaseOrderAttachmentCreate.as_view(), name='po-attachment-create'), + url(r'^(?P\d+)/edit/', views.PurchaseOrderAttachmentEdit.as_view(), name='po-attachment-edit'), + url(r'^(?P\d+)/delete/', views.PurchaseOrderAttachmentDelete.as_view(), name='po-attachment-delete'), +] + purchase_order_detail_urls = [ - url(r'^cancel/?', views.PurchaseOrderCancel.as_view(), name='purchase-order-cancel'), - url(r'^edit/?', views.PurchaseOrderEdit.as_view(), name='purchase-order-edit'), - url(r'^issue/?', views.PurchaseOrderIssue.as_view(), name='purchase-order-issue'), - url(r'^receive/?', views.PurchaseOrderReceive.as_view(), name='purchase-order-receive'), - url(r'^complete/?', views.PurchaseOrderComplete.as_view(), name='purchase-order-complete'), + url(r'^cancel/?', views.PurchaseOrderCancel.as_view(), name='po-cancel'), + url(r'^edit/?', views.PurchaseOrderEdit.as_view(), name='po-edit'), + url(r'^issue/?', views.PurchaseOrderIssue.as_view(), name='po-issue'), + url(r'^receive/?', views.PurchaseOrderReceive.as_view(), name='po-receive'), + url(r'^complete/?', views.PurchaseOrderComplete.as_view(), name='po-complete'), - url(r'^export/?', views.PurchaseOrderExport.as_view(), name='purchase-order-export'), + url(r'^export/?', views.PurchaseOrderExport.as_view(), name='po-export'), - url(r'^notes/', views.PurchaseOrderNotes.as_view(), name='purchase-order-notes'), + url(r'^notes/', views.PurchaseOrderNotes.as_view(), name='po-notes'), - url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='purchase-order-detail'), + url(r'^attachments/', views.PurchaseOrderDetail.as_view(template_name='order/po_attachments.html'), name='po-attachments'), + url(r'^.*$', views.PurchaseOrderDetail.as_view(), name='po-detail'), ] po_line_item_detail_urls = [ @@ -39,7 +46,7 @@ po_line_urls = [ purchase_order_urls = [ - url(r'^new/', views.PurchaseOrderCreate.as_view(), name='purchase-order-create'), + url(r'^new/', views.PurchaseOrderCreate.as_view(), name='po-create'), url(r'^order-parts/', views.OrderParts.as_view(), name='order-parts'), @@ -48,8 +55,10 @@ purchase_order_urls = [ url(r'^line/', include(po_line_urls)), + url(r'^attachments/', include(purchase_order_attachment_urls)), + # Display complete list of purchase orders - url(r'^.*$', views.PurchaseOrderIndex.as_view(), name='purchase-order-index'), + url(r'^.*$', views.PurchaseOrderIndex.as_view(), name='po-index'), ] order_urls = [ diff --git a/InvenTree/order/views.py b/InvenTree/order/views.py index 2b31740bd2..67d5b926d7 100644 --- a/InvenTree/order/views.py +++ b/InvenTree/order/views.py @@ -15,7 +15,7 @@ from django.forms import HiddenInput import logging from decimal import Decimal, InvalidOperation -from .models import PurchaseOrder, PurchaseOrderLineItem +from .models import PurchaseOrder, PurchaseOrderLineItem, PurchaseOrderAttachment from .admin import POLineItemResource from build.models import Build from company.models import Company, SupplierPart @@ -70,6 +70,84 @@ class PurchaseOrderDetail(DetailView): return ctx +class PurchaseOrderAttachmentCreate(AjaxCreateView): + """ + View for creating a new PurchaseOrderAtt + """ + + model = PurchaseOrderAttachment + form_class = order_forms.EditPurchaseOrderAttachmentForm + ajax_form_title = _("Add Purchase Order Attachment") + ajax_template_name = "modal_form.html" + + def get_data(self): + return { + "success": _("Added attachment") + } + + def get_initial(self): + """ + Get initial data for creating a new PurchaseOrderAttachment object. + + - Client must request this form with a parent PurchaseOrder in midn. + - e.g. ?order= + """ + + initials = super(AjaxCreateView, self).get_initial() + + initials["order"] = PurchaseOrder.objects.get(id=self.request.GET.get('order', -1)) + + return initials + + def get_form(self): + """ + Create a form to upload a new PurchaseOrderAttachment + + - Hide the 'order' field + """ + + form = super(AjaxCreateView, self).get_form() + + form.fields['order'].widget = HiddenInput() + + return form + + +class PurchaseOrderAttachmentEdit(AjaxUpdateView): + """ View for editing a PurchaseOrderAttachment object """ + + model = PurchaseOrderAttachment + form_class = order_forms.EditPurchaseOrderAttachmentForm + ajax_form_title = _("Edit Attachment") + + def get_data(self): + return { + 'success': _('Attachment updated') + } + + def get_form(self): + form = super(AjaxUpdateView, self).get_form() + + # Hide the 'order' field + form.fields['order'].widget = HiddenInput() + + return form + + +class PurchaseOrderAttachmentDelete(AjaxDeleteView): + """ View for deleting a PurchaseOrderAttachment """ + + model = PurchaseOrderAttachment + ajax_form_title = _("Delete Attachment") + ajax_template_name = "order/po_delete.html" + context_object_name = "attachment" + + def get_data(self): + return { + "danger": _("Deleted attachment") + } + + class PurchaseOrderNotes(UpdateView): """ View for updating the 'notes' field of a PurchaseOrder """ diff --git a/InvenTree/part/migrations/0032_auto_20200322_0453.py b/InvenTree/part/migrations/0032_auto_20200322_0453.py new file mode 100644 index 0000000000..29fb25f1e7 --- /dev/null +++ b/InvenTree/part/migrations/0032_auto_20200322_0453.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.9 on 2020-03-22 04:53 + +import InvenTree.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('part', '0031_auto_20200318_1044'), + ] + + operations = [ + migrations.AlterField( + model_name='partattachment', + name='attachment', + field=models.FileField(help_text='Select file to attach', upload_to=InvenTree.models.rename_attachment), + ), + ] diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index d8cb8b07e0..4e579ea44c 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -34,7 +34,7 @@ import hashlib from InvenTree import helpers from InvenTree import validators -from InvenTree.models import InvenTreeTree +from InvenTree.models import InvenTreeTree, InvenTreeAttachment from InvenTree.fields import InvenTreeURLField from InvenTree.helpers import decimal2string @@ -941,28 +941,17 @@ def attach_file(instance, filename): return os.path.join('part_files', str(instance.part.id), filename) -class PartAttachment(models.Model): - """ A PartAttachment links a file to a part - Parts can have multiple files such as datasheets, etc - - Attributes: - part: Link to a Part object - attachment: File - comment: String descriptor for the attachment +class PartAttachment(InvenTreeAttachment): """ + Model for storing file attachments against a Part object + """ + + def getSubdir(self): + return os.path.join("part_files", str(self.part.id)) part = models.ForeignKey(Part, on_delete=models.CASCADE, related_name='attachments') - attachment = models.FileField(upload_to=attach_file, - help_text=_('Select file to attach')) - - comment = models.CharField(max_length=100, help_text=_('File comment')) - - @property - def basename(self): - return os.path.basename(self.attachment.name) - class PartStar(models.Model): """ A PartStar object creates a relationship between a User and a Part. diff --git a/InvenTree/part/templates/part/attachment_delete.html b/InvenTree/part/templates/part/attachment_delete.html index 1adffcc710..4ee7f03cb1 100644 --- a/InvenTree/part/templates/part/attachment_delete.html +++ b/InvenTree/part/templates/part/attachment_delete.html @@ -1,7 +1,7 @@ {% extends "modal_delete_form.html" %} +{% load i18n %} {% block pre_form_content %} -Are you sure you wish to delete this attachment? +{% trans "Are you sure you want to delete this attachment?" %}
-This will remove the file '{{ attachment.basename }}'. {% endblock %} \ No newline at end of file diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index 36be170bcb..0d376f8e5b 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -13,20 +13,20 @@ from django.conf.urls import url, include from . import views part_attachment_urls = [ - url('^new/?', views.PartAttachmentCreate.as_view(), name='part-attachment-create'), + url(r'^new/?', views.PartAttachmentCreate.as_view(), name='part-attachment-create'), url(r'^(?P\d+)/edit/?', views.PartAttachmentEdit.as_view(), name='part-attachment-edit'), url(r'^(?P\d+)/delete/?', views.PartAttachmentDelete.as_view(), name='part-attachment-delete'), ] part_parameter_urls = [ - url('^template/new/', views.PartParameterTemplateCreate.as_view(), name='part-param-template-create'), - url('^template/(?P\d+)/edit/', views.PartParameterTemplateEdit.as_view(), name='part-param-template-edit'), - url('^template/(?P\d+)/delete/', views.PartParameterTemplateDelete.as_view(), name='part-param-template-edit'), + url(r'^template/new/', views.PartParameterTemplateCreate.as_view(), name='part-param-template-create'), + url(r'^template/(?P\d+)/edit/', views.PartParameterTemplateEdit.as_view(), name='part-param-template-edit'), + url(r'^template/(?P\d+)/delete/', views.PartParameterTemplateDelete.as_view(), name='part-param-template-edit'), - url('^new/', views.PartParameterCreate.as_view(), name='part-param-create'), - url('^(?P\d+)/edit/', views.PartParameterEdit.as_view(), name='part-param-edit'), - url('^(?P\d+)/delete/', views.PartParameterDelete.as_view(), name='part-param-delete'), + url(r'^new/', views.PartParameterCreate.as_view(), name='part-param-create'), + url(r'^(?P\d+)/edit/', views.PartParameterEdit.as_view(), name='part-param-edit'), + url(r'^(?P\d+)/delete/', views.PartParameterDelete.as_view(), name='part-param-delete'), ] diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 1752607d2a..01f8ff41bb 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -112,6 +112,7 @@ class PartAttachmentCreate(AjaxCreateView): class PartAttachmentEdit(AjaxUpdateView): """ View for editing a PartAttachment object """ + model = PartAttachment form_class = part_forms.EditPartAttachmentForm ajax_template_name = 'modal_form.html' diff --git a/InvenTree/stock/templates/stock/item_base.html b/InvenTree/stock/templates/stock/item_base.html index 3e398ba16a..3f5fdca9ad 100644 --- a/InvenTree/stock/templates/stock/item_base.html +++ b/InvenTree/stock/templates/stock/item_base.html @@ -117,7 +117,7 @@ {% if item.purchase_order %} {% trans "Purchase Order" %} - {{ item.purchase_order }} + {{ item.purchase_order }} {% endif %} {% if item.customer %} diff --git a/InvenTree/templates/navbar.html b/InvenTree/templates/navbar.html index 691b73f982..c7e5a574e3 100644 --- a/InvenTree/templates/navbar.html +++ b/InvenTree/templates/navbar.html @@ -11,7 +11,7 @@
  • {% trans "Stock" %}
  • {% trans "Build" %}
  • {% trans "Suppliers" %}
  • -
  • {% trans "Orders" %}
  • +
  • {% trans "Orders" %}