Merge pull request #965 from SchrodingersGat/api-stock-fix

Major bugfix for multiple annotations in API querysets
This commit is contained in:
Oliver 2020-09-05 23:42:25 +10:00 committed by GitHub
commit 22e30903b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 907 additions and 511 deletions

View File

@ -14,4 +14,11 @@
pk: 3
fields:
name: Zerg Corp
description: We eat the competition
description: We eat the competition
- model: company.company
pk: 4
fields:
name: A customer
description: A company that we sell things to!
is_customer: True

View File

@ -4,7 +4,7 @@ JSON serializers for Company app
from rest_framework import serializers
from django.db.models import Count
from sql_util.utils import SubqueryCount
from .models import Company
from .models import SupplierPart, SupplierPriceBreak
@ -38,11 +38,17 @@ class CompanySerializer(InvenTreeModelSerializer):
@staticmethod
def annotate_queryset(queryset):
return queryset.annotate(
parts_supplied=Count('supplied_parts'),
parts_manufactured=Count('manufactured_parts')
# Add count of parts manufactured
queryset = queryset.annotate(
parts_manufactured=SubqueryCount('manufactured_parts')
)
queryset = queryset.annotate(
parts_supplied=SubqueryCount('supplied_parts')
)
return queryset
url = serializers.CharField(source='get_absolute_url', read_only=True)
image = serializers.CharField(source='get_thumbnail_url', read_only=True)

View File

@ -33,6 +33,7 @@ InvenTree | {% trans "Supplier List" %}
loadCompanyTable("#company-table", "{% url 'api-company-list' %}",
{
pagetype: '{{ pagetype }}',
params: {
{% for key,value in filters.items %}{{ key }}: "{{ value }}",{% endfor %}
}

View File

@ -51,18 +51,21 @@ class CompanyIndex(ListView):
'button_text': _('New Supplier'),
'filters': {'is_supplier': 'true'},
'create_url': reverse('supplier-create'),
'pagetype': 'suppliers',
},
reverse('manufacturer-index'): {
'title': _('Manufacturers'),
'button_text': _('New Manufacturer'),
'filters': {'is_manufacturer': 'true'},
'create_url': reverse('manufacturer-create'),
'pagetype': 'manufacturers',
},
reverse('customer-index'): {
'title': _('Customers'),
'button_text': _('New Customer'),
'filters': {'is_customer': 'true'},
'create_url': reverse('customer-create'),
'pagetype': 'customers',
}
}
@ -71,6 +74,7 @@ class CompanyIndex(ListView):
'button_text': _('New Company'),
'filters': {},
'create_url': reverse('company-create'),
'pagetype': 'companies'
}
context = None

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-09-02 13:57+0000\n"
"POT-Creation-Date: 2020-09-05 13:32+0000\n"
"PO-Revision-Date: 2020-05-03 11:32+0200\n"
"Last-Translator: Christian Schlüter <chschlue@gmail.com>\n"
"Language-Team: C <kde-i18n-doc@kde.org>\n"
@ -302,7 +302,7 @@ msgstr "Eltern-Bau, dem dieser Bau zugewiesen ist"
#: part/templates/part/part_app_base.html:7
#: part/templates/part/set_category.html:13 templates/js/barcode.html:336
#: templates/js/bom.html:135 templates/js/build.html:43
#: templates/js/company.html:115 templates/js/part.html:212
#: templates/js/company.html:137 templates/js/part.html:215
#: templates/js/stock.html:429
msgid "Part"
msgstr "Teil"
@ -418,6 +418,7 @@ msgstr "Lagerobjekt-Anzahl dem Bau zuweisen"
#: build/templates/build/allocate.html:17
#: company/templates/company/detail_part.html:18 order/views.py:779
#: part/templates/part/category.html:106
msgid "Order Parts"
msgstr "Teile bestellen"
@ -491,10 +492,10 @@ msgstr "Keine BOM-Einträge gefunden"
#: company/templates/company/supplier_part_detail.html:27
#: order/templates/order/purchase_order_detail.html:159
#: part/templates/part/detail.html:51 part/templates/part/set_category.html:14
#: templates/js/bom.html:158 templates/js/company.html:64
#: templates/js/bom.html:158 templates/js/company.html:56
#: templates/js/order.html:159 templates/js/order.html:234
#: templates/js/part.html:120 templates/js/part.html:268
#: templates/js/part.html:449 templates/js/stock.html:444
#: templates/js/part.html:120 templates/js/part.html:271
#: templates/js/part.html:452 templates/js/stock.html:444
#: templates/js/stock.html:658
msgid "Description"
msgstr "Beschreibung"
@ -505,8 +506,8 @@ msgstr "Beschreibung"
msgid "Reference"
msgstr "Referenz"
#: build/templates/build/allocate.html:338 part/models.py:1320
#: templates/js/part.html:453 templates/js/table_filters.html:100
#: build/templates/build/allocate.html:338 part/models.py:1332
#: templates/js/part.html:456 templates/js/table_filters.html:100
msgid "Required"
msgstr "benötigt"
@ -881,7 +882,7 @@ msgid "Description of the company"
msgstr "Firmenbeschreibung"
#: company/models.py:91 company/templates/company/company_base.html:48
#: templates/js/company.html:69
#: templates/js/company.html:61
msgid "Website"
msgstr "Website"
@ -988,7 +989,7 @@ msgid "Assigned Stock"
msgstr "Zugewiesen"
#: company/templates/company/company_base.html:7
#: company/templates/company/company_base.html:22 templates/js/company.html:41
#: company/templates/company/company_base.html:22 templates/js/company.html:33
msgid "Company"
msgstr "Firma"
@ -1004,7 +1005,7 @@ msgstr "Telefon"
#: company/templates/company/detail.html:16
#: company/templates/company/supplier_part_base.html:76
#: company/templates/company/supplier_part_detail.html:30 part/bom.py:172
#: templates/js/company.html:52 templates/js/company.html:164
#: templates/js/company.html:44 templates/js/company.html:186
msgid "Manufacturer"
msgstr "Hersteller"
@ -1013,15 +1014,15 @@ msgstr "Hersteller"
#: company/templates/company/supplier_part_detail.html:21
#: order/templates/order/order_base.html:74
#: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:170
#: stock/templates/stock/item_base.html:239 templates/js/company.html:56
#: templates/js/company.html:140 templates/js/order.html:146
#: stock/templates/stock/item_base.html:239 templates/js/company.html:48
#: templates/js/company.html:162 templates/js/order.html:146
msgid "Supplier"
msgstr "Zulieferer"
#: company/templates/company/detail.html:26
#: order/templates/order/sales_order_base.html:73 stock/models.py:354
#: stock/models.py:355 stock/templates/stock/item_base.html:161
#: templates/js/company.html:48 templates/js/order.html:221
#: templates/js/company.html:40 templates/js/order.html:221
msgid "Customer"
msgstr "Kunde"
@ -1036,7 +1037,8 @@ msgid "New Supplier Part"
msgstr "Neues Zulieferer-Teil"
#: company/templates/company/detail_part.html:15
#: part/templates/part/supplier.html:14 templates/stock_table.html:10
#: part/templates/part/category.html:103 part/templates/part/supplier.html:14
#: templates/stock_table.html:10
msgid "Options"
msgstr "Optionen"
@ -1057,16 +1059,16 @@ msgstr "Neues Teil hinzufügen"
msgid "New Supplier"
msgstr "Neuer Zulieferer"
#: company/templates/company/detail_part.html:50 company/views.py:182
#: company/templates/company/detail_part.html:50 company/views.py:186
msgid "Create new Supplier"
msgstr "Neuen Zulieferer anlegen"
#: company/templates/company/detail_part.html:55 company/views.py:57
#: company/templates/company/detail_part.html:55 company/views.py:58
#: part/templates/part/supplier.html:50
msgid "New Manufacturer"
msgstr "Neuer Hersteller"
#: company/templates/company/detail_part.html:56 company/views.py:185
#: company/templates/company/detail_part.html:56 company/views.py:189
msgid "Create new Manufacturer"
msgstr "Neuen Hersteller anlegen"
@ -1076,6 +1078,7 @@ msgstr "Zuliefererbestand"
#: company/templates/company/detail_stock.html:35
#: company/templates/company/supplier_part_stock.html:33
#: part/templates/part/category.html:100 part/templates/part/category.html:107
#: part/templates/part/stock.html:51 templates/stock_table.html:5
msgid "Export"
msgstr "Exportieren"
@ -1134,7 +1137,7 @@ msgstr "Neuer Auftrag"
#: company/templates/company/supplier_part_base.html:6
#: company/templates/company/supplier_part_base.html:19 stock/models.py:328
#: stock/templates/stock/item_base.html:244 templates/js/company.html:156
#: stock/templates/stock/item_base.html:244 templates/js/company.html:178
msgid "Supplier Part"
msgstr "Zulieferer-Teil"
@ -1168,7 +1171,7 @@ msgstr "SKU"
#: company/templates/company/supplier_part_base.html:80
#: company/templates/company/supplier_part_detail.html:31 part/bom.py:173
#: templates/js/company.html:180
#: templates/js/company.html:202
msgid "MPN"
msgstr "MPN"
@ -1221,7 +1224,7 @@ msgstr "Bepreisung"
#: company/templates/company/supplier_part_tabs.html:8
#: company/templates/company/tabs.html:12 part/templates/part/tabs.html:18
#: stock/templates/stock/location.html:12 templates/js/part.html:124
#: templates/js/part.html:295 templates/js/stock.html:452
#: templates/js/part.html:298 templates/js/stock.html:452
#: templates/navbar.html:19
msgid "Stock"
msgstr "Lagerbestand"
@ -1242,83 +1245,83 @@ msgstr "Teile"
msgid "Suppliers"
msgstr "Zulieferer"
#: company/views.py:56 templates/navbar.html:25
#: company/views.py:57 templates/navbar.html:25
msgid "Manufacturers"
msgstr "Hersteller"
#: company/views.py:62 templates/navbar.html:32
#: company/views.py:64 templates/navbar.html:32
msgid "Customers"
msgstr "Kunden"
#: company/views.py:63
#: company/views.py:65
msgid "New Customer"
msgstr "Neuer Kunde"
#: company/views.py:70
#: company/views.py:73
msgid "Companies"
msgstr "Firmen"
#: company/views.py:71
#: company/views.py:74
msgid "New Company"
msgstr "Neue Firma"
#: company/views.py:147
#: company/views.py:151
msgid "Update Company Image"
msgstr "Firmenbild aktualisieren"
#: company/views.py:152
#: company/views.py:156
msgid "Updated company image"
msgstr "Aktualisiertes Firmenbild"
#: company/views.py:162
#: company/views.py:166
msgid "Edit Company"
msgstr "Firma bearbeiten"
#: company/views.py:166
#: company/views.py:170
msgid "Edited company information"
msgstr "Firmeninformation bearbeitet"
#: company/views.py:188
#: company/views.py:192
msgid "Create new Customer"
msgstr "Neuen Kunden anlegen"
#: company/views.py:190
#: company/views.py:194
msgid "Create new Company"
msgstr "Neue Firma anlegen"
#: company/views.py:217
#: company/views.py:221
msgid "Created new company"
msgstr "Neue Firma angelegt"
#: company/views.py:227
#: company/views.py:231
msgid "Delete Company"
msgstr "Firma löschen"
#: company/views.py:232
#: company/views.py:236
msgid "Company was deleted"
msgstr "Firma gelöscht"
#: company/views.py:256
#: company/views.py:260
msgid "Edit Supplier Part"
msgstr "Zuliefererteil bearbeiten"
#: company/views.py:265 templates/js/stock.html:785
#: company/views.py:269 templates/js/stock.html:785
msgid "Create new Supplier Part"
msgstr "Neues Zuliefererteil anlegen"
#: company/views.py:325
#: company/views.py:329
msgid "Delete Supplier Part"
msgstr "Zuliefererteil entfernen"
#: company/views.py:395
#: company/views.py:399
msgid "Add Price Break"
msgstr "Preisstaffel hinzufügen"
#: company/views.py:437
#: company/views.py:441
msgid "Edit Price Break"
msgstr "Preisstaffel bearbeiten"
#: company/views.py:452
#: company/views.py:456
msgid "Delete Price Break"
msgstr "Preisstaffel löschen"
@ -1423,7 +1426,7 @@ msgstr ""
msgid "Date order was completed"
msgstr "Bestellung als vollständig markieren"
#: order/models.py:185 order/models.py:259 part/views.py:1250
#: order/models.py:185 order/models.py:259 part/views.py:1266
#: stock/models.py:239 stock/models.py:682
msgid "Quantity must be greater than zero"
msgstr "Anzahl muss größer Null sein"
@ -1609,6 +1612,7 @@ msgstr "Bestellpositionen"
#: order/templates/order/purchase_order_detail.html:38
#: order/templates/order/purchase_order_detail.html:118
#: part/templates/part/category.html:151 part/templates/part/category.html:192
#: templates/js/stock.html:790
msgid "New Location"
msgstr "Neuer Standort"
@ -1654,7 +1658,7 @@ msgid "Select parts to receive against this order"
msgstr ""
#: order/templates/order/receive_parts.html:21
#: part/templates/part/part_base.html:129 templates/js/part.html:311
#: part/templates/part/part_base.html:129 templates/js/part.html:314
msgid "On Order"
msgstr "bestellt"
@ -1983,20 +1987,36 @@ msgid "Select part category"
msgstr "Teilekategorie wählen"
#: part/forms.py:134
msgid "Perform 'deep copy' which will duplicate all BOM data for this part"
#, fuzzy
#| msgid "Perform 'deep copy' which will duplicate all BOM data for this part"
msgid "Duplicate all BOM data for this part"
msgstr ""
"Tiefe Kopie ausführen. Dies wird alle Daten der Stückliste für dieses Teil "
"duplizieren"
#: part/forms.py:139
#: part/forms.py:135
msgid "Copy BOM"
msgstr ""
#: part/forms.py:140
msgid "Duplicate all parameter data for this part"
msgstr ""
#: part/forms.py:141
#, fuzzy
#| msgid "Parameters"
msgid "Copy Parameters"
msgstr "Parameter"
#: part/forms.py:146
msgid "Confirm part creation"
msgstr "Erstellen des Teils bestätigen"
#: part/forms.py:237
#: part/forms.py:245
msgid "Input quantity for price calculation"
msgstr "Eintragsmenge zur Preisberechnung"
#: part/forms.py:240
#: part/forms.py:248
msgid "Select currency for price calculation"
msgstr "Währung zur Preisberechnung wählen"
@ -2130,13 +2150,13 @@ msgstr "Bemerkungen - unterstüzt Markdown-Formatierung"
msgid "Stored BOM checksum"
msgstr "Prüfsumme der Stückliste gespeichert"
#: part/models.py:1272
#: part/models.py:1284
#, fuzzy
#| msgid "Stock item cannot be created for a template Part"
msgid "Test templates can only be created for trackable parts"
msgstr "Lagerobjekt kann nicht für Vorlagen-Teile angelegt werden"
#: part/models.py:1289
#: part/models.py:1301
#, fuzzy
#| msgid ""
#| "A stock item with this serial number already exists for template part "
@ -2146,114 +2166,114 @@ msgstr ""
"Ein Teil mit dieser Seriennummer existiert bereits für die Teilevorlage "
"{part}"
#: part/models.py:1308 templates/js/part.html:444 templates/js/stock.html:92
#: part/models.py:1320 templates/js/part.html:447 templates/js/stock.html:92
#, fuzzy
#| msgid "Instance Name"
msgid "Test Name"
msgstr "Instanzname"
#: part/models.py:1309
#: part/models.py:1321
#, fuzzy
#| msgid "Serial number for this item"
msgid "Enter a name for the test"
msgstr "Seriennummer für dieses Teil"
#: part/models.py:1314
#: part/models.py:1326
#, fuzzy
#| msgid "Description"
msgid "Test Description"
msgstr "Beschreibung"
#: part/models.py:1315
#: part/models.py:1327
#, fuzzy
#| msgid "Brief description of the build"
msgid "Enter description for this test"
msgstr "Kurze Beschreibung des Baus"
#: part/models.py:1321
#: part/models.py:1333
msgid "Is this test required to pass?"
msgstr ""
#: part/models.py:1326 templates/js/part.html:461
#: part/models.py:1338 templates/js/part.html:464
#, fuzzy
#| msgid "Required Parts"
msgid "Requires Value"
msgstr "benötigte Teile"
#: part/models.py:1327
#: part/models.py:1339
msgid "Does this test require a value when adding a test result?"
msgstr ""
#: part/models.py:1332 templates/js/part.html:468
#: part/models.py:1344 templates/js/part.html:471
#, fuzzy
#| msgid "Delete Attachment"
msgid "Requires Attachment"
msgstr "Anhang löschen"
#: part/models.py:1333
#: part/models.py:1345
msgid "Does this test require a file attachment when adding a test result?"
msgstr ""
#: part/models.py:1366
#: part/models.py:1378
msgid "Parameter template name must be unique"
msgstr "Vorlagen-Name des Parameters muss eindeutig sein"
#: part/models.py:1371
#: part/models.py:1383
msgid "Parameter Name"
msgstr "Name des Parameters"
#: part/models.py:1373
#: part/models.py:1385
msgid "Parameter Units"
msgstr "Parameter Einheit"
#: part/models.py:1399
#: part/models.py:1411
msgid "Parent Part"
msgstr "Ausgangsteil"
#: part/models.py:1401
#: part/models.py:1413
msgid "Parameter Template"
msgstr "Parameter Vorlage"
#: part/models.py:1403
#: part/models.py:1415
msgid "Parameter Value"
msgstr "Parameter Wert"
#: part/models.py:1432
#: part/models.py:1451
msgid "Select parent part"
msgstr "Ausgangsteil auswählen"
#: part/models.py:1440
#: part/models.py:1459
msgid "Select part to be used in BOM"
msgstr "Teil für die Nutzung in der Stückliste auswählen"
#: part/models.py:1446
#: part/models.py:1465
msgid "BOM quantity for this BOM item"
msgstr "Stücklisten-Anzahl für dieses Stücklisten-Teil"
#: part/models.py:1449
#: part/models.py:1468
msgid "Estimated build wastage quantity (absolute or percentage)"
msgstr "Geschätzter Ausschuss (absolut oder prozentual)"
#: part/models.py:1452
#: part/models.py:1471
msgid "BOM item reference"
msgstr "Referenz des Objekts auf der Stückliste"
#: part/models.py:1455
#: part/models.py:1474
msgid "BOM item notes"
msgstr "Notizen zum Stücklisten-Objekt"
#: part/models.py:1457
#: part/models.py:1476
msgid "BOM line checksum"
msgstr "Prüfsumme der Stückliste"
#: part/models.py:1521 part/views.py:1256 part/views.py:1308
#: part/models.py:1540 part/views.py:1272 part/views.py:1324
#: stock/models.py:229
#, fuzzy
#| msgid "Overage must be an integer value or a percentage"
msgid "Quantity must be integer value for trackable parts"
msgstr "Überschuss muss eine Ganzzahl oder ein Prozentwert sein"
#: part/models.py:1530
#: part/models.py:1549
#, fuzzy
#| msgid "New BOM Item"
msgid "BOM Item"
@ -2317,7 +2337,7 @@ msgstr "Stückliste bearbeiten"
msgid "Validate Bill of Materials"
msgstr "Stückliste validieren"
#: part/templates/part/bom.html:46 part/views.py:1543
#: part/templates/part/bom.html:46 part/views.py:1559
msgid "Export Bill of Materials"
msgstr "Stückliste exportieren"
@ -2409,6 +2429,22 @@ msgstr ""
msgid "All parts"
msgstr "Alle Teile"
#: part/templates/part/category.html:18 part/views.py:1897
msgid "Create new part category"
msgstr "Teilkategorie anlegen"
#: part/templates/part/category.html:22
#, fuzzy
#| msgid "Edit Part Category"
msgid "Edit part category"
msgstr "Teilkategorie bearbeiten"
#: part/templates/part/category.html:25
#, fuzzy
#| msgid "Select part category"
msgid "Delete part category"
msgstr "Teilekategorie wählen"
#: part/templates/part/category.html:34 part/templates/part/category.html:73
msgid "Category Details"
msgstr "Kategorie-Details"
@ -2433,6 +2469,62 @@ msgstr "Unter-Kategorien"
msgid "Parts (Including subcategories)"
msgstr "Teile (inklusive Unter-Kategorien)"
#: part/templates/part/category.html:100
msgid "Export Part Data"
msgstr ""
#: part/templates/part/category.html:105
#, fuzzy
#| msgid "Part category"
msgid "Set category"
msgstr "Teile-Kategorie"
#: part/templates/part/category.html:105
#, fuzzy
#| msgid "Set Part Category"
msgid "Set Category"
msgstr "Teilkategorie auswählen"
#: part/templates/part/category.html:106
#, fuzzy
#| msgid "Order part"
msgid "Order parts"
msgstr "Teil bestellen"
#: part/templates/part/category.html:107
#, fuzzy
#| msgid "Export"
msgid "Export Data"
msgstr "Exportieren"
#: part/templates/part/category.html:152
#, fuzzy
#| msgid "Create New Location"
msgid "Create new location"
msgstr "Neuen Standort anlegen"
#: part/templates/part/category.html:157 part/templates/part/category.html:186
#, fuzzy
#| msgid "Category"
msgid "New Category"
msgstr "Kategorie"
#: part/templates/part/category.html:158
#, fuzzy
#| msgid "Create new part category"
msgid "Create new category"
msgstr "Teilkategorie anlegen"
#: part/templates/part/category.html:187
#, fuzzy
#| msgid "Create new part category"
msgid "Create new Part Category"
msgstr "Teilkategorie anlegen"
#: part/templates/part/category.html:193 stock/views.py:1080
msgid "Create new Stock Location"
msgstr "Neuen Lager-Standort erstellen"
#: part/templates/part/detail.html:9
msgid "Part Details"
msgstr "Teile-Details"
@ -2463,7 +2555,7 @@ msgid "Variant Of"
msgstr "Variante von"
#: part/templates/part/detail.html:70 part/templates/part/set_category.html:15
#: templates/js/part.html:282
#: templates/js/part.html:285
msgid "Category"
msgstr "Kategorie"
@ -2643,8 +2735,8 @@ msgstr "Dieses Teil ist eine Vorlage."
msgid "This part is a variant of"
msgstr "Dieses Teil ist eine Variante von"
#: part/templates/part/part_base.html:33 templates/js/company.html:131
#: templates/js/part.html:259
#: part/templates/part/part_base.html:33 templates/js/company.html:153
#: templates/js/part.html:262
msgid "Inactive"
msgstr "Inaktiv"
@ -2763,7 +2855,7 @@ msgid "Part Stock"
msgstr "Teilbestand"
#: part/templates/part/stock_count.html:7 templates/js/bom.html:204
#: templates/js/part.html:319
#: templates/js/part.html:322
msgid "No Stock"
msgstr "Kein Bestand"
@ -2896,141 +2988,137 @@ msgstr "Kategorie für {n} Teile setzen"
msgid "Create Variant"
msgstr "Variante anlegen"
#: part/views.py:358
#: part/views.py:367
msgid "Duplicate Part"
msgstr "Teil duplizieren"
#: part/views.py:363
#: part/views.py:372
msgid "Copied part"
msgstr "Teil kopiert"
#: part/views.py:474
#: part/views.py:490
msgid "Create new part"
msgstr "Neues Teil anlegen"
#: part/views.py:479
#: part/views.py:495
msgid "Created new part"
msgstr "Neues Teil angelegt"
#: part/views.py:653
#: part/views.py:669
msgid "Part QR Code"
msgstr "Teil-QR-Code"
#: part/views.py:670
#: part/views.py:686
msgid "Upload Part Image"
msgstr "Teilbild hochladen"
#: part/views.py:675 part/views.py:710
#: part/views.py:691 part/views.py:726
msgid "Updated part image"
msgstr "Teilbild aktualisiert"
#: part/views.py:684
#: part/views.py:700
msgid "Select Part Image"
msgstr "Teilbild auswählen"
#: part/views.py:713
#: part/views.py:729
msgid "Part image not found"
msgstr "Teilbild nicht gefunden"
#: part/views.py:724
#: part/views.py:740
msgid "Edit Part Properties"
msgstr "Teileigenschaften bearbeiten"
#: part/views.py:746
#: part/views.py:762
msgid "Validate BOM"
msgstr "BOM validieren"
#: part/views.py:909
#: part/views.py:925
msgid "No BOM file provided"
msgstr "Keine Stückliste angegeben"
#: part/views.py:1259
#: part/views.py:1275
msgid "Enter a valid quantity"
msgstr "Bitte eine gültige Anzahl eingeben"
#: part/views.py:1284 part/views.py:1287
#: part/views.py:1300 part/views.py:1303
msgid "Select valid part"
msgstr "Bitte ein gültiges Teil auswählen"
#: part/views.py:1293
#: part/views.py:1309
msgid "Duplicate part selected"
msgstr "Teil doppelt ausgewählt"
#: part/views.py:1331
#: part/views.py:1347
msgid "Select a part"
msgstr "Teil auswählen"
#: part/views.py:1337
#: part/views.py:1353
#, fuzzy
#| msgid "Select part to be used in BOM"
msgid "Selected part creates a circular BOM"
msgstr "Teil für die Nutzung in der Stückliste auswählen"
#: part/views.py:1341
#: part/views.py:1357
msgid "Specify quantity"
msgstr "Anzahl angeben"
#: part/views.py:1591
#: part/views.py:1607
msgid "Confirm Part Deletion"
msgstr "Löschen des Teils bestätigen"
#: part/views.py:1598
#: part/views.py:1614
msgid "Part was deleted"
msgstr "Teil wurde gelöscht"
#: part/views.py:1607
#: part/views.py:1623
msgid "Part Pricing"
msgstr "Teilbepreisung"
#: part/views.py:1729
#: part/views.py:1745
msgid "Create Part Parameter Template"
msgstr "Teilparametervorlage anlegen"
#: part/views.py:1737
#: part/views.py:1753
msgid "Edit Part Parameter Template"
msgstr "Teilparametervorlage bearbeiten"
#: part/views.py:1744
#: part/views.py:1760
msgid "Delete Part Parameter Template"
msgstr "Teilparametervorlage löschen"
#: part/views.py:1752
#: part/views.py:1768
msgid "Create Part Parameter"
msgstr "Teilparameter anlegen"
#: part/views.py:1802
#: part/views.py:1818
msgid "Edit Part Parameter"
msgstr "Teilparameter bearbeiten"
#: part/views.py:1816
#: part/views.py:1832
msgid "Delete Part Parameter"
msgstr "Teilparameter löschen"
#: part/views.py:1832
#: part/views.py:1848
msgid "Edit Part Category"
msgstr "Teilkategorie bearbeiten"
#: part/views.py:1867
#: part/views.py:1883
msgid "Delete Part Category"
msgstr "Teilkategorie löschen"
#: part/views.py:1873
#: part/views.py:1889
msgid "Part category was deleted"
msgstr "Teilekategorie wurde gelöscht"
#: part/views.py:1881
msgid "Create new part category"
msgstr "Teilkategorie anlegen"
#: part/views.py:1932
#: part/views.py:1948
msgid "Create BOM item"
msgstr "BOM-Position anlegen"
#: part/views.py:1998
#: part/views.py:2014
msgid "Edit BOM item"
msgstr "BOM-Position beaarbeiten"
#: part/views.py:2046
#: part/views.py:2062
msgid "Confim BOM item deletion"
msgstr "Löschung von BOM-Position bestätigen"
@ -3796,10 +3884,6 @@ msgstr "{n} Teile im Lager gelöscht"
msgid "Edit Stock Item"
msgstr "Lagerobjekt bearbeiten"
#: stock/views.py:1080
msgid "Create new Stock Location"
msgstr "Neuen Lager-Standort erstellen"
#: stock/views.py:1101
msgid "Serialize Stock"
msgstr "Lagerbestand erfassen"
@ -4082,23 +4166,35 @@ msgstr "Keine Baue passen zur Anfrage"
msgid "No parts allocated for"
msgstr "Keine Teile zugeordnet zu"
#: templates/js/company.html:29
#: templates/js/company.html:75
#, fuzzy
#| msgid "Suppliers"
msgid "Parts Supplied"
msgstr "Zulieferer"
#: templates/js/company.html:84
#, fuzzy
#| msgid "Manufacturer"
msgid "Parts Manufactured"
msgstr "Hersteller"
#: templates/js/company.html:96
msgid "No company information found"
msgstr "Keine Firmeninformation gefunden"
#: templates/js/company.html:106
#: templates/js/company.html:128
msgid "No supplier parts found"
msgstr "Keine Zuliefererteile gefunden"
#: templates/js/company.html:123 templates/js/part.html:237
#: templates/js/company.html:145 templates/js/part.html:240
msgid "Template part"
msgstr "Vorlagenteil"
#: templates/js/company.html:127 templates/js/part.html:241
#: templates/js/company.html:149 templates/js/part.html:244
msgid "Assembled part"
msgstr "Baugruppe"
#: templates/js/company.html:184
#: templates/js/company.html:206
msgid "Link"
msgstr "Link"
@ -4118,67 +4214,67 @@ msgstr "Keine Aufträge gefunden"
msgid "Shipment Date"
msgstr "Versanddatum"
#: templates/js/part.html:134
#: templates/js/part.html:137
#, fuzzy
#| msgid "No parts found"
msgid "No variants found"
msgstr "Keine Teile gefunden"
#: templates/js/part.html:198 templates/js/stock.html:409
#: templates/js/part.html:201 templates/js/stock.html:409
msgid "Select"
msgstr "Auswählen"
#: templates/js/part.html:245
#: templates/js/part.html:248
msgid "Starred part"
msgstr "Favoritenteil"
#: templates/js/part.html:249
#: templates/js/part.html:252
msgid "Salable part"
msgstr "Verkäufliches Teil"
#: templates/js/part.html:288
#: templates/js/part.html:291
msgid "No category"
msgstr "Keine Kategorie"
#: templates/js/part.html:306 templates/js/table_filters.html:167
#: templates/js/part.html:309 templates/js/table_filters.html:167
msgid "Low stock"
msgstr "Bestand niedrig"
#: templates/js/part.html:315
#: templates/js/part.html:318
msgid "Building"
msgstr "Im Bau"
#: templates/js/part.html:334
#: templates/js/part.html:337
msgid "No parts found"
msgstr "Keine Teile gefunden"
#: templates/js/part.html:394
#: templates/js/part.html:397
msgid "YES"
msgstr ""
#: templates/js/part.html:396
#: templates/js/part.html:399
msgid "NO"
msgstr ""
#: templates/js/part.html:430
#: templates/js/part.html:433
#, fuzzy
#| msgid "No stock items matching query"
msgid "No test templates matching query"
msgstr "Keine zur Anfrage passenden Lagerobjekte"
#: templates/js/part.html:481 templates/js/stock.html:63
#: templates/js/part.html:484 templates/js/stock.html:63
#, fuzzy
#| msgid "Edit Sales Order"
msgid "Edit test result"
msgstr "Auftrag bearbeiten"
#: templates/js/part.html:482 templates/js/stock.html:64
#: templates/js/part.html:485 templates/js/stock.html:64
#, fuzzy
#| msgid "Delete attachment"
msgid "Delete test result"
msgstr "Anhang löschen"
#: templates/js/part.html:488
#: templates/js/part.html:491
msgid "This test is defined for a parent part"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-09-02 13:57+0000\n"
"POT-Creation-Date: 2020-09-05 13:32+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -284,7 +284,7 @@ msgstr ""
#: part/templates/part/part_app_base.html:7
#: part/templates/part/set_category.html:13 templates/js/barcode.html:336
#: templates/js/bom.html:135 templates/js/build.html:43
#: templates/js/company.html:115 templates/js/part.html:212
#: templates/js/company.html:137 templates/js/part.html:215
#: templates/js/stock.html:429
msgid "Part"
msgstr ""
@ -397,6 +397,7 @@ msgstr ""
#: build/templates/build/allocate.html:17
#: company/templates/company/detail_part.html:18 order/views.py:779
#: part/templates/part/category.html:106
msgid "Order Parts"
msgstr ""
@ -470,10 +471,10 @@ msgstr ""
#: company/templates/company/supplier_part_detail.html:27
#: order/templates/order/purchase_order_detail.html:159
#: part/templates/part/detail.html:51 part/templates/part/set_category.html:14
#: templates/js/bom.html:158 templates/js/company.html:64
#: templates/js/bom.html:158 templates/js/company.html:56
#: templates/js/order.html:159 templates/js/order.html:234
#: templates/js/part.html:120 templates/js/part.html:268
#: templates/js/part.html:449 templates/js/stock.html:444
#: templates/js/part.html:120 templates/js/part.html:271
#: templates/js/part.html:452 templates/js/stock.html:444
#: templates/js/stock.html:658
msgid "Description"
msgstr ""
@ -484,8 +485,8 @@ msgstr ""
msgid "Reference"
msgstr ""
#: build/templates/build/allocate.html:338 part/models.py:1320
#: templates/js/part.html:453 templates/js/table_filters.html:100
#: build/templates/build/allocate.html:338 part/models.py:1332
#: templates/js/part.html:456 templates/js/table_filters.html:100
msgid "Required"
msgstr ""
@ -852,7 +853,7 @@ msgid "Description of the company"
msgstr ""
#: company/models.py:91 company/templates/company/company_base.html:48
#: templates/js/company.html:69
#: templates/js/company.html:61
msgid "Website"
msgstr ""
@ -955,7 +956,7 @@ msgid "Assigned Stock"
msgstr ""
#: company/templates/company/company_base.html:7
#: company/templates/company/company_base.html:22 templates/js/company.html:41
#: company/templates/company/company_base.html:22 templates/js/company.html:33
msgid "Company"
msgstr ""
@ -971,7 +972,7 @@ msgstr ""
#: company/templates/company/detail.html:16
#: company/templates/company/supplier_part_base.html:76
#: company/templates/company/supplier_part_detail.html:30 part/bom.py:172
#: templates/js/company.html:52 templates/js/company.html:164
#: templates/js/company.html:44 templates/js/company.html:186
msgid "Manufacturer"
msgstr ""
@ -980,15 +981,15 @@ msgstr ""
#: company/templates/company/supplier_part_detail.html:21
#: order/templates/order/order_base.html:74
#: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:170
#: stock/templates/stock/item_base.html:239 templates/js/company.html:56
#: templates/js/company.html:140 templates/js/order.html:146
#: stock/templates/stock/item_base.html:239 templates/js/company.html:48
#: templates/js/company.html:162 templates/js/order.html:146
msgid "Supplier"
msgstr ""
#: company/templates/company/detail.html:26
#: order/templates/order/sales_order_base.html:73 stock/models.py:354
#: stock/models.py:355 stock/templates/stock/item_base.html:161
#: templates/js/company.html:48 templates/js/order.html:221
#: templates/js/company.html:40 templates/js/order.html:221
msgid "Customer"
msgstr ""
@ -1003,7 +1004,8 @@ msgid "New Supplier Part"
msgstr ""
#: company/templates/company/detail_part.html:15
#: part/templates/part/supplier.html:14 templates/stock_table.html:10
#: part/templates/part/category.html:103 part/templates/part/supplier.html:14
#: templates/stock_table.html:10
msgid "Options"
msgstr ""
@ -1024,16 +1026,16 @@ msgstr ""
msgid "New Supplier"
msgstr ""
#: company/templates/company/detail_part.html:50 company/views.py:182
#: company/templates/company/detail_part.html:50 company/views.py:186
msgid "Create new Supplier"
msgstr ""
#: company/templates/company/detail_part.html:55 company/views.py:57
#: company/templates/company/detail_part.html:55 company/views.py:58
#: part/templates/part/supplier.html:50
msgid "New Manufacturer"
msgstr ""
#: company/templates/company/detail_part.html:56 company/views.py:185
#: company/templates/company/detail_part.html:56 company/views.py:189
msgid "Create new Manufacturer"
msgstr ""
@ -1043,6 +1045,7 @@ msgstr ""
#: company/templates/company/detail_stock.html:35
#: company/templates/company/supplier_part_stock.html:33
#: part/templates/part/category.html:100 part/templates/part/category.html:107
#: part/templates/part/stock.html:51 templates/stock_table.html:5
msgid "Export"
msgstr ""
@ -1100,7 +1103,7 @@ msgstr ""
#: company/templates/company/supplier_part_base.html:6
#: company/templates/company/supplier_part_base.html:19 stock/models.py:328
#: stock/templates/stock/item_base.html:244 templates/js/company.html:156
#: stock/templates/stock/item_base.html:244 templates/js/company.html:178
msgid "Supplier Part"
msgstr ""
@ -1134,7 +1137,7 @@ msgstr ""
#: company/templates/company/supplier_part_base.html:80
#: company/templates/company/supplier_part_detail.html:31 part/bom.py:173
#: templates/js/company.html:180
#: templates/js/company.html:202
msgid "MPN"
msgstr ""
@ -1187,7 +1190,7 @@ msgstr ""
#: company/templates/company/supplier_part_tabs.html:8
#: company/templates/company/tabs.html:12 part/templates/part/tabs.html:18
#: stock/templates/stock/location.html:12 templates/js/part.html:124
#: templates/js/part.html:295 templates/js/stock.html:452
#: templates/js/part.html:298 templates/js/stock.html:452
#: templates/navbar.html:19
msgid "Stock"
msgstr ""
@ -1208,83 +1211,83 @@ msgstr ""
msgid "Suppliers"
msgstr ""
#: company/views.py:56 templates/navbar.html:25
#: company/views.py:57 templates/navbar.html:25
msgid "Manufacturers"
msgstr ""
#: company/views.py:62 templates/navbar.html:32
#: company/views.py:64 templates/navbar.html:32
msgid "Customers"
msgstr ""
#: company/views.py:63
#: company/views.py:65
msgid "New Customer"
msgstr ""
#: company/views.py:70
#: company/views.py:73
msgid "Companies"
msgstr ""
#: company/views.py:71
#: company/views.py:74
msgid "New Company"
msgstr ""
#: company/views.py:147
#: company/views.py:151
msgid "Update Company Image"
msgstr ""
#: company/views.py:152
#: company/views.py:156
msgid "Updated company image"
msgstr ""
#: company/views.py:162
#: company/views.py:166
msgid "Edit Company"
msgstr ""
#: company/views.py:166
#: company/views.py:170
msgid "Edited company information"
msgstr ""
#: company/views.py:188
#: company/views.py:192
msgid "Create new Customer"
msgstr ""
#: company/views.py:190
#: company/views.py:194
msgid "Create new Company"
msgstr ""
#: company/views.py:217
#: company/views.py:221
msgid "Created new company"
msgstr ""
#: company/views.py:227
#: company/views.py:231
msgid "Delete Company"
msgstr ""
#: company/views.py:232
#: company/views.py:236
msgid "Company was deleted"
msgstr ""
#: company/views.py:256
#: company/views.py:260
msgid "Edit Supplier Part"
msgstr ""
#: company/views.py:265 templates/js/stock.html:785
#: company/views.py:269 templates/js/stock.html:785
msgid "Create new Supplier Part"
msgstr ""
#: company/views.py:325
#: company/views.py:329
msgid "Delete Supplier Part"
msgstr ""
#: company/views.py:395
#: company/views.py:399
msgid "Add Price Break"
msgstr ""
#: company/views.py:437
#: company/views.py:441
msgid "Edit Price Break"
msgstr ""
#: company/views.py:452
#: company/views.py:456
msgid "Delete Price Break"
msgstr ""
@ -1377,7 +1380,7 @@ msgstr ""
msgid "Date order was completed"
msgstr ""
#: order/models.py:185 order/models.py:259 part/views.py:1250
#: order/models.py:185 order/models.py:259 part/views.py:1266
#: stock/models.py:239 stock/models.py:682
msgid "Quantity must be greater than zero"
msgstr ""
@ -1562,6 +1565,7 @@ msgstr ""
#: order/templates/order/purchase_order_detail.html:38
#: order/templates/order/purchase_order_detail.html:118
#: part/templates/part/category.html:151 part/templates/part/category.html:192
#: templates/js/stock.html:790
msgid "New Location"
msgstr ""
@ -1607,7 +1611,7 @@ msgid "Select parts to receive against this order"
msgstr ""
#: order/templates/order/receive_parts.html:21
#: part/templates/part/part_base.html:129 templates/js/part.html:311
#: part/templates/part/part_base.html:129 templates/js/part.html:314
msgid "On Order"
msgstr ""
@ -1922,18 +1926,30 @@ msgid "Select part category"
msgstr ""
#: part/forms.py:134
msgid "Perform 'deep copy' which will duplicate all BOM data for this part"
msgid "Duplicate all BOM data for this part"
msgstr ""
#: part/forms.py:139
#: part/forms.py:135
msgid "Copy BOM"
msgstr ""
#: part/forms.py:140
msgid "Duplicate all parameter data for this part"
msgstr ""
#: part/forms.py:141
msgid "Copy Parameters"
msgstr ""
#: part/forms.py:146
msgid "Confirm part creation"
msgstr ""
#: part/forms.py:237
#: part/forms.py:245
msgid "Input quantity for price calculation"
msgstr ""
#: part/forms.py:240
#: part/forms.py:248
msgid "Select currency for price calculation"
msgstr ""
@ -2063,108 +2079,108 @@ msgstr ""
msgid "Stored BOM checksum"
msgstr ""
#: part/models.py:1272
#: part/models.py:1284
msgid "Test templates can only be created for trackable parts"
msgstr ""
#: part/models.py:1289
#: part/models.py:1301
msgid "Test with this name already exists for this part"
msgstr ""
#: part/models.py:1308 templates/js/part.html:444 templates/js/stock.html:92
#: part/models.py:1320 templates/js/part.html:447 templates/js/stock.html:92
msgid "Test Name"
msgstr ""
#: part/models.py:1309
#: part/models.py:1321
msgid "Enter a name for the test"
msgstr ""
#: part/models.py:1314
#: part/models.py:1326
msgid "Test Description"
msgstr ""
#: part/models.py:1315
#: part/models.py:1327
msgid "Enter description for this test"
msgstr ""
#: part/models.py:1321
#: part/models.py:1333
msgid "Is this test required to pass?"
msgstr ""
#: part/models.py:1326 templates/js/part.html:461
#: part/models.py:1338 templates/js/part.html:464
msgid "Requires Value"
msgstr ""
#: part/models.py:1327
#: part/models.py:1339
msgid "Does this test require a value when adding a test result?"
msgstr ""
#: part/models.py:1332 templates/js/part.html:468
#: part/models.py:1344 templates/js/part.html:471
msgid "Requires Attachment"
msgstr ""
#: part/models.py:1333
#: part/models.py:1345
msgid "Does this test require a file attachment when adding a test result?"
msgstr ""
#: part/models.py:1366
#: part/models.py:1378
msgid "Parameter template name must be unique"
msgstr ""
#: part/models.py:1371
#: part/models.py:1383
msgid "Parameter Name"
msgstr ""
#: part/models.py:1373
#: part/models.py:1385
msgid "Parameter Units"
msgstr ""
#: part/models.py:1399
#: part/models.py:1411
msgid "Parent Part"
msgstr ""
#: part/models.py:1401
#: part/models.py:1413
msgid "Parameter Template"
msgstr ""
#: part/models.py:1403
#: part/models.py:1415
msgid "Parameter Value"
msgstr ""
#: part/models.py:1432
#: part/models.py:1451
msgid "Select parent part"
msgstr ""
#: part/models.py:1440
#: part/models.py:1459
msgid "Select part to be used in BOM"
msgstr ""
#: part/models.py:1446
#: part/models.py:1465
msgid "BOM quantity for this BOM item"
msgstr ""
#: part/models.py:1449
#: part/models.py:1468
msgid "Estimated build wastage quantity (absolute or percentage)"
msgstr ""
#: part/models.py:1452
#: part/models.py:1471
msgid "BOM item reference"
msgstr ""
#: part/models.py:1455
#: part/models.py:1474
msgid "BOM item notes"
msgstr ""
#: part/models.py:1457
#: part/models.py:1476
msgid "BOM line checksum"
msgstr ""
#: part/models.py:1521 part/views.py:1256 part/views.py:1308
#: part/models.py:1540 part/views.py:1272 part/views.py:1324
#: stock/models.py:229
msgid "Quantity must be integer value for trackable parts"
msgstr ""
#: part/models.py:1530
#: part/models.py:1549
msgid "BOM Item"
msgstr ""
@ -2226,7 +2242,7 @@ msgstr ""
msgid "Validate Bill of Materials"
msgstr ""
#: part/templates/part/bom.html:46 part/views.py:1543
#: part/templates/part/bom.html:46 part/views.py:1559
msgid "Export Bill of Materials"
msgstr ""
@ -2302,6 +2318,18 @@ msgstr ""
msgid "All parts"
msgstr ""
#: part/templates/part/category.html:18 part/views.py:1897
msgid "Create new part category"
msgstr ""
#: part/templates/part/category.html:22
msgid "Edit part category"
msgstr ""
#: part/templates/part/category.html:25
msgid "Delete part category"
msgstr ""
#: part/templates/part/category.html:34 part/templates/part/category.html:73
msgid "Category Details"
msgstr ""
@ -2326,6 +2354,46 @@ msgstr ""
msgid "Parts (Including subcategories)"
msgstr ""
#: part/templates/part/category.html:100
msgid "Export Part Data"
msgstr ""
#: part/templates/part/category.html:105
msgid "Set category"
msgstr ""
#: part/templates/part/category.html:105
msgid "Set Category"
msgstr ""
#: part/templates/part/category.html:106
msgid "Order parts"
msgstr ""
#: part/templates/part/category.html:107
msgid "Export Data"
msgstr ""
#: part/templates/part/category.html:152
msgid "Create new location"
msgstr ""
#: part/templates/part/category.html:157 part/templates/part/category.html:186
msgid "New Category"
msgstr ""
#: part/templates/part/category.html:158
msgid "Create new category"
msgstr ""
#: part/templates/part/category.html:187
msgid "Create new Part Category"
msgstr ""
#: part/templates/part/category.html:193 stock/views.py:1080
msgid "Create new Stock Location"
msgstr ""
#: part/templates/part/detail.html:9
msgid "Part Details"
msgstr ""
@ -2352,7 +2420,7 @@ msgid "Variant Of"
msgstr ""
#: part/templates/part/detail.html:70 part/templates/part/set_category.html:15
#: templates/js/part.html:282
#: templates/js/part.html:285
msgid "Category"
msgstr ""
@ -2522,8 +2590,8 @@ msgstr ""
msgid "This part is a variant of"
msgstr ""
#: part/templates/part/part_base.html:33 templates/js/company.html:131
#: templates/js/part.html:259
#: part/templates/part/part_base.html:33 templates/js/company.html:153
#: templates/js/part.html:262
msgid "Inactive"
msgstr ""
@ -2626,7 +2694,7 @@ msgid "Part Stock"
msgstr ""
#: part/templates/part/stock_count.html:7 templates/js/bom.html:204
#: templates/js/part.html:319
#: templates/js/part.html:322
msgid "No Stock"
msgstr ""
@ -2739,139 +2807,135 @@ msgstr ""
msgid "Create Variant"
msgstr ""
#: part/views.py:358
#: part/views.py:367
msgid "Duplicate Part"
msgstr ""
#: part/views.py:363
#: part/views.py:372
msgid "Copied part"
msgstr ""
#: part/views.py:474
#: part/views.py:490
msgid "Create new part"
msgstr ""
#: part/views.py:479
#: part/views.py:495
msgid "Created new part"
msgstr ""
#: part/views.py:653
#: part/views.py:669
msgid "Part QR Code"
msgstr ""
#: part/views.py:670
#: part/views.py:686
msgid "Upload Part Image"
msgstr ""
#: part/views.py:675 part/views.py:710
#: part/views.py:691 part/views.py:726
msgid "Updated part image"
msgstr ""
#: part/views.py:684
#: part/views.py:700
msgid "Select Part Image"
msgstr ""
#: part/views.py:713
#: part/views.py:729
msgid "Part image not found"
msgstr ""
#: part/views.py:724
#: part/views.py:740
msgid "Edit Part Properties"
msgstr ""
#: part/views.py:746
#: part/views.py:762
msgid "Validate BOM"
msgstr ""
#: part/views.py:909
#: part/views.py:925
msgid "No BOM file provided"
msgstr ""
#: part/views.py:1259
#: part/views.py:1275
msgid "Enter a valid quantity"
msgstr ""
#: part/views.py:1284 part/views.py:1287
#: part/views.py:1300 part/views.py:1303
msgid "Select valid part"
msgstr ""
#: part/views.py:1293
#: part/views.py:1309
msgid "Duplicate part selected"
msgstr ""
#: part/views.py:1331
#: part/views.py:1347
msgid "Select a part"
msgstr ""
#: part/views.py:1337
#: part/views.py:1353
msgid "Selected part creates a circular BOM"
msgstr ""
#: part/views.py:1341
#: part/views.py:1357
msgid "Specify quantity"
msgstr ""
#: part/views.py:1591
#: part/views.py:1607
msgid "Confirm Part Deletion"
msgstr ""
#: part/views.py:1598
#: part/views.py:1614
msgid "Part was deleted"
msgstr ""
#: part/views.py:1607
#: part/views.py:1623
msgid "Part Pricing"
msgstr ""
#: part/views.py:1729
#: part/views.py:1745
msgid "Create Part Parameter Template"
msgstr ""
#: part/views.py:1737
#: part/views.py:1753
msgid "Edit Part Parameter Template"
msgstr ""
#: part/views.py:1744
#: part/views.py:1760
msgid "Delete Part Parameter Template"
msgstr ""
#: part/views.py:1752
#: part/views.py:1768
msgid "Create Part Parameter"
msgstr ""
#: part/views.py:1802
#: part/views.py:1818
msgid "Edit Part Parameter"
msgstr ""
#: part/views.py:1816
#: part/views.py:1832
msgid "Delete Part Parameter"
msgstr ""
#: part/views.py:1832
#: part/views.py:1848
msgid "Edit Part Category"
msgstr ""
#: part/views.py:1867
#: part/views.py:1883
msgid "Delete Part Category"
msgstr ""
#: part/views.py:1873
#: part/views.py:1889
msgid "Part category was deleted"
msgstr ""
#: part/views.py:1881
msgid "Create new part category"
msgstr ""
#: part/views.py:1932
#: part/views.py:1948
msgid "Create BOM item"
msgstr ""
#: part/views.py:1998
#: part/views.py:2014
msgid "Edit BOM item"
msgstr ""
#: part/views.py:2046
#: part/views.py:2062
msgid "Confim BOM item deletion"
msgstr ""
@ -3526,10 +3590,6 @@ msgstr ""
msgid "Edit Stock Item"
msgstr ""
#: stock/views.py:1080
msgid "Create new Stock Location"
msgstr ""
#: stock/views.py:1101
msgid "Serialize Stock"
msgstr ""
@ -3780,23 +3840,31 @@ msgstr ""
msgid "No parts allocated for"
msgstr ""
#: templates/js/company.html:29
#: templates/js/company.html:75
msgid "Parts Supplied"
msgstr ""
#: templates/js/company.html:84
msgid "Parts Manufactured"
msgstr ""
#: templates/js/company.html:96
msgid "No company information found"
msgstr ""
#: templates/js/company.html:106
#: templates/js/company.html:128
msgid "No supplier parts found"
msgstr ""
#: templates/js/company.html:123 templates/js/part.html:237
#: templates/js/company.html:145 templates/js/part.html:240
msgid "Template part"
msgstr ""
#: templates/js/company.html:127 templates/js/part.html:241
#: templates/js/company.html:149 templates/js/part.html:244
msgid "Assembled part"
msgstr ""
#: templates/js/company.html:184
#: templates/js/company.html:206
msgid "Link"
msgstr ""
@ -3816,59 +3884,59 @@ msgstr ""
msgid "Shipment Date"
msgstr ""
#: templates/js/part.html:134
#: templates/js/part.html:137
msgid "No variants found"
msgstr ""
#: templates/js/part.html:198 templates/js/stock.html:409
#: templates/js/part.html:201 templates/js/stock.html:409
msgid "Select"
msgstr ""
#: templates/js/part.html:245
#: templates/js/part.html:248
msgid "Starred part"
msgstr ""
#: templates/js/part.html:249
#: templates/js/part.html:252
msgid "Salable part"
msgstr ""
#: templates/js/part.html:288
#: templates/js/part.html:291
msgid "No category"
msgstr ""
#: templates/js/part.html:306 templates/js/table_filters.html:167
#: templates/js/part.html:309 templates/js/table_filters.html:167
msgid "Low stock"
msgstr ""
#: templates/js/part.html:315
#: templates/js/part.html:318
msgid "Building"
msgstr ""
#: templates/js/part.html:334
#: templates/js/part.html:337
msgid "No parts found"
msgstr ""
#: templates/js/part.html:394
#: templates/js/part.html:397
msgid "YES"
msgstr ""
#: templates/js/part.html:396
#: templates/js/part.html:399
msgid "NO"
msgstr ""
#: templates/js/part.html:430
#: templates/js/part.html:433
msgid "No test templates matching query"
msgstr ""
#: templates/js/part.html:481 templates/js/stock.html:63
#: templates/js/part.html:484 templates/js/stock.html:63
msgid "Edit test result"
msgstr ""
#: templates/js/part.html:482 templates/js/stock.html:64
#: templates/js/part.html:485 templates/js/stock.html:64
msgid "Delete test result"
msgstr ""
#: templates/js/part.html:488
#: templates/js/part.html:491
msgid "This test is defined for a parent part"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-09-02 13:57+0000\n"
"POT-Creation-Date: 2020-09-05 13:32+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -284,7 +284,7 @@ msgstr ""
#: part/templates/part/part_app_base.html:7
#: part/templates/part/set_category.html:13 templates/js/barcode.html:336
#: templates/js/bom.html:135 templates/js/build.html:43
#: templates/js/company.html:115 templates/js/part.html:212
#: templates/js/company.html:137 templates/js/part.html:215
#: templates/js/stock.html:429
msgid "Part"
msgstr ""
@ -397,6 +397,7 @@ msgstr ""
#: build/templates/build/allocate.html:17
#: company/templates/company/detail_part.html:18 order/views.py:779
#: part/templates/part/category.html:106
msgid "Order Parts"
msgstr ""
@ -470,10 +471,10 @@ msgstr ""
#: company/templates/company/supplier_part_detail.html:27
#: order/templates/order/purchase_order_detail.html:159
#: part/templates/part/detail.html:51 part/templates/part/set_category.html:14
#: templates/js/bom.html:158 templates/js/company.html:64
#: templates/js/bom.html:158 templates/js/company.html:56
#: templates/js/order.html:159 templates/js/order.html:234
#: templates/js/part.html:120 templates/js/part.html:268
#: templates/js/part.html:449 templates/js/stock.html:444
#: templates/js/part.html:120 templates/js/part.html:271
#: templates/js/part.html:452 templates/js/stock.html:444
#: templates/js/stock.html:658
msgid "Description"
msgstr ""
@ -484,8 +485,8 @@ msgstr ""
msgid "Reference"
msgstr ""
#: build/templates/build/allocate.html:338 part/models.py:1320
#: templates/js/part.html:453 templates/js/table_filters.html:100
#: build/templates/build/allocate.html:338 part/models.py:1332
#: templates/js/part.html:456 templates/js/table_filters.html:100
msgid "Required"
msgstr ""
@ -852,7 +853,7 @@ msgid "Description of the company"
msgstr ""
#: company/models.py:91 company/templates/company/company_base.html:48
#: templates/js/company.html:69
#: templates/js/company.html:61
msgid "Website"
msgstr ""
@ -955,7 +956,7 @@ msgid "Assigned Stock"
msgstr ""
#: company/templates/company/company_base.html:7
#: company/templates/company/company_base.html:22 templates/js/company.html:41
#: company/templates/company/company_base.html:22 templates/js/company.html:33
msgid "Company"
msgstr ""
@ -971,7 +972,7 @@ msgstr ""
#: company/templates/company/detail.html:16
#: company/templates/company/supplier_part_base.html:76
#: company/templates/company/supplier_part_detail.html:30 part/bom.py:172
#: templates/js/company.html:52 templates/js/company.html:164
#: templates/js/company.html:44 templates/js/company.html:186
msgid "Manufacturer"
msgstr ""
@ -980,15 +981,15 @@ msgstr ""
#: company/templates/company/supplier_part_detail.html:21
#: order/templates/order/order_base.html:74
#: order/templates/order/order_wizard/select_pos.html:30 part/bom.py:170
#: stock/templates/stock/item_base.html:239 templates/js/company.html:56
#: templates/js/company.html:140 templates/js/order.html:146
#: stock/templates/stock/item_base.html:239 templates/js/company.html:48
#: templates/js/company.html:162 templates/js/order.html:146
msgid "Supplier"
msgstr ""
#: company/templates/company/detail.html:26
#: order/templates/order/sales_order_base.html:73 stock/models.py:354
#: stock/models.py:355 stock/templates/stock/item_base.html:161
#: templates/js/company.html:48 templates/js/order.html:221
#: templates/js/company.html:40 templates/js/order.html:221
msgid "Customer"
msgstr ""
@ -1003,7 +1004,8 @@ msgid "New Supplier Part"
msgstr ""
#: company/templates/company/detail_part.html:15
#: part/templates/part/supplier.html:14 templates/stock_table.html:10
#: part/templates/part/category.html:103 part/templates/part/supplier.html:14
#: templates/stock_table.html:10
msgid "Options"
msgstr ""
@ -1024,16 +1026,16 @@ msgstr ""
msgid "New Supplier"
msgstr ""
#: company/templates/company/detail_part.html:50 company/views.py:182
#: company/templates/company/detail_part.html:50 company/views.py:186
msgid "Create new Supplier"
msgstr ""
#: company/templates/company/detail_part.html:55 company/views.py:57
#: company/templates/company/detail_part.html:55 company/views.py:58
#: part/templates/part/supplier.html:50
msgid "New Manufacturer"
msgstr ""
#: company/templates/company/detail_part.html:56 company/views.py:185
#: company/templates/company/detail_part.html:56 company/views.py:189
msgid "Create new Manufacturer"
msgstr ""
@ -1043,6 +1045,7 @@ msgstr ""
#: company/templates/company/detail_stock.html:35
#: company/templates/company/supplier_part_stock.html:33
#: part/templates/part/category.html:100 part/templates/part/category.html:107
#: part/templates/part/stock.html:51 templates/stock_table.html:5
msgid "Export"
msgstr ""
@ -1100,7 +1103,7 @@ msgstr ""
#: company/templates/company/supplier_part_base.html:6
#: company/templates/company/supplier_part_base.html:19 stock/models.py:328
#: stock/templates/stock/item_base.html:244 templates/js/company.html:156
#: stock/templates/stock/item_base.html:244 templates/js/company.html:178
msgid "Supplier Part"
msgstr ""
@ -1134,7 +1137,7 @@ msgstr ""
#: company/templates/company/supplier_part_base.html:80
#: company/templates/company/supplier_part_detail.html:31 part/bom.py:173
#: templates/js/company.html:180
#: templates/js/company.html:202
msgid "MPN"
msgstr ""
@ -1187,7 +1190,7 @@ msgstr ""
#: company/templates/company/supplier_part_tabs.html:8
#: company/templates/company/tabs.html:12 part/templates/part/tabs.html:18
#: stock/templates/stock/location.html:12 templates/js/part.html:124
#: templates/js/part.html:295 templates/js/stock.html:452
#: templates/js/part.html:298 templates/js/stock.html:452
#: templates/navbar.html:19
msgid "Stock"
msgstr ""
@ -1208,83 +1211,83 @@ msgstr ""
msgid "Suppliers"
msgstr ""
#: company/views.py:56 templates/navbar.html:25
#: company/views.py:57 templates/navbar.html:25
msgid "Manufacturers"
msgstr ""
#: company/views.py:62 templates/navbar.html:32
#: company/views.py:64 templates/navbar.html:32
msgid "Customers"
msgstr ""
#: company/views.py:63
#: company/views.py:65
msgid "New Customer"
msgstr ""
#: company/views.py:70
#: company/views.py:73
msgid "Companies"
msgstr ""
#: company/views.py:71
#: company/views.py:74
msgid "New Company"
msgstr ""
#: company/views.py:147
#: company/views.py:151
msgid "Update Company Image"
msgstr ""
#: company/views.py:152
#: company/views.py:156
msgid "Updated company image"
msgstr ""
#: company/views.py:162
#: company/views.py:166
msgid "Edit Company"
msgstr ""
#: company/views.py:166
#: company/views.py:170
msgid "Edited company information"
msgstr ""
#: company/views.py:188
#: company/views.py:192
msgid "Create new Customer"
msgstr ""
#: company/views.py:190
#: company/views.py:194
msgid "Create new Company"
msgstr ""
#: company/views.py:217
#: company/views.py:221
msgid "Created new company"
msgstr ""
#: company/views.py:227
#: company/views.py:231
msgid "Delete Company"
msgstr ""
#: company/views.py:232
#: company/views.py:236
msgid "Company was deleted"
msgstr ""
#: company/views.py:256
#: company/views.py:260
msgid "Edit Supplier Part"
msgstr ""
#: company/views.py:265 templates/js/stock.html:785
#: company/views.py:269 templates/js/stock.html:785
msgid "Create new Supplier Part"
msgstr ""
#: company/views.py:325
#: company/views.py:329
msgid "Delete Supplier Part"
msgstr ""
#: company/views.py:395
#: company/views.py:399
msgid "Add Price Break"
msgstr ""
#: company/views.py:437
#: company/views.py:441
msgid "Edit Price Break"
msgstr ""
#: company/views.py:452
#: company/views.py:456
msgid "Delete Price Break"
msgstr ""
@ -1377,7 +1380,7 @@ msgstr ""
msgid "Date order was completed"
msgstr ""
#: order/models.py:185 order/models.py:259 part/views.py:1250
#: order/models.py:185 order/models.py:259 part/views.py:1266
#: stock/models.py:239 stock/models.py:682
msgid "Quantity must be greater than zero"
msgstr ""
@ -1562,6 +1565,7 @@ msgstr ""
#: order/templates/order/purchase_order_detail.html:38
#: order/templates/order/purchase_order_detail.html:118
#: part/templates/part/category.html:151 part/templates/part/category.html:192
#: templates/js/stock.html:790
msgid "New Location"
msgstr ""
@ -1607,7 +1611,7 @@ msgid "Select parts to receive against this order"
msgstr ""
#: order/templates/order/receive_parts.html:21
#: part/templates/part/part_base.html:129 templates/js/part.html:311
#: part/templates/part/part_base.html:129 templates/js/part.html:314
msgid "On Order"
msgstr ""
@ -1922,18 +1926,30 @@ msgid "Select part category"
msgstr ""
#: part/forms.py:134
msgid "Perform 'deep copy' which will duplicate all BOM data for this part"
msgid "Duplicate all BOM data for this part"
msgstr ""
#: part/forms.py:139
#: part/forms.py:135
msgid "Copy BOM"
msgstr ""
#: part/forms.py:140
msgid "Duplicate all parameter data for this part"
msgstr ""
#: part/forms.py:141
msgid "Copy Parameters"
msgstr ""
#: part/forms.py:146
msgid "Confirm part creation"
msgstr ""
#: part/forms.py:237
#: part/forms.py:245
msgid "Input quantity for price calculation"
msgstr ""
#: part/forms.py:240
#: part/forms.py:248
msgid "Select currency for price calculation"
msgstr ""
@ -2063,108 +2079,108 @@ msgstr ""
msgid "Stored BOM checksum"
msgstr ""
#: part/models.py:1272
#: part/models.py:1284
msgid "Test templates can only be created for trackable parts"
msgstr ""
#: part/models.py:1289
#: part/models.py:1301
msgid "Test with this name already exists for this part"
msgstr ""
#: part/models.py:1308 templates/js/part.html:444 templates/js/stock.html:92
#: part/models.py:1320 templates/js/part.html:447 templates/js/stock.html:92
msgid "Test Name"
msgstr ""
#: part/models.py:1309
#: part/models.py:1321
msgid "Enter a name for the test"
msgstr ""
#: part/models.py:1314
#: part/models.py:1326
msgid "Test Description"
msgstr ""
#: part/models.py:1315
#: part/models.py:1327
msgid "Enter description for this test"
msgstr ""
#: part/models.py:1321
#: part/models.py:1333
msgid "Is this test required to pass?"
msgstr ""
#: part/models.py:1326 templates/js/part.html:461
#: part/models.py:1338 templates/js/part.html:464
msgid "Requires Value"
msgstr ""
#: part/models.py:1327
#: part/models.py:1339
msgid "Does this test require a value when adding a test result?"
msgstr ""
#: part/models.py:1332 templates/js/part.html:468
#: part/models.py:1344 templates/js/part.html:471
msgid "Requires Attachment"
msgstr ""
#: part/models.py:1333
#: part/models.py:1345
msgid "Does this test require a file attachment when adding a test result?"
msgstr ""
#: part/models.py:1366
#: part/models.py:1378
msgid "Parameter template name must be unique"
msgstr ""
#: part/models.py:1371
#: part/models.py:1383
msgid "Parameter Name"
msgstr ""
#: part/models.py:1373
#: part/models.py:1385
msgid "Parameter Units"
msgstr ""
#: part/models.py:1399
#: part/models.py:1411
msgid "Parent Part"
msgstr ""
#: part/models.py:1401
#: part/models.py:1413
msgid "Parameter Template"
msgstr ""
#: part/models.py:1403
#: part/models.py:1415
msgid "Parameter Value"
msgstr ""
#: part/models.py:1432
#: part/models.py:1451
msgid "Select parent part"
msgstr ""
#: part/models.py:1440
#: part/models.py:1459
msgid "Select part to be used in BOM"
msgstr ""
#: part/models.py:1446
#: part/models.py:1465
msgid "BOM quantity for this BOM item"
msgstr ""
#: part/models.py:1449
#: part/models.py:1468
msgid "Estimated build wastage quantity (absolute or percentage)"
msgstr ""
#: part/models.py:1452
#: part/models.py:1471
msgid "BOM item reference"
msgstr ""
#: part/models.py:1455
#: part/models.py:1474
msgid "BOM item notes"
msgstr ""
#: part/models.py:1457
#: part/models.py:1476
msgid "BOM line checksum"
msgstr ""
#: part/models.py:1521 part/views.py:1256 part/views.py:1308
#: part/models.py:1540 part/views.py:1272 part/views.py:1324
#: stock/models.py:229
msgid "Quantity must be integer value for trackable parts"
msgstr ""
#: part/models.py:1530
#: part/models.py:1549
msgid "BOM Item"
msgstr ""
@ -2226,7 +2242,7 @@ msgstr ""
msgid "Validate Bill of Materials"
msgstr ""
#: part/templates/part/bom.html:46 part/views.py:1543
#: part/templates/part/bom.html:46 part/views.py:1559
msgid "Export Bill of Materials"
msgstr ""
@ -2302,6 +2318,18 @@ msgstr ""
msgid "All parts"
msgstr ""
#: part/templates/part/category.html:18 part/views.py:1897
msgid "Create new part category"
msgstr ""
#: part/templates/part/category.html:22
msgid "Edit part category"
msgstr ""
#: part/templates/part/category.html:25
msgid "Delete part category"
msgstr ""
#: part/templates/part/category.html:34 part/templates/part/category.html:73
msgid "Category Details"
msgstr ""
@ -2326,6 +2354,46 @@ msgstr ""
msgid "Parts (Including subcategories)"
msgstr ""
#: part/templates/part/category.html:100
msgid "Export Part Data"
msgstr ""
#: part/templates/part/category.html:105
msgid "Set category"
msgstr ""
#: part/templates/part/category.html:105
msgid "Set Category"
msgstr ""
#: part/templates/part/category.html:106
msgid "Order parts"
msgstr ""
#: part/templates/part/category.html:107
msgid "Export Data"
msgstr ""
#: part/templates/part/category.html:152
msgid "Create new location"
msgstr ""
#: part/templates/part/category.html:157 part/templates/part/category.html:186
msgid "New Category"
msgstr ""
#: part/templates/part/category.html:158
msgid "Create new category"
msgstr ""
#: part/templates/part/category.html:187
msgid "Create new Part Category"
msgstr ""
#: part/templates/part/category.html:193 stock/views.py:1080
msgid "Create new Stock Location"
msgstr ""
#: part/templates/part/detail.html:9
msgid "Part Details"
msgstr ""
@ -2352,7 +2420,7 @@ msgid "Variant Of"
msgstr ""
#: part/templates/part/detail.html:70 part/templates/part/set_category.html:15
#: templates/js/part.html:282
#: templates/js/part.html:285
msgid "Category"
msgstr ""
@ -2522,8 +2590,8 @@ msgstr ""
msgid "This part is a variant of"
msgstr ""
#: part/templates/part/part_base.html:33 templates/js/company.html:131
#: templates/js/part.html:259
#: part/templates/part/part_base.html:33 templates/js/company.html:153
#: templates/js/part.html:262
msgid "Inactive"
msgstr ""
@ -2626,7 +2694,7 @@ msgid "Part Stock"
msgstr ""
#: part/templates/part/stock_count.html:7 templates/js/bom.html:204
#: templates/js/part.html:319
#: templates/js/part.html:322
msgid "No Stock"
msgstr ""
@ -2739,139 +2807,135 @@ msgstr ""
msgid "Create Variant"
msgstr ""
#: part/views.py:358
#: part/views.py:367
msgid "Duplicate Part"
msgstr ""
#: part/views.py:363
#: part/views.py:372
msgid "Copied part"
msgstr ""
#: part/views.py:474
#: part/views.py:490
msgid "Create new part"
msgstr ""
#: part/views.py:479
#: part/views.py:495
msgid "Created new part"
msgstr ""
#: part/views.py:653
#: part/views.py:669
msgid "Part QR Code"
msgstr ""
#: part/views.py:670
#: part/views.py:686
msgid "Upload Part Image"
msgstr ""
#: part/views.py:675 part/views.py:710
#: part/views.py:691 part/views.py:726
msgid "Updated part image"
msgstr ""
#: part/views.py:684
#: part/views.py:700
msgid "Select Part Image"
msgstr ""
#: part/views.py:713
#: part/views.py:729
msgid "Part image not found"
msgstr ""
#: part/views.py:724
#: part/views.py:740
msgid "Edit Part Properties"
msgstr ""
#: part/views.py:746
#: part/views.py:762
msgid "Validate BOM"
msgstr ""
#: part/views.py:909
#: part/views.py:925
msgid "No BOM file provided"
msgstr ""
#: part/views.py:1259
#: part/views.py:1275
msgid "Enter a valid quantity"
msgstr ""
#: part/views.py:1284 part/views.py:1287
#: part/views.py:1300 part/views.py:1303
msgid "Select valid part"
msgstr ""
#: part/views.py:1293
#: part/views.py:1309
msgid "Duplicate part selected"
msgstr ""
#: part/views.py:1331
#: part/views.py:1347
msgid "Select a part"
msgstr ""
#: part/views.py:1337
#: part/views.py:1353
msgid "Selected part creates a circular BOM"
msgstr ""
#: part/views.py:1341
#: part/views.py:1357
msgid "Specify quantity"
msgstr ""
#: part/views.py:1591
#: part/views.py:1607
msgid "Confirm Part Deletion"
msgstr ""
#: part/views.py:1598
#: part/views.py:1614
msgid "Part was deleted"
msgstr ""
#: part/views.py:1607
#: part/views.py:1623
msgid "Part Pricing"
msgstr ""
#: part/views.py:1729
#: part/views.py:1745
msgid "Create Part Parameter Template"
msgstr ""
#: part/views.py:1737
#: part/views.py:1753
msgid "Edit Part Parameter Template"
msgstr ""
#: part/views.py:1744
#: part/views.py:1760
msgid "Delete Part Parameter Template"
msgstr ""
#: part/views.py:1752
#: part/views.py:1768
msgid "Create Part Parameter"
msgstr ""
#: part/views.py:1802
#: part/views.py:1818
msgid "Edit Part Parameter"
msgstr ""
#: part/views.py:1816
#: part/views.py:1832
msgid "Delete Part Parameter"
msgstr ""
#: part/views.py:1832
#: part/views.py:1848
msgid "Edit Part Category"
msgstr ""
#: part/views.py:1867
#: part/views.py:1883
msgid "Delete Part Category"
msgstr ""
#: part/views.py:1873
#: part/views.py:1889
msgid "Part category was deleted"
msgstr ""
#: part/views.py:1881
msgid "Create new part category"
msgstr ""
#: part/views.py:1932
#: part/views.py:1948
msgid "Create BOM item"
msgstr ""
#: part/views.py:1998
#: part/views.py:2014
msgid "Edit BOM item"
msgstr ""
#: part/views.py:2046
#: part/views.py:2062
msgid "Confim BOM item deletion"
msgstr ""
@ -3526,10 +3590,6 @@ msgstr ""
msgid "Edit Stock Item"
msgstr ""
#: stock/views.py:1080
msgid "Create new Stock Location"
msgstr ""
#: stock/views.py:1101
msgid "Serialize Stock"
msgstr ""
@ -3780,23 +3840,31 @@ msgstr ""
msgid "No parts allocated for"
msgstr ""
#: templates/js/company.html:29
#: templates/js/company.html:75
msgid "Parts Supplied"
msgstr ""
#: templates/js/company.html:84
msgid "Parts Manufactured"
msgstr ""
#: templates/js/company.html:96
msgid "No company information found"
msgstr ""
#: templates/js/company.html:106
#: templates/js/company.html:128
msgid "No supplier parts found"
msgstr ""
#: templates/js/company.html:123 templates/js/part.html:237
#: templates/js/company.html:145 templates/js/part.html:240
msgid "Template part"
msgstr ""
#: templates/js/company.html:127 templates/js/part.html:241
#: templates/js/company.html:149 templates/js/part.html:244
msgid "Assembled part"
msgstr ""
#: templates/js/company.html:184
#: templates/js/company.html:206
msgid "Link"
msgstr ""
@ -3816,59 +3884,59 @@ msgstr ""
msgid "Shipment Date"
msgstr ""
#: templates/js/part.html:134
#: templates/js/part.html:137
msgid "No variants found"
msgstr ""
#: templates/js/part.html:198 templates/js/stock.html:409
#: templates/js/part.html:201 templates/js/stock.html:409
msgid "Select"
msgstr ""
#: templates/js/part.html:245
#: templates/js/part.html:248
msgid "Starred part"
msgstr ""
#: templates/js/part.html:249
#: templates/js/part.html:252
msgid "Salable part"
msgstr ""
#: templates/js/part.html:288
#: templates/js/part.html:291
msgid "No category"
msgstr ""
#: templates/js/part.html:306 templates/js/table_filters.html:167
#: templates/js/part.html:309 templates/js/table_filters.html:167
msgid "Low stock"
msgstr ""
#: templates/js/part.html:315
#: templates/js/part.html:318
msgid "Building"
msgstr ""
#: templates/js/part.html:334
#: templates/js/part.html:337
msgid "No parts found"
msgstr ""
#: templates/js/part.html:394
#: templates/js/part.html:397
msgid "YES"
msgstr ""
#: templates/js/part.html:396
#: templates/js/part.html:399
msgid "NO"
msgstr ""
#: templates/js/part.html:430
#: templates/js/part.html:433
msgid "No test templates matching query"
msgstr ""
#: templates/js/part.html:481 templates/js/stock.html:63
#: templates/js/part.html:484 templates/js/stock.html:63
msgid "Edit test result"
msgstr ""
#: templates/js/part.html:482 templates/js/stock.html:64
#: templates/js/part.html:485 templates/js/stock.html:64
msgid "Delete test result"
msgstr ""
#: templates/js/part.html:488
#: templates/js/part.html:491
msgid "This test is defined for a parent part"
msgstr ""

View File

@ -7,7 +7,7 @@ from __future__ import unicode_literals
from rest_framework import serializers
from django.db.models import Count
from sql_util.utils import SubqueryCount
from InvenTree.serializers import InvenTreeModelSerializer
from InvenTree.serializers import InvenTreeAttachmentSerializerField
@ -39,10 +39,12 @@ class POSerializer(InvenTreeModelSerializer):
Add extra information to the queryset
"""
return queryset.annotate(
line_items=Count('lines'),
queryset = queryset.annotate(
line_items=SubqueryCount('lines')
)
return queryset
supplier_detail = CompanyBriefSerializer(source='supplier', many=False, read_only=True)
line_items = serializers.IntegerField(read_only=True)
@ -147,10 +149,12 @@ class SalesOrderSerializer(InvenTreeModelSerializer):
Add extra information to the queryset
"""
return queryset.annotate(
line_items=Count('lines'),
queryset = queryset.annotate(
line_items=SubqueryCount('lines')
)
return queryset
customer_detail = CompanyBriefSerializer(source='customer', many=False, read_only=True)
line_items = serializers.IntegerField(read_only=True)

View File

@ -377,6 +377,7 @@ class PartList(generics.ListCreateAPIView):
def get_queryset(self, *args, **kwargs):
queryset = super().get_queryset(*args, **kwargs)
queryset = part_serializers.PartSerializer.prefetch_queryset(queryset)
queryset = part_serializers.PartSerializer.annotate_queryset(queryset)

View File

@ -13,12 +13,16 @@ from .models import PartParameter, PartParameterTemplate
from .models import PartAttachment
from .models import PartTestTemplate
from stock.models import StockItem
from decimal import Decimal
from django.db.models import Q, Sum
from sql_util.utils import SubquerySum, SubqueryCount
from django.db.models import Q
from django.db.models.functions import Coalesce
from InvenTree.status_codes import StockStatus, PurchaseOrderStatus, BuildStatus
from InvenTree.status_codes import PurchaseOrderStatus, BuildStatus
from InvenTree.serializers import InvenTreeModelSerializer
from InvenTree.serializers import InvenTreeAttachmentSerializerField
@ -189,29 +193,45 @@ class PartSerializer(InvenTreeModelSerializer):
to reduce database trips.
"""
# Filter to limit stock items to "available"
stock_filter = Q(stock_items__status__in=StockStatus.AVAILABLE_CODES)
# Annotate with the total 'in stock' quantity
queryset = queryset.annotate(
in_stock=Coalesce(
SubquerySum('stock_items__quantity', filter=StockItem.IN_STOCK_FILTER),
Decimal(0)
),
)
# Filter to limit orders to "open"
order_filter = Q(supplier_parts__purchase_order_line_items__order__status__in=PurchaseOrderStatus.OPEN)
# Annotate with the total number of stock items
queryset = queryset.annotate(
stock_item_count=SubqueryCount('stock_items')
)
# Filter to limit builds to "active"
build_filter = Q(builds__status__in=BuildStatus.ACTIVE_CODES)
build_filter = Q(
status__in=BuildStatus.ACTIVE_CODES
)
# Annotate the number total stock count
# Annotate with the total 'building' quantity
queryset = queryset.annotate(
in_stock=Coalesce(Sum('stock_items__quantity', filter=stock_filter, distinct=True), Decimal(0)),
ordering=Coalesce(Sum(
'supplier_parts__purchase_order_line_items__quantity',
filter=order_filter,
distinct=True
), Decimal(0)) - Coalesce(Sum(
'supplier_parts__purchase_order_line_items__received',
filter=order_filter,
distinct=True
), Decimal(0)),
building=Coalesce(
Sum('builds__quantity', filter=build_filter, distinct=True), Decimal(0)
SubquerySum('builds__quantity', filter=build_filter),
Decimal(0),
)
)
# Filter to limit orders to "open"
order_filter = Q(
order__status__in=PurchaseOrderStatus.OPEN
)
# Annotate with the total 'on order' quantity
queryset = queryset.annotate(
ordering=Coalesce(
SubquerySum('supplier_parts__purchase_order_line_items__quantity', filter=order_filter),
Decimal(0),
) - Coalesce(
SubquerySum('supplier_parts__purchase_order_line_items__received', filter=order_filter),
Decimal(0),
)
)
@ -231,6 +251,7 @@ class PartSerializer(InvenTreeModelSerializer):
in_stock = serializers.FloatField(read_only=True)
ordering = serializers.FloatField(read_only=True)
building = serializers.FloatField(read_only=True)
stock_item_count = serializers.IntegerField(read_only=True)
image = serializers.CharField(source='get_image_url', read_only=True)
thumbnail = serializers.CharField(source='get_thumbnail_url', read_only=True)
@ -273,6 +294,7 @@ class PartSerializer(InvenTreeModelSerializer):
'revision',
'salable',
'starred',
'stock_item_count',
'thumbnail',
'trackable',
'units',

View File

@ -15,14 +15,14 @@
{% endif %}
<p>
<div class='btn-group action-buttons'>
<button class='btn btn-default' id='cat-create' title='Create new part category'>
<button class='btn btn-default' id='cat-create' title='{% trans "Create new part category" %}'>
<span class='fas fa-plus-circle icon-green'/>
</button>
{% if category %}
<button class='btn btn-default' id='cat-edit' title='Edit part category'>
<button class='btn btn-default' id='cat-edit' title='{% trans "Edit part category" %}'>
<span class='fas fa-edit icon-blue'/>
</button>
<button class='btn btn-default' id='cat-delete' title='Delete part category'>
<button class='btn btn-default' id='cat-delete' title='{% trans "Delete part category" %}'>
<span class='fas fa-trash-alt icon-red'/>
</button>
{% endif %}
@ -97,14 +97,14 @@
<div id='button-toolbar'>
<div class='button-toolbar container-fluid' style="float: right;">
<button class='btn btn-default' id='part-export' title='Export Part Data'>Export</button>
<button class='btn btn-default' id='part-export' title='{% trans "Export Part Data" %}'>{% trans "Export" %}</button>
<button class='btn btn-success' id='part-create'>New Part</button>
<div class='btn dropdown'>
<button id='part-options' class='btn btn-primary dropdown-toggle' type='button' data-toggle="dropdown">Options<span class='caret'></span></button>
<button id='part-options' class='btn btn-primary dropdown-toggle' type='button' data-toggle="dropdown">{% trans "Options" %}<span class='caret'></span></button>
<ul class='dropdown-menu'>
<li><a href='#' id='multi-part-category' title='Set category'>Set Category</a></li>
<li><a href='#' id='multi-part-order' title='Order parts'>Order Parts</a></li>
<li><a href='#' id='multi-part-export' title='Export'>Export Data</a></li>
<li><a href='#' id='multi-part-category' title='{% trans "Set category" %}'>{% trans "Set Category" %}</a></li>
<li><a href='#' id='multi-part-order' title='{% trans "Order parts" %}'>{% trans "Order Parts" %}</a></li>
<li><a href='#' id='multi-part-export' title='{% trans "Export" %}'>{% trans "Export Data" %}</a></li>
</ul>
</div>
<div class='filter-list' id='filter-list-parts'>
@ -148,14 +148,14 @@
secondary: [
{
field: 'default_location',
label: 'New Location',
title: 'Create new location',
label: '{% trans "New Location" %}',
title: '{% trans "Create new location" %}',
url: "{% url 'stock-location-create' %}",
},
{
field: 'parent',
label: 'New Category',
title: 'Create new category',
label: '{% trans "New Category" %}',
title: '{% trans "Create new category" %}',
url: "{% url 'category-create' %}",
},
]
@ -183,14 +183,14 @@
secondary: [
{
field: 'category',
label: 'New Category',
title: 'Create new Part Category',
label: '{% trans "New Category" %}',
title: '{% trans "Create new Part Category" %}',
url: "{% url 'category-create' %}",
},
{
field: 'default_location',
label: 'New Location',
title: 'Create new Stock Location',
label: '{% trans "New Location" %}',
title: '{% trans "Create new Stock Location" %}',
url: "{% url 'stock-location-create' %}",
}
]
@ -216,10 +216,12 @@
{% endif %}
$('#cat-delete').click(function() {
launchModalForm("{% url 'category-delete' category.id %}",
{
redirect: redirect
});
launchModalForm(
"{% url 'category-delete' category.id %}",
{
redirect: redirect
}
);
});
{% endif %}

View File

@ -1,8 +1,15 @@
from rest_framework.test import APITestCase
from rest_framework import status
from django.urls import reverse
from django.contrib.auth import get_user_model
from part.models import Part
from stock.models import StockItem
from company.models import Company
from InvenTree.status_codes import StockStatus
class PartAPITest(APITestCase):
"""
@ -213,3 +220,77 @@ class PartAPITest(APITestCase):
)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
class PartAPIAggregationTest(APITestCase):
"""
Tests to ensure that the various aggregation annotations are working correctly...
"""
fixtures = [
'category',
'company',
'part',
'location',
'bom',
'test_templates',
]
def setUp(self):
# Create a user for auth
User = get_user_model()
User.objects.create_user('testuser', 'test@testing.com', 'password')
self.client.login(username='testuser', password='password')
# Add a new part
self.part = Part.objects.create(
name='Banana',
)
# Create some stock items associated with the part
# First create 600 units which are OK
StockItem.objects.create(part=self.part, quantity=100)
StockItem.objects.create(part=self.part, quantity=200)
StockItem.objects.create(part=self.part, quantity=300)
# Now create another 400 units which are LOST
StockItem.objects.create(part=self.part, quantity=400, status=StockStatus.LOST)
def get_part_data(self):
url = reverse('api-part-list')
response = self.client.get(url, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
for part in response.data:
if part['pk'] == self.part.pk:
return part
# We should never get here!
self.assertTrue(False)
def test_stock_quantity(self):
"""
Simple test for the stock quantity
"""
data = self.get_part_data()
self.assertEqual(data['in_stock'], 600)
self.assertEqual(data['stock_item_count'], 4)
# Add some more stock items!!
for i in range(100):
StockItem.objects.create(part=self.part, quantity=5)
# Add another stock item which is assigned to a customer (and shouldn't count)
customer = Company.objects.get(pk=4)
StockItem.objects.create(part=self.part, quantity=9999, customer=customer)
data = self.get_part_data()
self.assertEqual(data['in_stock'], 1100)
self.assertEqual(data['stock_item_count'], 105)

View File

@ -9,9 +9,12 @@ from .models import StockItemTracking
from .models import StockItemAttachment
from .models import StockItemTestResult
from django.db.models import Sum, Count
from django.db.models.functions import Coalesce
from sql_util.utils import SubquerySum, SubqueryCount
from decimal import Decimal
from company.serializers import SupplierPartSerializer
from part.serializers import PartBriefSerializer
from InvenTree.serializers import UserSerializerBrief, InvenTreeModelSerializer
@ -90,11 +93,18 @@ class StockItemSerializer(InvenTreeModelSerializer):
performing database queries as efficiently as possible.
"""
# Annotate the queryset with the total allocated to sales orders
queryset = queryset.annotate(
allocated=Coalesce(
Sum('sales_order_allocations__quantity', distinct=True), 0) + Coalesce(
Sum('allocations__quantity', distinct=True), 0),
tracking_items=Count('tracking_info'),
SubquerySum('sales_order_allocations__quantity'), Decimal(0)
) + Coalesce(
SubquerySum('allocations__quantity'), Decimal(0)
)
)
# Annotate the queryset with the number of tracking items
queryset = queryset.annotate(
tracking_items=SubqueryCount('tracking_info')
)
return queryset

View File

@ -21,6 +21,73 @@ function loadCompanyTable(table, url, options={}) {
setupFilterList("company", $(table));
var columns = [
{
field: 'pk',
title: 'ID',
visible: false,
switchable: false,
},
{
field: 'name',
title: '{% trans "Company" %}',
sortable: true,
switchable: false,
formatter: function(value, row, index, field) {
var html = imageHoverIcon(row.image) + renderLink(value, row.url);
if (row.is_customer) {
html += `<span title='{% trans "Customer" %}' class='fas fa-user-tie label-right'></span>`;
}
if (row.is_manufacturer) {
html += `<span title='{% trans "Manufacturer" %}' class='fas fa-industry label-right'></span>`;
}
if (row.is_supplier) {
html += `<span title='{% trans "Supplier" %}' class='fas fa-building label-right'></span>`;
}
return html;
}
},
{
field: 'description',
title: '{% trans "Description" %}',
sortable: true,
},
{
field: 'website',
title: '{% trans "Website" %}',
formatter: function(value, row, index, field) {
if (value) {
return renderLink(value, value);
}
return '';
}
},
];
if (options.pagetype == 'suppliers') {
columns.push({
sortable: true,
field: 'parts_supplied',
title: '{% trans "Parts Supplied" %}',
formatter: function(value, row) {
return renderLink(value, `/company/${row.pk}/parts/`);
}
});
} else if (options.pagetype == 'manufacturers') {
columns.push({
sortable: true,
field: 'parts_manufactured',
title: '{% trans "Parts Manufactured" %}',
formatter: function(value, row) {
return renderLink(value, `/company/${row.pk}/parts/`);
}
});
}
$(table).inventreeTable({
url: url,
method: 'get',
@ -28,53 +95,8 @@ function loadCompanyTable(table, url, options={}) {
groupBy: false,
formatNoMatches: function() { return "{% trans "No company information found" %}"; },
showColumns: true,
name: 'company',
columns: [
{
field: 'pk',
title: 'ID',
visible: false,
switchable: false,
},
{
field: 'name',
title: '{% trans "Company" %}',
sortable: true,
switchable: false,
formatter: function(value, row, index, field) {
var html = imageHoverIcon(row.image) + renderLink(value, row.url);
if (row.is_customer) {
html += `<span title='{% trans "Customer" %}' class='fas fa-user-tie label-right'></span>`;
}
if (row.is_manufacturer) {
html += `<span title='{% trans "Manufacturer" %}' class='fas fa-industry label-right'></span>`;
}
if (row.is_supplier) {
html += `<span title='{% trans "Supplier" %}' class='fas fa-building label-right'></span>`;
}
return html;
}
},
{
field: 'description',
title: '{% trans "Description" %}',
sortable: true,
},
{
field: 'website',
title: '{% trans "Website" %}',
formatter: function(value, row, index, field) {
if (value) {
return renderLink(value, value);
}
return '';
}
},
],
name: options.pagetype || 'company',
columns: columns,
});
}

View File

@ -122,6 +122,9 @@ function loadPartVariantTable(table, partId, options) {
{
field: 'in_stock',
title: '{% trans "Stock" %}',
formatter: function(value, row) {
return renderLink(value, `/part/${row.pk}/stock/`);
}
}
];

View File

@ -7,6 +7,7 @@ django-dbbackup==3.3.0 # Database backup / restore functionality
django-cors-headers==3.2.0 # CORS headers extension for DRF
django_filter==2.2.0 # Extended filtering options
django-mptt==0.11.0 # Modified Preorder Tree Traversal
django-sql-utils==0.5.0 # Advanced query annotation / aggregation
django-markdownx==3.0.1 # Markdown form fields
django-markdownify==0.8.0 # Markdown rendering
coreapi==2.3.0 # API documentation